blob: dc8b5bf12e10ad0e37f31d3185a5396acf4a1109 [file] [log] [blame]
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Ta-wei Yen87c49842016-05-13 21:19:52 -070019import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
20
Ta-wei Yen30a69c82016-12-27 14:52:32 -080021import android.Manifest.permission;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070022import android.app.AppOpsManager;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080023import android.app.PendingIntent;
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -070024import android.content.ComponentName;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070025import android.content.Context;
26import android.content.Intent;
Derek Tan97ebb422014-09-05 16:55:38 -070027import android.content.SharedPreferences;
Derek Tan740e1672017-06-27 14:56:27 -070028import android.content.pm.ComponentInfo;
Amith Yamasani6e118872016-02-19 12:53:51 -080029import android.content.pm.PackageInfo;
Shishir Agrawal60f9c952014-06-23 12:00:43 -070030import android.content.pm.PackageManager;
Jack Yu84291ec2017-05-26 16:07:50 -070031import android.net.NetworkStats;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070032import android.net.Uri;
33import android.os.AsyncResult;
34import android.os.Binder;
35import android.os.Bundle;
36import android.os.Handler;
yinxu504e1392017-04-12 16:03:22 -070037import android.os.IBinder;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070038import android.os.Looper;
39import android.os.Message;
yinxu504e1392017-04-12 16:03:22 -070040import android.os.Messenger;
Tyler Gunn65d45c22017-06-05 11:22:26 -070041import android.os.PersistableBundle;
Brad Ebinger7e934f52017-12-14 14:26:15 -080042import android.os.RemoteException;
Adam Lesinski903a54c2016-04-11 14:49:52 -070043import android.os.ResultReceiver;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070044import android.os.ServiceManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070045import android.os.ShellCallback;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070046import android.os.UserHandle;
Stuart Scott981d8582015-04-21 14:09:50 -070047import android.os.UserManager;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070048import android.os.WorkSource;
Derek Tan97ebb422014-09-05 16:55:38 -070049import android.preference.PreferenceManager;
Ihab Awadf2177b72013-11-25 13:33:23 -080050import android.provider.Settings;
Meng Wang1a7c35a2016-05-05 20:56:15 -070051import android.service.carrier.CarrierIdentifier;
Santos Cordon7a1885b2015-02-03 11:15:19 -080052import android.telecom.PhoneAccount;
Nancy Chen31f9ba12016-01-06 11:42:12 -080053import android.telecom.PhoneAccountHandle;
Andrew Lee9431b832015-03-09 18:46:45 -070054import android.telecom.TelecomManager;
Junda Liu12f7d802015-05-01 12:06:44 -070055import android.telephony.CarrierConfigManager;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070056import android.telephony.CellInfo;
Sooraj Sasindran9a909312016-07-18 11:57:25 -070057import android.telephony.ClientRequestStats;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -070058import android.telephony.IccOpenLogicalChannelResponse;
Hall Liu1aa510f2017-11-22 17:40:08 -080059import android.telephony.LocationAccessPolicy;
Ta-wei Yen87c49842016-05-13 21:19:52 -070060import android.telephony.ModemActivityInfo;
Jake Hambye994d462014-02-03 13:10:13 -080061import android.telephony.NeighboringCellInfo;
yinxu504e1392017-04-12 16:03:22 -070062import android.telephony.NetworkScanRequest;
Wink Saville5d475dd2014-10-17 15:00:58 -070063import android.telephony.RadioAccessFamily;
Tyler Gunn65d45c22017-06-05 11:22:26 -070064import android.telephony.Rlog;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070065import android.telephony.ServiceState;
Nathan Harold46b42aa2017-03-10 19:38:22 -080066import android.telephony.SignalStrength;
Jack Yu84291ec2017-05-26 16:07:50 -070067import android.telephony.SmsManager;
Wink Saville0f3b5fc2014-11-11 08:40:49 -080068import android.telephony.SubscriptionInfo;
Jeff Sharkey85190e62014-12-05 09:40:12 -080069import android.telephony.SubscriptionManager;
Sanket Padawe99ef1e32016-05-18 16:12:33 -070070import android.telephony.TelephonyHistogram;
Ta-wei Yenb6929602016-05-24 15:48:27 -070071import android.telephony.TelephonyManager;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +000072import android.telephony.UiccSlotInfo;
Tyler Gunn65d45c22017-06-05 11:22:26 -070073import android.telephony.UssdResponse;
Ta-wei Yenb6929602016-05-24 15:48:27 -070074import android.telephony.VisualVoicemailSmsFilterSettings;
Brad Ebingera12246d2018-01-16 09:39:35 -080075import android.telephony.ims.aidl.IImsConfig;
76import android.telephony.ims.aidl.IImsMmTelFeature;
77import android.telephony.ims.aidl.IImsRcsFeature;
78import android.telephony.ims.aidl.IImsRegistration;
Brad Ebingere21f25f2018-02-08 16:11:32 -080079import android.telephony.ims.stub.ImsRegistrationImplBase;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070080import android.text.TextUtils;
Jeff Sharkey85190e62014-12-05 09:40:12 -080081import android.util.ArraySet;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070082import android.util.Log;
Jake Hambye994d462014-02-03 13:10:13 -080083import android.util.Pair;
Jeff Sharkey85190e62014-12-05 09:40:12 -080084import android.util.Slog;
Ta-wei Yen30a69c82016-12-27 14:52:32 -080085
Andrew Lee312e8172014-10-23 17:01:36 -070086import com.android.ims.ImsManager;
Brad Ebinger34bef922017-11-09 10:27:08 -080087import com.android.ims.internal.IImsServiceFeatureCallback;
Shishir Agrawal566b7612013-10-28 14:41:00 -070088import com.android.internal.telephony.CallManager;
Tyler Gunn52dcf772017-04-26 11:30:31 -070089import com.android.internal.telephony.CallStateException;
Shishir Agrawal302c8692015-06-19 13:49:39 -070090import com.android.internal.telephony.CellNetworkScanResult;
Shishir Agrawal566b7612013-10-28 14:41:00 -070091import com.android.internal.telephony.CommandException;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070092import com.android.internal.telephony.DefaultPhoneNotifier;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070093import com.android.internal.telephony.ITelephony;
Jake Hambye994d462014-02-03 13:10:13 -080094import com.android.internal.telephony.IccCard;
Jack Yu8e4fdc22018-04-13 14:05:37 -070095import com.android.internal.telephony.LocaleTracker;
Narayan Kamath1c496c22015-04-16 14:40:19 +010096import com.android.internal.telephony.MccTable;
yinxub1bed742017-04-17 11:45:04 -070097import com.android.internal.telephony.NetworkScanRequestTracker;
Shishir Agrawal302c8692015-06-19 13:49:39 -070098import com.android.internal.telephony.OperatorInfo;
Santos Cordon7d4ddf62013-07-10 11:58:08 -070099import com.android.internal.telephony.Phone;
Nathan Harolda667c152016-12-14 11:27:20 -0800100import com.android.internal.telephony.PhoneConstantConversions;
Ta-wei Yen87c49842016-05-13 21:19:52 -0700101import com.android.internal.telephony.PhoneConstants;
Wink Saville36469e72014-06-11 15:17:00 -0700102import com.android.internal.telephony.PhoneFactory;
Wink Saville5d475dd2014-10-17 15:00:58 -0700103import com.android.internal.telephony.ProxyController;
Sanket Padawe99ef1e32016-05-18 16:12:33 -0700104import com.android.internal.telephony.RIL;
Svet Ganovb320e182015-04-16 12:30:10 -0700105import com.android.internal.telephony.RILConstants;
Jack Yu8e4fdc22018-04-13 14:05:37 -0700106import com.android.internal.telephony.ServiceStateTracker;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800107import com.android.internal.telephony.SubscriptionController;
Jeff Davidsond9a1bb52018-02-13 18:17:36 -0800108import com.android.internal.telephony.TelephonyPermissions;
Derek Tan740e1672017-06-27 14:56:27 -0700109import com.android.internal.telephony.euicc.EuiccConnector;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700110import com.android.internal.telephony.uicc.IccIoResult;
111import com.android.internal.telephony.uicc.IccUtils;
Nathan Haroldb3014052017-01-25 15:57:32 -0800112import com.android.internal.telephony.uicc.SIMRecords;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700113import com.android.internal.telephony.uicc.UiccCard;
Nathan Haroldb3014052017-01-25 15:57:32 -0800114import com.android.internal.telephony.uicc.UiccCardApplication;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700115import com.android.internal.telephony.uicc.UiccController;
Jeff Davidsond9a1bb52018-02-13 18:17:36 -0800116import com.android.internal.telephony.uicc.UiccProfile;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000117import com.android.internal.telephony.uicc.UiccSlot;
fionaxu7ed723d2017-05-30 18:58:54 -0700118import com.android.internal.telephony.util.VoicemailNotificationSettingsUtil;
Jake Hambye994d462014-02-03 13:10:13 -0800119import com.android.internal.util.HexDump;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700120import com.android.phone.vvm.PhoneAccountHandleConverter;
Ta-wei Yen527a9c02017-01-06 15:29:25 -0800121import com.android.phone.vvm.RemoteVvmTaskManager;
Ta-wei Yenc9df0432017-04-17 17:09:07 -0700122import com.android.phone.vvm.VisualVoicemailSettingsUtil;
Ta-wei Yenc8905312017-03-28 11:14:45 -0700123import com.android.phone.vvm.VisualVoicemailSmsFilterConfig;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800124
Ta-wei Yenc236d6b2016-06-21 13:33:12 -0700125import java.io.FileDescriptor;
126import java.io.PrintWriter;
Ta-wei Yen30a69c82016-12-27 14:52:32 -0800127import java.nio.charset.StandardCharsets;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700128import java.util.ArrayList;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800129import java.util.Arrays;
Jake Hambye994d462014-02-03 13:10:13 -0800130import java.util.List;
Narayan Kamath1c496c22015-04-16 14:40:19 +0100131import java.util.Locale;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800132import java.util.Map;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700133
134/**
135 * Implementation of the ITelephony interface.
136 */
Santos Cordon117fee72014-05-16 17:56:12 -0700137public class PhoneInterfaceManager extends ITelephony.Stub {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700138 private static final String LOG_TAG = "PhoneInterfaceManager";
139 private static final boolean DBG = (PhoneGlobals.DBG_LEVEL >= 2);
140 private static final boolean DBG_LOC = false;
Jeff Sharkey85190e62014-12-05 09:40:12 -0800141 private static final boolean DBG_MERGE = false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700142
143 // Message codes used with mMainThreadHandler
144 private static final int CMD_HANDLE_PIN_MMI = 1;
145 private static final int CMD_HANDLE_NEIGHBORING_CELL = 2;
146 private static final int EVENT_NEIGHBORING_CELL_DONE = 3;
147 private static final int CMD_ANSWER_RINGING_CALL = 4;
148 private static final int CMD_END_CALL = 5; // not used yet
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700149 private static final int CMD_TRANSMIT_APDU_LOGICAL_CHANNEL = 7;
150 private static final int EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE = 8;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700151 private static final int CMD_OPEN_CHANNEL = 9;
152 private static final int EVENT_OPEN_CHANNEL_DONE = 10;
153 private static final int CMD_CLOSE_CHANNEL = 11;
154 private static final int EVENT_CLOSE_CHANNEL_DONE = 12;
Jake Hambye994d462014-02-03 13:10:13 -0800155 private static final int CMD_NV_READ_ITEM = 13;
156 private static final int EVENT_NV_READ_ITEM_DONE = 14;
157 private static final int CMD_NV_WRITE_ITEM = 15;
158 private static final int EVENT_NV_WRITE_ITEM_DONE = 16;
159 private static final int CMD_NV_WRITE_CDMA_PRL = 17;
160 private static final int EVENT_NV_WRITE_CDMA_PRL_DONE = 18;
161 private static final int CMD_NV_RESET_CONFIG = 19;
162 private static final int EVENT_NV_RESET_CONFIG_DONE = 20;
Jake Hamby7c27be32014-03-03 13:25:59 -0800163 private static final int CMD_GET_PREFERRED_NETWORK_TYPE = 21;
164 private static final int EVENT_GET_PREFERRED_NETWORK_TYPE_DONE = 22;
165 private static final int CMD_SET_PREFERRED_NETWORK_TYPE = 23;
166 private static final int EVENT_SET_PREFERRED_NETWORK_TYPE_DONE = 24;
Sailesh Nepal35b59452014-03-06 09:26:56 -0800167 private static final int CMD_SEND_ENVELOPE = 25;
168 private static final int EVENT_SEND_ENVELOPE_DONE = 26;
Shuo Qian74b16b12018-04-27 01:32:07 +0000169 private static final int CMD_INVOKE_OEM_RIL_REQUEST_RAW = 27;
170 private static final int EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE = 28;
Derek Tan6b088ee2014-09-05 14:15:18 -0700171 private static final int CMD_TRANSMIT_APDU_BASIC_CHANNEL = 29;
172 private static final int EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE = 30;
173 private static final int CMD_EXCHANGE_SIM_IO = 31;
174 private static final int EVENT_EXCHANGE_SIM_IO_DONE = 32;
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800175 private static final int CMD_SET_VOICEMAIL_NUMBER = 33;
176 private static final int EVENT_SET_VOICEMAIL_NUMBER_DONE = 34;
Stuart Scott54788802015-03-30 13:18:01 -0700177 private static final int CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC = 35;
178 private static final int EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE = 36;
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700179 private static final int CMD_GET_MODEM_ACTIVITY_INFO = 37;
180 private static final int EVENT_GET_MODEM_ACTIVITY_INFO_DONE = 38;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700181 private static final int CMD_PERFORM_NETWORK_SCAN = 39;
182 private static final int EVENT_PERFORM_NETWORK_SCAN_DONE = 40;
183 private static final int CMD_SET_NETWORK_SELECTION_MODE_MANUAL = 41;
184 private static final int EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE = 42;
Meng Wang1a7c35a2016-05-05 20:56:15 -0700185 private static final int CMD_SET_ALLOWED_CARRIERS = 43;
186 private static final int EVENT_SET_ALLOWED_CARRIERS_DONE = 44;
187 private static final int CMD_GET_ALLOWED_CARRIERS = 45;
188 private static final int EVENT_GET_ALLOWED_CARRIERS_DONE = 46;
pkanwar32d516d2016-10-14 19:37:38 -0700189 private static final int CMD_HANDLE_USSD_REQUEST = 47;
Nathan Haroldb3014052017-01-25 15:57:32 -0800190 private static final int CMD_GET_FORBIDDEN_PLMNS = 48;
191 private static final int EVENT_GET_FORBIDDEN_PLMNS_DONE = 49;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000192 private static final int CMD_SWITCH_SLOTS = 50;
193 private static final int EVENT_SWITCH_SLOTS_DONE = 51;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700194
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -0800195 // Parameters of select command.
196 private static final int SELECT_COMMAND = 0xA4;
197 private static final int SELECT_P1 = 0x04;
198 private static final int SELECT_P2 = 0;
199 private static final int SELECT_P3 = 0x10;
200
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700201 /** The singleton instance. */
202 private static PhoneInterfaceManager sInstance;
203
Wink Saville3ab207e2014-11-20 13:07:20 -0800204 private PhoneGlobals mApp;
205 private Phone mPhone;
206 private CallManager mCM;
Stuart Scott981d8582015-04-21 14:09:50 -0700207 private UserManager mUserManager;
Wink Saville3ab207e2014-11-20 13:07:20 -0800208 private AppOpsManager mAppOps;
209 private MainThreadHandler mMainThreadHandler;
Wink Savilleac1bdfd2014-11-20 23:04:44 -0800210 private SubscriptionController mSubscriptionController;
Wink Saville3ab207e2014-11-20 13:07:20 -0800211 private SharedPreferences mTelephonySharedPreferences;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700212
Derek Tan97ebb422014-09-05 16:55:38 -0700213 private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
214 private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
Jeff Sharkey85190e62014-12-05 09:40:12 -0800215 private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
Derek Tan89e89d42014-07-08 17:00:10 -0700216
Derek Tan740e1672017-06-27 14:56:27 -0700217 // The AID of ISD-R.
218 private static final String ISDR_AID = "A0000005591010FFFFFFFF8900000100";
219
yinxub1bed742017-04-17 11:45:04 -0700220 private NetworkScanRequestTracker mNetworkScanRequestTracker;
221
David Kelly5e06a7f2018-03-12 14:10:59 +0000222 private static final int TYPE_ALLOCATION_CODE_LENGTH = 8;
223 private static final int MANUFACTURER_CODE_LENGTH = 8;
224
Derek Tan89e89d42014-07-08 17:00:10 -0700225 /**
Shishir Agrawal566b7612013-10-28 14:41:00 -0700226 * A request object to use for transmitting data to an ICC.
227 */
228 private static final class IccAPDUArgument {
229 public int channel, cla, command, p1, p2, p3;
230 public String data;
231
232 public IccAPDUArgument(int channel, int cla, int command,
233 int p1, int p2, int p3, String data) {
234 this.channel = channel;
235 this.cla = cla;
236 this.command = command;
237 this.p1 = p1;
238 this.p2 = p2;
239 this.p3 = p3;
240 this.data = data;
241 }
242 }
243
244 /**
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700245 * A request object to use for transmitting data to an ICC.
246 */
247 private static final class ManualNetworkSelectionArgument {
248 public OperatorInfo operatorInfo;
249 public boolean persistSelection;
250
251 public ManualNetworkSelectionArgument(OperatorInfo operatorInfo, boolean persistSelection) {
252 this.operatorInfo = operatorInfo;
253 this.persistSelection = persistSelection;
254 }
255 }
256
257 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700258 * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
259 * request after sending. The main thread will notify the request when it is complete.
260 */
261 private static final class MainThreadRequest {
262 /** The argument to use for the request */
263 public Object argument;
264 /** The result of the request that is run on the main thread */
265 public Object result;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800266 // The subscriber id that this request applies to. Defaults to
267 // SubscriptionManager.INVALID_SUBSCRIPTION_ID
268 public Integer subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700269
270 public MainThreadRequest(Object argument) {
271 this.argument = argument;
272 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800273
274 public MainThreadRequest(Object argument, Integer subId) {
275 this.argument = argument;
Sanket Padawe56e75a32016-02-08 12:18:19 -0800276 if (subId != null) {
277 this.subId = subId;
278 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800279 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700280 }
281
Sailesh Nepalcc0375f2013-11-13 09:15:18 -0800282 private static final class IncomingThirdPartyCallArgs {
283 public final ComponentName component;
284 public final String callId;
285 public final String callerDisplayName;
286
287 public IncomingThirdPartyCallArgs(ComponentName component, String callId,
288 String callerDisplayName) {
289 this.component = component;
290 this.callId = callId;
291 this.callerDisplayName = callerDisplayName;
292 }
293 }
294
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700295 /**
296 * A handler that processes messages on the main thread in the phone process. Since many
297 * of the Phone calls are not thread safe this is needed to shuttle the requests from the
298 * inbound binder threads to the main thread in the phone process. The Binder thread
299 * may provide a {@link MainThreadRequest} object in the msg.obj field that they are waiting
300 * on, which will be notified when the operation completes and will contain the result of the
301 * request.
302 *
303 * <p>If a MainThreadRequest object is provided in the msg.obj field,
304 * note that request.result must be set to something non-null for the calling thread to
305 * unblock.
306 */
307 private final class MainThreadHandler extends Handler {
308 @Override
309 public void handleMessage(Message msg) {
310 MainThreadRequest request;
311 Message onCompleted;
312 AsyncResult ar;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800313 UiccCard uiccCard;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700314 IccAPDUArgument iccArgument;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700315
316 switch (msg.what) {
pkanwar32d516d2016-10-14 19:37:38 -0700317 case CMD_HANDLE_USSD_REQUEST: {
318 request = (MainThreadRequest) msg.obj;
319 final Phone phone = getPhoneFromRequest(request);
320 Pair<String, ResultReceiver> ussdObject = (Pair) request.argument;
321 String ussdRequest = ussdObject.first;
322 ResultReceiver wrappedCallback = ussdObject.second;
Tyler Gunn65d45c22017-06-05 11:22:26 -0700323
324 if (!isUssdApiAllowed(request.subId)) {
325 // Carrier does not support use of this API, return failure.
326 Rlog.w(LOG_TAG, "handleUssdRequest: carrier does not support USSD apis.");
327 UssdResponse response = new UssdResponse(ussdRequest, null);
328 Bundle returnData = new Bundle();
329 returnData.putParcelable(TelephonyManager.USSD_RESPONSE, response);
330 wrappedCallback.send(TelephonyManager.USSD_RETURN_FAILURE, returnData);
331
332 request.result = true;
333 synchronized (request) {
334 request.notifyAll();
335 }
336 return;
337 }
338
Tyler Gunn52dcf772017-04-26 11:30:31 -0700339 try {
340 request.result = phone != null ?
341 phone.handleUssdRequest(ussdRequest, wrappedCallback)
342 : false;
343 } catch (CallStateException cse) {
344 request.result = false;
345 }
pkanwar32d516d2016-10-14 19:37:38 -0700346 // Wake up the requesting thread
347 synchronized (request) {
348 request.notifyAll();
349 }
350 break;
351 }
352
Yorke Lee716f67e2015-06-17 15:39:16 -0700353 case CMD_HANDLE_PIN_MMI: {
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700354 request = (MainThreadRequest) msg.obj;
Yorke Lee716f67e2015-06-17 15:39:16 -0700355 final Phone phone = getPhoneFromRequest(request);
356 request.result = phone != null ?
357 getPhoneFromRequest(request).handlePinMmi((String) request.argument)
358 : false;
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700359 // Wake up the requesting thread
360 synchronized (request) {
361 request.notifyAll();
362 }
363 break;
Yorke Lee716f67e2015-06-17 15:39:16 -0700364 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700365
366 case CMD_HANDLE_NEIGHBORING_CELL:
367 request = (MainThreadRequest) msg.obj;
368 onCompleted = obtainMessage(EVENT_NEIGHBORING_CELL_DONE,
369 request);
Sooraj Sasindran9a909312016-07-18 11:57:25 -0700370 mPhone.getNeighboringCids(onCompleted, (WorkSource)request.argument);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700371 break;
372
373 case EVENT_NEIGHBORING_CELL_DONE:
374 ar = (AsyncResult) msg.obj;
375 request = (MainThreadRequest) ar.userObj;
376 if (ar.exception == null && ar.result != null) {
377 request.result = ar.result;
378 } else {
379 // create an empty list to notify the waiting thread
Jake Hambye994d462014-02-03 13:10:13 -0800380 request.result = new ArrayList<NeighboringCellInfo>(0);
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700381 }
382 // Wake up the requesting thread
383 synchronized (request) {
384 request.notifyAll();
385 }
386 break;
387
388 case CMD_ANSWER_RINGING_CALL:
Wink Saville08874612014-08-31 19:19:58 -0700389 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800390 int answer_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700391 answerRingingCallInternal(answer_subId);
Mengjun Lengb3369682017-10-19 18:39:20 +0800392 request.result = ""; // dummy result for notifying the waiting thread
393 // Wake up the requesting thread
394 synchronized (request) {
395 request.notifyAll();
396 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700397 break;
398
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700399 case CMD_END_CALL:
400 request = (MainThreadRequest) msg.obj;
Stuart Scott584921c2015-01-15 17:10:34 -0800401 int end_subId = request.subId;
Wink Saville08874612014-08-31 19:19:58 -0700402 final boolean hungUp;
Anthony Leeae4e36d2015-05-21 07:17:46 -0700403 Phone phone = getPhone(end_subId);
404 if (phone == null) {
405 if (DBG) log("CMD_END_CALL: no phone for id: " + end_subId);
406 break;
407 }
408 int phoneType = phone.getPhoneType();
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700409 if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
410 // CDMA: If the user presses the Power button we treat it as
411 // ending the complete call session
Wink Saville08874612014-08-31 19:19:58 -0700412 hungUp = PhoneUtils.hangupRingingAndActive(getPhone(end_subId));
Santos Cordon7d4ddf62013-07-10 11:58:08 -0700413 } else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
414 // GSM: End the call as per the Phone state
415 hungUp = PhoneUtils.hangup(mCM);
416 } else {
417 throw new IllegalStateException("Unexpected phone type: " + phoneType);
418 }
419 if (DBG) log("CMD_END_CALL: " + (hungUp ? "hung up!" : "no call to hang up"));
420 request.result = hungUp;
421 // Wake up the requesting thread
422 synchronized (request) {
423 request.notifyAll();
424 }
425 break;
426
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700427 case CMD_TRANSMIT_APDU_LOGICAL_CHANNEL:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700428 request = (MainThreadRequest) msg.obj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700429 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800430 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700431 if (uiccCard == null) {
432 loge("iccTransmitApduLogicalChannel: No UICC");
433 request.result = new IccIoResult(0x6F, 0, (byte[])null);
434 synchronized (request) {
435 request.notifyAll();
436 }
437 } else {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700438 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE,
439 request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700440 uiccCard.iccTransmitApduLogicalChannel(
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700441 iccArgument.channel, iccArgument.cla, iccArgument.command,
442 iccArgument.p1, iccArgument.p2, iccArgument.p3, iccArgument.data,
Shishir Agrawal566b7612013-10-28 14:41:00 -0700443 onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700444 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700445 break;
446
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700447 case EVENT_TRANSMIT_APDU_LOGICAL_CHANNEL_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700448 ar = (AsyncResult) msg.obj;
449 request = (MainThreadRequest) ar.userObj;
450 if (ar.exception == null && ar.result != null) {
451 request.result = ar.result;
452 } else {
453 request.result = new IccIoResult(0x6F, 0, (byte[])null);
454 if (ar.result == null) {
455 loge("iccTransmitApduLogicalChannel: Empty response");
Jake Hambye994d462014-02-03 13:10:13 -0800456 } else if (ar.exception instanceof CommandException) {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700457 loge("iccTransmitApduLogicalChannel: CommandException: " +
Jake Hambye994d462014-02-03 13:10:13 -0800458 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700459 } else {
460 loge("iccTransmitApduLogicalChannel: Unknown exception");
461 }
462 }
463 synchronized (request) {
464 request.notifyAll();
465 }
466 break;
467
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700468 case CMD_TRANSMIT_APDU_BASIC_CHANNEL:
469 request = (MainThreadRequest) msg.obj;
470 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800471 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700472 if (uiccCard == null) {
473 loge("iccTransmitApduBasicChannel: No UICC");
474 request.result = new IccIoResult(0x6F, 0, (byte[])null);
475 synchronized (request) {
476 request.notifyAll();
477 }
478 } else {
479 onCompleted = obtainMessage(EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE,
480 request);
481 uiccCard.iccTransmitApduBasicChannel(
482 iccArgument.cla, iccArgument.command, iccArgument.p1, iccArgument.p2,
483 iccArgument.p3, iccArgument.data, onCompleted);
484 }
485 break;
486
487 case EVENT_TRANSMIT_APDU_BASIC_CHANNEL_DONE:
488 ar = (AsyncResult) msg.obj;
489 request = (MainThreadRequest) ar.userObj;
490 if (ar.exception == null && ar.result != null) {
491 request.result = ar.result;
492 } else {
493 request.result = new IccIoResult(0x6F, 0, (byte[])null);
494 if (ar.result == null) {
495 loge("iccTransmitApduBasicChannel: Empty response");
496 } else if (ar.exception instanceof CommandException) {
497 loge("iccTransmitApduBasicChannel: CommandException: " +
498 ar.exception);
499 } else {
500 loge("iccTransmitApduBasicChannel: Unknown exception");
501 }
502 }
503 synchronized (request) {
504 request.notifyAll();
505 }
506 break;
507
508 case CMD_EXCHANGE_SIM_IO:
509 request = (MainThreadRequest) msg.obj;
510 iccArgument = (IccAPDUArgument) request.argument;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800511 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700512 if (uiccCard == null) {
513 loge("iccExchangeSimIO: No UICC");
514 request.result = new IccIoResult(0x6F, 0, (byte[])null);
515 synchronized (request) {
516 request.notifyAll();
517 }
518 } else {
519 onCompleted = obtainMessage(EVENT_EXCHANGE_SIM_IO_DONE,
520 request);
521 uiccCard.iccExchangeSimIO(iccArgument.cla, /* fileID */
522 iccArgument.command, iccArgument.p1, iccArgument.p2, iccArgument.p3,
523 iccArgument.data, onCompleted);
524 }
525 break;
526
527 case EVENT_EXCHANGE_SIM_IO_DONE:
528 ar = (AsyncResult) msg.obj;
529 request = (MainThreadRequest) ar.userObj;
530 if (ar.exception == null && ar.result != null) {
531 request.result = ar.result;
532 } else {
533 request.result = new IccIoResult(0x6f, 0, (byte[])null);
534 }
535 synchronized (request) {
536 request.notifyAll();
537 }
538 break;
539
Derek Tan4d5e5c12014-02-04 11:54:58 -0800540 case CMD_SEND_ENVELOPE:
541 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800542 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700543 if (uiccCard == null) {
544 loge("sendEnvelopeWithStatus: No UICC");
545 request.result = new IccIoResult(0x6F, 0, (byte[])null);
546 synchronized (request) {
547 request.notifyAll();
548 }
549 } else {
550 onCompleted = obtainMessage(EVENT_SEND_ENVELOPE_DONE, request);
551 uiccCard.sendEnvelopeWithStatus((String)request.argument, onCompleted);
552 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800553 break;
554
555 case EVENT_SEND_ENVELOPE_DONE:
556 ar = (AsyncResult) msg.obj;
557 request = (MainThreadRequest) ar.userObj;
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700558 if (ar.exception == null && ar.result != null) {
559 request.result = ar.result;
Derek Tan4d5e5c12014-02-04 11:54:58 -0800560 } else {
Shishir Agrawal9f9877d2014-03-14 09:36:27 -0700561 request.result = new IccIoResult(0x6F, 0, (byte[])null);
562 if (ar.result == null) {
563 loge("sendEnvelopeWithStatus: Empty response");
564 } else if (ar.exception instanceof CommandException) {
565 loge("sendEnvelopeWithStatus: CommandException: " +
566 ar.exception);
567 } else {
568 loge("sendEnvelopeWithStatus: exception:" + ar.exception);
569 }
Derek Tan4d5e5c12014-02-04 11:54:58 -0800570 }
571 synchronized (request) {
572 request.notifyAll();
573 }
574 break;
575
Shishir Agrawal566b7612013-10-28 14:41:00 -0700576 case CMD_OPEN_CHANNEL:
577 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800578 uiccCard = getUiccCardFromRequest(request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800579 Pair<String, Integer> openChannelArgs = (Pair<String, Integer>) request.argument;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700580 if (uiccCard == null) {
581 loge("iccOpenLogicalChannel: No UICC");
Shishir Agrawalfc0492a2016-02-17 11:15:33 -0800582 request.result = new IccOpenLogicalChannelResponse(-1,
583 IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE, null);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700584 synchronized (request) {
585 request.notifyAll();
586 }
587 } else {
588 onCompleted = obtainMessage(EVENT_OPEN_CHANNEL_DONE, request);
Ajay Nambid7454d32015-12-03 13:50:00 -0800589 uiccCard.iccOpenLogicalChannel(openChannelArgs.first,
590 openChannelArgs.second, onCompleted);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700591 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700592 break;
593
594 case EVENT_OPEN_CHANNEL_DONE:
595 ar = (AsyncResult) msg.obj;
596 request = (MainThreadRequest) ar.userObj;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700597 IccOpenLogicalChannelResponse openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700598 if (ar.exception == null && ar.result != null) {
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700599 int[] result = (int[]) ar.result;
600 int channelId = result[0];
601 byte[] selectResponse = null;
602 if (result.length > 1) {
603 selectResponse = new byte[result.length - 1];
604 for (int i = 1; i < result.length; ++i) {
605 selectResponse[i - 1] = (byte) result[i];
606 }
607 }
608 openChannelResp = new IccOpenLogicalChannelResponse(channelId,
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700609 IccOpenLogicalChannelResponse.STATUS_NO_ERROR, selectResponse);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700610 } else {
Shishir Agrawal566b7612013-10-28 14:41:00 -0700611 if (ar.result == null) {
612 loge("iccOpenLogicalChannel: Empty response");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700613 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700614 if (ar.exception != null) {
615 loge("iccOpenLogicalChannel: Exception: " + ar.exception);
616 }
617
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700618 int errorCode = IccOpenLogicalChannelResponse.STATUS_UNKNOWN_ERROR;
Junda Liua754ba12015-05-20 01:17:52 -0700619 if (ar.exception instanceof CommandException) {
620 CommandException.Error error =
621 ((CommandException) (ar.exception)).getCommandError();
622 if (error == CommandException.Error.MISSING_RESOURCE) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700623 errorCode = IccOpenLogicalChannelResponse.STATUS_MISSING_RESOURCE;
Junda Liua754ba12015-05-20 01:17:52 -0700624 } else if (error == CommandException.Error.NO_SUCH_ELEMENT) {
Shishir Agrawal527e8bf2014-08-25 08:54:56 -0700625 errorCode = IccOpenLogicalChannelResponse.STATUS_NO_SUCH_ELEMENT;
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -0700626 }
627 }
628 openChannelResp = new IccOpenLogicalChannelResponse(
629 IccOpenLogicalChannelResponse.INVALID_CHANNEL, errorCode, null);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700630 }
Shishir Agrawal82c8a462014-07-31 18:13:17 -0700631 request.result = openChannelResp;
Shishir Agrawal566b7612013-10-28 14:41:00 -0700632 synchronized (request) {
633 request.notifyAll();
634 }
635 break;
636
637 case CMD_CLOSE_CHANNEL:
638 request = (MainThreadRequest) msg.obj;
Shishir Agrawalc04d9752016-02-19 10:41:00 -0800639 uiccCard = getUiccCardFromRequest(request);
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700640 if (uiccCard == null) {
641 loge("iccCloseLogicalChannel: No UICC");
Yoshiaki Naka2e29d822016-09-02 19:27:39 +0900642 request.result = false;
Shishir Agrawaleb8771e2014-07-22 11:24:08 -0700643 synchronized (request) {
644 request.notifyAll();
645 }
646 } else {
647 onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
648 uiccCard.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
649 }
Shishir Agrawal566b7612013-10-28 14:41:00 -0700650 break;
651
652 case EVENT_CLOSE_CHANNEL_DONE:
Jake Hambye994d462014-02-03 13:10:13 -0800653 handleNullReturnEvent(msg, "iccCloseLogicalChannel");
654 break;
655
656 case CMD_NV_READ_ITEM:
657 request = (MainThreadRequest) msg.obj;
658 onCompleted = obtainMessage(EVENT_NV_READ_ITEM_DONE, request);
659 mPhone.nvReadItem((Integer) request.argument, onCompleted);
660 break;
661
662 case EVENT_NV_READ_ITEM_DONE:
Shishir Agrawal566b7612013-10-28 14:41:00 -0700663 ar = (AsyncResult) msg.obj;
664 request = (MainThreadRequest) ar.userObj;
Jake Hambye994d462014-02-03 13:10:13 -0800665 if (ar.exception == null && ar.result != null) {
666 request.result = ar.result; // String
Shishir Agrawal566b7612013-10-28 14:41:00 -0700667 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800668 request.result = "";
669 if (ar.result == null) {
670 loge("nvReadItem: Empty response");
671 } else if (ar.exception instanceof CommandException) {
672 loge("nvReadItem: CommandException: " +
673 ar.exception);
Shishir Agrawal566b7612013-10-28 14:41:00 -0700674 } else {
Jake Hambye994d462014-02-03 13:10:13 -0800675 loge("nvReadItem: Unknown exception");
Shishir Agrawal566b7612013-10-28 14:41:00 -0700676 }
677 }
678 synchronized (request) {
679 request.notifyAll();
680 }
681 break;
682
Jake Hambye994d462014-02-03 13:10:13 -0800683 case CMD_NV_WRITE_ITEM:
684 request = (MainThreadRequest) msg.obj;
685 onCompleted = obtainMessage(EVENT_NV_WRITE_ITEM_DONE, request);
686 Pair<Integer, String> idValue = (Pair<Integer, String>) request.argument;
687 mPhone.nvWriteItem(idValue.first, idValue.second, onCompleted);
688 break;
689
690 case EVENT_NV_WRITE_ITEM_DONE:
691 handleNullReturnEvent(msg, "nvWriteItem");
692 break;
693
694 case CMD_NV_WRITE_CDMA_PRL:
695 request = (MainThreadRequest) msg.obj;
696 onCompleted = obtainMessage(EVENT_NV_WRITE_CDMA_PRL_DONE, request);
697 mPhone.nvWriteCdmaPrl((byte[]) request.argument, onCompleted);
698 break;
699
700 case EVENT_NV_WRITE_CDMA_PRL_DONE:
701 handleNullReturnEvent(msg, "nvWriteCdmaPrl");
702 break;
703
704 case CMD_NV_RESET_CONFIG:
705 request = (MainThreadRequest) msg.obj;
706 onCompleted = obtainMessage(EVENT_NV_RESET_CONFIG_DONE, request);
707 mPhone.nvResetConfig((Integer) request.argument, onCompleted);
708 break;
709
710 case EVENT_NV_RESET_CONFIG_DONE:
711 handleNullReturnEvent(msg, "nvResetConfig");
712 break;
713
Jake Hamby7c27be32014-03-03 13:25:59 -0800714 case CMD_GET_PREFERRED_NETWORK_TYPE:
715 request = (MainThreadRequest) msg.obj;
716 onCompleted = obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE_DONE, request);
Stuart Scott54788802015-03-30 13:18:01 -0700717 getPhoneFromRequest(request).getPreferredNetworkType(onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800718 break;
719
720 case EVENT_GET_PREFERRED_NETWORK_TYPE_DONE:
721 ar = (AsyncResult) msg.obj;
722 request = (MainThreadRequest) ar.userObj;
723 if (ar.exception == null && ar.result != null) {
724 request.result = ar.result; // Integer
725 } else {
Sanket Padawecfc2d352016-01-05 19:52:14 -0800726 request.result = null;
Jake Hamby7c27be32014-03-03 13:25:59 -0800727 if (ar.result == null) {
728 loge("getPreferredNetworkType: Empty response");
729 } else if (ar.exception instanceof CommandException) {
730 loge("getPreferredNetworkType: CommandException: " +
731 ar.exception);
732 } else {
733 loge("getPreferredNetworkType: Unknown exception");
734 }
735 }
736 synchronized (request) {
737 request.notifyAll();
738 }
739 break;
740
741 case CMD_SET_PREFERRED_NETWORK_TYPE:
742 request = (MainThreadRequest) msg.obj;
743 onCompleted = obtainMessage(EVENT_SET_PREFERRED_NETWORK_TYPE_DONE, request);
744 int networkType = (Integer) request.argument;
Stuart Scott54788802015-03-30 13:18:01 -0700745 getPhoneFromRequest(request).setPreferredNetworkType(networkType, onCompleted);
Jake Hamby7c27be32014-03-03 13:25:59 -0800746 break;
747
748 case EVENT_SET_PREFERRED_NETWORK_TYPE_DONE:
749 handleNullReturnEvent(msg, "setPreferredNetworkType");
750 break;
751
Shuo Qian74b16b12018-04-27 01:32:07 +0000752 case CMD_INVOKE_OEM_RIL_REQUEST_RAW:
753 request = (MainThreadRequest)msg.obj;
754 onCompleted = obtainMessage(EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE, request);
755 mPhone.invokeOemRilRequestRaw((byte[])request.argument, onCompleted);
756 break;
757
758 case EVENT_INVOKE_OEM_RIL_REQUEST_RAW_DONE:
759 ar = (AsyncResult)msg.obj;
760 request = (MainThreadRequest)ar.userObj;
761 request.result = ar;
762 synchronized (request) {
763 request.notifyAll();
764 }
765 break;
766
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800767 case CMD_SET_VOICEMAIL_NUMBER:
768 request = (MainThreadRequest) msg.obj;
769 onCompleted = obtainMessage(EVENT_SET_VOICEMAIL_NUMBER_DONE, request);
770 Pair<String, String> tagNum = (Pair<String, String>) request.argument;
Stuart Scott584921c2015-01-15 17:10:34 -0800771 getPhoneFromRequest(request).setVoiceMailNumber(tagNum.first, tagNum.second,
772 onCompleted);
Shishir Agrawal76d5da92014-11-09 16:17:25 -0800773 break;
774
775 case EVENT_SET_VOICEMAIL_NUMBER_DONE:
776 handleNullReturnEvent(msg, "setVoicemailNumber");
777 break;
778
Stuart Scott54788802015-03-30 13:18:01 -0700779 case CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC:
780 request = (MainThreadRequest) msg.obj;
781 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE,
782 request);
783 getPhoneFromRequest(request).setNetworkSelectionModeAutomatic(onCompleted);
784 break;
785
786 case EVENT_SET_NETWORK_SELECTION_MODE_AUTOMATIC_DONE:
787 handleNullReturnEvent(msg, "setNetworkSelectionModeAutomatic");
788 break;
789
Shishir Agrawal302c8692015-06-19 13:49:39 -0700790 case CMD_PERFORM_NETWORK_SCAN:
791 request = (MainThreadRequest) msg.obj;
792 onCompleted = obtainMessage(EVENT_PERFORM_NETWORK_SCAN_DONE, request);
793 getPhoneFromRequest(request).getAvailableNetworks(onCompleted);
794 break;
795
796 case EVENT_PERFORM_NETWORK_SCAN_DONE:
797 ar = (AsyncResult) msg.obj;
798 request = (MainThreadRequest) ar.userObj;
799 CellNetworkScanResult cellScanResult;
800 if (ar.exception == null && ar.result != null) {
801 cellScanResult = new CellNetworkScanResult(
802 CellNetworkScanResult.STATUS_SUCCESS,
803 (List<OperatorInfo>) ar.result);
804 } else {
805 if (ar.result == null) {
806 loge("getCellNetworkScanResults: Empty response");
807 }
808 if (ar.exception != null) {
809 loge("getCellNetworkScanResults: Exception: " + ar.exception);
810 }
811 int errorCode = CellNetworkScanResult.STATUS_UNKNOWN_ERROR;
812 if (ar.exception instanceof CommandException) {
813 CommandException.Error error =
814 ((CommandException) (ar.exception)).getCommandError();
815 if (error == CommandException.Error.RADIO_NOT_AVAILABLE) {
816 errorCode = CellNetworkScanResult.STATUS_RADIO_NOT_AVAILABLE;
817 } else if (error == CommandException.Error.GENERIC_FAILURE) {
818 errorCode = CellNetworkScanResult.STATUS_RADIO_GENERIC_FAILURE;
819 }
820 }
821 cellScanResult = new CellNetworkScanResult(errorCode, null);
822 }
823 request.result = cellScanResult;
824 synchronized (request) {
825 request.notifyAll();
826 }
827 break;
828
829 case CMD_SET_NETWORK_SELECTION_MODE_MANUAL:
830 request = (MainThreadRequest) msg.obj;
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700831 ManualNetworkSelectionArgument selArg =
832 (ManualNetworkSelectionArgument) request.argument;
Shishir Agrawal302c8692015-06-19 13:49:39 -0700833 onCompleted = obtainMessage(EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE,
834 request);
Shishir Agrawal77ba3172015-09-10 14:50:19 -0700835 getPhoneFromRequest(request).selectNetworkManually(selArg.operatorInfo,
836 selArg.persistSelection, onCompleted);
Shishir Agrawal302c8692015-06-19 13:49:39 -0700837 break;
838
839 case EVENT_SET_NETWORK_SELECTION_MODE_MANUAL_DONE:
840 handleNullReturnEvent(msg, "setNetworkSelectionModeManual");
841 break;
842
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700843 case CMD_GET_MODEM_ACTIVITY_INFO:
844 request = (MainThreadRequest) msg.obj;
845 onCompleted = obtainMessage(EVENT_GET_MODEM_ACTIVITY_INFO_DONE, request);
Prerepa Viswanadham61a60ad2015-06-08 18:07:51 -0700846 mPhone.getModemActivityInfo(onCompleted);
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700847 break;
848
849 case EVENT_GET_MODEM_ACTIVITY_INFO_DONE:
850 ar = (AsyncResult) msg.obj;
851 request = (MainThreadRequest) ar.userObj;
852 if (ar.exception == null && ar.result != null) {
853 request.result = ar.result;
854 } else {
855 if (ar.result == null) {
856 loge("queryModemActivityInfo: Empty response");
857 } else if (ar.exception instanceof CommandException) {
858 loge("queryModemActivityInfo: CommandException: " +
859 ar.exception);
860 } else {
861 loge("queryModemActivityInfo: Unknown exception");
862 }
863 }
Amit Mahajand4766222016-01-28 15:28:28 -0800864 // Result cannot be null. Return ModemActivityInfo with all fields set to 0.
865 if (request.result == null) {
866 request.result = new ModemActivityInfo(0, 0, 0, null, 0, 0);
867 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -0700868 synchronized (request) {
869 request.notifyAll();
870 }
871 break;
872
Meng Wang1a7c35a2016-05-05 20:56:15 -0700873 case CMD_SET_ALLOWED_CARRIERS:
874 request = (MainThreadRequest) msg.obj;
875 onCompleted = obtainMessage(EVENT_SET_ALLOWED_CARRIERS_DONE, request);
876 mPhone.setAllowedCarriers(
877 (List<CarrierIdentifier>) request.argument,
878 onCompleted);
879 break;
880
881 case EVENT_SET_ALLOWED_CARRIERS_DONE:
882 ar = (AsyncResult) msg.obj;
883 request = (MainThreadRequest) ar.userObj;
884 if (ar.exception == null && ar.result != null) {
885 request.result = ar.result;
886 } else {
887 if (ar.result == null) {
888 loge("setAllowedCarriers: Empty response");
889 } else if (ar.exception instanceof CommandException) {
890 loge("setAllowedCarriers: CommandException: " +
891 ar.exception);
892 } else {
893 loge("setAllowedCarriers: Unknown exception");
894 }
895 }
896 // Result cannot be null. Return -1 on error.
897 if (request.result == null) {
898 request.result = new int[]{-1};
899 }
900 synchronized (request) {
901 request.notifyAll();
902 }
903 break;
904
905 case CMD_GET_ALLOWED_CARRIERS:
906 request = (MainThreadRequest) msg.obj;
907 onCompleted = obtainMessage(EVENT_GET_ALLOWED_CARRIERS_DONE, request);
908 mPhone.getAllowedCarriers(onCompleted);
909 break;
910
911 case EVENT_GET_ALLOWED_CARRIERS_DONE:
912 ar = (AsyncResult) msg.obj;
913 request = (MainThreadRequest) ar.userObj;
914 if (ar.exception == null && ar.result != null) {
915 request.result = ar.result;
916 } else {
917 if (ar.result == null) {
918 loge("getAllowedCarriers: Empty response");
919 } else if (ar.exception instanceof CommandException) {
920 loge("getAllowedCarriers: CommandException: " +
921 ar.exception);
922 } else {
923 loge("getAllowedCarriers: Unknown exception");
924 }
925 }
926 // Result cannot be null. Return empty list of CarrierIdentifier.
927 if (request.result == null) {
928 request.result = new ArrayList<CarrierIdentifier>(0);
929 }
930 synchronized (request) {
931 request.notifyAll();
932 }
933 break;
934
Nathan Haroldb3014052017-01-25 15:57:32 -0800935 case EVENT_GET_FORBIDDEN_PLMNS_DONE:
936 ar = (AsyncResult) msg.obj;
937 request = (MainThreadRequest) ar.userObj;
938 if (ar.exception == null && ar.result != null) {
939 request.result = ar.result;
940 } else {
941 request.result = new IllegalArgumentException(
942 "Failed to retrieve Forbidden Plmns");
943 if (ar.result == null) {
944 loge("getForbiddenPlmns: Empty response");
945 } else {
946 loge("getForbiddenPlmns: Unknown exception");
947 }
948 }
949 synchronized (request) {
950 request.notifyAll();
951 }
952 break;
953
954 case CMD_GET_FORBIDDEN_PLMNS:
955 request = (MainThreadRequest) msg.obj;
956 uiccCard = getUiccCardFromRequest(request);
957 if (uiccCard == null) {
958 loge("getForbiddenPlmns() UiccCard is null");
959 request.result = new IllegalArgumentException(
960 "getForbiddenPlmns() UiccCard is null");
961 synchronized (request) {
962 request.notifyAll();
963 }
964 break;
965 }
966 Integer appType = (Integer) request.argument;
967 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
968 if (uiccApp == null) {
969 loge("getForbiddenPlmns() no app with specified type -- "
970 + appType);
971 request.result = new IllegalArgumentException("Failed to get UICC App");
972 synchronized (request) {
973 request.notifyAll();
974 }
975 break;
976 } else {
977 if (DBG) logv("getForbiddenPlmns() found app " + uiccApp.getAid()
978 + " specified type -- " + appType);
979 }
980 onCompleted = obtainMessage(EVENT_GET_FORBIDDEN_PLMNS_DONE, request);
981 ((SIMRecords) uiccApp.getIccRecords()).getForbiddenPlmns(
982 onCompleted);
983 break;
984
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +0000985 case CMD_SWITCH_SLOTS:
986 request = (MainThreadRequest) msg.obj;
987 int[] physicalSlots = (int[]) request.argument;
988 onCompleted = obtainMessage(EVENT_SWITCH_SLOTS_DONE, request);
989 UiccController.getInstance().switchSlots(physicalSlots, onCompleted);
990 break;
991
992 case EVENT_SWITCH_SLOTS_DONE:
993 ar = (AsyncResult) msg.obj;
994 request = (MainThreadRequest) ar.userObj;
995 request.result = (ar.exception == null);
996 synchronized (request) {
997 request.notifyAll();
998 }
999 break;
1000
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001001 default:
1002 Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
1003 break;
1004 }
1005 }
Jake Hambye994d462014-02-03 13:10:13 -08001006
1007 private void handleNullReturnEvent(Message msg, String command) {
1008 AsyncResult ar = (AsyncResult) msg.obj;
1009 MainThreadRequest request = (MainThreadRequest) ar.userObj;
1010 if (ar.exception == null) {
1011 request.result = true;
1012 } else {
1013 request.result = false;
1014 if (ar.exception instanceof CommandException) {
1015 loge(command + ": CommandException: " + ar.exception);
1016 } else {
1017 loge(command + ": Unknown exception");
1018 }
1019 }
1020 synchronized (request) {
1021 request.notifyAll();
1022 }
1023 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001024 }
1025
1026 /**
1027 * Posts the specified command to be executed on the main thread,
1028 * waits for the request to complete, and returns the result.
1029 * @see #sendRequestAsync
1030 */
1031 private Object sendRequest(int command, Object argument) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001032 return sendRequest(command, argument, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Saville36469e72014-06-11 15:17:00 -07001033 }
1034
1035 /**
1036 * Posts the specified command to be executed on the main thread,
1037 * waits for the request to complete, and returns the result.
1038 * @see #sendRequestAsync
1039 */
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001040 private Object sendRequest(int command, Object argument, Integer subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001041 if (Looper.myLooper() == mMainThreadHandler.getLooper()) {
1042 throw new RuntimeException("This method will deadlock if called from the main thread.");
1043 }
1044
Shishir Agrawal76d5da92014-11-09 16:17:25 -08001045 MainThreadRequest request = new MainThreadRequest(argument, subId);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001046 Message msg = mMainThreadHandler.obtainMessage(command, request);
1047 msg.sendToTarget();
1048
1049 // Wait for the request to complete
1050 synchronized (request) {
1051 while (request.result == null) {
1052 try {
1053 request.wait();
1054 } catch (InterruptedException e) {
1055 // Do nothing, go back and wait until the request is complete
1056 }
1057 }
1058 }
1059 return request.result;
1060 }
1061
1062 /**
1063 * Asynchronous ("fire and forget") version of sendRequest():
1064 * Posts the specified command to be executed on the main thread, and
1065 * returns immediately.
1066 * @see #sendRequest
1067 */
1068 private void sendRequestAsync(int command) {
1069 mMainThreadHandler.sendEmptyMessage(command);
1070 }
1071
1072 /**
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001073 * Same as {@link #sendRequestAsync(int)} except it takes an argument.
1074 * @see {@link #sendRequest(int,Object)}
1075 */
1076 private void sendRequestAsync(int command, Object argument) {
1077 MainThreadRequest request = new MainThreadRequest(argument);
1078 Message msg = mMainThreadHandler.obtainMessage(command, request);
1079 msg.sendToTarget();
1080 }
1081
1082 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001083 * Initialize the singleton PhoneInterfaceManager instance.
1084 * This is only done once, at startup, from PhoneApp.onCreate().
1085 */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001086 /* package */ static PhoneInterfaceManager init(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001087 synchronized (PhoneInterfaceManager.class) {
1088 if (sInstance == null) {
Sailesh Nepal194161e2014-07-03 08:57:44 -07001089 sInstance = new PhoneInterfaceManager(app, phone);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001090 } else {
1091 Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance);
1092 }
1093 return sInstance;
1094 }
1095 }
1096
1097 /** Private constructor; @see init() */
Sailesh Nepal194161e2014-07-03 08:57:44 -07001098 private PhoneInterfaceManager(PhoneGlobals app, Phone phone) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001099 mApp = app;
1100 mPhone = phone;
1101 mCM = PhoneGlobals.getInstance().mCM;
Stuart Scott981d8582015-04-21 14:09:50 -07001102 mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001103 mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
1104 mMainThreadHandler = new MainThreadHandler();
Andrew Leedf14ead2014-10-17 14:22:52 -07001105 mTelephonySharedPreferences =
Derek Tan97ebb422014-09-05 16:55:38 -07001106 PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001107 mSubscriptionController = SubscriptionController.getInstance();
yinxub1bed742017-04-17 11:45:04 -07001108 mNetworkScanRequestTracker = new NetworkScanRequestTracker();
Wink Saville3ab207e2014-11-20 13:07:20 -08001109
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001110 publish();
1111 }
1112
1113 private void publish() {
1114 if (DBG) log("publish: " + this);
1115
1116 ServiceManager.addService("phone", this);
1117 }
1118
Stuart Scott584921c2015-01-15 17:10:34 -08001119 private Phone getPhoneFromRequest(MainThreadRequest request) {
Sanket Padawe56e75a32016-02-08 12:18:19 -08001120 return (request.subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID)
1121 ? mPhone : getPhone(request.subId);
Stuart Scott584921c2015-01-15 17:10:34 -08001122 }
1123
Shishir Agrawalc04d9752016-02-19 10:41:00 -08001124 private UiccCard getUiccCardFromRequest(MainThreadRequest request) {
1125 Phone phone = getPhoneFromRequest(request);
1126 return phone == null ? null :
1127 UiccController.getInstance().getUiccCard(phone.getPhoneId());
1128 }
1129
Wink Saville36469e72014-06-11 15:17:00 -07001130 // returns phone associated with the subId.
Wink Savilleb564aae2014-10-23 10:18:09 -07001131 private Phone getPhone(int subId) {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08001132 return PhoneFactory.getPhone(mSubscriptionController.getPhoneId(subId));
Wink Saville36469e72014-06-11 15:17:00 -07001133 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001134 //
1135 // Implementation of the ITelephony interface.
1136 //
1137
1138 public void dial(String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001139 dialForSubscriber(getPreferredVoiceSubscription(), number);
Wink Saville36469e72014-06-11 15:17:00 -07001140 }
1141
Wink Savilleb564aae2014-10-23 10:18:09 -07001142 public void dialForSubscriber(int subId, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001143 if (DBG) log("dial: " + number);
1144 // No permission check needed here: This is just a wrapper around the
1145 // ACTION_DIAL intent, which is available to any app since it puts up
1146 // the UI before it does anything.
1147
Malcolm Chenaabec062018-02-28 15:00:40 -08001148 final long identity = Binder.clearCallingIdentity();
1149 try {
1150 String url = createTelUrl(number);
1151 if (url == null) {
1152 return;
1153 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001154
Malcolm Chenaabec062018-02-28 15:00:40 -08001155 // PENDING: should we just silently fail if phone is offhook or ringing?
1156 PhoneConstants.State state = mCM.getState(subId);
1157 if (state != PhoneConstants.State.OFFHOOK && state != PhoneConstants.State.RINGING) {
1158 Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
1159 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1160 mApp.startActivity(intent);
1161 }
1162 } finally {
1163 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001164 }
1165 }
1166
1167 public void call(String callingPackage, String number) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001168 callForSubscriber(getPreferredVoiceSubscription(), callingPackage, number);
Wink Saville36469e72014-06-11 15:17:00 -07001169 }
1170
Wink Savilleb564aae2014-10-23 10:18:09 -07001171 public void callForSubscriber(int subId, String callingPackage, String number) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001172 if (DBG) log("call: " + number);
1173
1174 // This is just a wrapper around the ACTION_CALL intent, but we still
1175 // need to do a permission check since we're calling startActivity()
1176 // from the context of the phone app.
1177 enforceCallPermission();
1178
1179 if (mAppOps.noteOp(AppOpsManager.OP_CALL_PHONE, Binder.getCallingUid(), callingPackage)
1180 != AppOpsManager.MODE_ALLOWED) {
1181 return;
1182 }
1183
Malcolm Chenaabec062018-02-28 15:00:40 -08001184 final long identity = Binder.clearCallingIdentity();
1185 try {
1186 String url = createTelUrl(number);
1187 if (url == null) {
1188 return;
1189 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001190
Malcolm Chenaabec062018-02-28 15:00:40 -08001191 boolean isValid = false;
1192 final List<SubscriptionInfo> slist = getActiveSubscriptionInfoListPrivileged();
1193 if (slist != null) {
1194 for (SubscriptionInfo subInfoRecord : slist) {
1195 if (subInfoRecord.getSubscriptionId() == subId) {
1196 isValid = true;
1197 break;
1198 }
Wink Saville3ab207e2014-11-20 13:07:20 -08001199 }
Wink Saville08874612014-08-31 19:19:58 -07001200 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001201 if (!isValid) {
1202 return;
1203 }
Wink Saville08874612014-08-31 19:19:58 -07001204
Malcolm Chenaabec062018-02-28 15:00:40 -08001205 Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
1206 intent.putExtra(SUBSCRIPTION_KEY, subId);
1207 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1208 mApp.startActivity(intent);
1209 } finally {
1210 Binder.restoreCallingIdentity(identity);
1211 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001212 }
1213
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001214 /**
1215 * End a call based on call state
1216 * @return true is a call was ended
1217 */
1218 public boolean endCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001219 return endCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001220 }
1221
1222 /**
1223 * End a call based on the call state of the subId
1224 * @return true is a call was ended
1225 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001226 public boolean endCallForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001227 enforceCallPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001228
1229 final long identity = Binder.clearCallingIdentity();
1230 try {
1231 return (Boolean) sendRequest(CMD_END_CALL, null, new Integer(subId));
1232 } finally {
1233 Binder.restoreCallingIdentity(identity);
1234 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001235 }
1236
1237 public void answerRingingCall() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001238 answerRingingCallForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001239 }
1240
Wink Savilleb564aae2014-10-23 10:18:09 -07001241 public void answerRingingCallForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001242 if (DBG) log("answerRingingCall...");
1243 // TODO: there should eventually be a separate "ANSWER_PHONE" permission,
1244 // but that can probably wait till the big TelephonyManager API overhaul.
1245 // For now, protect this call with the MODIFY_PHONE_STATE permission.
1246 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001247
1248 final long identity = Binder.clearCallingIdentity();
1249 try {
1250 sendRequest(CMD_ANSWER_RINGING_CALL, null, new Integer(subId));
1251 } finally {
1252 Binder.restoreCallingIdentity(identity);
1253 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001254 }
1255
1256 /**
1257 * Make the actual telephony calls to implement answerRingingCall().
1258 * This should only be called from the main thread of the Phone app.
1259 * @see #answerRingingCall
1260 *
1261 * TODO: it would be nice to return true if we answered the call, or
1262 * false if there wasn't actually a ringing incoming call, or some
1263 * other error occurred. (In other words, pass back the return value
1264 * from PhoneUtils.answerCall() or PhoneUtils.answerAndEndActive().)
1265 * But that would require calling this method via sendRequest() rather
1266 * than sendRequestAsync(), and right now we don't actually *need* that
1267 * return value, so let's just return void for now.
1268 */
Wink Savilleb564aae2014-10-23 10:18:09 -07001269 private void answerRingingCallInternal(int subId) {
Wink Saville08874612014-08-31 19:19:58 -07001270 final boolean hasRingingCall = !getPhone(subId).getRingingCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001271 if (hasRingingCall) {
Wink Saville08874612014-08-31 19:19:58 -07001272 final boolean hasActiveCall = !getPhone(subId).getForegroundCall().isIdle();
1273 final boolean hasHoldingCall = !getPhone(subId).getBackgroundCall().isIdle();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001274 if (hasActiveCall && hasHoldingCall) {
1275 // Both lines are in use!
1276 // TODO: provide a flag to let the caller specify what
1277 // policy to use if both lines are in use. (The current
1278 // behavior is hardwired to "answer incoming, end ongoing",
1279 // which is how the CALL button is specced to behave.)
1280 PhoneUtils.answerAndEndActive(mCM, mCM.getFirstActiveRingingCall());
1281 return;
1282 } else {
1283 // answerCall() will automatically hold the current active
1284 // call, if there is one.
1285 PhoneUtils.answerCall(mCM.getFirstActiveRingingCall());
1286 return;
1287 }
1288 } else {
1289 // No call was ringing.
1290 return;
1291 }
1292 }
1293
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001294 /**
Santos Cordon5422a8d2014-09-12 04:20:56 -07001295 * This method is no longer used and can be removed once TelephonyManager stops referring to it.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001296 */
Santos Cordon5422a8d2014-09-12 04:20:56 -07001297 public void silenceRinger() {
1298 Log.e(LOG_TAG, "silenseRinger not supported");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001299 }
1300
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001301 @Override
1302 public boolean isOffhook(String callingPackage) {
1303 return isOffhookForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001304 }
1305
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001306 @Override
1307 public boolean isOffhookForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08001308 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08001309 mApp, subId, callingPackage, "isOffhookForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001310 return false;
1311 }
1312
Malcolm Chenaabec062018-02-28 15:00:40 -08001313 final long identity = Binder.clearCallingIdentity();
1314 try {
1315 final Phone phone = getPhone(subId);
1316 if (phone != null) {
1317 return (phone.getState() == PhoneConstants.State.OFFHOOK);
1318 } else {
1319 return false;
1320 }
1321 } finally {
1322 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001323 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001324 }
1325
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001326 @Override
1327 public boolean isRinging(String callingPackage) {
1328 return (isRingingForSubscriber(getDefaultSubscription(), callingPackage));
Wink Saville36469e72014-06-11 15:17:00 -07001329 }
1330
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001331 @Override
1332 public boolean isRingingForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08001333 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08001334 mApp, subId, callingPackage, "isRingingForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001335 return false;
1336 }
1337
Malcolm Chenaabec062018-02-28 15:00:40 -08001338 final long identity = Binder.clearCallingIdentity();
1339 try {
1340 final Phone phone = getPhone(subId);
1341 if (phone != null) {
1342 return (phone.getState() == PhoneConstants.State.RINGING);
1343 } else {
1344 return false;
1345 }
1346 } finally {
1347 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001348 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001349 }
1350
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001351 @Override
1352 public boolean isIdle(String callingPackage) {
1353 return isIdleForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001354 }
1355
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001356 @Override
1357 public boolean isIdleForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08001358 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08001359 mApp, subId, callingPackage, "isIdleForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001360 return false;
1361 }
1362
Malcolm Chenaabec062018-02-28 15:00:40 -08001363 final long identity = Binder.clearCallingIdentity();
1364 try {
1365 final Phone phone = getPhone(subId);
1366 if (phone != null) {
1367 return (phone.getState() == PhoneConstants.State.IDLE);
1368 } else {
1369 return false;
1370 }
1371 } finally {
1372 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001373 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001374 }
1375
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001376 public boolean supplyPin(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001377 return supplyPinForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001378 }
1379
Wink Savilleb564aae2014-10-23 10:18:09 -07001380 public boolean supplyPinForSubscriber(int subId, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001381 int [] resultArray = supplyPinReportResultForSubscriber(subId, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001382 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1383 }
1384
1385 public boolean supplyPuk(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001386 return supplyPukForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001387 }
1388
Wink Savilleb564aae2014-10-23 10:18:09 -07001389 public boolean supplyPukForSubscriber(int subId, String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001390 int [] resultArray = supplyPukReportResultForSubscriber(subId, puk, pin);
Wink Saville9de0f752013-10-22 19:04:03 -07001391 return (resultArray[0] == PhoneConstants.PIN_RESULT_SUCCESS) ? true : false;
1392 }
1393
1394 /** {@hide} */
1395 public int[] supplyPinReportResult(String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001396 return supplyPinReportResultForSubscriber(getDefaultSubscription(), pin);
Wink Saville36469e72014-06-11 15:17:00 -07001397 }
1398
Wink Savilleb564aae2014-10-23 10:18:09 -07001399 public int[] supplyPinReportResultForSubscriber(int subId, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001400 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001401
1402 final long identity = Binder.clearCallingIdentity();
1403 try {
1404 final UnlockSim checkSimPin = new UnlockSim(getPhone(subId).getIccCard());
1405 checkSimPin.start();
1406 return checkSimPin.unlockSim(null, pin);
1407 } finally {
1408 Binder.restoreCallingIdentity(identity);
1409 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001410 }
1411
Wink Saville9de0f752013-10-22 19:04:03 -07001412 /** {@hide} */
1413 public int[] supplyPukReportResult(String puk, String pin) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001414 return supplyPukReportResultForSubscriber(getDefaultSubscription(), puk, pin);
Wink Saville36469e72014-06-11 15:17:00 -07001415 }
1416
Wink Savilleb564aae2014-10-23 10:18:09 -07001417 public int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001418 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001419
1420 final long identity = Binder.clearCallingIdentity();
1421 try {
1422 final UnlockSim checkSimPuk = new UnlockSim(getPhone(subId).getIccCard());
1423 checkSimPuk.start();
1424 return checkSimPuk.unlockSim(puk, pin);
1425 } finally {
1426 Binder.restoreCallingIdentity(identity);
1427 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001428 }
1429
1430 /**
Wink Saville9de0f752013-10-22 19:04:03 -07001431 * Helper thread to turn async call to SimCard#supplyPin into
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001432 * a synchronous one.
1433 */
1434 private static class UnlockSim extends Thread {
1435
1436 private final IccCard mSimCard;
1437
1438 private boolean mDone = false;
Wink Saville9de0f752013-10-22 19:04:03 -07001439 private int mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1440 private int mRetryCount = -1;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001441
1442 // For replies from SimCard interface
1443 private Handler mHandler;
1444
1445 // For async handler to identify request type
1446 private static final int SUPPLY_PIN_COMPLETE = 100;
1447
1448 public UnlockSim(IccCard simCard) {
1449 mSimCard = simCard;
1450 }
1451
1452 @Override
1453 public void run() {
1454 Looper.prepare();
1455 synchronized (UnlockSim.this) {
1456 mHandler = new Handler() {
1457 @Override
1458 public void handleMessage(Message msg) {
1459 AsyncResult ar = (AsyncResult) msg.obj;
1460 switch (msg.what) {
1461 case SUPPLY_PIN_COMPLETE:
1462 Log.d(LOG_TAG, "SUPPLY_PIN_COMPLETE");
1463 synchronized (UnlockSim.this) {
Wink Saville9de0f752013-10-22 19:04:03 -07001464 mRetryCount = msg.arg1;
1465 if (ar.exception != null) {
1466 if (ar.exception instanceof CommandException &&
1467 ((CommandException)(ar.exception)).getCommandError()
1468 == CommandException.Error.PASSWORD_INCORRECT) {
1469 mResult = PhoneConstants.PIN_PASSWORD_INCORRECT;
1470 } else {
1471 mResult = PhoneConstants.PIN_GENERAL_FAILURE;
1472 }
1473 } else {
1474 mResult = PhoneConstants.PIN_RESULT_SUCCESS;
1475 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001476 mDone = true;
1477 UnlockSim.this.notifyAll();
1478 }
1479 break;
1480 }
1481 }
1482 };
1483 UnlockSim.this.notifyAll();
1484 }
1485 Looper.loop();
1486 }
1487
1488 /*
1489 * Use PIN or PUK to unlock SIM card
1490 *
1491 * If PUK is null, unlock SIM card with PIN
1492 *
1493 * If PUK is not null, unlock SIM card with PUK and set PIN code
1494 */
Wink Saville9de0f752013-10-22 19:04:03 -07001495 synchronized int[] unlockSim(String puk, String pin) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001496
1497 while (mHandler == null) {
1498 try {
1499 wait();
1500 } catch (InterruptedException e) {
1501 Thread.currentThread().interrupt();
1502 }
1503 }
1504 Message callback = Message.obtain(mHandler, SUPPLY_PIN_COMPLETE);
1505
1506 if (puk == null) {
1507 mSimCard.supplyPin(pin, callback);
1508 } else {
1509 mSimCard.supplyPuk(puk, pin, callback);
1510 }
1511
1512 while (!mDone) {
1513 try {
1514 Log.d(LOG_TAG, "wait for done");
1515 wait();
1516 } catch (InterruptedException e) {
1517 // Restore the interrupted status
1518 Thread.currentThread().interrupt();
1519 }
1520 }
1521 Log.d(LOG_TAG, "done");
Wink Saville9de0f752013-10-22 19:04:03 -07001522 int[] resultArray = new int[2];
1523 resultArray[0] = mResult;
1524 resultArray[1] = mRetryCount;
1525 return resultArray;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001526 }
1527 }
1528
1529 public void updateServiceLocation() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001530 updateServiceLocationForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001531
1532 }
1533
Wink Savilleb564aae2014-10-23 10:18:09 -07001534 public void updateServiceLocationForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001535 // No permission check needed here: this call is harmless, and it's
1536 // needed for the ServiceState.requestStateUpdate() call (which is
1537 // already intentionally exposed to 3rd parties.)
Malcolm Chenaabec062018-02-28 15:00:40 -08001538 final long identity = Binder.clearCallingIdentity();
1539 try {
1540 final Phone phone = getPhone(subId);
1541 if (phone != null) {
1542 phone.updateServiceLocation();
1543 }
1544 } finally {
1545 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001546 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001547 }
1548
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001549 @Override
1550 public boolean isRadioOn(String callingPackage) {
1551 return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07001552 }
1553
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001554 @Override
1555 public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08001556 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08001557 mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001558 return false;
1559 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001560
1561 final long identity = Binder.clearCallingIdentity();
1562 try {
1563 return isRadioOnForSubscriber(subId);
1564 } finally {
1565 Binder.restoreCallingIdentity(identity);
1566 }
Robert Greenwalt36b23af2015-07-06 17:59:14 -07001567 }
1568
1569 private boolean isRadioOnForSubscriber(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001570 final long identity = Binder.clearCallingIdentity();
1571 try {
1572 final Phone phone = getPhone(subId);
1573 if (phone != null) {
1574 return phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF;
1575 } else {
1576 return false;
1577 }
1578 } finally {
1579 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001580 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001581 }
1582
1583 public void toggleRadioOnOff() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001584 toggleRadioOnOffForSubscriber(getDefaultSubscription());
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001585 }
Wink Saville36469e72014-06-11 15:17:00 -07001586
Wink Savilleb564aae2014-10-23 10:18:09 -07001587 public void toggleRadioOnOffForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001588 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001589
1590 final long identity = Binder.clearCallingIdentity();
1591 try {
1592 final Phone phone = getPhone(subId);
1593 if (phone != null) {
1594 phone.setRadioPower(!isRadioOnForSubscriber(subId));
1595 }
1596 } finally {
1597 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001598 }
Wink Saville36469e72014-06-11 15:17:00 -07001599 }
1600
1601 public boolean setRadio(boolean turnOn) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001602 return setRadioForSubscriber(getDefaultSubscription(), turnOn);
Wink Saville36469e72014-06-11 15:17:00 -07001603 }
1604
Wink Savilleb564aae2014-10-23 10:18:09 -07001605 public boolean setRadioForSubscriber(int subId, boolean turnOn) {
Wink Saville36469e72014-06-11 15:17:00 -07001606 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001607
1608 final long identity = Binder.clearCallingIdentity();
1609 try {
1610 final Phone phone = getPhone(subId);
1611 if (phone == null) {
1612 return false;
1613 }
1614 if ((phone.getServiceState().getState() != ServiceState.STATE_POWER_OFF) != turnOn) {
1615 toggleRadioOnOffForSubscriber(subId);
1616 }
1617 return true;
1618 } finally {
1619 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001620 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001621 }
Wink Saville36469e72014-06-11 15:17:00 -07001622
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001623 public boolean needMobileRadioShutdown() {
1624 /*
1625 * If any of the Radios are available, it will need to be
1626 * shutdown. So return true if any Radio is available.
1627 */
Malcolm Chenaabec062018-02-28 15:00:40 -08001628 final long identity = Binder.clearCallingIdentity();
1629 try {
1630 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1631 Phone phone = PhoneFactory.getPhone(i);
1632 if (phone != null && phone.isRadioAvailable()) return true;
1633 }
1634 logv(TelephonyManager.getDefault().getPhoneCount() + " Phones are shutdown.");
1635 return false;
1636 } finally {
1637 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001638 }
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001639 }
1640
Malcolm Chenaabec062018-02-28 15:00:40 -08001641 @Override
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001642 public void shutdownMobileRadios() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001643 enforceModifyPermission();
1644
1645 final long identity = Binder.clearCallingIdentity();
1646 try {
1647 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
1648 logv("Shutting down Phone " + i);
1649 shutdownRadioUsingPhoneId(i);
1650 }
1651 } finally {
1652 Binder.restoreCallingIdentity(identity);
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001653 }
1654 }
1655
1656 private void shutdownRadioUsingPhoneId(int phoneId) {
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07001657 Phone phone = PhoneFactory.getPhone(phoneId);
1658 if (phone != null && phone.isRadioAvailable()) {
1659 phone.shutdownRadio();
1660 }
1661 }
1662
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001663 public boolean setRadioPower(boolean turnOn) {
Jack Yub4e16162017-05-15 12:48:40 -07001664 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001665
1666 final long identity = Binder.clearCallingIdentity();
1667 try {
1668 final Phone defaultPhone = PhoneFactory.getDefaultPhone();
1669 if (defaultPhone != null) {
1670 defaultPhone.setRadioPower(turnOn);
1671 return true;
1672 } else {
1673 loge("There's no default phone.");
1674 return false;
1675 }
1676 } finally {
1677 Binder.restoreCallingIdentity(identity);
Wei Liu9ae2a062016-08-08 11:09:34 -07001678 }
Wink Saville36469e72014-06-11 15:17:00 -07001679 }
1680
Wink Savilleb564aae2014-10-23 10:18:09 -07001681 public boolean setRadioPowerForSubscriber(int subId, boolean turnOn) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001682 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001683
1684 final long identity = Binder.clearCallingIdentity();
1685 try {
1686 final Phone phone = getPhone(subId);
1687 if (phone != null) {
1688 phone.setRadioPower(turnOn);
1689 return true;
1690 } else {
1691 return false;
1692 }
1693 } finally {
1694 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001695 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001696 }
1697
Wink Saville36469e72014-06-11 15:17:00 -07001698 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001699 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001700 public boolean enableDataConnectivity() {
1701 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001702
1703 final long identity = Binder.clearCallingIdentity();
1704 try {
1705 int subId = mSubscriptionController.getDefaultDataSubId();
1706 final Phone phone = getPhone(subId);
1707 if (phone != null) {
1708 phone.setUserDataEnabled(true);
1709 return true;
1710 } else {
1711 return false;
1712 }
1713 } finally {
1714 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001715 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001716 }
1717
Wink Saville36469e72014-06-11 15:17:00 -07001718 // FIXME: subId version needed
Sanket Padawe356d7632015-06-22 14:03:32 -07001719 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001720 public boolean disableDataConnectivity() {
1721 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001722
1723 final long identity = Binder.clearCallingIdentity();
1724 try {
1725 int subId = mSubscriptionController.getDefaultDataSubId();
1726 final Phone phone = getPhone(subId);
1727 if (phone != null) {
1728 phone.setUserDataEnabled(false);
1729 return true;
1730 } else {
1731 return false;
1732 }
1733 } finally {
1734 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001735 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001736 }
1737
Sanket Padawe356d7632015-06-22 14:03:32 -07001738 @Override
Jack Yuacf8a132017-05-01 17:00:48 -07001739 public boolean isDataConnectivityPossible(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001740 final long identity = Binder.clearCallingIdentity();
1741 try {
1742 final Phone phone = getPhone(subId);
1743 if (phone != null) {
1744 return phone.isDataAllowed();
1745 } else {
1746 return false;
1747 }
1748 } finally {
1749 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001750 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001751 }
1752
1753 public boolean handlePinMmi(String dialString) {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001754 return handlePinMmiForSubscriber(getDefaultSubscription(), dialString);
Wink Saville36469e72014-06-11 15:17:00 -07001755 }
1756
pkanwarae03a6b2016-11-06 20:37:09 -08001757 public void handleUssdRequest(int subId, String ussdRequest, ResultReceiver wrappedCallback) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001758 enforceCallPermission();
1759
1760 final long identity = Binder.clearCallingIdentity();
1761 try {
1762 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1763 return;
1764 }
1765 Pair<String, ResultReceiver> ussdObject = new Pair(ussdRequest, wrappedCallback);
1766 sendRequest(CMD_HANDLE_USSD_REQUEST, ussdObject, subId);
1767 } finally {
1768 Binder.restoreCallingIdentity(identity);
1769 }
pkanwar32d516d2016-10-14 19:37:38 -07001770 };
1771
Wink Savilleb564aae2014-10-23 10:18:09 -07001772 public boolean handlePinMmiForSubscriber(int subId, String dialString) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001773 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08001774
1775 final long identity = Binder.clearCallingIdentity();
1776 try {
1777 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1778 return false;
1779 }
1780 return (Boolean) sendRequest(CMD_HANDLE_PIN_MMI, dialString, subId);
1781 } finally {
1782 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001783 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001784 }
1785
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001786 public int getCallState() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07001787 return getCallStateForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001788 }
1789
Sanket Padawe13bac7b2017-03-20 15:04:47 -07001790 public int getCallStateForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08001791 final long identity = Binder.clearCallingIdentity();
1792 try {
1793 Phone phone = PhoneFactory.getPhone(slotIndex);
1794 return phone == null ? TelephonyManager.CALL_STATE_IDLE :
1795 PhoneConstantConversions.convertCallState(phone.getState());
1796 } finally {
1797 Binder.restoreCallingIdentity(identity);
1798 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001799 }
1800
Sanket Padawe356d7632015-06-22 14:03:32 -07001801 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001802 public int getDataState() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001803 final long identity = Binder.clearCallingIdentity();
1804 try {
1805 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1806 if (phone != null) {
1807 return PhoneConstantConversions.convertDataState(phone.getDataConnectionState());
1808 } else {
1809 return PhoneConstantConversions.convertDataState(
1810 PhoneConstants.DataState.DISCONNECTED);
1811 }
1812 } finally {
1813 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001814 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001815 }
1816
Sanket Padawe356d7632015-06-22 14:03:32 -07001817 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001818 public int getDataActivity() {
Malcolm Chenaabec062018-02-28 15:00:40 -08001819 final long identity = Binder.clearCallingIdentity();
1820 try {
1821 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1822 if (phone != null) {
1823 return DefaultPhoneNotifier.convertDataActivityState(phone.getDataActivityState());
1824 } else {
1825 return TelephonyManager.DATA_ACTIVITY_NONE;
1826 }
1827 } finally {
1828 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001829 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001830 }
1831
1832 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001833 public Bundle getCellLocation(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001834 mPhone.getContext().getSystemService(AppOpsManager.class)
1835 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001836 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Hall Liu1aa510f2017-11-22 17:40:08 -08001837 callingPackage, Binder.getCallingUid(),Binder.getCallingPid())) {
Svetoslav64fad262015-04-14 14:35:21 -07001838 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001839 }
1840
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00001841 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001842 final long identity = Binder.clearCallingIdentity();
1843 try {
1844 if (DBG_LOC) log("getCellLocation: is active user");
1845 Bundle data = new Bundle();
1846 Phone phone = getPhone(mSubscriptionController.getDefaultDataSubId());
1847 if (phone == null) {
1848 return null;
1849 }
1850
1851 phone.getCellLocation(workSource).fillInNotifierBundle(data);
1852 return data;
1853 } finally {
1854 Binder.restoreCallingIdentity(identity);
1855 }
Svetoslav64fad262015-04-14 14:35:21 -07001856 }
1857
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001858 @Override
Jonathan Basseri03923952017-07-19 12:22:35 -07001859 public String getNetworkCountryIsoForPhone(int phoneId) {
1860 // Reporting the correct network country is ambiguous when IWLAN could conflict with
1861 // registered cell info, so return a NULL country instead.
1862 final long identity = Binder.clearCallingIdentity();
1863 try {
1864 final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
Jack Yu8e4fdc22018-04-13 14:05:37 -07001865 // Todo: fix this when we can get the actual cellular network info when the device
1866 // is on IWLAN.
Jonathan Basseri03923952017-07-19 12:22:35 -07001867 if (TelephonyManager.NETWORK_TYPE_IWLAN
1868 == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
1869 return "";
1870 }
Malcolm Chenaabec062018-02-28 15:00:40 -08001871 Phone phone = PhoneFactory.getPhone(phoneId);
1872 if (phone != null) {
1873 ServiceStateTracker sst = phone.getServiceStateTracker();
1874 if (sst != null) {
1875 LocaleTracker lt = sst.getLocaleTracker();
1876 if (lt != null) {
1877 return lt.getCurrentCountry();
1878 }
1879 }
1880 }
1881 return "";
Jonathan Basseri03923952017-07-19 12:22:35 -07001882 } finally {
1883 Binder.restoreCallingIdentity(identity);
1884 }
Jonathan Basseri03923952017-07-19 12:22:35 -07001885 }
1886
1887 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001888 public void enableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001889 enableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001890 }
1891
Sanket Padawe356d7632015-06-22 14:03:32 -07001892 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001893 public void enableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001894 mApp.enforceCallingOrSelfPermission(
1895 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001896
1897 final long identity = Binder.clearCallingIdentity();
1898 try {
1899 final Phone phone = getPhone(subId);
1900 if (phone != null) {
1901 phone.enableLocationUpdates();
1902 }
1903 } finally {
1904 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001905 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001906 }
1907
1908 @Override
1909 public void disableLocationUpdates() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07001910 disableLocationUpdatesForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07001911 }
1912
Sanket Padawe356d7632015-06-22 14:03:32 -07001913 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07001914 public void disableLocationUpdatesForSubscriber(int subId) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001915 mApp.enforceCallingOrSelfPermission(
1916 android.Manifest.permission.CONTROL_LOCATION_UPDATES, null);
Malcolm Chenaabec062018-02-28 15:00:40 -08001917
1918 final long identity = Binder.clearCallingIdentity();
1919 try {
1920 final Phone phone = getPhone(subId);
1921 if (phone != null) {
1922 phone.disableLocationUpdates();
1923 }
1924 } finally {
1925 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07001926 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001927 }
1928
1929 @Override
1930 @SuppressWarnings("unchecked")
1931 public List<NeighboringCellInfo> getNeighboringCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001932 mPhone.getContext().getSystemService(AppOpsManager.class)
1933 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001934 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Hall Liu1aa510f2017-11-22 17:40:08 -08001935 callingPackage, Binder.getCallingUid(), Binder.getCallingPid())) {
Svetoslav64fad262015-04-14 14:35:21 -07001936 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001937 }
1938
1939 if (mAppOps.noteOp(AppOpsManager.OP_NEIGHBORING_CELLS, Binder.getCallingUid(),
1940 callingPackage) != AppOpsManager.MODE_ALLOWED) {
1941 return null;
1942 }
Svetoslav64fad262015-04-14 14:35:21 -07001943
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001944 if (DBG_LOC) log("getNeighboringCellInfo: is active user");
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001945
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001946 ArrayList<NeighboringCellInfo> cells = null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001947
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00001948 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001949
1950 final long identity = Binder.clearCallingIdentity();
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001951 try {
1952 cells = (ArrayList<NeighboringCellInfo>) sendRequest(
1953 CMD_HANDLE_NEIGHBORING_CELL, workSource,
1954 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1955 } catch (RuntimeException e) {
1956 Log.e(LOG_TAG, "getNeighboringCellInfo " + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08001957 } finally {
1958 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001959 }
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001960 return cells;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001961 }
1962
1963
1964 @Override
Svetoslav64fad262015-04-14 14:35:21 -07001965 public List<CellInfo> getAllCellInfo(String callingPackage) {
Hall Liu1aa510f2017-11-22 17:40:08 -08001966 mPhone.getContext().getSystemService(AppOpsManager.class)
1967 .checkPackage(Binder.getCallingUid(), callingPackage);
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001968 if (!LocationAccessPolicy.canAccessCellLocation(mPhone.getContext(),
Hall Liu1aa510f2017-11-22 17:40:08 -08001969 callingPackage, Binder.getCallingUid(), Binder.getCallingPid())) {
Svetoslav64fad262015-04-14 14:35:21 -07001970 return null;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001971 }
1972
Svetoslav Ganov4a9d4482017-06-20 19:53:35 -07001973 if (DBG_LOC) log("getAllCellInfo: is active user");
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00001974 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001975 final long identity = Binder.clearCallingIdentity();
1976 try {
1977 List<CellInfo> cellInfos = new ArrayList<CellInfo>();
1978 for (Phone phone : PhoneFactory.getPhones()) {
1979 final List<CellInfo> info = phone.getAllCellInfo(workSource);
1980 if (info != null) cellInfos.addAll(info);
1981 }
1982 return cellInfos;
1983 } finally {
1984 Binder.restoreCallingIdentity(identity);
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001985 }
1986 }
1987
Sailesh Nepalbd76e4e2013-10-27 13:59:44 -07001988 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001989 public void setCellInfoListRate(int rateInMillis) {
Jack Yua8d8cb82017-01-16 10:15:34 -08001990 enforceModifyPermission();
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00001991 WorkSource workSource = getWorkSource(Binder.getCallingUid());
Malcolm Chenaabec062018-02-28 15:00:40 -08001992
1993 final long identity = Binder.clearCallingIdentity();
1994 try {
1995 mPhone.setCellInfoListRate(rateInMillis, workSource);
1996 } finally {
1997 Binder.restoreCallingIdentity(identity);
1998 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07001999 }
2000
Shishir Agrawala9f32182016-04-12 12:00:16 -07002001 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002002 public String getImeiForSlot(int slotIndex, String callingPackage) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002003 Phone phone = PhoneFactory.getPhone(slotIndex);
2004 if (phone == null) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002005 return null;
2006 }
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002007 int subId = phone.getSubId();
2008 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2009 mApp, subId, callingPackage, "getImeiForSlot")) {
2010 return null;
2011 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002012
2013 final long identity = Binder.clearCallingIdentity();
2014 try {
2015 return phone.getImei();
2016 } finally {
2017 Binder.restoreCallingIdentity(identity);
2018 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002019 }
2020
2021 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002022 public String getTypeAllocationCodeForSlot(int slotIndex) {
2023 Phone phone = PhoneFactory.getPhone(slotIndex);
2024 String tac = null;
2025 if (phone != null) {
2026 String imei = phone.getImei();
2027 tac = imei == null ? null : imei.substring(0, TYPE_ALLOCATION_CODE_LENGTH);
2028 }
2029 return tac;
2030 }
2031
2032 @Override
Jack Yu2af8d712017-03-15 17:14:14 -07002033 public String getMeidForSlot(int slotIndex, String callingPackage) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002034 Phone phone = PhoneFactory.getPhone(slotIndex);
2035 if (phone == null) {
Jack Yu2af8d712017-03-15 17:14:14 -07002036 return null;
2037 }
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002038 int subId = phone.getSubId();
2039 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2040 mApp, subId, callingPackage, "getMeidForSlot")) {
2041 return null;
2042 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002043
2044 final long identity = Binder.clearCallingIdentity();
2045 try {
2046 return phone.getMeid();
2047 } finally {
2048 Binder.restoreCallingIdentity(identity);
2049 }
Jack Yu2af8d712017-03-15 17:14:14 -07002050 }
2051
2052 @Override
David Kelly5e06a7f2018-03-12 14:10:59 +00002053 public String getManufacturerCodeForSlot(int slotIndex) {
2054 Phone phone = PhoneFactory.getPhone(slotIndex);
2055 String manufacturerCode = null;
2056 if (phone != null) {
2057 String meid = phone.getMeid();
2058 manufacturerCode = meid == null ? null : meid.substring(0, MANUFACTURER_CODE_LENGTH);
2059 }
2060 return manufacturerCode;
2061 }
2062
2063 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002064 public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002065 Phone phone = PhoneFactory.getPhone(slotIndex);
2066 if (phone == null) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002067 return null;
2068 }
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002069 int subId = phone.getSubId();
2070 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
2071 mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
2072 return null;
2073 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002074
2075 final long identity = Binder.clearCallingIdentity();
2076 try {
2077 return phone.getDeviceSvn();
2078 } finally {
2079 Binder.restoreCallingIdentity(identity);
2080 }
Shishir Agrawala9f32182016-04-12 12:00:16 -07002081 }
2082
fionaxuf32acdf2017-11-27 22:51:16 -08002083 @Override
2084 public int getSubscriptionCarrierId(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002085 final long identity = Binder.clearCallingIdentity();
2086 try {
2087 final Phone phone = getPhone(subId);
2088 return phone == null ? TelephonyManager.UNKNOWN_CARRIER_ID : phone.getCarrierId();
2089 } finally {
2090 Binder.restoreCallingIdentity(identity);
2091 }
fionaxuf32acdf2017-11-27 22:51:16 -08002092 }
2093
2094 @Override
2095 public String getSubscriptionCarrierName(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002096 final long identity = Binder.clearCallingIdentity();
2097 try {
2098 final Phone phone = getPhone(subId);
2099 return phone == null ? null : phone.getCarrierName();
2100 } finally {
2101 Binder.restoreCallingIdentity(identity);
2102 }
fionaxuf32acdf2017-11-27 22:51:16 -08002103 }
2104
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002105 //
2106 // Internal helper methods.
2107 //
2108
Sanket Padaweee13a9b2016-03-08 17:30:28 -08002109 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002110 * Make sure the caller has the MODIFY_PHONE_STATE permission.
2111 *
2112 * @throws SecurityException if the caller does not have the required permission
2113 */
2114 private void enforceModifyPermission() {
2115 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
2116 }
2117
2118 /**
2119 * Make sure the caller has the CALL_PHONE permission.
2120 *
2121 * @throws SecurityException if the caller does not have the required permission
2122 */
2123 private void enforceCallPermission() {
2124 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.CALL_PHONE, null);
2125 }
2126
Stuart Scott8eef64f2015-04-08 15:13:54 -07002127 private void enforceConnectivityInternalPermission() {
2128 mApp.enforceCallingOrSelfPermission(
2129 android.Manifest.permission.CONNECTIVITY_INTERNAL,
2130 "ConnectivityService");
2131 }
2132
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002133 private String createTelUrl(String number) {
2134 if (TextUtils.isEmpty(number)) {
2135 return null;
2136 }
2137
Jake Hambye994d462014-02-03 13:10:13 -08002138 return "tel:" + number;
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002139 }
2140
Ihab Awadf9e92732013-12-05 18:02:52 -08002141 private static void log(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002142 Log.d(LOG_TAG, "[PhoneIntfMgr] " + msg);
2143 }
2144
Naveen Kalla1fd79bd2014-08-08 00:48:59 -07002145 private static void logv(String msg) {
2146 Log.v(LOG_TAG, "[PhoneIntfMgr] " + msg);
2147 }
2148
Ihab Awadf9e92732013-12-05 18:02:52 -08002149 private static void loge(String msg) {
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002150 Log.e(LOG_TAG, "[PhoneIntfMgr] " + msg);
2151 }
2152
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002153 @Override
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002154 public int getActivePhoneType() {
Shishir Agrawala9f32182016-04-12 12:00:16 -07002155 return getActivePhoneTypeForSlot(getSlotForDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002156 }
2157
Sanket Padawe356d7632015-06-22 14:03:32 -07002158 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002159 public int getActivePhoneTypeForSlot(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002160 final long identity = Binder.clearCallingIdentity();
2161 try {
2162 final Phone phone = PhoneFactory.getPhone(slotIndex);
2163 if (phone == null) {
2164 return PhoneConstants.PHONE_TYPE_NONE;
2165 } else {
2166 return phone.getPhoneType();
2167 }
2168 } finally {
2169 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002170 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002171 }
2172
2173 /**
2174 * Returns the CDMA ERI icon index to display
2175 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002176 @Override
2177 public int getCdmaEriIconIndex(String callingPackage) {
2178 return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002179 }
2180
Sanket Padawe356d7632015-06-22 14:03:32 -07002181 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002182 public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002183 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002184 mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002185 return -1;
2186 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002187
2188 final long identity = Binder.clearCallingIdentity();
2189 try {
2190 final Phone phone = getPhone(subId);
2191 if (phone != null) {
2192 return phone.getCdmaEriIconIndex();
2193 } else {
2194 return -1;
2195 }
2196 } finally {
2197 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002198 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002199 }
2200
2201 /**
2202 * Returns the CDMA ERI icon mode,
2203 * 0 - ON
2204 * 1 - FLASHING
2205 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002206 @Override
2207 public int getCdmaEriIconMode(String callingPackage) {
2208 return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002209 }
2210
Sanket Padawe356d7632015-06-22 14:03:32 -07002211 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002212 public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002213 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002214 mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002215 return -1;
2216 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002217
2218 final long identity = Binder.clearCallingIdentity();
2219 try {
2220 final Phone phone = getPhone(subId);
2221 if (phone != null) {
2222 return phone.getCdmaEriIconMode();
2223 } else {
2224 return -1;
2225 }
2226 } finally {
2227 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002228 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002229 }
2230
2231 /**
2232 * Returns the CDMA ERI text,
2233 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002234 @Override
2235 public String getCdmaEriText(String callingPackage) {
2236 return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002237 }
2238
Sanket Padawe356d7632015-06-22 14:03:32 -07002239 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002240 public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002241 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002242 mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002243 return null;
2244 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002245
2246 final long identity = Binder.clearCallingIdentity();
2247 try {
2248 final Phone phone = getPhone(subId);
2249 if (phone != null) {
2250 return phone.getCdmaEriText();
2251 } else {
2252 return null;
2253 }
2254 } finally {
2255 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002256 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002257 }
2258
2259 /**
Junda Liuca05d5d2014-08-14 22:36:34 -07002260 * Returns the CDMA MDN.
2261 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002262 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002263 public String getCdmaMdn(int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002264 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2265 mApp, subId, "getCdmaMdn");
Malcolm Chenaabec062018-02-28 15:00:40 -08002266
2267 final long identity = Binder.clearCallingIdentity();
2268 try {
2269 final Phone phone = getPhone(subId);
2270 if (mPhone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && phone != null) {
2271 return phone.getLine1Number();
2272 } else {
2273 return null;
2274 }
2275 } finally {
2276 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002277 }
2278 }
2279
2280 /**
2281 * Returns the CDMA MIN.
2282 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002283 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002284 public String getCdmaMin(int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002285 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2286 mApp, subId, "getCdmaMin");
Malcolm Chenaabec062018-02-28 15:00:40 -08002287
2288 final long identity = Binder.clearCallingIdentity();
2289 try {
2290 final Phone phone = getPhone(subId);
2291 if (phone != null && phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
2292 return phone.getCdmaMin();
2293 } else {
2294 return null;
2295 }
2296 } finally {
2297 Binder.restoreCallingIdentity(identity);
Junda Liuca05d5d2014-08-14 22:36:34 -07002298 }
2299 }
2300
2301 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002302 * Returns true if CDMA provisioning needs to run.
2303 */
2304 public boolean needsOtaServiceProvisioning() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002305 final long identity = Binder.clearCallingIdentity();
2306 try {
2307 return mPhone.needsOtaServiceProvisioning();
2308 } finally {
2309 Binder.restoreCallingIdentity(identity);
2310 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002311 }
2312
2313 /**
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002314 * Sets the voice mail number of a given subId.
2315 */
2316 @Override
2317 public boolean setVoiceMailNumber(int subId, String alphaTag, String number) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002318 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setVoiceMailNumber");
Malcolm Chenaabec062018-02-28 15:00:40 -08002319
2320 final long identity = Binder.clearCallingIdentity();
2321 try {
2322 Boolean success = (Boolean) sendRequest(CMD_SET_VOICEMAIL_NUMBER,
2323 new Pair<String, String>(alphaTag, number), new Integer(subId));
2324 return success;
2325 } finally {
2326 Binder.restoreCallingIdentity(identity);
2327 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002328 }
2329
Ta-wei Yen87c49842016-05-13 21:19:52 -07002330 @Override
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002331 public Bundle getVisualVoicemailSettings(String callingPackage, int subId) {
2332 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2333 String systemDialer = TelecomManager.from(mPhone.getContext()).getSystemDialerPackage();
2334 if (!TextUtils.equals(callingPackage, systemDialer)) {
2335 throw new SecurityException("caller must be system dialer");
2336 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002337
2338 final long identity = Binder.clearCallingIdentity();
2339 try {
2340 PhoneAccountHandle phoneAccountHandle = PhoneAccountHandleConverter.fromSubId(subId);
2341 if (phoneAccountHandle == null) {
2342 return null;
2343 }
2344 return VisualVoicemailSettingsUtil.dump(mPhone.getContext(), phoneAccountHandle);
2345 } finally {
2346 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002347 }
Ta-wei Yenc9df0432017-04-17 17:09:07 -07002348 }
2349
2350 @Override
Ta-wei Yen409ac562017-03-06 16:00:44 -08002351 public String getVisualVoicemailPackageName(String callingPackage, int subId) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002352 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002353 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002354 mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
Ta-wei Yendca928f2017-01-10 16:17:08 -08002355 return null;
2356 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002357
Jeff Davidson87b3c102018-03-15 17:16:18 -07002358 final long identity = Binder.clearCallingIdentity();
2359 try {
2360 return RemoteVvmTaskManager
2361 .getRemotePackage(mPhone.getContext(), subId).getPackageName();
2362 } finally {
2363 Binder.restoreCallingIdentity(identity);
2364 }
Ta-wei Yendca928f2017-01-10 16:17:08 -08002365 }
2366
2367 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002368 public void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
2369 VisualVoicemailSmsFilterSettings settings) {
2370 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002371
2372 final long identity = Binder.clearCallingIdentity();
2373 try {
2374 VisualVoicemailSmsFilterConfig.enableVisualVoicemailSmsFilter(
2375 mPhone.getContext(), callingPackage, subId, settings);
2376 } finally {
2377 Binder.restoreCallingIdentity(identity);
2378 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002379 }
2380
2381 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002382 public void disableVisualVoicemailSmsFilter(String callingPackage, int subId) {
2383 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002384
2385 final long identity = Binder.clearCallingIdentity();
2386 try {
2387 VisualVoicemailSmsFilterConfig.disableVisualVoicemailSmsFilter(
2388 mPhone.getContext(), callingPackage, subId);
2389 } finally {
2390 Binder.restoreCallingIdentity(identity);
2391 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002392 }
2393
2394 @Override
Ta-wei Yenb6929602016-05-24 15:48:27 -07002395 public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(
2396 String callingPackage, int subId) {
2397 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Malcolm Chenaabec062018-02-28 15:00:40 -08002398
2399 final long identity = Binder.clearCallingIdentity();
2400 try {
2401 return VisualVoicemailSmsFilterConfig.getVisualVoicemailSmsFilterSettings(
2402 mPhone.getContext(), callingPackage, subId);
2403 } finally {
2404 Binder.restoreCallingIdentity(identity);
2405 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002406 }
2407
2408 @Override
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002409 public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
Ta-wei Yenb6929602016-05-24 15:48:27 -07002410 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002411
2412 final long identity = Binder.clearCallingIdentity();
2413 try {
2414 return VisualVoicemailSmsFilterConfig.getActiveVisualVoicemailSmsFilterSettings(
2415 mPhone.getContext(), subId);
2416 } finally {
2417 Binder.restoreCallingIdentity(identity);
2418 }
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002419 }
2420
2421 @Override
2422 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, int subId,
2423 String number, int port, String text, PendingIntent sentIntent) {
2424 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Ta-wei Yen527a9c02017-01-06 15:29:25 -08002425 enforceVisualVoicemailPackage(callingPackage, subId);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08002426 enforceSendSmsPermission();
2427 // Make the calls as the phone process.
2428 final long identity = Binder.clearCallingIdentity();
2429 try {
2430 SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subId);
2431 if (port == 0) {
2432 smsManager.sendTextMessageWithSelfPermissions(number, null, text,
2433 sentIntent, null, false);
2434 } else {
2435 byte[] data = text.getBytes(StandardCharsets.UTF_8);
2436 smsManager.sendDataMessageWithSelfPermissions(number, null,
2437 (short) port, data, sentIntent, null);
2438 }
2439 } finally {
2440 Binder.restoreCallingIdentity(identity);
2441 }
Ta-wei Yen87c49842016-05-13 21:19:52 -07002442 }
Shishir Agrawal76d5da92014-11-09 16:17:25 -08002443 /**
fionaxu0152e512016-11-14 13:36:14 -08002444 * Sets the voice activation state of a given subId.
2445 */
2446 @Override
2447 public void setVoiceActivationState(int subId, int activationState) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002448 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2449 mApp, subId, "setVoiceActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002450
2451 final long identity = Binder.clearCallingIdentity();
2452 try {
2453 final Phone phone = getPhone(subId);
2454 if (phone != null) {
2455 phone.setVoiceActivationState(activationState);
2456 } else {
2457 loge("setVoiceActivationState fails with invalid subId: " + subId);
2458 }
2459 } finally {
2460 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002461 }
2462 }
2463
2464 /**
2465 * Sets the data activation state of a given subId.
2466 */
2467 @Override
2468 public void setDataActivationState(int subId, int activationState) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002469 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2470 mApp, subId, "setDataActivationState");
Malcolm Chenaabec062018-02-28 15:00:40 -08002471
2472 final long identity = Binder.clearCallingIdentity();
2473 try {
2474 final Phone phone = getPhone(subId);
2475 if (phone != null) {
2476 phone.setDataActivationState(activationState);
2477 } else {
2478 loge("setVoiceActivationState fails with invalid subId: " + subId);
2479 }
2480 } finally {
2481 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002482 }
2483 }
2484
2485 /**
2486 * Returns the voice activation state of a given subId.
2487 */
2488 @Override
2489 public int getVoiceActivationState(int subId, String callingPackage) {
goneil9e8ba382017-12-13 12:57:23 -08002490 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002491
fionaxu0152e512016-11-14 13:36:14 -08002492 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002493 final long identity = Binder.clearCallingIdentity();
2494 try {
2495 if (phone != null) {
2496 return phone.getVoiceActivationState();
2497 } else {
2498 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2499 }
2500 } finally {
2501 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002502 }
2503 }
2504
2505 /**
2506 * Returns the data activation state of a given subId.
2507 */
2508 @Override
2509 public int getDataActivationState(int subId, String callingPackage) {
goneil9e8ba382017-12-13 12:57:23 -08002510 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08002511
fionaxu0152e512016-11-14 13:36:14 -08002512 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08002513 final long identity = Binder.clearCallingIdentity();
2514 try {
2515 if (phone != null) {
2516 return phone.getDataActivationState();
2517 } else {
2518 return TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
2519 }
2520 } finally {
2521 Binder.restoreCallingIdentity(identity);
fionaxu0152e512016-11-14 13:36:14 -08002522 }
2523 }
2524
2525 /**
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002526 * Returns the unread count of voicemails
2527 */
2528 public int getVoiceMessageCount() {
Wink Savilleadd7cc52014-09-08 14:23:09 -07002529 return getVoiceMessageCountForSubscriber(getDefaultSubscription());
Wink Saville36469e72014-06-11 15:17:00 -07002530 }
2531
2532 /**
2533 * Returns the unread count of voicemails for a subId
2534 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002535 @Override
Wink Savilleb564aae2014-10-23 10:18:09 -07002536 public int getVoiceMessageCountForSubscriber( int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002537 final long identity = Binder.clearCallingIdentity();
2538 try {
2539 final Phone phone = getPhone(subId);
2540 if (phone != null) {
2541 return phone.getVoiceMessageCount();
2542 } else {
2543 return 0;
2544 }
2545 } finally {
2546 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002547 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002548 }
2549
2550 /**
pkanwar8a4dcfb2017-01-19 13:43:16 -08002551 * returns true, if the device is in a state where both voice and data
2552 * are supported simultaneously. This can change based on location or network condition.
2553 */
2554 @Override
2555 public boolean isConcurrentVoiceAndDataAllowed(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002556 final long identity = Binder.clearCallingIdentity();
2557 try {
2558 final Phone phone = getPhone(subId);
2559 return (phone == null ? false : phone.isConcurrentVoiceAndDataAllowed());
2560 } finally {
2561 Binder.restoreCallingIdentity(identity);
2562 }
pkanwar8a4dcfb2017-01-19 13:43:16 -08002563 }
2564
2565 /**
fionaxu235cc5e2017-03-06 22:25:57 -08002566 * Send the dialer code if called from the current default dialer or the caller has
2567 * carrier privilege.
2568 * @param inputCode The dialer code to send
2569 */
2570 @Override
2571 public void sendDialerSpecialCode(String callingPackage, String inputCode) {
2572 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
2573 String defaultDialer = TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage();
2574 if (!TextUtils.equals(callingPackage, defaultDialer)) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002575 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
2576 getDefaultSubscription(), "sendDialerSpecialCode");
fionaxu235cc5e2017-03-06 22:25:57 -08002577 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002578
2579 final long identity = Binder.clearCallingIdentity();
2580 try {
2581 mPhone.sendDialerSpecialCode(inputCode);
2582 } finally {
2583 Binder.restoreCallingIdentity(identity);
2584 }
fionaxu235cc5e2017-03-06 22:25:57 -08002585 }
2586
2587 /**
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002588 * Returns the data network type.
2589 * Legacy call, permission-free.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002590 *
2591 * @Deprecated to be removed Q3 2013 use {@link #getDataNetworkType}.
2592 */
2593 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002594 public int getNetworkType() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002595 final long identity = Binder.clearCallingIdentity();
2596 try {
2597 final Phone phone = getPhone(getDefaultSubscription());
2598 if (phone != null) {
2599 return phone.getServiceState().getDataNetworkType();
2600 } else {
2601 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2602 }
2603 } finally {
2604 Binder.restoreCallingIdentity(identity);
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002605 }
Wink Saville36469e72014-06-11 15:17:00 -07002606 }
2607
2608 /**
2609 * Returns the network type for a subId
2610 */
2611 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002612 public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002613 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002614 mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002615 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2616 }
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002617
Malcolm Chenaabec062018-02-28 15:00:40 -08002618 final long identity = Binder.clearCallingIdentity();
2619 try {
2620 final Phone phone = getPhone(subId);
2621 if (phone != null) {
2622 return phone.getServiceState().getDataNetworkType();
2623 } else {
2624 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2625 }
2626 } finally {
2627 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002628 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002629 }
2630
2631 /**
2632 * Returns the data network type
2633 */
2634 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002635 public int getDataNetworkType(String callingPackage) {
2636 return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002637 }
2638
2639 /**
2640 * Returns the data network type for a subId
2641 */
2642 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002643 public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002644 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002645 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002646 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2647 }
2648
Malcolm Chenaabec062018-02-28 15:00:40 -08002649 final long identity = Binder.clearCallingIdentity();
2650 try {
2651 final Phone phone = getPhone(subId);
2652 if (phone != null) {
2653 return phone.getServiceState().getDataNetworkType();
2654 } else {
2655 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2656 }
2657 } finally {
2658 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002659 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002660 }
2661
2662 /**
Wink Saville36469e72014-06-11 15:17:00 -07002663 * Returns the Voice network type for a subId
2664 */
2665 @Override
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002666 public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002667 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002668 mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
Robert Greenwalta5dcfcb2015-07-10 09:06:29 -07002669 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2670 }
2671
Malcolm Chenaabec062018-02-28 15:00:40 -08002672 final long identity = Binder.clearCallingIdentity();
2673 try {
2674 final Phone phone = getPhone(subId);
2675 if (phone != null) {
2676 return phone.getServiceState().getVoiceNetworkType();
2677 } else {
2678 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
2679 }
2680 } finally {
2681 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002682 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002683 }
2684
2685 /**
2686 * @return true if a ICC card is present
2687 */
2688 public boolean hasIccCard() {
Wink Saville36469e72014-06-11 15:17:00 -07002689 // FIXME Make changes to pass defaultSimId of type int
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002690 return hasIccCardUsingSlotIndex(mSubscriptionController.getSlotIndex(
2691 getDefaultSubscription()));
Wink Saville36469e72014-06-11 15:17:00 -07002692 }
2693
2694 /**
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002695 * @return true if a ICC card is present for a slotIndex
Wink Saville36469e72014-06-11 15:17:00 -07002696 */
Sanket Padawe356d7632015-06-22 14:03:32 -07002697 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07002698 public boolean hasIccCardUsingSlotIndex(int slotIndex) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002699 final long identity = Binder.clearCallingIdentity();
2700 try {
2701 final Phone phone = PhoneFactory.getPhone(slotIndex);
2702 if (phone != null) {
2703 return phone.getIccCard().hasIccCard();
2704 } else {
2705 return false;
2706 }
2707 } finally {
2708 Binder.restoreCallingIdentity(identity);
Amit Mahajana6fc2a82015-01-06 11:53:51 -08002709 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002710 }
2711
2712 /**
2713 * Return if the current radio is LTE on CDMA. This
2714 * is a tri-state return value as for a period of time
2715 * the mode may be unknown.
2716 *
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002717 * @param callingPackage the name of the package making the call.
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002718 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
Jake Hambye994d462014-02-03 13:10:13 -08002719 * or {@link Phone#LTE_ON_CDMA_TRUE}
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002720 */
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002721 @Override
2722 public int getLteOnCdmaMode(String callingPackage) {
2723 return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
Wink Saville36469e72014-06-11 15:17:00 -07002724 }
2725
Sanket Padawe356d7632015-06-22 14:03:32 -07002726 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002727 public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002728 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002729 mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07002730 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2731 }
2732
Malcolm Chenaabec062018-02-28 15:00:40 -08002733 final long identity = Binder.clearCallingIdentity();
2734 try {
2735 final Phone phone = getPhone(subId);
2736 if (phone == null) {
2737 return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
2738 } else {
2739 return phone.getLteOnCdmaMode();
2740 }
2741 } finally {
2742 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07002743 }
Wink Saville36469e72014-06-11 15:17:00 -07002744 }
2745
2746 public void setPhone(Phone phone) {
2747 mPhone = phone;
2748 }
2749
2750 /**
2751 * {@hide}
2752 * Returns Default subId, 0 in the case of single standby.
2753 */
Wink Savilleb564aae2014-10-23 10:18:09 -07002754 private int getDefaultSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002755 return mSubscriptionController.getDefaultSubId();
Wink Saville36469e72014-06-11 15:17:00 -07002756 }
2757
Shishir Agrawala9f32182016-04-12 12:00:16 -07002758 private int getSlotForDefaultSubscription() {
2759 return mSubscriptionController.getPhoneId(getDefaultSubscription());
2760 }
2761
Wink Savilleb564aae2014-10-23 10:18:09 -07002762 private int getPreferredVoiceSubscription() {
Wink Savilleac1bdfd2014-11-20 23:04:44 -08002763 return mSubscriptionController.getDefaultVoiceSubId();
Santos Cordon7d4ddf62013-07-10 11:58:08 -07002764 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002765
2766 /**
2767 * @see android.telephony.TelephonyManager.WifiCallingChoices
2768 */
2769 public int getWhenToMakeWifiCalls() {
Malcolm Chenaabec062018-02-28 15:00:40 -08002770 final long identity = Binder.clearCallingIdentity();
2771 try {
2772 return Settings.System.getInt(mPhone.getContext().getContentResolver(),
2773 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
2774 getWhenToMakeWifiCallsDefaultPreference());
2775 } finally {
2776 Binder.restoreCallingIdentity(identity);
2777 }
Ihab Awadf2177b72013-11-25 13:33:23 -08002778 }
2779
2780 /**
2781 * @see android.telephony.TelephonyManager.WifiCallingChoices
2782 */
2783 public void setWhenToMakeWifiCalls(int preference) {
Malcolm Chenaabec062018-02-28 15:00:40 -08002784 final long identity = Binder.clearCallingIdentity();
2785 try {
2786 if (DBG) log("setWhenToMakeWifiCallsStr, storing setting = " + preference);
2787 Settings.System.putInt(mPhone.getContext().getContentResolver(),
2788 Settings.System.WHEN_TO_MAKE_WIFI_CALLS, preference);
2789 } finally {
2790 Binder.restoreCallingIdentity(identity);
2791 }
Ihab Awadf9e92732013-12-05 18:02:52 -08002792 }
2793
Sailesh Nepald1e68152013-12-12 19:08:02 -08002794 private static int getWhenToMakeWifiCallsDefaultPreference() {
Santos Cordonda120f42014-08-06 04:44:34 -07002795 // TODO: Use a build property to choose this value.
Evan Charlton9829e882013-12-19 15:30:38 -08002796 return TelephonyManager.WifiCallingChoices.ALWAYS_USE;
Ihab Awadf2177b72013-11-25 13:33:23 -08002797 }
Shishir Agrawal69f68122013-12-16 17:25:49 -08002798
Shishir Agrawal566b7612013-10-28 14:41:00 -07002799 @Override
Derek Tan740e1672017-06-27 14:56:27 -07002800 public IccOpenLogicalChannelResponse iccOpenLogicalChannel(
2801 int subId, String callingPackage, String aid, int p2) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002802 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2803 mApp, subId, "iccOpenLogicalChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002804 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002805
Malcolm Chenaabec062018-02-28 15:00:40 -08002806 final long identity = Binder.clearCallingIdentity();
2807 try {
2808 if (TextUtils.equals(ISDR_AID, aid)) {
2809 // Only allows LPA to open logical channel to ISD-R.
2810 ComponentInfo bestComponent =
2811 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2812 if (bestComponent == null
2813 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2814 loge("The calling package is not allowed to access ISD-R.");
2815 throw new SecurityException(
2816 "The calling package is not allowed to access ISD-R.");
2817 }
Derek Tan740e1672017-06-27 14:56:27 -07002818 }
Derek Tan740e1672017-06-27 14:56:27 -07002819
Malcolm Chenaabec062018-02-28 15:00:40 -08002820 if (DBG) {
2821 log("iccOpenLogicalChannel: subId=" + subId + " aid=" + aid + " p2=" + p2);
2822 }
2823 IccOpenLogicalChannelResponse response = (IccOpenLogicalChannelResponse) sendRequest(
2824 CMD_OPEN_CHANNEL, new Pair<String, Integer>(aid, p2), subId);
2825 if (DBG) log("iccOpenLogicalChannel: " + response);
2826 return response;
2827 } finally {
2828 Binder.restoreCallingIdentity(identity);
2829 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002830 }
2831
2832 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002833 public boolean iccCloseLogicalChannel(int subId, int channel) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002834 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2835 mApp, subId, "iccCloseLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002836
Malcolm Chenaabec062018-02-28 15:00:40 -08002837 final long identity = Binder.clearCallingIdentity();
2838 try {
2839 if (DBG) log("iccCloseLogicalChannel: subId=" + subId + " chnl=" + channel);
2840 if (channel < 0) {
2841 return false;
2842 }
2843 Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, channel, subId);
2844 if (DBG) log("iccCloseLogicalChannel: " + success);
2845 return success;
2846 } finally {
2847 Binder.restoreCallingIdentity(identity);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002848 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002849 }
2850
2851 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002852 public String iccTransmitApduLogicalChannel(int subId, int channel, int cla,
Shishir Agrawal566b7612013-10-28 14:41:00 -07002853 int command, int p1, int p2, int p3, String data) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002854 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2855 mApp, subId, "iccTransmitApduLogicalChannel");
Shishir Agrawal566b7612013-10-28 14:41:00 -07002856
Malcolm Chenaabec062018-02-28 15:00:40 -08002857 final long identity = Binder.clearCallingIdentity();
2858 try {
2859 if (DBG) {
2860 log("iccTransmitApduLogicalChannel: subId=" + subId + " chnl=" + channel
2861 + " cla=" + cla + " cmd=" + command + " p1=" + p1 + " p2=" + p2 + " p3="
2862 + p3 + " data=" + data);
2863 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002864
Malcolm Chenaabec062018-02-28 15:00:40 -08002865 if (channel < 0) {
2866 return "";
2867 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002868
Malcolm Chenaabec062018-02-28 15:00:40 -08002869 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_LOGICAL_CHANNEL,
2870 new IccAPDUArgument(channel, cla, command, p1, p2, p3, data), subId);
2871 if (DBG) log("iccTransmitApduLogicalChannel: " + response);
Shishir Agrawal566b7612013-10-28 14:41:00 -07002872
Malcolm Chenaabec062018-02-28 15:00:40 -08002873 // Append the returned status code to the end of the response payload.
2874 String s = Integer.toHexString(
2875 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2876 if (response.payload != null) {
2877 s = IccUtils.bytesToHexString(response.payload) + s;
2878 }
2879 return s;
2880 } finally {
2881 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002882 }
Shishir Agrawal566b7612013-10-28 14:41:00 -07002883 }
Jake Hambye994d462014-02-03 13:10:13 -08002884
Evan Charltonc66da362014-05-16 14:06:40 -07002885 @Override
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002886 public String iccTransmitApduBasicChannel(int subId, String callingPackage, int cla,
2887 int command, int p1, int p2, int p3, String data) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002888 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2889 mApp, subId, "iccTransmitApduBasicChannel");
Malcolm Chenaabec062018-02-28 15:00:40 -08002890 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002891
Malcolm Chenaabec062018-02-28 15:00:40 -08002892 final long identity = Binder.clearCallingIdentity();
2893 try {
2894 if (command == SELECT_COMMAND && p1 == SELECT_P1 && p2 == SELECT_P2 && p3 == SELECT_P3
2895 && TextUtils.equals(ISDR_AID, data)) {
2896 // Only allows LPA to select ISD-R.
2897 ComponentInfo bestComponent =
2898 EuiccConnector.findBestComponent(mPhone.getContext().getPackageManager());
2899 if (bestComponent == null
2900 || !TextUtils.equals(callingPackage, bestComponent.packageName)) {
2901 loge("The calling package is not allowed to select ISD-R.");
2902 throw new SecurityException(
2903 "The calling package is not allowed to select ISD-R.");
2904 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002905 }
Holly Jiuyu Sun1cc2d552018-01-26 15:51:16 -08002906
Malcolm Chenaabec062018-02-28 15:00:40 -08002907 if (DBG) {
2908 log("iccTransmitApduBasicChannel: subId=" + subId + " cla=" + cla + " cmd="
2909 + command + " p1=" + p1 + " p2=" + p2 + " p3=" + p3 + " data=" + data);
2910 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002911
Malcolm Chenaabec062018-02-28 15:00:40 -08002912 IccIoResult response = (IccIoResult) sendRequest(CMD_TRANSMIT_APDU_BASIC_CHANNEL,
2913 new IccAPDUArgument(0, cla, command, p1, p2, p3, data), subId);
2914 if (DBG) log("iccTransmitApduBasicChannel: " + response);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002915
Malcolm Chenaabec062018-02-28 15:00:40 -08002916 // Append the returned status code to the end of the response payload.
2917 String s = Integer.toHexString(
2918 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
2919 if (response.payload != null) {
2920 s = IccUtils.bytesToHexString(response.payload) + s;
2921 }
2922 return s;
2923 } finally {
2924 Binder.restoreCallingIdentity(identity);
Shishir Agrawal5ec14172014-08-05 17:05:45 -07002925 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002926 }
2927
2928 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002929 public byte[] iccExchangeSimIO(int subId, int fileID, int command, int p1, int p2, int p3,
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002930 String filePath) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002931 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2932 mApp, subId, "iccExchangeSimIO");
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002933
Malcolm Chenaabec062018-02-28 15:00:40 -08002934 final long identity = Binder.clearCallingIdentity();
2935 try {
2936 if (DBG) {
2937 log("Exchange SIM_IO " + subId + ":" + fileID + ":" + command + " "
2938 + p1 + " " + p2 + " " + p3 + ":" + filePath);
2939 }
2940
2941 IccIoResult response =
2942 (IccIoResult) sendRequest(CMD_EXCHANGE_SIM_IO,
2943 new IccAPDUArgument(-1, fileID, command, p1, p2, p3, filePath),
2944 subId);
2945
2946 if (DBG) {
2947 log("Exchange SIM_IO [R]" + response);
2948 }
2949
2950 byte[] result = null;
2951 int length = 2;
2952 if (response.payload != null) {
2953 length = 2 + response.payload.length;
2954 result = new byte[length];
2955 System.arraycopy(response.payload, 0, result, 0, response.payload.length);
2956 } else {
2957 result = new byte[length];
2958 }
2959
2960 result[length - 1] = (byte) response.sw2;
2961 result[length - 2] = (byte) response.sw1;
2962 return result;
2963 } finally {
2964 Binder.restoreCallingIdentity(identity);
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002965 }
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002966 }
2967
Nathan Haroldb3014052017-01-25 15:57:32 -08002968 /**
2969 * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
2970 * on a particular subscription
2971 */
2972 public String[] getForbiddenPlmns(int subId, int appType) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08002973 // TODO(b/73884967): Migrate to TelephonyPermissions check.
Nathan Harold892104e2017-04-13 18:19:05 -07002974 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PHONE_STATE,
2975 "Requires READ_PHONE_STATE");
Nathan Haroldb3014052017-01-25 15:57:32 -08002976 if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
2977 loge("getForbiddenPlmnList(): App Type must be USIM or SIM");
2978 return null;
2979 }
Malcolm Chenaabec062018-02-28 15:00:40 -08002980
2981 final long identity = Binder.clearCallingIdentity();
2982 try {
2983 Object response = sendRequest(CMD_GET_FORBIDDEN_PLMNS, new Integer(appType), subId);
2984 if (response instanceof String[]) {
2985 return (String[]) response;
2986 }
2987 // Response is an Exception of some kind,
2988 // which is signalled to the user as a NULL retval
2989 return null;
2990 } finally {
2991 Binder.restoreCallingIdentity(identity);
Nathan Haroldb3014052017-01-25 15:57:32 -08002992 }
Nathan Haroldb3014052017-01-25 15:57:32 -08002993 }
2994
Shishir Agrawalda0bb0d2014-07-29 21:18:53 -07002995 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08002996 public String sendEnvelopeWithStatus(int subId, String content) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08002997 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
2998 mApp, subId, "sendEnvelopeWithStatus");
Evan Charltonc66da362014-05-16 14:06:40 -07002999
Malcolm Chenaabec062018-02-28 15:00:40 -08003000 final long identity = Binder.clearCallingIdentity();
3001 try {
3002 IccIoResult response = (IccIoResult) sendRequest(CMD_SEND_ENVELOPE, content, subId);
3003 if (response.payload == null) {
3004 return "";
3005 }
Evan Charltonc66da362014-05-16 14:06:40 -07003006
Malcolm Chenaabec062018-02-28 15:00:40 -08003007 // Append the returned status code to the end of the response payload.
3008 String s = Integer.toHexString(
3009 (response.sw1 << 8) + response.sw2 + 0x10000).substring(1);
3010 s = IccUtils.bytesToHexString(response.payload) + s;
3011 return s;
3012 } finally {
3013 Binder.restoreCallingIdentity(identity);
3014 }
Evan Charltonc66da362014-05-16 14:06:40 -07003015 }
3016
Jake Hambye994d462014-02-03 13:10:13 -08003017 /**
3018 * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3019 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3020 *
3021 * @param itemID the ID of the item to read
3022 * @return the NV item as a String, or null on error.
3023 */
3024 @Override
3025 public String nvReadItem(int itemID) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003026 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3027 mApp, getDefaultSubscription(), "nvReadItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003028
3029 final long identity = Binder.clearCallingIdentity();
3030 try {
3031 if (DBG) log("nvReadItem: item " + itemID);
3032 String value = (String) sendRequest(CMD_NV_READ_ITEM, itemID);
3033 if (DBG) log("nvReadItem: item " + itemID + " is \"" + value + '"');
3034 return value;
3035 } finally {
3036 Binder.restoreCallingIdentity(identity);
3037 }
Jake Hambye994d462014-02-03 13:10:13 -08003038 }
3039
3040 /**
3041 * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}
3042 * and {@code ril_nv_items.h}. Used for device configuration by some CDMA operators.
3043 *
3044 * @param itemID the ID of the item to read
3045 * @param itemValue the value to write, as a String
3046 * @return true on success; false on any failure
3047 */
3048 @Override
3049 public boolean nvWriteItem(int itemID, String itemValue) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003050 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3051 mApp, getDefaultSubscription(), "nvWriteItem");
Malcolm Chenaabec062018-02-28 15:00:40 -08003052
3053 final long identity = Binder.clearCallingIdentity();
3054 try {
3055 if (DBG) log("nvWriteItem: item " + itemID + " value \"" + itemValue + '"');
3056 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_ITEM,
3057 new Pair<Integer, String>(itemID, itemValue));
3058 if (DBG) log("nvWriteItem: item " + itemID + ' ' + (success ? "ok" : "fail"));
3059 return success;
3060 } finally {
3061 Binder.restoreCallingIdentity(identity);
3062 }
Jake Hambye994d462014-02-03 13:10:13 -08003063 }
3064
3065 /**
3066 * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
3067 * Used for device configuration by some CDMA operators.
3068 *
3069 * @param preferredRoamingList byte array containing the new PRL
3070 * @return true on success; false on any failure
3071 */
3072 @Override
3073 public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003074 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3075 mApp, getDefaultSubscription(), "nvWriteCdmaPrl");
Malcolm Chenaabec062018-02-28 15:00:40 -08003076
3077 final long identity = Binder.clearCallingIdentity();
3078 try {
3079 if (DBG) log("nvWriteCdmaPrl: value: " + HexDump.toHexString(preferredRoamingList));
3080 Boolean success = (Boolean) sendRequest(CMD_NV_WRITE_CDMA_PRL, preferredRoamingList);
3081 if (DBG) log("nvWriteCdmaPrl: " + (success ? "ok" : "fail"));
3082 return success;
3083 } finally {
3084 Binder.restoreCallingIdentity(identity);
3085 }
Jake Hambye994d462014-02-03 13:10:13 -08003086 }
3087
3088 /**
3089 * Perform the specified type of NV config reset.
3090 * Used for device configuration by some CDMA operators.
3091 *
3092 * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset)
3093 * @return true on success; false on any failure
3094 */
3095 @Override
3096 public boolean nvResetConfig(int resetType) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003097 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3098 mApp, getDefaultSubscription(), "nvResetConfig");
Malcolm Chenaabec062018-02-28 15:00:40 -08003099
3100 final long identity = Binder.clearCallingIdentity();
3101 try {
3102 if (DBG) log("nvResetConfig: type " + resetType);
3103 Boolean success = (Boolean) sendRequest(CMD_NV_RESET_CONFIG, resetType);
3104 if (DBG) log("nvResetConfig: type " + resetType + ' ' + (success ? "ok" : "fail"));
3105 return success;
3106 } finally {
3107 Binder.restoreCallingIdentity(identity);
3108 }
Jake Hambye994d462014-02-03 13:10:13 -08003109 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003110
Svet Ganovb320e182015-04-16 12:30:10 -07003111 public String[] getPcscfAddress(String apnType, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003112 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003113 mApp, mPhone.getSubId(), callingPackage, "getPcscfAddress")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003114 return new String[0];
3115 }
3116
Malcolm Chenaabec062018-02-28 15:00:40 -08003117 final long identity = Binder.clearCallingIdentity();
3118 try {
3119 return mPhone.getPcscfAddress(apnType);
3120 } finally {
3121 Binder.restoreCallingIdentity(identity);
3122 }
Wink Saville36469e72014-06-11 15:17:00 -07003123 }
3124
Brad Ebinger51f743a2017-01-23 13:50:20 -08003125 /**
Brad Ebingera12246d2018-01-16 09:39:35 -08003126 * Enables IMS for the framework. This will trigger IMS registration and ImsFeature capability
3127 * status updates, if not already enabled.
Brad Ebinger51f743a2017-01-23 13:50:20 -08003128 */
Brad Ebingera12246d2018-01-16 09:39:35 -08003129 public void enableIms(int slotId) {
Brad Ebinger51f743a2017-01-23 13:50:20 -08003130 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003131
3132 final long identity = Binder.clearCallingIdentity();
3133 try {
3134 PhoneFactory.getImsResolver().enableIms(slotId);
3135 } finally {
3136 Binder.restoreCallingIdentity(identity);
3137 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003138 }
3139
3140 /**
Brad Ebingera12246d2018-01-16 09:39:35 -08003141 * Disables IMS for the framework. This will trigger IMS de-registration and trigger ImsFeature
3142 * status updates to disabled.
Brad Ebinger34bef922017-11-09 10:27:08 -08003143 */
Brad Ebingera12246d2018-01-16 09:39:35 -08003144 public void disableIms(int slotId) {
3145 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003146
3147 final long identity = Binder.clearCallingIdentity();
3148 try {
3149 PhoneFactory.getImsResolver().disableIms(slotId);
3150 } finally {
3151 Binder.restoreCallingIdentity(identity);
3152 }
Brad Ebingera12246d2018-01-16 09:39:35 -08003153 }
3154
3155 /**
3156 * Returns the {@link IImsMmTelFeature} that corresponds to the given slot Id for the MMTel
3157 * feature or {@link null} if the service is not available. If the feature is available, the
3158 * {@link IImsServiceFeatureCallback} callback is registered as a listener for feature updates.
3159 */
3160 public IImsMmTelFeature getMmTelFeatureAndListen(int slotId,
Brad Ebinger34bef922017-11-09 10:27:08 -08003161 IImsServiceFeatureCallback callback) {
3162 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003163
3164 final long identity = Binder.clearCallingIdentity();
3165 try {
3166 return PhoneFactory.getImsResolver().getMmTelFeatureAndListen(slotId, callback);
3167 } finally {
3168 Binder.restoreCallingIdentity(identity);
3169 }
Brad Ebinger34bef922017-11-09 10:27:08 -08003170 }
3171
3172 /**
3173 * Returns the {@link IImsRcsFeature} that corresponds to the given slot Id for the RCS
3174 * feature during emergency calling or {@link null} if the service is not available. If the
3175 * feature is available, the {@link IImsServiceFeatureCallback} callback is registered as a
3176 * listener for feature updates.
3177 */
3178 public IImsRcsFeature getRcsFeatureAndListen(int slotId, IImsServiceFeatureCallback callback) {
3179 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003180
3181 final long identity = Binder.clearCallingIdentity();
3182 try {
3183 return PhoneFactory.getImsResolver().getRcsFeatureAndListen(slotId, callback);
3184 } finally {
3185 Binder.restoreCallingIdentity(identity);
3186 }
Brad Ebinger51f743a2017-01-23 13:50:20 -08003187 }
3188
Brad Ebinger7e934f52017-12-14 14:26:15 -08003189 /**
3190 * Returns the {@link IImsRegistration} structure associated with the slotId and feature
3191 * specified.
3192 */
3193 public IImsRegistration getImsRegistration(int slotId, int feature) throws RemoteException {
3194 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003195
3196 final long identity = Binder.clearCallingIdentity();
3197 try {
3198 return PhoneFactory.getImsResolver().getImsRegistration(slotId, feature);
3199 } finally {
3200 Binder.restoreCallingIdentity(identity);
3201 }
Brad Ebinger7e934f52017-12-14 14:26:15 -08003202 }
3203
Brad Ebingera12246d2018-01-16 09:39:35 -08003204 /**
3205 * Returns the {@link IImsConfig} structure associated with the slotId and feature
3206 * specified.
3207 */
3208 public IImsConfig getImsConfig(int slotId, int feature) throws RemoteException {
3209 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003210
3211 final long identity = Binder.clearCallingIdentity();
3212 try {
3213 return PhoneFactory.getImsResolver().getImsConfig(slotId, feature);
3214 } finally {
3215 Binder.restoreCallingIdentity(identity);
3216 }
Brad Ebingera12246d2018-01-16 09:39:35 -08003217 }
3218
Brad Ebinger884c07b2018-02-15 16:17:40 -08003219 /**
Brad Ebinger67801702018-03-02 13:43:36 -08003220 * @return true if the IMS resolver is busy resolving a binding and should not be considered
3221 * available, false if the IMS resolver is idle.
3222 */
3223 public boolean isResolvingImsBinding() {
3224 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003225
3226 final long identity = Binder.clearCallingIdentity();
3227 try {
3228 return PhoneFactory.getImsResolver().isResolvingBinding();
3229 } finally {
3230 Binder.restoreCallingIdentity(identity);
3231 }
Brad Ebinger67801702018-03-02 13:43:36 -08003232 }
3233
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003234 /**
3235 * Sets the ImsService Package Name that Telephony will bind to.
3236 *
3237 * @param slotId the slot ID that the ImsService should bind for.
3238 * @param isCarrierImsService true if the ImsService is the carrier override, false if the
3239 * ImsService is the device default ImsService.
3240 * @param packageName The package name of the application that contains the ImsService to bind
3241 * to.
3242 * @return true if setting the ImsService to bind to succeeded, false if it did not.
3243 * @hide
3244 */
3245 public boolean setImsService(int slotId, boolean isCarrierImsService, String packageName) {
Brad Ebingera6377d92018-04-06 09:56:40 -07003246 int[] subIds = SubscriptionManager.getSubId(slotId);
3247 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3248 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3249 "setImsService");
3250
Malcolm Chenaabec062018-02-28 15:00:40 -08003251 final long identity = Binder.clearCallingIdentity();
3252 try {
3253 return PhoneFactory.getImsResolver().overrideImsServiceConfiguration(slotId,
3254 isCarrierImsService, packageName);
3255 } finally {
3256 Binder.restoreCallingIdentity(identity);
3257 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003258 }
3259
3260 /**
3261 * Return the ImsService configuration.
3262 *
3263 * @param slotId The slot that the ImsService is associated with.
3264 * @param isCarrierImsService true, if the ImsService is a carrier override, false if it is
3265 * the device default.
3266 * @return the package name of the ImsService configuration.
3267 */
3268 public String getImsService(int slotId, boolean isCarrierImsService) {
Brad Ebingera6377d92018-04-06 09:56:40 -07003269 int[] subIds = SubscriptionManager.getSubId(slotId);
3270 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(mApp,
3271 (subIds != null ? subIds[0] : SubscriptionManager.INVALID_SUBSCRIPTION_ID),
3272 "getImsService");
3273
Malcolm Chenaabec062018-02-28 15:00:40 -08003274 final long identity = Binder.clearCallingIdentity();
3275 try {
3276 return PhoneFactory.getImsResolver().getImsServiceConfiguration(slotId,
3277 isCarrierImsService);
3278 } finally {
3279 Binder.restoreCallingIdentity(identity);
3280 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003281 }
3282
Wink Saville36469e72014-06-11 15:17:00 -07003283 public void setImsRegistrationState(boolean registered) {
3284 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003285
3286 final long identity = Binder.clearCallingIdentity();
3287 try {
3288 mPhone.setImsRegistrationState(registered);
3289 } finally {
3290 Binder.restoreCallingIdentity(identity);
3291 }
Wink Saville36469e72014-06-11 15:17:00 -07003292 }
3293
3294 /**
Stuart Scott54788802015-03-30 13:18:01 -07003295 * Set the network selection mode to automatic.
3296 *
3297 */
3298 @Override
3299 public void setNetworkSelectionModeAutomatic(int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003300 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3301 mApp, subId, "setNetworkSelectionModeAutomatic");
Malcolm Chenaabec062018-02-28 15:00:40 -08003302
3303 final long identity = Binder.clearCallingIdentity();
3304 try {
3305 if (DBG) log("setNetworkSelectionModeAutomatic: subId " + subId);
3306 sendRequest(CMD_SET_NETWORK_SELECTION_MODE_AUTOMATIC, null, subId);
3307 } finally {
3308 Binder.restoreCallingIdentity(identity);
3309 }
Stuart Scott54788802015-03-30 13:18:01 -07003310 }
3311
3312 /**
Shishir Agrawal302c8692015-06-19 13:49:39 -07003313 * Set the network selection mode to manual with the selected carrier.
3314 */
3315 @Override
yinxu6e5abd72017-12-01 11:35:19 -08003316 public boolean setNetworkSelectionModeManual(int subId, String operatorNumeric,
Shishir Agrawal77ba3172015-09-10 14:50:19 -07003317 boolean persistSelection) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003318 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3319 mApp, subId, "setNetworkSelectionModeManual");
Malcolm Chenaabec062018-02-28 15:00:40 -08003320
3321 final long identity = Binder.clearCallingIdentity();
3322 try {
3323 OperatorInfo operator = new OperatorInfo(
yinxu6e5abd72017-12-01 11:35:19 -08003324 /* operatorAlphaLong */ "",
3325 /* operatorAlphaShort */ "",
Malcolm Chenaabec062018-02-28 15:00:40 -08003326 operatorNumeric);
3327 if (DBG) log("setNetworkSelectionModeManual: subId:" + subId + " operator:" + operator);
3328 ManualNetworkSelectionArgument arg = new ManualNetworkSelectionArgument(operator,
3329 persistSelection);
3330 return (Boolean) sendRequest(CMD_SET_NETWORK_SELECTION_MODE_MANUAL, arg, subId);
3331 } finally {
3332 Binder.restoreCallingIdentity(identity);
3333 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003334 }
3335
3336 /**
3337 * Scans for available networks.
3338 */
3339 @Override
3340 public CellNetworkScanResult getCellNetworkScanResults(int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003341 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3342 mApp, subId, "getCellNetworkScanResults");
Malcolm Chenaabec062018-02-28 15:00:40 -08003343
3344 final long identity = Binder.clearCallingIdentity();
3345 try {
3346 if (DBG) log("getCellNetworkScanResults: subId " + subId);
3347 CellNetworkScanResult result = (CellNetworkScanResult) sendRequest(
3348 CMD_PERFORM_NETWORK_SCAN, null, subId);
3349 return result;
3350 } finally {
3351 Binder.restoreCallingIdentity(identity);
3352 }
Shishir Agrawal302c8692015-06-19 13:49:39 -07003353 }
3354
3355 /**
yinxub1bed742017-04-17 11:45:04 -07003356 * Starts a new network scan and returns the id of this scan.
yinxu504e1392017-04-12 16:03:22 -07003357 *
yinxub1bed742017-04-17 11:45:04 -07003358 * @param subId id of the subscription
3359 * @param request contains the radio access networks with bands/channels to scan
3360 * @param messenger callback messenger for scan results or errors
3361 * @param binder for the purpose of auto clean when the user thread crashes
yinxu504e1392017-04-12 16:03:22 -07003362 * @return the id of the requested scan which can be used to stop the scan.
3363 */
3364 @Override
3365 public int requestNetworkScan(int subId, NetworkScanRequest request, Messenger messenger,
3366 IBinder binder) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003367 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3368 mApp, subId, "requestNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003369
3370 final long identity = Binder.clearCallingIdentity();
3371 try {
3372 return mNetworkScanRequestTracker.startNetworkScan(
3373 request, messenger, binder, getPhone(subId));
3374 } finally {
3375 Binder.restoreCallingIdentity(identity);
3376 }
yinxu504e1392017-04-12 16:03:22 -07003377 }
3378
3379 /**
3380 * Stops an existing network scan with the given scanId.
yinxub1bed742017-04-17 11:45:04 -07003381 *
3382 * @param subId id of the subscription
3383 * @param scanId id of the scan that needs to be stopped
yinxu504e1392017-04-12 16:03:22 -07003384 */
3385 @Override
3386 public void stopNetworkScan(int subId, int scanId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003387 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3388 mApp, subId, "stopNetworkScan");
Malcolm Chenaabec062018-02-28 15:00:40 -08003389
3390 final long identity = Binder.clearCallingIdentity();
3391 try {
3392 mNetworkScanRequestTracker.stopNetworkScan(scanId);
3393 } finally {
3394 Binder.restoreCallingIdentity(identity);
3395 }
yinxu504e1392017-04-12 16:03:22 -07003396 }
3397
3398 /**
Junda Liu84d15a22014-07-02 11:21:04 -07003399 * Get the calculated preferred network type.
3400 * Used for debugging incorrect network type.
3401 *
3402 * @return the preferred network type, defined in RILConstants.java.
3403 */
3404 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003405 public int getCalculatedPreferredNetworkType(String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003406 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003407 mApp, mPhone.getSubId(), callingPackage, "getCalculatedPreferredNetworkType")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003408 return RILConstants.PREFERRED_NETWORK_MODE;
3409 }
3410
Malcolm Chenaabec062018-02-28 15:00:40 -08003411 final long identity = Binder.clearCallingIdentity();
3412 try {
3413 // FIXME: need to get SubId from somewhere.
3414 return PhoneFactory.calculatePreferredNetworkType(mPhone.getContext(), 0);
3415 } finally {
3416 Binder.restoreCallingIdentity(identity);
3417 }
Junda Liu84d15a22014-07-02 11:21:04 -07003418 }
3419
3420 /**
Jake Hamby7c27be32014-03-03 13:25:59 -08003421 * Get the preferred network type.
3422 * Used for device configuration by some CDMA operators.
3423 *
3424 * @return the preferred network type, defined in RILConstants.java.
3425 */
3426 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003427 public int getPreferredNetworkType(int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003428 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3429 mApp, subId, "getPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003430
3431 final long identity = Binder.clearCallingIdentity();
3432 try {
3433 if (DBG) log("getPreferredNetworkType");
3434 int[] result = (int[]) sendRequest(CMD_GET_PREFERRED_NETWORK_TYPE, null, subId);
3435 int networkType = (result != null ? result[0] : -1);
3436 if (DBG) log("getPreferredNetworkType: " + networkType);
3437 return networkType;
3438 } finally {
3439 Binder.restoreCallingIdentity(identity);
3440 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003441 }
3442
3443 /**
3444 * Set the preferred network type.
3445 * Used for device configuration by some CDMA operators.
3446 *
3447 * @param networkType the preferred network type, defined in RILConstants.java.
3448 * @return true on success; false on any failure.
3449 */
3450 @Override
Stuart Scott54788802015-03-30 13:18:01 -07003451 public boolean setPreferredNetworkType(int subId, int networkType) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003452 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3453 mApp, subId, "setPreferredNetworkType");
Malcolm Chenaabec062018-02-28 15:00:40 -08003454
3455 final long identity = Binder.clearCallingIdentity();
3456 try {
3457 if (DBG) log("setPreferredNetworkType: subId " + subId + " type " + networkType);
3458 Boolean success = (Boolean) sendRequest(
3459 CMD_SET_PREFERRED_NETWORK_TYPE, networkType, subId);
3460 if (DBG) log("setPreferredNetworkType: " + (success ? "ok" : "fail"));
3461 if (success) {
3462 Settings.Global.putInt(mPhone.getContext().getContentResolver(),
3463 Settings.Global.PREFERRED_NETWORK_MODE + subId, networkType);
3464 }
3465 return success;
3466 } finally {
3467 Binder.restoreCallingIdentity(identity);
Junda Liu80bc0d12014-07-14 16:36:44 -07003468 }
Jake Hamby7c27be32014-03-03 13:25:59 -08003469 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003470
3471 /**
Junda Liu475951f2014-11-07 16:45:03 -08003472 * Check TETHER_DUN_REQUIRED and TETHER_DUN_APN settings, net.tethering.noprovisioning
3473 * SystemProperty, and config_tether_apndata to decide whether DUN APN is required for
3474 * tethering.
3475 *
3476 * @return 0: Not required. 1: required. 2: Not set.
3477 * @hide
3478 */
3479 @Override
3480 public int getTetherApnRequired() {
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003481 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08003482
3483 final long identity = Binder.clearCallingIdentity();
3484 try {
3485 int dunRequired = Settings.Global.getInt(mPhone.getContext().getContentResolver(),
3486 Settings.Global.TETHER_DUN_REQUIRED, 2);
3487 // If not set, check net.tethering.noprovisioning, TETHER_DUN_APN setting and
3488 // config_tether_apndata.
3489 if (dunRequired == 2 && mPhone.hasMatchedTetherApnSetting()) {
3490 dunRequired = 1;
3491 }
3492 return dunRequired;
3493 } finally {
3494 Binder.restoreCallingIdentity(identity);
Junda Liu475951f2014-11-07 16:45:03 -08003495 }
Junda Liu475951f2014-11-07 16:45:03 -08003496 }
3497
3498 /**
Robert Greenwalted86e582014-05-21 20:03:20 -07003499 * Set mobile data enabled
3500 * Used by the user through settings etc to turn on/off mobile data
3501 *
3502 * @param enable {@code true} turn turn data on, else {@code false}
3503 */
3504 @Override
Malcolm Chenfd5068e2017-11-28 16:20:07 -08003505 public void setUserDataEnabled(int subId, boolean enable) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003506 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3507 mApp, subId, "setUserDataEnabled");
Malcolm Chenaabec062018-02-28 15:00:40 -08003508
3509 final long identity = Binder.clearCallingIdentity();
3510 try {
3511 int phoneId = mSubscriptionController.getPhoneId(subId);
3512 if (DBG) log("setUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3513 Phone phone = PhoneFactory.getPhone(phoneId);
3514 if (phone != null) {
3515 if (DBG) log("setUserDataEnabled: subId=" + subId + " enable=" + enable);
3516 phone.setUserDataEnabled(enable);
3517 } else {
3518 loge("setUserDataEnabled: no phone for subId=" + subId);
3519 }
3520 } finally {
3521 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003522 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003523 }
3524
3525 /**
Malcolm Chenfd5068e2017-11-28 16:20:07 -08003526 * Get the user enabled state of Mobile Data.
3527 *
3528 * TODO: remove and use isUserDataEnabled.
3529 * This can't be removed now because some vendor codes
3530 * calls through ITelephony directly while they should
3531 * use TelephonyManager.
3532 *
3533 * @return true on enabled
3534 */
3535 @Override
3536 public boolean getDataEnabled(int subId) {
3537 return isUserDataEnabled(subId);
3538 }
3539
3540 /**
3541 * Get whether mobile data is enabled per user setting.
3542 *
3543 * There are other factors deciding whether mobile data is actually enabled, but they are
3544 * not considered here. See {@link #isDataEnabled(int)} for more details.
Robert Greenwalt646120a2014-05-23 11:54:03 -07003545 *
Jeff Davidsona1920712016-11-18 17:05:56 -08003546 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
Robert Greenwalted86e582014-05-21 20:03:20 -07003547 *
3548 * @return {@code true} if data is enabled else {@code false}
3549 */
3550 @Override
Malcolm Chenfd5068e2017-11-28 16:20:07 -08003551 public boolean isUserDataEnabled(int subId) {
Robert Greenwalt646120a2014-05-23 11:54:03 -07003552 try {
3553 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3554 null);
3555 } catch (Exception e) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003556 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3557 mApp, subId, "isUserDataEnabled");
Robert Greenwalt646120a2014-05-23 11:54:03 -07003558 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003559
3560 final long identity = Binder.clearCallingIdentity();
3561 try {
3562 int phoneId = mSubscriptionController.getPhoneId(subId);
3563 if (DBG) log("isUserDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3564 Phone phone = PhoneFactory.getPhone(phoneId);
3565 if (phone != null) {
3566 boolean retVal = phone.isUserDataEnabled();
3567 if (DBG) log("isUserDataEnabled: subId=" + subId + " retVal=" + retVal);
3568 return retVal;
3569 } else {
3570 if (DBG) loge("isUserDataEnabled: no phone subId=" + subId + " retVal=false");
3571 return false;
3572 }
3573 } finally {
3574 Binder.restoreCallingIdentity(identity);
Malcolm Chenfd5068e2017-11-28 16:20:07 -08003575 }
3576 }
3577
3578 /**
3579 * Get whether mobile data is enabled.
3580 *
3581 * Comparable to {@link #isUserDataEnabled(int)}, this considers all factors deciding
3582 * whether mobile data is actually enabled.
3583 *
3584 * Accepts either ACCESS_NETWORK_STATE, MODIFY_PHONE_STATE or carrier privileges.
3585 *
3586 * @return {@code true} if data is enabled else {@code false}
3587 */
3588 @Override
3589 public boolean isDataEnabled(int subId) {
3590 try {
3591 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_NETWORK_STATE,
3592 null);
3593 } catch (Exception e) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003594 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
3595 mApp, subId, "isDataEnabled");
Malcolm Chenfd5068e2017-11-28 16:20:07 -08003596 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003597
3598 final long identity = Binder.clearCallingIdentity();
3599 try {
3600 int phoneId = mSubscriptionController.getPhoneId(subId);
3601 if (DBG) log("isDataEnabled: subId=" + subId + " phoneId=" + phoneId);
3602 Phone phone = PhoneFactory.getPhone(phoneId);
3603 if (phone != null) {
3604 boolean retVal = phone.isDataEnabled();
3605 if (DBG) log("isDataEnabled: subId=" + subId + " retVal=" + retVal);
3606 return retVal;
3607 } else {
3608 if (DBG) loge("isDataEnabled: no phone subId=" + subId + " retVal=false");
3609 return false;
3610 }
3611 } finally {
3612 Binder.restoreCallingIdentity(identity);
Wink Savillee7353bb2014-12-05 14:21:41 -08003613 }
Robert Greenwalted86e582014-05-21 20:03:20 -07003614 }
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003615
3616 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003617 public int getCarrierPrivilegeStatus(int subId) {
3618 final Phone phone = getPhone(subId);
3619 if (phone == null) {
3620 loge("getCarrierPrivilegeStatus: Invalid subId");
3621 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3622 }
3623 UiccCard card = UiccController.getInstance().getUiccCard(phone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003624 if (card == null) {
Shishir Agrawal5e5becd2014-11-18 11:38:23 -08003625 loge("getCarrierPrivilegeStatus: No UICC");
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003626 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3627 }
3628 return card.getCarrierPrivilegeStatusForCurrentTransaction(
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003629 phone.getContext().getPackageManager());
Shishir Agrawal60f9c952014-06-23 12:00:43 -07003630 }
Junda Liu29340342014-07-10 15:23:27 -07003631
3632 @Override
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003633 public int getCarrierPrivilegeStatusForUid(int subId, int uid) {
3634 final Phone phone = getPhone(subId);
3635 if (phone == null) {
3636 loge("getCarrierPrivilegeStatus: Invalid subId");
3637 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
3638 }
3639 UiccProfile profile =
3640 UiccController.getInstance().getUiccProfileForPhone(phone.getPhoneId());
3641 if (profile == null) {
3642 loge("getCarrierPrivilegeStatus: No UICC");
3643 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3644 }
3645 return profile.getCarrierPrivilegeStatusForUid(phone.getContext().getPackageManager(), uid);
3646 }
3647
3648 @Override
Zach Johnson50ecba32015-05-19 00:24:21 -07003649 public int checkCarrierPrivilegesForPackage(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003650 if (TextUtils.isEmpty(pkgName))
3651 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Shishir Agrawal21409252015-01-15 23:33:50 -08003652 UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
Shishir Agrawaleb8771e2014-07-22 11:24:08 -07003653 if (card == null) {
3654 loge("checkCarrierPrivilegesForPackage: No UICC");
3655 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3656 }
Zach Johnson50ecba32015-05-19 00:24:21 -07003657 return card.getCarrierPrivilegeStatus(mPhone.getContext().getPackageManager(), pkgName);
3658 }
3659
3660 @Override
3661 public int checkCarrierPrivilegesForPackageAnyPhone(String pkgName) {
Junda Liu317d70b2016-03-08 09:33:53 -08003662 if (TextUtils.isEmpty(pkgName))
3663 return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
Zach Johnson50ecba32015-05-19 00:24:21 -07003664 int result = TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
3665 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3666 UiccCard card = UiccController.getInstance().getUiccCard(i);
3667 if (card == null) {
Jonathan Basseri7d320df2015-06-16 12:17:08 -07003668 // No UICC in that slot.
Zach Johnson50ecba32015-05-19 00:24:21 -07003669 continue;
3670 }
3671
3672 result = card.getCarrierPrivilegeStatus(
3673 mPhone.getContext().getPackageManager(), pkgName);
3674 if (result == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3675 break;
3676 }
3677 }
3678
3679 return result;
Junda Liu29340342014-07-10 15:23:27 -07003680 }
Derek Tan89e89d42014-07-08 17:00:10 -07003681
3682 @Override
Junda Liue64de782015-04-16 17:19:16 -07003683 public List<String> getCarrierPackageNamesForIntentAndPhone(Intent intent, int phoneId) {
3684 if (!SubscriptionManager.isValidPhoneId(phoneId)) {
3685 loge("phoneId " + phoneId + " is not valid.");
3686 return null;
3687 }
3688 UiccCard card = UiccController.getInstance().getUiccCard(phoneId);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003689 if (card == null) {
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003690 loge("getCarrierPackageNamesForIntent: No UICC");
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003691 return null ;
3692 }
Diego Pontorieroaf74c862014-08-28 11:51:16 -07003693 return card.getCarrierPackageNamesForIntent(
Svetoslav483aff72015-04-21 14:16:07 -07003694 mPhone.getContext().getPackageManager(), intent);
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003695 }
3696
Amith Yamasani6e118872016-02-19 12:53:51 -08003697 @Override
3698 public List<String> getPackagesWithCarrierPrivileges() {
3699 PackageManager pm = mPhone.getContext().getPackageManager();
3700 List<String> privilegedPackages = new ArrayList<>();
3701 List<PackageInfo> packages = null;
3702 for (int i = 0; i < TelephonyManager.getDefault().getPhoneCount(); i++) {
3703 UiccCard card = UiccController.getInstance().getUiccCard(i);
3704 if (card == null) {
3705 // No UICC in that slot.
3706 continue;
3707 }
3708 if (card.hasCarrierPrivilegeRules()) {
3709 if (packages == null) {
3710 // Only check packages in user 0 for now
3711 packages = pm.getInstalledPackagesAsUser(
3712 PackageManager.MATCH_DISABLED_COMPONENTS
3713 | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
3714 | PackageManager.GET_SIGNATURES, UserHandle.USER_SYSTEM);
3715 }
3716 for (int p = packages.size() - 1; p >= 0; p--) {
3717 PackageInfo pkgInfo = packages.get(p);
3718 if (pkgInfo != null && pkgInfo.packageName != null
3719 && card.getCarrierPrivilegeStatus(pkgInfo)
3720 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
3721 privilegedPackages.add(pkgInfo.packageName);
3722 }
3723 }
3724 }
3725 }
3726 return privilegedPackages;
3727 }
3728
Wink Savilleb564aae2014-10-23 10:18:09 -07003729 private String getIccId(int subId) {
Sanket Padawe356d7632015-06-22 14:03:32 -07003730 final Phone phone = getPhone(subId);
3731 UiccCard card = phone == null ? null : phone.getUiccCard();
Derek Tan97ebb422014-09-05 16:55:38 -07003732 if (card == null) {
3733 loge("getIccId: No UICC");
3734 return null;
3735 }
3736 String iccId = card.getIccId();
3737 if (TextUtils.isEmpty(iccId)) {
3738 loge("getIccId: ICC ID is null or empty.");
3739 return null;
3740 }
3741 return iccId;
3742 }
3743
Shishir Agrawaleb6439a2014-07-21 13:19:38 -07003744 @Override
Jeff Sharkey85190e62014-12-05 09:40:12 -08003745 public boolean setLine1NumberForDisplayForSubscriber(int subId, String alphaTag,
3746 String number) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003747 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3748 subId, "setLine1NumberForDisplayForSubscriber");
Derek Tan97ebb422014-09-05 16:55:38 -07003749
Malcolm Chenaabec062018-02-28 15:00:40 -08003750 final long identity = Binder.clearCallingIdentity();
3751 try {
3752 final String iccId = getIccId(subId);
3753 final Phone phone = getPhone(subId);
3754 if (phone == null) {
3755 return false;
3756 }
3757 final String subscriberId = phone.getSubscriberId();
3758
3759 if (DBG_MERGE) {
3760 Slog.d(LOG_TAG, "Setting line number for ICC=" + iccId + ", subscriberId="
3761 + subscriberId + " to " + number);
3762 }
3763
3764 if (TextUtils.isEmpty(iccId)) {
3765 return false;
3766 }
3767
3768 final SharedPreferences.Editor editor = mTelephonySharedPreferences.edit();
3769
3770 final String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3771 if (alphaTag == null) {
3772 editor.remove(alphaTagPrefKey);
3773 } else {
3774 editor.putString(alphaTagPrefKey, alphaTag);
3775 }
3776
3777 // Record both the line number and IMSI for this ICCID, since we need to
3778 // track all merged IMSIs based on line number
3779 final String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3780 final String subscriberPrefKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3781 if (number == null) {
3782 editor.remove(numberPrefKey);
3783 editor.remove(subscriberPrefKey);
3784 } else {
3785 editor.putString(numberPrefKey, number);
3786 editor.putString(subscriberPrefKey, subscriberId);
3787 }
3788
3789 editor.commit();
3790 return true;
3791 } finally {
3792 Binder.restoreCallingIdentity(identity);
Sanket Padawe356d7632015-06-22 14:03:32 -07003793 }
Derek Tan7226c842014-07-02 17:42:23 -07003794 }
3795
3796 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003797 public String getLine1NumberForDisplay(int subId, String callingPackage) {
Makoto Onukifee69342015-06-29 14:44:50 -07003798 // This is open to apps with WRITE_SMS.
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003799 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003800 mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
Amit Mahajan9cf11512015-11-09 11:40:48 -08003801 if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
Svet Ganovb320e182015-04-16 12:30:10 -07003802 return null;
3803 }
Derek Tan97ebb422014-09-05 16:55:38 -07003804
Malcolm Chenaabec062018-02-28 15:00:40 -08003805 final long identity = Binder.clearCallingIdentity();
3806 try {
3807 String iccId = getIccId(subId);
3808 if (iccId != null) {
3809 String numberPrefKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3810 if (DBG_MERGE) {
3811 log("getLine1NumberForDisplay returning "
3812 + mTelephonySharedPreferences.getString(numberPrefKey, null));
3813 }
3814 return mTelephonySharedPreferences.getString(numberPrefKey, null);
Amit Mahajan9cf11512015-11-09 11:40:48 -08003815 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003816 if (DBG_MERGE) log("getLine1NumberForDisplay returning null as iccId is null");
3817 return null;
3818 } finally {
3819 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003820 }
Derek Tan7226c842014-07-02 17:42:23 -07003821 }
3822
3823 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07003824 public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003825 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003826 mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
Svet Ganovb320e182015-04-16 12:30:10 -07003827 return null;
3828 }
Derek Tan97ebb422014-09-05 16:55:38 -07003829
Malcolm Chenaabec062018-02-28 15:00:40 -08003830 final long identity = Binder.clearCallingIdentity();
3831 try {
3832 String iccId = getIccId(subId);
3833 if (iccId != null) {
3834 String alphaTagPrefKey = PREF_CARRIERS_ALPHATAG_PREFIX + iccId;
3835 return mTelephonySharedPreferences.getString(alphaTagPrefKey, null);
3836 }
3837 return null;
3838 } finally {
3839 Binder.restoreCallingIdentity(identity);
Derek Tan7226c842014-07-02 17:42:23 -07003840 }
Derek Tan7226c842014-07-02 17:42:23 -07003841 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003842
3843 @Override
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003844 public String[] getMergedSubscriberIds(String callingPackage) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003845 // This API isn't public, so no need to provide a valid subscription ID - we're not worried
3846 // about carrier-privileged callers not having access.
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003847 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08003848 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
3849 "getMergedSubscriberIds")) {
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003850 return null;
3851 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003852
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003853 final long identity = Binder.clearCallingIdentity();
3854 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08003855 final Context context = mPhone.getContext();
3856 final TelephonyManager tele = TelephonyManager.from(context);
3857 final SubscriptionManager sub = SubscriptionManager.from(context);
3858
3859 // Figure out what subscribers are currently active
3860 final ArraySet<String> activeSubscriberIds = new ArraySet<>();
3861 // Clear calling identity, when calling TelephonyManager, because callerUid must be
3862 // the process, where TelephonyManager was instantiated.
3863 // Otherwise AppOps check will fail.
3864
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003865 final int[] subIds = sub.getActiveSubscriptionIdList();
3866 for (int subId : subIds) {
3867 activeSubscriberIds.add(tele.getSubscriberId(subId));
3868 }
Malcolm Chenaabec062018-02-28 15:00:40 -08003869
3870 // First pass, find a number override for an active subscriber
3871 String mergeNumber = null;
3872 final Map<String, ?> prefs = mTelephonySharedPreferences.getAll();
3873 for (String key : prefs.keySet()) {
3874 if (key.startsWith(PREF_CARRIERS_SUBSCRIBER_PREFIX)) {
3875 final String subscriberId = (String) prefs.get(key);
3876 if (activeSubscriberIds.contains(subscriberId)) {
3877 final String iccId = key.substring(
3878 PREF_CARRIERS_SUBSCRIBER_PREFIX.length());
3879 final String numberKey = PREF_CARRIERS_NUMBER_PREFIX + iccId;
3880 mergeNumber = (String) prefs.get(numberKey);
3881 if (DBG_MERGE) {
3882 Slog.d(LOG_TAG, "Found line number " + mergeNumber
3883 + " for active subscriber " + subscriberId);
3884 }
3885 if (!TextUtils.isEmpty(mergeNumber)) {
3886 break;
3887 }
3888 }
3889 }
3890 }
3891
3892 // Shortcut when no active merged subscribers
3893 if (TextUtils.isEmpty(mergeNumber)) {
3894 return null;
3895 }
3896
3897 // Second pass, find all subscribers under that line override
3898 final ArraySet<String> result = new ArraySet<>();
3899 for (String key : prefs.keySet()) {
3900 if (key.startsWith(PREF_CARRIERS_NUMBER_PREFIX)) {
3901 final String number = (String) prefs.get(key);
3902 if (mergeNumber.equals(number)) {
3903 final String iccId = key.substring(PREF_CARRIERS_NUMBER_PREFIX.length());
3904 final String subscriberKey = PREF_CARRIERS_SUBSCRIBER_PREFIX + iccId;
3905 final String subscriberId = (String) prefs.get(subscriberKey);
3906 if (!TextUtils.isEmpty(subscriberId)) {
3907 result.add(subscriberId);
3908 }
3909 }
3910 }
3911 }
3912
3913 final String[] resultArray = result.toArray(new String[result.size()]);
3914 Arrays.sort(resultArray);
3915 if (DBG_MERGE) {
3916 Slog.d(LOG_TAG,
3917 "Found subscribers " + Arrays.toString(resultArray) + " after merge");
3918 }
3919 return resultArray;
Fyodor Kupolov8e53b0b2015-06-17 13:17:50 -07003920 } finally {
3921 Binder.restoreCallingIdentity(identity);
Jeff Sharkey85190e62014-12-05 09:40:12 -08003922 }
Jeff Sharkey85190e62014-12-05 09:40:12 -08003923 }
3924
3925 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003926 public boolean setOperatorBrandOverride(int subId, String brand) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003927 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(
3928 subId, "setOperatorBrandOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003929
3930 final long identity = Binder.clearCallingIdentity();
3931 try {
3932 final Phone phone = getPhone(subId);
3933 return phone == null ? false : phone.setOperatorBrandOverride(brand);
3934 } finally {
3935 Binder.restoreCallingIdentity(identity);
3936 }
Shishir Agrawalb1ebf8c2014-07-17 16:32:41 -07003937 }
Steven Liu4bf01bc2014-07-17 11:05:29 -05003938
3939 @Override
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003940 public boolean setRoamingOverride(int subId, List<String> gsmRoamingList,
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003941 List<String> gsmNonRoamingList, List<String> cdmaRoamingList,
3942 List<String> cdmaNonRoamingList) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08003943 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(subId, "setRoamingOverride");
Malcolm Chenaabec062018-02-28 15:00:40 -08003944
3945 final long identity = Binder.clearCallingIdentity();
3946 try {
3947 final Phone phone = getPhone(subId);
3948 if (phone == null) {
3949 return false;
3950 }
3951 return phone.setRoamingOverride(gsmRoamingList, gsmNonRoamingList, cdmaRoamingList,
3952 cdmaNonRoamingList);
3953 } finally {
3954 Binder.restoreCallingIdentity(identity);
Shishir Agrawalc04d9752016-02-19 10:41:00 -08003955 }
Shishir Agrawal621a47c2014-12-01 10:25:09 -08003956 }
3957
3958 @Override
Shuo Qian74b16b12018-04-27 01:32:07 +00003959 @Deprecated
3960 public int invokeOemRilRequestRaw(byte[] oemReq, byte[] oemResp) {
3961 enforceModifyPermission();
3962
3963 int returnValue = 0;
3964 try {
3965 AsyncResult result = (AsyncResult)sendRequest(CMD_INVOKE_OEM_RIL_REQUEST_RAW, oemReq);
3966 if(result.exception == null) {
3967 if (result.result != null) {
3968 byte[] responseData = (byte[])(result.result);
3969 if(responseData.length > oemResp.length) {
3970 Log.w(LOG_TAG, "Buffer to copy response too small: Response length is " +
3971 responseData.length + "bytes. Buffer Size is " +
3972 oemResp.length + "bytes.");
3973 }
3974 System.arraycopy(responseData, 0, oemResp, 0, responseData.length);
3975 returnValue = responseData.length;
3976 }
3977 } else {
3978 CommandException ex = (CommandException) result.exception;
3979 returnValue = ex.getCommandError().ordinal();
3980 if(returnValue > 0) returnValue *= -1;
3981 }
3982 } catch (RuntimeException e) {
3983 Log.w(LOG_TAG, "sendOemRilRequestRaw: Runtime Exception");
3984 returnValue = (CommandException.Error.GENERIC_FAILURE.ordinal());
3985 if(returnValue > 0) returnValue *= -1;
3986 }
3987
3988 return returnValue;
3989 }
3990
3991 @Override
Wink Saville5d475dd2014-10-17 15:00:58 -07003992 public void setRadioCapability(RadioAccessFamily[] rafs) {
3993 try {
3994 ProxyController.getInstance().setRadioCapability(rafs);
3995 } catch (RuntimeException e) {
3996 Log.w(LOG_TAG, "setRadioCapability: Runtime Exception");
3997 }
3998 }
3999
4000 @Override
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004001 public int getRadioAccessFamily(int phoneId, String callingPackage) {
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004002 Phone phone = PhoneFactory.getPhone(phoneId);
4003 if (phone == null) {
4004 return RadioAccessFamily.RAF_UNKNOWN;
4005 }
4006 int subId = phone.getSubId();
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004007 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004008 mApp, subId, callingPackage, "getRadioAccessFamily")) {
Robert Greenwalt36b23af2015-07-06 17:59:14 -07004009 return RadioAccessFamily.RAF_UNKNOWN;
4010 }
4011
Malcolm Chenaabec062018-02-28 15:00:40 -08004012 final long identity = Binder.clearCallingIdentity();
4013 try {
4014 return ProxyController.getInstance().getRadioAccessFamily(phoneId);
4015 } finally {
4016 Binder.restoreCallingIdentity(identity);
4017 }
Wink Saville5d475dd2014-10-17 15:00:58 -07004018 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004019
4020 @Override
4021 public void enableVideoCalling(boolean enable) {
4022 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004023
4024 final long identity = Binder.clearCallingIdentity();
4025 try {
4026 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId()).setVtSetting(enable);
4027 } finally {
4028 Binder.restoreCallingIdentity(identity);
4029 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004030 }
4031
4032 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004033 public boolean isVideoCallingEnabled(String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004034 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004035 mApp, mPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
Svet Ganovb320e182015-04-16 12:30:10 -07004036 return false;
4037 }
4038
Malcolm Chenaabec062018-02-28 15:00:40 -08004039 final long identity = Binder.clearCallingIdentity();
4040 try {
4041 // Check the user preference and the system-level IMS setting. Even if the user has
4042 // enabled video calling, if IMS is disabled we aren't able to support video calling.
4043 // In the long run, we may instead need to check if there exists a connection service
4044 // which can support video calling.
4045 ImsManager imsManager =
4046 ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());
4047 return imsManager.isVtEnabledByPlatform()
4048 && imsManager.isEnhanced4gLteModeSettingEnabledByUser()
4049 && imsManager.isVtEnabledByUser();
4050 } finally {
4051 Binder.restoreCallingIdentity(identity);
4052 }
Andrew Leedf14ead2014-10-17 14:22:52 -07004053 }
Libin.Tang@motorola.comafe82642014-12-18 13:27:53 -06004054
Andrew Leea1239f22015-03-02 17:44:07 -08004055 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004056 public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
4057 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4058 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4059 return false;
4060 }
4061
4062 final long identity = Binder.clearCallingIdentity();
4063 try {
4064 CarrierConfigManager configManager =
4065 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4066 return configManager.getConfigForSubId(mPhone.getSubId())
4067 .getBoolean(CarrierConfigManager.KEY_DTMF_TYPE_ENABLED_BOOL);
4068 } finally {
4069 Binder.restoreCallingIdentity(identity);
4070 }
Andrew Leea1239f22015-03-02 17:44:07 -08004071 }
4072
4073 @Override
Malcolm Chenaabec062018-02-28 15:00:40 -08004074 public boolean isWorldPhone(int subId, String callingPackage) {
4075 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4076 mApp, subId, callingPackage, "isVideoCallingEnabled")) {
4077 return false;
4078 }
4079
4080 final long identity = Binder.clearCallingIdentity();
4081 try {
4082 CarrierConfigManager configManager =
4083 (CarrierConfigManager) mApp.getSystemService(Context.CARRIER_CONFIG_SERVICE);
4084 return configManager.getConfigForSubId(mPhone.getSubId())
4085 .getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL);
4086 } finally {
4087 Binder.restoreCallingIdentity(identity);
4088 }
Andrew Leea1239f22015-03-02 17:44:07 -08004089 }
4090
Andrew Lee9431b832015-03-09 18:46:45 -07004091 @Override
4092 public boolean isTtyModeSupported() {
4093 TelecomManager telecomManager = TelecomManager.from(mPhone.getContext());
Wooki Wu1f82f7a2016-02-15 15:59:58 +08004094 return telecomManager.isTtySupported();
Andrew Lee9431b832015-03-09 18:46:45 -07004095 }
4096
4097 @Override
4098 public boolean isHearingAidCompatibilitySupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004099 final long identity = Binder.clearCallingIdentity();
4100 try {
4101 return mPhone.getContext().getResources().getBoolean(R.bool.hac_enabled);
4102 } finally {
4103 Binder.restoreCallingIdentity(identity);
4104 }
Andrew Lee9431b832015-03-09 18:46:45 -07004105 }
4106
Hall Liu73714012018-01-22 19:15:32 -08004107 public boolean isRttSupported() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004108 final long identity = Binder.clearCallingIdentity();
4109 try {
4110 boolean isCarrierSupported = mApp.getCarrierConfigForSubId(
4111 mPhone.getSubId()).getBoolean(
4112 CarrierConfigManager.KEY_RTT_SUPPORTED_BOOL);
4113 boolean isDeviceSupported =
4114 mPhone.getContext().getResources().getBoolean(R.bool.config_support_rtt);
4115 return isCarrierSupported && isDeviceSupported;
4116 } finally {
4117 Binder.restoreCallingIdentity(identity);
4118 }
Hall Liu73714012018-01-22 19:15:32 -08004119 }
4120
Hall Liub1585172018-04-06 16:23:39 -07004121 public boolean isRttEnabled() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004122 final long identity = Binder.clearCallingIdentity();
4123 try {
4124 return isRttSupported() && Settings.Secure.getInt(
4125 mPhone.getContext().getContentResolver(),
4126 Settings.Secure.RTT_CALLING_MODE, 0) != 0;
4127 } finally {
4128 Binder.restoreCallingIdentity(identity);
4129 }
Hall Liub1585172018-04-06 16:23:39 -07004130 }
4131
Sanket Padawe7310cc72015-01-14 09:53:20 -08004132 /**
4133 * Returns the unique device ID of phone, for example, the IMEI for
4134 * GSM and the MEID for CDMA phones. Return null if device ID is not available.
4135 *
4136 * <p>Requires Permission:
4137 * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
4138 */
4139 @Override
Svet Ganovb320e182015-04-16 12:30:10 -07004140 public String getDeviceId(String callingPackage) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004141 final Phone phone = PhoneFactory.getPhone(0);
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004142 if (phone == null) {
Sanket Padawe7310cc72015-01-14 09:53:20 -08004143 return null;
4144 }
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004145 int subId = phone.getSubId();
4146 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
4147 mApp, subId, callingPackage, "getDeviceId")) {
4148 return null;
4149 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004150
4151 final long identity = Binder.clearCallingIdentity();
4152 try {
4153 return phone.getDeviceId();
4154 } finally {
4155 Binder.restoreCallingIdentity(identity);
4156 }
Sanket Padawe7310cc72015-01-14 09:53:20 -08004157 }
4158
Ping Sun014fe8e2016-03-02 19:16:45 +08004159 /**
4160 * {@hide}
4161 * Returns the IMS Registration Status on a particular subid
4162 *
4163 * @param subId
4164 */
Brad Ebingere21f25f2018-02-08 16:11:32 -08004165 public boolean isImsRegistered(int subId) {
Ping Sun014fe8e2016-03-02 19:16:45 +08004166 Phone phone = getPhone(subId);
4167 if (phone != null) {
4168 return phone.isImsRegistered();
4169 } else {
4170 return false;
4171 }
4172 }
4173
Santos Cordon7a1885b2015-02-03 11:15:19 -08004174 @Override
4175 public int getSubIdForPhoneAccount(PhoneAccount phoneAccount) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004176 final long identity = Binder.clearCallingIdentity();
4177 try {
4178 return PhoneUtils.getSubIdForPhoneAccount(phoneAccount);
4179 } finally {
4180 Binder.restoreCallingIdentity(identity);
4181 }
Santos Cordon7a1885b2015-02-03 11:15:19 -08004182 }
Nathan Harolddcfc7932015-03-18 10:01:20 -07004183
Brad Ebingere21f25f2018-02-08 16:11:32 -08004184 /**
4185 * @return the VoWiFi calling availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004186 */
Brad Ebingere21f25f2018-02-08 16:11:32 -08004187 public boolean isWifiCallingAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004188 final long identity = Binder.clearCallingIdentity();
4189 try {
4190 Phone phone = getPhone(subId);
4191 if (phone != null) {
4192 return phone.isWifiCallingEnabled();
4193 } else {
4194 return false;
4195 }
4196 } finally {
4197 Binder.restoreCallingIdentity(identity);
Brad Ebingere21f25f2018-02-08 16:11:32 -08004198 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004199 }
4200
Brad Ebingere21f25f2018-02-08 16:11:32 -08004201 /**
4202 * @return the VoLTE availability.
Nathan Haroldc55097a2015-03-11 18:14:50 -07004203 */
Brad Ebingere21f25f2018-02-08 16:11:32 -08004204 public boolean isVolteAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004205 final long identity = Binder.clearCallingIdentity();
4206 try {
4207 Phone phone = getPhone(subId);
4208 if (phone != null) {
4209 return phone.isVolteEnabled();
4210 } else {
4211 return false;
4212 }
4213 } finally {
4214 Binder.restoreCallingIdentity(identity);
Brad Ebingere21f25f2018-02-08 16:11:32 -08004215 }
Nathan Haroldc55097a2015-03-11 18:14:50 -07004216 }
Svet Ganovb320e182015-04-16 12:30:10 -07004217
Brad Ebingere21f25f2018-02-08 16:11:32 -08004218 /**
4219 * @return the VT calling availability.
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004220 */
Brad Ebingere21f25f2018-02-08 16:11:32 -08004221 public boolean isVideoTelephonyAvailable(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004222 final long identity = Binder.clearCallingIdentity();
4223 try {
4224 Phone phone = getPhone(subId);
4225 if (phone != null) {
4226 return phone.isVideoEnabled();
4227 } else {
4228 return false;
4229 }
4230 } finally {
4231 Binder.restoreCallingIdentity(identity);
Brad Ebingere21f25f2018-02-08 16:11:32 -08004232 }
4233 }
4234
4235 /**
4236 * @return the IMS registration technology for the MMTEL feature. Valid return values are
4237 * defined in {@link ImsRegistrationImplBase}.
4238 */
4239 public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004240 final long identity = Binder.clearCallingIdentity();
4241 try {
4242 Phone phone = getPhone(subId);
4243 if (phone != null) {
4244 return phone.getImsRegistrationTech();
4245 } else {
4246 return ImsRegistrationImplBase.REGISTRATION_TECH_NONE;
4247 }
4248 } finally {
4249 Binder.restoreCallingIdentity(identity);
Brad Ebingere21f25f2018-02-08 16:11:32 -08004250 }
Etan Cohen3b7a1bc2015-05-28 15:57:13 -07004251 }
4252
Stuart Scott8eef64f2015-04-08 15:13:54 -07004253 @Override
4254 public void factoryReset(int subId) {
4255 enforceConnectivityInternalPermission();
Stuart Scott981d8582015-04-21 14:09:50 -07004256 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_NETWORK_RESET)) {
4257 return;
4258 }
4259
Svet Ganovcc087f82015-05-12 20:35:54 -07004260 final long identity = Binder.clearCallingIdentity();
4261 try {
Stuart Scott981d8582015-04-21 14:09:50 -07004262 if (SubscriptionManager.isUsableSubIdValue(subId) && !mUserManager.hasUserRestriction(
4263 UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
Svet Ganovcc087f82015-05-12 20:35:54 -07004264 // Enable data
Malcolm Chenfd5068e2017-11-28 16:20:07 -08004265 setUserDataEnabled(subId, true);
Svet Ganovcc087f82015-05-12 20:35:54 -07004266 // Set network selection mode to automatic
4267 setNetworkSelectionModeAutomatic(subId);
4268 // Set preferred mobile network type to the best available
Kitta Koutarouab8a69b2018-03-05 14:16:45 +09004269 String defaultNetwork = TelephonyManager.getTelephonyProperty(
4270 mSubscriptionController.getPhoneId(subId),
4271 "ro.telephony.default_network",
4272 null);
4273 int networkType = !TextUtils.isEmpty(defaultNetwork)
4274 ? Integer.parseInt(defaultNetwork) : Phone.PREFERRED_NT_MODE;
4275 setPreferredNetworkType(subId, networkType);
Svet Ganovcc087f82015-05-12 20:35:54 -07004276 // Turn off roaming
Malcolm Chenf6b97f42017-04-19 16:03:24 -07004277 mPhone.setDataRoamingEnabled(false);
Svet Ganovcc087f82015-05-12 20:35:54 -07004278 }
4279 } finally {
4280 Binder.restoreCallingIdentity(identity);
Stuart Scott8eef64f2015-04-08 15:13:54 -07004281 }
4282 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004283
4284 @Override
4285 public String getLocaleFromDefaultSim() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004286 final long identity = Binder.clearCallingIdentity();
4287 try {
4288 // We query all subscriptions instead of just the active ones, because
4289 // this might be called early on in the provisioning flow when the
4290 // subscriptions potentially aren't active yet.
4291 final List<SubscriptionInfo> slist = getAllSubscriptionInfoList();
4292 if (slist == null || slist.isEmpty()) {
Narayan Kamath1c496c22015-04-16 14:40:19 +01004293 return null;
4294 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004295
Malcolm Chenaabec062018-02-28 15:00:40 -08004296 // This function may be called very early, say, from the setup wizard, at
4297 // which point we won't have a default subscription set. If that's the case
4298 // we just choose the first, which will be valid in "most cases".
4299 final int defaultSubId = getDefaultSubscription();
4300 SubscriptionInfo info = null;
4301 if (defaultSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
4302 info = slist.get(0);
4303 } else {
4304 for (SubscriptionInfo item : slist) {
4305 if (item.getSubscriptionId() == defaultSubId) {
4306 info = item;
4307 break;
4308 }
4309 }
4310
4311 if (info == null) {
4312 return null;
Tony Hill183b2de2015-06-24 14:53:58 +01004313 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004314 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004315
Malcolm Chenaabec062018-02-28 15:00:40 -08004316 // Try and fetch the locale from the carrier properties or from the SIM language
4317 // preferences (EF-PL and EF-LI)...
4318 final int mcc = info.getMcc();
4319 final Phone defaultPhone = getPhone(info.getSubscriptionId());
4320 String simLanguage = null;
4321 if (defaultPhone != null) {
4322 final Locale localeFromDefaultSim = defaultPhone.getLocaleFromSimAndCarrierPrefs();
4323 if (localeFromDefaultSim != null) {
4324 if (!localeFromDefaultSim.getCountry().isEmpty()) {
4325 if (DBG) log("Using locale from default SIM:" + localeFromDefaultSim);
4326 return localeFromDefaultSim.toLanguageTag();
4327 } else {
4328 simLanguage = localeFromDefaultSim.getLanguage();
4329 }
4330 }
4331 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004332
Malcolm Chenaabec062018-02-28 15:00:40 -08004333 // The SIM language preferences only store a language (e.g. fr = French), not an
4334 // exact locale (e.g. fr_FR = French/France). So, if the locale returned from
4335 // the SIM and carrier preferences does not include a country we add the country
4336 // determined from the SIM MCC to provide an exact locale.
4337 final Locale mccLocale = MccTable.getLocaleFromMcc(mPhone.getContext(), mcc,
4338 simLanguage);
4339 if (mccLocale != null) {
4340 if (DBG) log("No locale from default SIM, using mcc locale:" + mccLocale);
4341 return mccLocale.toLanguageTag();
4342 }
4343
4344 if (DBG) log("No locale found - returning null");
4345 return null;
4346 } finally {
4347 Binder.restoreCallingIdentity(identity);
4348 }
Narayan Kamath1c496c22015-04-16 14:40:19 +01004349 }
4350
4351 private List<SubscriptionInfo> getAllSubscriptionInfoList() {
Malcolm Chenaabec062018-02-28 15:00:40 -08004352 return mSubscriptionController.getAllSubInfoList(
4353 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004354 }
4355
Malcolm Chenaabec062018-02-28 15:00:40 -08004356 /**
4357 * NOTE: this method assumes permission checks are done and caller identity has been cleared.
4358 */
4359 private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
4360 return mSubscriptionController.getActiveSubscriptionInfoList(
4361 mPhone.getContext().getOpPackageName());
Narayan Kamath1c496c22015-04-16 14:40:19 +01004362 }
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004363
4364 /**
Adam Lesinski903a54c2016-04-11 14:49:52 -07004365 * Responds to the ResultReceiver with the {@link android.telephony.ModemActivityInfo} object
4366 * representing the state of the modem.
4367 *
4368 * NOTE: This clears the modem state, so there should only every be one caller.
4369 * @hide
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004370 */
4371 @Override
Adam Lesinski903a54c2016-04-11 14:49:52 -07004372 public void requestModemActivityInfo(ResultReceiver result) {
4373 enforceModifyPermission();
4374
Malcolm Chenaabec062018-02-28 15:00:40 -08004375 final long identity = Binder.clearCallingIdentity();
4376 try {
4377 ModemActivityInfo info =
4378 (ModemActivityInfo) sendRequest(CMD_GET_MODEM_ACTIVITY_INFO, null);
4379 Bundle bundle = new Bundle();
4380 bundle.putParcelable(TelephonyManager.MODEM_ACTIVITY_RESULT_KEY, info);
4381 result.send(0, bundle);
4382 } finally {
4383 Binder.restoreCallingIdentity(identity);
4384 }
4385
Prerepa Viswanadham7fcff692015-06-03 11:20:55 -07004386 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004387
4388 /**
4389 * {@hide}
4390 * Returns the service state information on specified subscription.
4391 */
4392 @Override
4393 public ServiceState getServiceStateForSubscriber(int subId, String callingPackage) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004394 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004395 mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
Jack Yu85bd38a2015-11-09 11:34:32 -08004396 return null;
4397 }
4398
Malcolm Chenaabec062018-02-28 15:00:40 -08004399 final long identity = Binder.clearCallingIdentity();
4400 try {
4401 final Phone phone = getPhone(subId);
4402 if (phone == null) {
4403 return null;
4404 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004405
Malcolm Chenaabec062018-02-28 15:00:40 -08004406 return phone.getServiceState();
4407 } finally {
4408 Binder.restoreCallingIdentity(identity);
4409 }
Jack Yu85bd38a2015-11-09 11:34:32 -08004410 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004411
4412 /**
4413 * Returns the URI for the per-account voicemail ringtone set in Phone settings.
4414 *
4415 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4416 * voicemail ringtone.
4417 * @return The URI for the ringtone to play when receiving a voicemail from a specific
4418 * PhoneAccount.
4419 */
4420 @Override
4421 public Uri getVoicemailRingtoneUri(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004422 final long identity = Binder.clearCallingIdentity();
4423 try {
4424 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4425 if (phone == null) {
4426 phone = mPhone;
4427 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004428
Malcolm Chenaabec062018-02-28 15:00:40 -08004429 return VoicemailNotificationSettingsUtil.getRingtoneUri(phone.getContext());
4430 } finally {
4431 Binder.restoreCallingIdentity(identity);
4432 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004433 }
4434
4435 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004436 * Sets the per-account voicemail ringtone.
4437 *
4438 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4439 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4440 *
4441 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4442 * voicemail ringtone.
4443 * @param uri The URI for the ringtone to play when receiving a voicemail from a specific
4444 * PhoneAccount.
4445 */
4446 @Override
4447 public void setVoicemailRingtoneUri(String callingPackage,
4448 PhoneAccountHandle phoneAccountHandle, Uri uri) {
4449 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4450 if (!TextUtils.equals(callingPackage,
4451 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004452 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4453 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4454 "setVoicemailRingtoneUri");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004455 }
Malcolm Chenaabec062018-02-28 15:00:40 -08004456
4457 final long identity = Binder.clearCallingIdentity();
4458 try {
4459 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4460 if (phone == null) {
4461 phone = mPhone;
4462 }
4463 VoicemailNotificationSettingsUtil.setRingtoneUri(phone.getContext(), uri);
4464 } finally {
4465 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004466 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004467 }
4468
4469 /**
Nancy Chen31f9ba12016-01-06 11:42:12 -08004470 * Returns whether vibration is set for voicemail notification in Phone settings.
4471 *
4472 * @param accountHandle The handle for the {@link PhoneAccount} for which to retrieve the
4473 * voicemail vibration setting.
4474 * @return {@code true} if the vibration is set for this PhoneAccount, {@code false} otherwise.
4475 */
4476 @Override
4477 public boolean isVoicemailVibrationEnabled(PhoneAccountHandle accountHandle) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004478 final long identity = Binder.clearCallingIdentity();
4479 try {
4480 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(accountHandle);
4481 if (phone == null) {
4482 phone = mPhone;
4483 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004484
Malcolm Chenaabec062018-02-28 15:00:40 -08004485 return VoicemailNotificationSettingsUtil.isVibrationEnabled(phone.getContext());
4486 } finally {
4487 Binder.restoreCallingIdentity(identity);
4488 }
Nancy Chen31f9ba12016-01-06 11:42:12 -08004489 }
4490
Youhan Wange64578a2016-05-02 15:32:42 -07004491 /**
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004492 * Sets the per-account voicemail vibration.
4493 *
4494 * <p>Requires that the calling app is the default dialer, or has carrier privileges, or
4495 * has permission {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
4496 *
4497 * @param phoneAccountHandle The handle for the {@link PhoneAccount} for which to set the
4498 * voicemail vibration setting.
4499 * @param enabled Whether to enable or disable vibration for voicemail notifications from a
4500 * specific PhoneAccount.
4501 */
4502 @Override
4503 public void setVoicemailVibrationEnabled(String callingPackage,
4504 PhoneAccountHandle phoneAccountHandle, boolean enabled) {
4505 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
4506 if (!TextUtils.equals(callingPackage,
4507 TelecomManager.from(mPhone.getContext()).getDefaultDialerPackage())) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004508 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4509 mApp, PhoneUtils.getSubIdForPhoneAccountHandle(phoneAccountHandle),
4510 "setVoicemailVibrationEnabled");
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004511 }
4512
Malcolm Chenaabec062018-02-28 15:00:40 -08004513 final long identity = Binder.clearCallingIdentity();
4514 try {
4515 Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(phoneAccountHandle);
4516 if (phone == null) {
4517 phone = mPhone;
4518 }
4519 VoicemailNotificationSettingsUtil.setVibrationEnabled(phone.getContext(), enabled);
4520 } finally {
4521 Binder.restoreCallingIdentity(identity);
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004522 }
Ta-wei Yenc33877d2017-01-23 18:11:21 -08004523 }
4524
4525 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004526 * Make sure either called from same process as self (phone) or IPC caller has read privilege.
4527 *
4528 * @throws SecurityException if the caller does not have the required permission
4529 */
4530 private void enforceReadPrivilegedPermission() {
4531 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
4532 null);
4533 }
4534
4535 /**
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004536 * Make sure either called from same process as self (phone) or IPC caller has send SMS
4537 * permission.
4538 *
4539 * @throws SecurityException if the caller does not have the required permission
4540 */
4541 private void enforceSendSmsPermission() {
4542 mApp.enforceCallingOrSelfPermission(permission.SEND_SMS, null);
4543 }
4544
4545 /**
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004546 * Make sure called from the package in charge of visual voicemail.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004547 *
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004548 * @throws SecurityException if the caller is not the visual voicemail package.
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004549 */
Ta-wei Yen527a9c02017-01-06 15:29:25 -08004550 private void enforceVisualVoicemailPackage(String callingPackage, int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004551 final long identity = Binder.clearCallingIdentity();
4552 try {
4553 ComponentName componentName =
4554 RemoteVvmTaskManager.getRemotePackage(mPhone.getContext(), subId);
4555 if (componentName == null) {
4556 throw new SecurityException(
4557 "Caller not current active visual voicemail package[null]");
4558 }
4559 String vvmPackage = componentName.getPackageName();
4560 if (!callingPackage.equals(vvmPackage)) {
4561 throw new SecurityException("Caller not current active visual voicemail package["
4562 + vvmPackage + "]");
4563 }
4564 } finally {
4565 Binder.restoreCallingIdentity(identity);
Ta-wei Yen30a69c82016-12-27 14:52:32 -08004566 }
4567 }
4568
4569 /**
Youhan Wange64578a2016-05-02 15:32:42 -07004570 * Return the application ID for the app type.
4571 *
4572 * @param subId the subscription ID that this request applies to.
4573 * @param appType the uicc app type.
4574 * @return Application ID for specificied app type, or null if no uicc.
4575 */
4576 @Override
4577 public String getAidForAppType(int subId, int appType) {
4578 enforceReadPrivilegedPermission();
4579 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004580
4581 final long identity = Binder.clearCallingIdentity();
Youhan Wange64578a2016-05-02 15:32:42 -07004582 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004583 if (phone == null) {
4584 return null;
4585 }
4586 String aid = null;
4587 try {
4588 aid = UiccController.getInstance().getUiccCard(phone.getPhoneId())
4589 .getApplicationByType(appType).getAid();
4590 } catch (Exception e) {
4591 Log.e(LOG_TAG, "Not getting aid. Exception ex=" + e);
4592 }
4593 return aid;
4594 } finally {
4595 Binder.restoreCallingIdentity(identity);
Youhan Wange64578a2016-05-02 15:32:42 -07004596 }
Youhan Wange64578a2016-05-02 15:32:42 -07004597 }
4598
Youhan Wang4001d252016-05-11 10:29:41 -07004599 /**
4600 * Return the Electronic Serial Number.
4601 *
4602 * @param subId the subscription ID that this request applies to.
4603 * @return ESN or null if error.
4604 */
4605 @Override
4606 public String getEsn(int subId) {
4607 enforceReadPrivilegedPermission();
4608 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004609
4610 final long identity = Binder.clearCallingIdentity();
Youhan Wang4001d252016-05-11 10:29:41 -07004611 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004612 if (phone == null) {
4613 return null;
4614 }
4615 String esn = null;
4616 try {
4617 esn = phone.getEsn();
4618 } catch (Exception e) {
4619 Log.e(LOG_TAG, "Not getting ESN. Exception ex=" + e);
4620 }
4621 return esn;
4622 } finally {
4623 Binder.restoreCallingIdentity(identity);
Youhan Wang4001d252016-05-11 10:29:41 -07004624 }
Youhan Wang4001d252016-05-11 10:29:41 -07004625 }
4626
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004627 /**
Youhan Wang66ad5d72016-07-18 17:56:58 -07004628 * Return the Preferred Roaming List Version.
4629 *
4630 * @param subId the subscription ID that this request applies to.
4631 * @return PRLVersion or null if error.
4632 */
4633 @Override
4634 public String getCdmaPrlVersion(int subId) {
4635 enforceReadPrivilegedPermission();
4636 Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004637
4638 final long identity = Binder.clearCallingIdentity();
Youhan Wang66ad5d72016-07-18 17:56:58 -07004639 try {
Malcolm Chenaabec062018-02-28 15:00:40 -08004640 if (phone == null) {
4641 return null;
4642 }
4643 String cdmaPrlVersion = null;
4644 try {
4645 cdmaPrlVersion = phone.getCdmaPrlVersion();
4646 } catch (Exception e) {
4647 Log.e(LOG_TAG, "Not getting PRLVersion", e);
4648 }
4649 return cdmaPrlVersion;
4650 } finally {
4651 Binder.restoreCallingIdentity(identity);
Youhan Wang66ad5d72016-07-18 17:56:58 -07004652 }
Youhan Wang66ad5d72016-07-18 17:56:58 -07004653 }
4654
4655 /**
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004656 * Get snapshot of Telephony histograms
4657 * @return List of Telephony histograms
4658 * @hide
4659 */
4660 @Override
4661 public List<TelephonyHistogram> getTelephonyHistograms() {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004662 TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
4663 mApp, getDefaultSubscription(), "getTelephonyHistograms");
Malcolm Chenaabec062018-02-28 15:00:40 -08004664
4665 final long identity = Binder.clearCallingIdentity();
4666 try {
4667 return RIL.getTelephonyRILTimingHistograms();
4668 } finally {
4669 Binder.restoreCallingIdentity(identity);
4670 }
Sanket Padawe99ef1e32016-05-18 16:12:33 -07004671 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004672
4673 /**
4674 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004675 * Set the allowed carrier list for slotIndex
Meng Wang1a7c35a2016-05-05 20:56:15 -07004676 * Require system privileges. In the future we may add this to carrier APIs.
4677 *
4678 * @return The number of carriers set successfully, should match length of carriers
4679 */
4680 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004681 public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004682 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004683
Meng Wang9b7c4e92017-02-17 11:41:27 -08004684 if (carriers == null) {
4685 throw new NullPointerException("carriers cannot be null");
4686 }
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004687
Malcolm Chenaabec062018-02-28 15:00:40 -08004688 final long identity = Binder.clearCallingIdentity();
4689 try {
4690 int subId = SubscriptionManager.getSubId(slotIndex)[0];
4691 int[] retVal = (int[]) sendRequest(CMD_SET_ALLOWED_CARRIERS, carriers, subId);
4692 return retVal[0];
4693 } finally {
4694 Binder.restoreCallingIdentity(identity);
4695 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004696 }
4697
4698 /**
4699 * {@hide}
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004700 * Get the allowed carrier list for slotIndex.
Meng Wang1a7c35a2016-05-05 20:56:15 -07004701 * Require system privileges. In the future we may add this to carrier APIs.
4702 *
4703 * @return List of {@link android.service.telephony.CarrierIdentifier}; empty list
4704 * means all carriers are allowed.
4705 */
4706 @Override
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004707 public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
Meng Wang1a7c35a2016-05-05 20:56:15 -07004708 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004709
4710 final long identity = Binder.clearCallingIdentity();
4711 try {
4712 int subId = SubscriptionManager.getSubId(slotIndex)[0];
4713 return (List<CarrierIdentifier>) sendRequest(CMD_GET_ALLOWED_CARRIERS, null, subId);
4714 } finally {
4715 Binder.restoreCallingIdentity(identity);
4716 }
Meng Wang1a7c35a2016-05-05 20:56:15 -07004717 }
4718
fionaxu59545b42016-05-25 15:53:37 -07004719 /**
4720 * Action set from carrier signalling broadcast receivers to enable/disable metered apns
4721 * @param subId the subscription ID that this action applies to.
4722 * @param enabled control enable or disable metered apns.
4723 * {@hide}
4724 */
4725 @Override
4726 public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
4727 enforceModifyPermission();
4728 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004729
4730 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004731 if (phone == null) {
4732 loge("carrierAction: SetMeteredApnsEnabled fails with invalid subId: " + subId);
4733 return;
4734 }
4735 try {
4736 phone.carrierActionSetMeteredApnsEnabled(enabled);
4737 } catch (Exception e) {
4738 Log.e(LOG_TAG, "carrierAction: SetMeteredApnsEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004739 } finally {
4740 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004741 }
4742 }
4743
4744 /**
4745 * Action set from carrier signalling broadcast receivers to enable/disable radio
4746 * @param subId the subscription ID that this action applies to.
4747 * @param enabled control enable or disable radio.
4748 * {@hide}
4749 */
4750 @Override
4751 public void carrierActionSetRadioEnabled(int subId, boolean enabled) {
4752 enforceModifyPermission();
4753 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004754
4755 final long identity = Binder.clearCallingIdentity();
fionaxu59545b42016-05-25 15:53:37 -07004756 if (phone == null) {
4757 loge("carrierAction: SetRadioEnabled fails with invalid sibId: " + subId);
4758 return;
4759 }
4760 try {
4761 phone.carrierActionSetRadioEnabled(enabled);
4762 } catch (Exception e) {
4763 Log.e(LOG_TAG, "carrierAction: SetRadioEnabled fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004764 } finally {
4765 Binder.restoreCallingIdentity(identity);
fionaxu59545b42016-05-25 15:53:37 -07004766 }
4767 }
4768
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004769 /**
fionaxu8da9cb12017-05-23 15:02:46 -07004770 * Action set from carrier signalling broadcast receivers to start/stop reporting the default
4771 * network status based on which carrier apps could apply actions accordingly,
4772 * enable/disable default url handler for example.
4773 *
4774 * @param subId the subscription ID that this action applies to.
4775 * @param report control start/stop reporting the default network status.
4776 * {@hide}
4777 */
4778 @Override
4779 public void carrierActionReportDefaultNetworkStatus(int subId, boolean report) {
4780 enforceModifyPermission();
4781 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004782
4783 final long identity = Binder.clearCallingIdentity();
fionaxu8da9cb12017-05-23 15:02:46 -07004784 if (phone == null) {
4785 loge("carrierAction: ReportDefaultNetworkStatus fails with invalid sibId: " + subId);
4786 return;
4787 }
4788 try {
4789 phone.carrierActionReportDefaultNetworkStatus(report);
4790 } catch (Exception e) {
4791 Log.e(LOG_TAG, "carrierAction: ReportDefaultNetworkStatus fails. Exception ex=" + e);
Malcolm Chenaabec062018-02-28 15:00:40 -08004792 } finally {
4793 Binder.restoreCallingIdentity(identity);
fionaxu8da9cb12017-05-23 15:02:46 -07004794 }
4795 }
4796
4797 /**
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004798 * Called when "adb shell dumpsys phone" is invoked. Dump is also automatically invoked when a
4799 * bug report is being generated.
4800 */
4801 @Override
Ta-wei Yen99282e02016-06-21 18:19:35 -07004802 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
dcashman22b950d2016-06-27 11:39:02 -07004803 if (mPhone.getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
4804 != PackageManager.PERMISSION_GRANTED) {
4805 writer.println("Permission Denial: can't dump Phone from pid="
4806 + Binder.getCallingPid()
4807 + ", uid=" + Binder.getCallingUid()
4808 + "without permission "
4809 + android.Manifest.permission.DUMP);
4810 return;
4811 }
Ta-wei Yen99282e02016-06-21 18:19:35 -07004812 DumpsysHandler.dump(mPhone.getContext(), fd, writer, args);
Ta-wei Yenc236d6b2016-06-21 13:33:12 -07004813 }
Jack Yueb89b242016-06-22 13:27:47 -07004814
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004815 @Override
4816 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
4817 String[] args, ShellCallback callback, ResultReceiver resultReceiver)
4818 throws RemoteException {
4819 (new TelephonyShellCommand(this)).exec(this, in, out, err, args, callback, resultReceiver);
4820 }
4821
Jack Yueb89b242016-06-22 13:27:47 -07004822 /**
Jack Yu84291ec2017-05-26 16:07:50 -07004823 * Get aggregated video call data usage since boot.
4824 *
4825 * @param perUidStats True if requesting data usage per uid, otherwise overall usage.
4826 * @return Snapshot of video call data usage
Jack Yueb89b242016-06-22 13:27:47 -07004827 * {@hide}
4828 */
4829 @Override
Jack Yu84291ec2017-05-26 16:07:50 -07004830 public NetworkStats getVtDataUsage(int subId, boolean perUidStats) {
Jack Yueb89b242016-06-22 13:27:47 -07004831 mApp.enforceCallingOrSelfPermission(android.Manifest.permission.READ_NETWORK_USAGE_HISTORY,
4832 null);
4833
Malcolm Chenaabec062018-02-28 15:00:40 -08004834 final long identity = Binder.clearCallingIdentity();
4835 try {
4836 // NetworkStatsService keeps tracking the active network interface and identity. It
4837 // records the delta with the corresponding network identity.
4838 // We just return the total video call data usage snapshot since boot.
4839 Phone phone = getPhone(subId);
4840 if (phone != null) {
4841 return phone.getVtDataUsage(perUidStats);
4842 }
4843 return null;
4844 } finally {
4845 Binder.restoreCallingIdentity(identity);
Jack Yueb89b242016-06-22 13:27:47 -07004846 }
Jack Yueb89b242016-06-22 13:27:47 -07004847 }
Jack Yu75ab2952016-07-08 14:29:33 -07004848
4849 /**
4850 * Policy control of data connection. Usually used when data limit is passed.
4851 * @param enabled True if enabling the data, otherwise disabling.
4852 * @param subId Subscription index
4853 * {@hide}
4854 */
4855 @Override
4856 public void setPolicyDataEnabled(boolean enabled, int subId) {
4857 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08004858
4859 final long identity = Binder.clearCallingIdentity();
4860 try {
4861 Phone phone = getPhone(subId);
4862 if (phone != null) {
4863 phone.setPolicyDataEnabled(enabled);
4864 }
4865 } finally {
4866 Binder.restoreCallingIdentity(identity);
Jack Yu75ab2952016-07-08 14:29:33 -07004867 }
4868 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004869
4870 /**
4871 * Get Client request stats
4872 * @return List of Client Request Stats
4873 * @hide
4874 */
4875 @Override
4876 public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
Jeff Davidsond9a1bb52018-02-13 18:17:36 -08004877 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
Jeff Davidsone371a1a2018-02-23 17:11:49 -08004878 mApp, subId, callingPackage, "getClientRequestStats")) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004879 return null;
4880 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004881 Phone phone = getPhone(subId);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004882
Malcolm Chenaabec062018-02-28 15:00:40 -08004883 final long identity = Binder.clearCallingIdentity();
4884 try {
4885 if (phone != null) {
4886 return phone.getClientRequestStats();
4887 }
4888
4889 return null;
4890 } finally {
4891 Binder.restoreCallingIdentity(identity);
4892 }
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004893 }
4894
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00004895 private WorkSource getWorkSource(int uid) {
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004896 String packageName = mPhone.getContext().getPackageManager().getNameForUid(uid);
Narayan Kamathbb8f7c42018-01-09 11:47:15 +00004897 return new WorkSource(uid, packageName);
Sooraj Sasindran9a909312016-07-18 11:57:25 -07004898 }
Jack Yueb4124c2017-02-16 15:32:43 -08004899
4900 /**
Grace Chen70990072017-03-24 17:21:30 -07004901 * Set SIM card power state.
Jack Yueb4124c2017-02-16 15:32:43 -08004902 *
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004903 * @param slotIndex SIM slot id.
Grace Chen70990072017-03-24 17:21:30 -07004904 * @param state State of SIM (power down, power up, pass through)
4905 * - {@link android.telephony.TelephonyManager#CARD_POWER_DOWN}
4906 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP}
4907 * - {@link android.telephony.TelephonyManager#CARD_POWER_UP_PASS_THROUGH}
Jack Yueb4124c2017-02-16 15:32:43 -08004908 *
4909 **/
4910 @Override
Grace Chen70990072017-03-24 17:21:30 -07004911 public void setSimPowerStateForSlot(int slotIndex, int state) {
Jack Yueb4124c2017-02-16 15:32:43 -08004912 enforceModifyPermission();
Sanket Padawe13bac7b2017-03-20 15:04:47 -07004913 Phone phone = PhoneFactory.getPhone(slotIndex);
4914
Malcolm Chenaabec062018-02-28 15:00:40 -08004915 final long identity = Binder.clearCallingIdentity();
4916 try {
4917 if (phone != null) {
4918 phone.setSimPowerState(state);
4919 }
4920 } finally {
4921 Binder.restoreCallingIdentity(identity);
Jack Yueb4124c2017-02-16 15:32:43 -08004922 }
4923 }
Shuo Qiandd210312017-04-12 22:11:33 +00004924
Tyler Gunn65d45c22017-06-05 11:22:26 -07004925 private boolean isUssdApiAllowed(int subId) {
4926 CarrierConfigManager configManager =
4927 (CarrierConfigManager) mPhone.getContext().getSystemService(
4928 Context.CARRIER_CONFIG_SERVICE);
4929 if (configManager == null) {
4930 return false;
4931 }
4932 PersistableBundle pb = configManager.getConfigForSubId(subId);
4933 if (pb == null) {
4934 return false;
4935 }
4936 return pb.getBoolean(
4937 CarrierConfigManager.KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL);
4938 }
4939
Shuo Qiandd210312017-04-12 22:11:33 +00004940 /**
4941 * Check if phone is in emergency callback mode
4942 * @return true if phone is in emergency callback mode
4943 * @param subId sub id
4944 */
4945 public boolean getEmergencyCallbackMode(int subId) {
4946 final Phone phone = getPhone(subId);
Malcolm Chenaabec062018-02-28 15:00:40 -08004947
4948 final long identity = Binder.clearCallingIdentity();
4949 try {
4950 if (phone != null) {
4951 return phone.isInEcm();
4952 } else {
4953 return false;
4954 }
4955 } finally {
4956 Binder.restoreCallingIdentity(identity);
Shuo Qiandd210312017-04-12 22:11:33 +00004957 }
4958 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004959
4960 /**
4961 * Get the current signal strength information for the given subscription.
4962 * Because this information is not updated when the device is in a low power state
4963 * it should not be relied-upon to be current.
4964 * @param subId Subscription index
4965 * @return the most recent cached signal strength info from the modem
4966 */
4967 @Override
4968 public SignalStrength getSignalStrength(int subId) {
Malcolm Chenaabec062018-02-28 15:00:40 -08004969 final long identity = Binder.clearCallingIdentity();
4970 try {
4971 Phone p = getPhone(subId);
4972 if (p == null) {
4973 return null;
4974 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004975
Malcolm Chenaabec062018-02-28 15:00:40 -08004976 return p.getSignalStrength();
4977 } finally {
4978 Binder.restoreCallingIdentity(identity);
4979 }
Nathan Harold46b42aa2017-03-10 19:38:22 -08004980 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00004981
4982 @Override
4983 public UiccSlotInfo[] getUiccSlotsInfo() {
4984 enforceReadPrivilegedPermission();
4985
Malcolm Chenaabec062018-02-28 15:00:40 -08004986 final long identity = Binder.clearCallingIdentity();
4987 try {
4988 UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
4989 if (slots == null) return null;
4990 UiccSlotInfo[] infos = new UiccSlotInfo[slots.length];
4991 for (int i = 0; i < slots.length; i++) {
4992 UiccSlot slot = slots[i];
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00004993
Malcolm Chenaabec062018-02-28 15:00:40 -08004994 String cardId = UiccController.getInstance().getUiccCard(i).getCardId();
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00004995
Malcolm Chenaabec062018-02-28 15:00:40 -08004996 int cardState = 0;
4997 switch (slot.getCardState()) {
4998 case CARDSTATE_ABSENT:
4999 cardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
5000 break;
5001 case CARDSTATE_PRESENT:
5002 cardState = UiccSlotInfo.CARD_STATE_INFO_PRESENT;
5003 break;
5004 case CARDSTATE_ERROR:
5005 cardState = UiccSlotInfo.CARD_STATE_INFO_ERROR;
5006 break;
5007 case CARDSTATE_RESTRICTED:
5008 cardState = UiccSlotInfo.CARD_STATE_INFO_RESTRICTED;
5009 break;
5010 default:
5011 break;
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005012
Malcolm Chenaabec062018-02-28 15:00:40 -08005013 }
5014
5015 infos[i] = new UiccSlotInfo(
5016 slot.isActive(),
5017 slot.isEuicc(),
5018 cardId,
5019 cardState,
5020 slot.getPhoneId(),
5021 slot.isExtendedApduSupported());
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005022 }
Malcolm Chenaabec062018-02-28 15:00:40 -08005023 return infos;
5024 } finally {
5025 Binder.restoreCallingIdentity(identity);
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005026 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005027 }
5028
5029 @Override
5030 public boolean switchSlots(int[] physicalSlots) {
5031 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005032
5033 final long identity = Binder.clearCallingIdentity();
5034 try {
5035 return (Boolean) sendRequest(CMD_SWITCH_SLOTS, physicalSlots);
5036 } finally {
5037 Binder.restoreCallingIdentity(identity);
5038 }
Holly Jiuyu Sun01c47ad2018-01-24 17:56:33 +00005039 }
Jack Yue6146032018-02-27 15:30:01 -08005040
5041 @Override
5042 public void setRadioIndicationUpdateMode(int subId, int filters, int mode) {
5043 enforceModifyPermission();
5044 final Phone phone = getPhone(subId);
5045 if (phone == null) {
5046 loge("setRadioIndicationUpdateMode fails with invalid subId: " + subId);
5047 return;
5048 }
5049
Malcolm Chenaabec062018-02-28 15:00:40 -08005050 final long identity = Binder.clearCallingIdentity();
5051 try {
5052 phone.setRadioIndicationUpdateMode(filters, mode);
5053 } finally {
5054 Binder.restoreCallingIdentity(identity);
5055 }
Jack Yue6146032018-02-27 15:30:01 -08005056 }
fionaxu2c8bbbd2018-03-21 00:08:13 -07005057
5058 @Override
5059 public void setCarrierTestOverride(int subId, String mccmnc, String imsi, String iccid, String
5060 gid1, String gid2, String plmn, String spn) {
5061 enforceModifyPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005062
5063 final long identity = Binder.clearCallingIdentity();
5064 try {
5065 final Phone phone = getPhone(subId);
5066 if (phone == null) {
5067 loge("setCarrierTestOverride fails with invalid subId: " + subId);
5068 return;
5069 }
5070 phone.setCarrierTestOverride(mccmnc, imsi, iccid, gid1, gid2, plmn, spn);
5071 } finally {
5072 Binder.restoreCallingIdentity(identity);
fionaxu2c8bbbd2018-03-21 00:08:13 -07005073 }
fionaxu2c8bbbd2018-03-21 00:08:13 -07005074 }
5075
5076 @Override
5077 public int getCarrierIdListVersion(int subId) {
5078 enforceReadPrivilegedPermission();
Malcolm Chenaabec062018-02-28 15:00:40 -08005079
5080 final long identity = Binder.clearCallingIdentity();
5081 try {
5082 final Phone phone = getPhone(subId);
5083 if (phone == null) {
5084 loge("getCarrierIdListVersion fails with invalid subId: " + subId);
5085 return TelephonyManager.UNKNOWN_CARRIER_ID_LIST_VERSION;
5086 }
5087 return phone.getCarrierIdListVersion();
5088 } finally {
5089 Binder.restoreCallingIdentity(identity);
fionaxu2c8bbbd2018-03-21 00:08:13 -07005090 }
fionaxu2c8bbbd2018-03-21 00:08:13 -07005091 }
Santos Cordon7d4ddf62013-07-10 11:58:08 -07005092}