blob: f5bfe102354ef7eef521659877c5dca3178af787 [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 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
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010024import android.content.Context;
Hall Liud892bec2018-11-30 14:51:45 -080025import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010026import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080027import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070028import android.os.RemoteException;
Shuo Qian489d9282020-07-09 11:30:03 -070029import android.provider.BlockedNumberContract;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.telephony.CarrierConfigManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070031import android.telephony.SubscriptionManager;
sqian9d4df8b2019-01-15 18:32:07 -080032import android.telephony.emergency.EmergencyNumber;
Brad Ebinger24c29992019-12-05 13:03:21 -080033import android.telephony.ims.feature.ImsFeature;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070034import android.util.Log;
35
36import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080037import com.android.internal.telephony.Phone;
38import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080039import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080040import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080041import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080042import com.android.modules.utils.BasicShellCommandHandler;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070043
44import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080045import java.util.ArrayList;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010046import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080047import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010048import java.util.Map;
49import java.util.TreeSet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050
51/**
52 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
53 * permission checks have been done before onCommand was called. Make sure any commands processed
54 * here also contain the appropriate permissions checks.
55 */
56
Hall Liua1548bd2019-12-24 14:14:12 -080057public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070058
59 private static final String LOG_TAG = "TelephonyShellCommand";
60 // Don't commit with this true.
61 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070062 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070063
64 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080065 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
sqian9d4df8b2019-01-15 18:32:07 -080066 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070067 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010068 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080069 private static final String DATA_TEST_MODE = "data";
70 private static final String DATA_ENABLE = "enable";
71 private static final String DATA_DISABLE = "disable";
Hall Liud892bec2018-11-30 14:51:45 -080072
Brad Ebinger999d3302020-11-25 14:31:39 -080073 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
74 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
75 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070076 private static final String IMS_ENABLE = "enable";
77 private static final String IMS_DISABLE = "disable";
Tyler Gunn7bcdc742019-10-04 15:56:59 -070078 // Used to disable or enable processing of conference event package data from the network.
79 // This is handy for testing scenarios where CEP data does not exist on a network which does
80 // support CEP data.
81 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070082
Hall Liud892bec2018-11-30 14:51:45 -080083 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -080084 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -080085
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010086 private static final String CC_GET_VALUE = "get-value";
87 private static final String CC_SET_VALUE = "set-value";
88 private static final String CC_CLEAR_VALUES = "clear-values";
89
Hui Wang0866fcc2020-10-12 12:14:23 -070090 private static final String GBA_SUBCOMMAND = "gba";
91 private static final String GBA_SET_SERVICE = "set-service";
92 private static final String GBA_GET_SERVICE = "get-service";
93 private static final String GBA_SET_RELEASE_TIME = "set-release";
94 private static final String GBA_GET_RELEASE_TIME = "get-release";
95
Hui Wang068ab862020-10-31 05:12:53 +000096 private static final String SINGLE_REGISTATION_CONFIG = "src";
97 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
98 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
99 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
100 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
101
Tyler Gunn92479152021-01-20 16:30:10 -0800102 private static final String D2D_SUBCOMMAND = "d2d";
103 private static final String D2D_SEND = "send";
104
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700105 // Take advantage of existing methods that already contain permissions checks when possible.
106 private final ITelephony mInterface;
107
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100108 private SubscriptionManager mSubscriptionManager;
109 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700110 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100111
112 private enum CcType {
113 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
114 STRING_ARRAY, UNKNOWN
115 }
116
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100117 private class CcOptionParseResult {
118 public int mSubId;
119 public boolean mPersistent;
120 }
121
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100122 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
123 // keys by looking at the end of the string which usually tells the type.
124 // For instance: "xxxx_string", "xxxx_string_array", etc.
125 // The carrier config keys in this map does not follow this convention. It is therefore not
126 // possible to infer the type for these keys by looking at the string.
127 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
128 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
129 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
130 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
131 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
132 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
133 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
134 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
135 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
136 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
137 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
138 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
139 CcType.STRING);
140 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
141 CcType.STRING_ARRAY);
142 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
143 CcType.STRING_ARRAY);
144 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
145 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
146 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
147 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
148 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
149 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
150 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
151 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
152 }
153 };
154
155 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700156 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100157 mCarrierConfigManager =
158 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
159 mSubscriptionManager = (SubscriptionManager)
160 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700161 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700162 }
163
164 @Override
165 public int onCommand(String cmd) {
166 if (cmd == null) {
167 return handleDefaultCommands(null);
168 }
169
170 switch (cmd) {
171 case IMS_SUBCOMMAND: {
172 return handleImsCommand();
173 }
Hall Liud892bec2018-11-30 14:51:45 -0800174 case NUMBER_VERIFICATION_SUBCOMMAND:
175 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800176 case EMERGENCY_NUMBER_TEST_MODE:
177 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100178 case CARRIER_CONFIG_SUBCOMMAND: {
179 return handleCcCommand();
180 }
Shuo Qianf5125122019-12-16 17:03:07 -0800181 case DATA_TEST_MODE:
182 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700183 case END_BLOCK_SUPPRESSION:
184 return handleEndBlockSuppressionCommand();
Hui Wang0866fcc2020-10-12 12:14:23 -0700185 case GBA_SUBCOMMAND:
186 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800187 case D2D_SUBCOMMAND:
188 return handleD2dCommand();
Hui Wang068ab862020-10-31 05:12:53 +0000189 case SINGLE_REGISTATION_CONFIG:
190 return handleSingleRegistrationConfigCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700191 default: {
192 return handleDefaultCommands(cmd);
193 }
194 }
195 }
196
197 @Override
198 public void onHelp() {
199 PrintWriter pw = getOutPrintWriter();
200 pw.println("Telephony Commands:");
201 pw.println(" help");
202 pw.println(" Print this help text.");
203 pw.println(" ims");
204 pw.println(" IMS Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800205 pw.println(" emergency-number-test-mode");
206 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700207 pw.println(" end-block-suppression");
208 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800209 pw.println(" data");
210 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100211 pw.println(" cc");
212 pw.println(" Carrier Config Commands.");
Hui Wang0866fcc2020-10-12 12:14:23 -0700213 pw.println(" gba");
214 pw.println(" GBA Commands.");
Hui Wang068ab862020-10-31 05:12:53 +0000215 pw.println(" src");
216 pw.println(" RCS VoLTE Single Registration Config Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700217 onHelpIms();
sqian9d4df8b2019-01-15 18:32:07 -0800218 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700219 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800220 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100221 onHelpCc();
Hui Wang0866fcc2020-10-12 12:14:23 -0700222 onHelpGba();
Hui Wang068ab862020-10-31 05:12:53 +0000223 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800224 onHelpD2D();
225 }
226
227 private void onHelpD2D() {
228 PrintWriter pw = getOutPrintWriter();
229 pw.println("D2D Comms Commands:");
230 pw.println(" d2d send TYPE VALUE");
231 pw.println(" Sends a D2D message of specified type and value.");
232 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
233 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
234 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
235 MESSAGE_CALL_AUDIO_CODEC));
236 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
237 + Communicator.messageToString(
238 MESSAGE_DEVICE_BATTERY_STATE));
239 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
240 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700241 }
242
243 private void onHelpIms() {
244 PrintWriter pw = getOutPrintWriter();
245 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800246 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700247 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
248 pw.println(" ImsService. Options are:");
249 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
250 pw.println(" is specified, it will choose the default voice SIM slot.");
251 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
252 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800253 pw.println(" -f: Set the feature that this override if for, if no option is");
254 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700255 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
256 pw.println(" Gets the package name of the currently defined ImsService.");
257 pw.println(" Options are:");
258 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
259 pw.println(" is specified, it will choose the default voice SIM slot.");
260 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000261 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800262 pw.println(" -f: The feature type that the query will be requested for. If none is");
263 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800264 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
265 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
266 pw.println(" configuration overrides. Options are:");
267 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
268 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700269 pw.println(" ims enable [-s SLOT_ID]");
270 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
271 pw.println(" if none is specified.");
272 pw.println(" ims disable [-s SLOT_ID]");
273 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
274 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700275 pw.println(" ims conference-event-package [enable/disable]");
276 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700277 }
278
Hall Liud892bec2018-11-30 14:51:45 -0800279 private void onHelpNumberVerification() {
280 PrintWriter pw = getOutPrintWriter();
281 pw.println("Number verification commands");
282 pw.println(" numverify override-package PACKAGE_NAME;");
283 pw.println(" Set the authorized package for number verification.");
284 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800285 pw.println(" numverify fake-call NUMBER;");
286 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
287 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800288 }
289
Shuo Qianf5125122019-12-16 17:03:07 -0800290 private void onHelpDataTestMode() {
291 PrintWriter pw = getOutPrintWriter();
292 pw.println("Mobile Data Test Mode Commands:");
293 pw.println(" data enable: enable mobile data connectivity");
294 pw.println(" data disable: disable mobile data connectivity");
295 }
296
sqian9d4df8b2019-01-15 18:32:07 -0800297 private void onHelpEmergencyNumber() {
298 PrintWriter pw = getOutPrintWriter();
299 pw.println("Emergency Number Test Mode Commands:");
300 pw.println(" emergency-number-test-mode ");
301 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
302 + " the test mode");
303 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700304 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800305 pw.println(" -c: clear the emergency number list in the test mode.");
306 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700307 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800308 pw.println(" -p: get the full emergency number list in the test mode.");
309 }
310
Shuo Qian489d9282020-07-09 11:30:03 -0700311 private void onHelpEndBlockSupperssion() {
312 PrintWriter pw = getOutPrintWriter();
313 pw.println("End Block Suppression command:");
314 pw.println(" end-block-suppression: disable suppressing blocking by contact");
315 pw.println(" with emergency services.");
316 }
317
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100318 private void onHelpCc() {
319 PrintWriter pw = getOutPrintWriter();
320 pw.println("Carrier Config Commands:");
321 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
322 pw.println(" Print carrier config values.");
323 pw.println(" Options are:");
324 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
325 pw.println(" is specified, it will choose the default voice SIM slot.");
326 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
327 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100328 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100329 pw.println(" Set carrier config KEY to NEW_VALUE.");
330 pw.println(" Options are:");
331 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
332 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100333 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100334 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
335 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
336 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
337 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
338 pw.println(" cc clear-values [-s SLOT_ID]");
339 pw.println(" Clear all carrier override values that has previously been set");
340 pw.println(" with set-value");
341 pw.println(" Options are:");
342 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
343 pw.println(" is specified, it will choose the default voice SIM slot.");
344 }
345
Hui Wang0866fcc2020-10-12 12:14:23 -0700346 private void onHelpGba() {
347 PrintWriter pw = getOutPrintWriter();
348 pw.println("Gba Commands:");
349 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
350 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
351 pw.println(" Options are:");
352 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
353 pw.println(" is specified, it will choose the default voice SIM slot.");
354 pw.println(" gba get-service [-s SLOT_ID]");
355 pw.println(" Gets the package name of the currently defined GbaService.");
356 pw.println(" Options are:");
357 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
358 pw.println(" is specified, it will choose the default voice SIM slot.");
359 pw.println(" gba set-release [-s SLOT_ID] n");
360 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
361 pw.println(" Do not release/unbind if n is -1.");
362 pw.println(" Options are:");
363 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
364 pw.println(" is specified, it will choose the default voice SIM slot.");
365 pw.println(" gba get-release [-s SLOT_ID]");
366 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
367 pw.println(" Options are:");
368 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
369 pw.println(" is specified, it will choose the default voice SIM slot.");
370 }
371
Hui Wang068ab862020-10-31 05:12:53 +0000372 private void onHelpSrc() {
373 PrintWriter pw = getOutPrintWriter();
374 pw.println("RCS VoLTE Single Registration Config Commands:");
375 pw.println(" src set-device-enabled true|false|null");
376 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
377 pw.println(" The value could be true, false, or null(undefined).");
378 pw.println(" src get-device-enabled");
379 pw.println(" Gets the device config for RCS VoLTE single registration.");
380 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
381 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
382 pw.println(" The value could be true, false, or null(undefined).");
383 pw.println(" Options are:");
384 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
385 pw.println(" is specified, it will choose the default voice SIM slot.");
386 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
387 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
388 pw.println(" Options are:");
389 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
390 pw.println(" is specified, it will choose the default voice SIM slot.");
391 }
392
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700393 private int handleImsCommand() {
394 String arg = getNextArg();
395 if (arg == null) {
396 onHelpIms();
397 return 0;
398 }
399
400 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800401 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700402 return handleImsSetServiceCommand();
403 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800404 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700405 return handleImsGetServiceCommand();
406 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800407 case IMS_CLEAR_SERVICE_OVERRIDE: {
408 return handleImsClearCarrierServiceCommand();
409 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700410 case IMS_ENABLE: {
411 return handleEnableIms();
412 }
413 case IMS_DISABLE: {
414 return handleDisableIms();
415 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700416 case IMS_CEP: {
417 return handleCepChange();
418 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700419 }
420
421 return -1;
422 }
423
Shuo Qianf5125122019-12-16 17:03:07 -0800424 private int handleDataTestModeCommand() {
425 PrintWriter errPw = getErrPrintWriter();
426 String arg = getNextArgRequired();
427 if (arg == null) {
428 onHelpDataTestMode();
429 return 0;
430 }
431 switch (arg) {
432 case DATA_ENABLE: {
433 try {
434 mInterface.enableDataConnectivity();
435 } catch (RemoteException ex) {
436 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
437 errPw.println("Exception: " + ex.getMessage());
438 return -1;
439 }
440 break;
441 }
442 case DATA_DISABLE: {
443 try {
444 mInterface.disableDataConnectivity();
445 } catch (RemoteException ex) {
446 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
447 errPw.println("Exception: " + ex.getMessage());
448 return -1;
449 }
450 break;
451 }
452 default:
453 onHelpDataTestMode();
454 break;
455 }
456 return 0;
457 }
458
sqian9d4df8b2019-01-15 18:32:07 -0800459 private int handleEmergencyNumberTestModeCommand() {
460 PrintWriter errPw = getErrPrintWriter();
461 String opt = getNextOption();
462 if (opt == null) {
463 onHelpEmergencyNumber();
464 return 0;
465 }
466
467 switch (opt) {
468 case "-a": {
469 String emergencyNumberCmd = getNextArgRequired();
470 if (emergencyNumberCmd == null
471 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700472 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800473 + " to be specified after -a in the command ");
474 return -1;
475 }
476 try {
477 mInterface.updateEmergencyNumberListTestMode(
478 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
479 new EmergencyNumber(emergencyNumberCmd, "", "",
480 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
481 new ArrayList<String>(),
482 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
483 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
484 } catch (RemoteException ex) {
485 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
486 + ", error " + ex.getMessage());
487 errPw.println("Exception: " + ex.getMessage());
488 return -1;
489 }
490 break;
491 }
492 case "-c": {
493 try {
494 mInterface.updateEmergencyNumberListTestMode(
495 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
496 } catch (RemoteException ex) {
497 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
498 errPw.println("Exception: " + ex.getMessage());
499 return -1;
500 }
501 break;
502 }
503 case "-r": {
504 String emergencyNumberCmd = getNextArgRequired();
505 if (emergencyNumberCmd == null
506 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700507 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800508 + " to be specified after -r in the command ");
509 return -1;
510 }
511 try {
512 mInterface.updateEmergencyNumberListTestMode(
513 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
514 new EmergencyNumber(emergencyNumberCmd, "", "",
515 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
516 new ArrayList<String>(),
517 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
518 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
519 } catch (RemoteException ex) {
520 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
521 + ", error " + ex.getMessage());
522 errPw.println("Exception: " + ex.getMessage());
523 return -1;
524 }
525 break;
526 }
527 case "-p": {
528 try {
529 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
530 } catch (RemoteException ex) {
531 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
532 errPw.println("Exception: " + ex.getMessage());
533 return -1;
534 }
535 break;
536 }
537 default:
538 onHelpEmergencyNumber();
539 break;
540 }
541 return 0;
542 }
543
Hall Liud892bec2018-11-30 14:51:45 -0800544 private int handleNumberVerificationCommand() {
545 String arg = getNextArg();
546 if (arg == null) {
547 onHelpNumberVerification();
548 return 0;
549 }
550
Hall Liuca5af3a2018-12-04 16:58:23 -0800551 if (!checkShellUid()) {
552 return -1;
553 }
554
Hall Liud892bec2018-11-30 14:51:45 -0800555 switch (arg) {
556 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800557 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
558 return 0;
559 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800560 case NUMBER_VERIFICATION_FAKE_CALL: {
561 boolean val = NumberVerificationManager.getInstance()
562 .checkIncomingCall(getNextArg());
563 getOutPrintWriter().println(val ? "1" : "0");
564 return 0;
565 }
Hall Liud892bec2018-11-30 14:51:45 -0800566 }
567
568 return -1;
569 }
570
Tyler Gunn92479152021-01-20 16:30:10 -0800571 private int handleD2dCommand() {
572 String arg = getNextArg();
573 if (arg == null) {
574 onHelpD2D();
575 return 0;
576 }
577
578 switch (arg) {
579 case D2D_SEND: {
580 return handleD2dSendCommand();
581 }
582 }
583
584 return -1;
585 }
586
587 private int handleD2dSendCommand() {
588 PrintWriter errPw = getErrPrintWriter();
589 String opt;
590 int messageType = -1;
591 int messageValue = -1;
592
593
594 String arg = getNextArg();
595 if (arg == null) {
596 onHelpD2D();
597 return 0;
598 }
599 try {
600 messageType = Integer.parseInt(arg);
601 } catch (NumberFormatException e) {
602 errPw.println("message type must be a valid integer");
603 return -1;
604 }
605
606 arg = getNextArg();
607 if (arg == null) {
608 onHelpD2D();
609 return 0;
610 }
611 try {
612 messageValue = Integer.parseInt(arg);
613 } catch (NumberFormatException e) {
614 errPw.println("message value must be a valid integer");
615 return -1;
616 }
617
618 try {
619 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
620 } catch (RemoteException e) {
621 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
622 errPw.println("Exception: " + e.getMessage());
623 return -1;
624 }
625
626 return 0;
627 }
628
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700629 // ims set-ims-service
630 private int handleImsSetServiceCommand() {
631 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700632 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700633 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800634 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700635
636 String opt;
637 while ((opt = getNextOption()) != null) {
638 switch (opt) {
639 case "-s": {
640 try {
641 slotId = Integer.parseInt(getNextArgRequired());
642 } catch (NumberFormatException e) {
643 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
644 return -1;
645 }
646 break;
647 }
648 case "-c": {
649 isCarrierService = true;
650 break;
651 }
652 case "-d": {
653 isCarrierService = false;
654 break;
655 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800656 case "-f": {
657 String featureString = getNextArgRequired();
658 String[] features = featureString.split(",");
659 for (int i = 0; i < features.length; i++) {
660 try {
661 Integer result = Integer.parseInt(features[i]);
662 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
663 || result >= ImsFeature.FEATURE_MAX) {
664 errPw.println("ims set-ims-service -f " + result
665 + " is an invalid feature.");
666 return -1;
667 }
668 featuresList.add(result);
669 } catch (NumberFormatException e) {
670 errPw.println("ims set-ims-service -f tried to parse " + features[i]
671 + " as an integer.");
672 return -1;
673 }
674 }
675 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700676 }
677 }
678 // Mandatory param, either -c or -d
679 if (isCarrierService == null) {
680 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
681 return -1;
682 }
683
684 String packageName = getNextArg();
685
686 try {
687 if (packageName == null) {
688 packageName = "";
689 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800690 int[] featureArray = new int[featuresList.size()];
691 for (int i = 0; i < featuresList.size(); i++) {
692 featureArray[i] = featuresList.get(i);
693 }
694 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
695 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700696 if (VDBG) {
697 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800698 + (isCarrierService ? "-c " : "-d ")
699 + "-f " + featuresList + " "
700 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700701 }
702 getOutPrintWriter().println(result);
703 } catch (RemoteException e) {
704 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800705 + (isCarrierService ? "-c " : "-d ")
706 + "-f " + featuresList + " "
707 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700708 errPw.println("Exception: " + e.getMessage());
709 return -1;
710 }
711 return 0;
712 }
713
Brad Ebinger999d3302020-11-25 14:31:39 -0800714 // ims clear-ims-service-override
715 private int handleImsClearCarrierServiceCommand() {
716 PrintWriter errPw = getErrPrintWriter();
717 int slotId = getDefaultSlot();
718
719 String opt;
720 while ((opt = getNextOption()) != null) {
721 switch (opt) {
722 case "-s": {
723 try {
724 slotId = Integer.parseInt(getNextArgRequired());
725 } catch (NumberFormatException e) {
726 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
727 return -1;
728 }
729 break;
730 }
731 }
732 }
733
734 try {
735 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
736 if (VDBG) {
737 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
738 + ", result=" + result);
739 }
740 getOutPrintWriter().println(result);
741 } catch (RemoteException e) {
742 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
743 + ", error" + e.getMessage());
744 errPw.println("Exception: " + e.getMessage());
745 return -1;
746 }
747 return 0;
748 }
749
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700750 // ims get-ims-service
751 private int handleImsGetServiceCommand() {
752 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700753 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700754 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800755 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700756
757 String opt;
758 while ((opt = getNextOption()) != null) {
759 switch (opt) {
760 case "-s": {
761 try {
762 slotId = Integer.parseInt(getNextArgRequired());
763 } catch (NumberFormatException e) {
764 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
765 return -1;
766 }
767 break;
768 }
769 case "-c": {
770 isCarrierService = true;
771 break;
772 }
773 case "-d": {
774 isCarrierService = false;
775 break;
776 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800777 case "-f": {
778 try {
779 featureType = Integer.parseInt(getNextArg());
780 } catch (NumberFormatException e) {
781 errPw.println("ims get-ims-service -f requires valid integer as feature.");
782 return -1;
783 }
784 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
785 || featureType >= ImsFeature.FEATURE_MAX) {
786 errPw.println("ims get-ims-service -f invalid feature.");
787 return -1;
788 }
789 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700790 }
791 }
792 // Mandatory param, either -c or -d
793 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800794 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700795 return -1;
796 }
797
798 String result;
799 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800800 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700801 } catch (RemoteException e) {
802 return -1;
803 }
804 if (VDBG) {
805 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800806 + (isCarrierService ? "-c " : "-d ")
807 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
808 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700809 }
810 getOutPrintWriter().println(result);
811 return 0;
812 }
813
814 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700815 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700816 String opt;
817 while ((opt = getNextOption()) != null) {
818 switch (opt) {
819 case "-s": {
820 try {
821 slotId = Integer.parseInt(getNextArgRequired());
822 } catch (NumberFormatException e) {
823 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
824 return -1;
825 }
826 break;
827 }
828 }
829 }
830 try {
831 mInterface.enableIms(slotId);
832 } catch (RemoteException e) {
833 return -1;
834 }
835 if (VDBG) {
836 Log.v(LOG_TAG, "ims enable -s " + slotId);
837 }
838 return 0;
839 }
840
841 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700842 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700843 String opt;
844 while ((opt = getNextOption()) != null) {
845 switch (opt) {
846 case "-s": {
847 try {
848 slotId = Integer.parseInt(getNextArgRequired());
849 } catch (NumberFormatException e) {
850 getErrPrintWriter().println(
851 "ims disable requires an integer as a SLOT_ID.");
852 return -1;
853 }
854 break;
855 }
856 }
857 }
858 try {
859 mInterface.disableIms(slotId);
860 } catch (RemoteException e) {
861 return -1;
862 }
863 if (VDBG) {
864 Log.v(LOG_TAG, "ims disable -s " + slotId);
865 }
866 return 0;
867 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700868
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700869 private int handleCepChange() {
870 Log.i(LOG_TAG, "handleCepChange");
871 String opt = getNextArg();
872 if (opt == null) {
873 return -1;
874 }
875 boolean isCepEnabled = opt.equals("enable");
876
877 try {
878 mInterface.setCepEnabled(isCepEnabled);
879 } catch (RemoteException e) {
880 return -1;
881 }
882 return 0;
883 }
884
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700885 private int getDefaultSlot() {
886 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
887 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
888 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
889 // If there is no default, default to slot 0.
890 slotId = DEFAULT_PHONE_ID;
891 }
892 return slotId;
893 }
sqian2fff4a32018-11-05 14:18:37 -0800894
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100895 // Parse options related to Carrier Config Commands.
896 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100897 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100898 CcOptionParseResult result = new CcOptionParseResult();
899 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
900 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100901
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100902 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100903 while ((opt = getNextOption()) != null) {
904 switch (opt) {
905 case "-s": {
906 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100907 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
908 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
909 errPw.println(tag + "No valid subscription found.");
910 return null;
911 }
912
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100913 } catch (IllegalArgumentException e) {
914 // Missing slot id
915 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100916 return null;
917 }
918 break;
919 }
920 case "-p": {
921 if (allowOptionPersistent) {
922 result.mPersistent = true;
923 } else {
924 errPw.println(tag + "Unexpected option " + opt);
925 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100926 }
927 break;
928 }
929 default: {
930 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100931 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100932 }
933 }
934 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100935 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100936 }
937
938 private int slotStringToSubId(String tag, String slotString) {
939 int slotId = -1;
940 try {
941 slotId = Integer.parseInt(slotString);
942 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +0800943 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
944 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
945 }
946
947 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100948 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
949 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
950 }
951
Qiong Liuf25799b2020-09-10 10:13:46 +0800952 Phone phone = PhoneFactory.getPhone(slotId);
953 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100954 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
955 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
956 }
Qiong Liuf25799b2020-09-10 10:13:46 +0800957 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100958 }
959
Hall Liud892bec2018-11-30 14:51:45 -0800960 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -0800961 // adb can run as root or as shell, depending on whether the device is rooted.
962 return Binder.getCallingUid() == Process.SHELL_UID
963 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -0800964 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100965
966 private int handleCcCommand() {
967 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
968 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -0800969 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100970 getErrPrintWriter().println("cc: Permission denied.");
971 return -1;
972 }
973
974 String arg = getNextArg();
975 if (arg == null) {
976 onHelpCc();
977 return 0;
978 }
979
980 switch (arg) {
981 case CC_GET_VALUE: {
982 return handleCcGetValue();
983 }
984 case CC_SET_VALUE: {
985 return handleCcSetValue();
986 }
987 case CC_CLEAR_VALUES: {
988 return handleCcClearValues();
989 }
990 default: {
991 getErrPrintWriter().println("cc: Unknown argument: " + arg);
992 }
993 }
994 return -1;
995 }
996
997 // cc get-value
998 private int handleCcGetValue() {
999 PrintWriter errPw = getErrPrintWriter();
1000 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1001 String key = null;
1002
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001003 // Parse all options
1004 CcOptionParseResult options = parseCcOptions(tag, false);
1005 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001006 return -1;
1007 }
1008
1009 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001010 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001011 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001012 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001013 return -1;
1014 }
1015
1016 // Get the key.
1017 key = getNextArg();
1018 if (key != null) {
1019 // A key was provided. Verify if it is a valid key
1020 if (!bundle.containsKey(key)) {
1021 errPw.println(tag + key + " is not a valid key.");
1022 return -1;
1023 }
1024
1025 // Print the carrier config value for key.
1026 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1027 } else {
1028 // No key provided. Show all values.
1029 // Iterate over a sorted list of all carrier config keys and print them.
1030 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1031 for (String k : sortedSet) {
1032 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1033 }
1034 }
1035 return 0;
1036 }
1037
1038 // cc set-value
1039 private int handleCcSetValue() {
1040 PrintWriter errPw = getErrPrintWriter();
1041 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1042
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001043 // Parse all options
1044 CcOptionParseResult options = parseCcOptions(tag, true);
1045 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001046 return -1;
1047 }
1048
1049 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001050 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001051 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001052 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001053 return -1;
1054 }
1055
1056 // Get the key.
1057 String key = getNextArg();
1058 if (key == null || key.equals("")) {
1059 errPw.println(tag + "KEY is missing");
1060 return -1;
1061 }
1062
1063 // Verify if the key is valid
1064 if (!originalValues.containsKey(key)) {
1065 errPw.println(tag + key + " is not a valid key.");
1066 return -1;
1067 }
1068
1069 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1070 ArrayList<String> valueList = new ArrayList<String>();
1071 while (peekNextArg() != null) {
1072 valueList.add(getNextArg());
1073 }
1074
1075 // Find the type of the carrier config value
1076 CcType type = getType(tag, key, originalValues);
1077 if (type == CcType.UNKNOWN) {
1078 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1079 return -1;
1080 }
1081
1082 // Create an override bundle containing the key and value that should be overriden.
1083 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1084 if (overrideBundle == null) {
1085 return -1;
1086 }
1087
1088 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001089 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001090
1091 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001092 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001093 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001094 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001095 return -1;
1096 }
1097
1098 // Print the original and new value.
1099 String originalValueString = ccValueToString(key, type, originalValues);
1100 String newValueString = ccValueToString(key, type, newValues);
1101 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1102 getOutPrintWriter().println("New value: \n" + newValueString);
1103
1104 return 0;
1105 }
1106
1107 // cc clear-values
1108 private int handleCcClearValues() {
1109 PrintWriter errPw = getErrPrintWriter();
1110 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1111
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001112 // Parse all options
1113 CcOptionParseResult options = parseCcOptions(tag, false);
1114 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001115 return -1;
1116 }
1117
1118 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001119 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001120 getOutPrintWriter()
1121 .println("All previously set carrier config override values has been cleared");
1122 return 0;
1123 }
1124
1125 private CcType getType(String tag, String key, PersistableBundle bundle) {
1126 // Find the type by checking the type of the current value stored in the bundle.
1127 Object value = bundle.get(key);
1128
1129 if (CC_TYPE_MAP.containsKey(key)) {
1130 return CC_TYPE_MAP.get(key);
1131 } else if (value != null) {
1132 if (value instanceof Boolean) {
1133 return CcType.BOOLEAN;
1134 } else if (value instanceof Double) {
1135 return CcType.DOUBLE;
1136 } else if (value instanceof double[]) {
1137 return CcType.DOUBLE_ARRAY;
1138 } else if (value instanceof Integer) {
1139 return CcType.INT;
1140 } else if (value instanceof int[]) {
1141 return CcType.INT_ARRAY;
1142 } else if (value instanceof Long) {
1143 return CcType.LONG;
1144 } else if (value instanceof long[]) {
1145 return CcType.LONG_ARRAY;
1146 } else if (value instanceof String) {
1147 return CcType.STRING;
1148 } else if (value instanceof String[]) {
1149 return CcType.STRING_ARRAY;
1150 }
1151 } else {
1152 // Current value was null and can therefore not be used in order to find the type.
1153 // Check the name of the key to infer the type. This check is not needed for primitive
1154 // data types (boolean, double, int and long), since they can not be null.
1155 if (key.endsWith("double_array")) {
1156 return CcType.DOUBLE_ARRAY;
1157 }
1158 if (key.endsWith("int_array")) {
1159 return CcType.INT_ARRAY;
1160 }
1161 if (key.endsWith("long_array")) {
1162 return CcType.LONG_ARRAY;
1163 }
1164 if (key.endsWith("string")) {
1165 return CcType.STRING;
1166 }
1167 if (key.endsWith("string_array") || key.endsWith("strings")) {
1168 return CcType.STRING_ARRAY;
1169 }
1170 }
1171
1172 // Not possible to infer the type by looking at the current value or the key.
1173 PrintWriter errPw = getErrPrintWriter();
1174 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1175 return CcType.UNKNOWN;
1176 }
1177
1178 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1179 String result;
1180 StringBuilder valueString = new StringBuilder();
1181 String typeString = type.toString();
1182 Object value = bundle.get(key);
1183
1184 if (value == null) {
1185 valueString.append("null");
1186 } else {
1187 switch (type) {
1188 case DOUBLE_ARRAY: {
1189 // Format the string representation of the int array as value1 value2......
1190 double[] valueArray = (double[]) value;
1191 for (int i = 0; i < valueArray.length; i++) {
1192 if (i != 0) {
1193 valueString.append(" ");
1194 }
1195 valueString.append(valueArray[i]);
1196 }
1197 break;
1198 }
1199 case INT_ARRAY: {
1200 // Format the string representation of the int array as value1 value2......
1201 int[] valueArray = (int[]) value;
1202 for (int i = 0; i < valueArray.length; i++) {
1203 if (i != 0) {
1204 valueString.append(" ");
1205 }
1206 valueString.append(valueArray[i]);
1207 }
1208 break;
1209 }
1210 case LONG_ARRAY: {
1211 // Format the string representation of the int array as value1 value2......
1212 long[] valueArray = (long[]) value;
1213 for (int i = 0; i < valueArray.length; i++) {
1214 if (i != 0) {
1215 valueString.append(" ");
1216 }
1217 valueString.append(valueArray[i]);
1218 }
1219 break;
1220 }
1221 case STRING: {
1222 valueString.append("\"" + value.toString() + "\"");
1223 break;
1224 }
1225 case STRING_ARRAY: {
1226 // Format the string representation of the string array as "value1" "value2"....
1227 String[] valueArray = (String[]) value;
1228 for (int i = 0; i < valueArray.length; i++) {
1229 if (i != 0) {
1230 valueString.append(" ");
1231 }
1232 if (valueArray[i] != null) {
1233 valueString.append("\"" + valueArray[i] + "\"");
1234 } else {
1235 valueString.append("null");
1236 }
1237 }
1238 break;
1239 }
1240 default: {
1241 valueString.append(value.toString());
1242 }
1243 }
1244 }
1245 return String.format("%-70s %-15s %s", key, typeString, valueString);
1246 }
1247
1248 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1249 ArrayList<String> valueList) {
1250 PrintWriter errPw = getErrPrintWriter();
1251 PersistableBundle bundle = new PersistableBundle();
1252
1253 // First verify that a valid number of values has been provided for the type.
1254 switch (type) {
1255 case BOOLEAN:
1256 case DOUBLE:
1257 case INT:
1258 case LONG: {
1259 if (valueList.size() != 1) {
1260 errPw.println(tag + "Expected 1 value for type " + type
1261 + ". Found: " + valueList.size());
1262 return null;
1263 }
1264 break;
1265 }
1266 case STRING: {
1267 if (valueList.size() > 1) {
1268 errPw.println(tag + "Expected 0 or 1 values for type " + type
1269 + ". Found: " + valueList.size());
1270 return null;
1271 }
1272 break;
1273 }
1274 }
1275
1276 // Parse the value according to type and add it to the Bundle.
1277 switch (type) {
1278 case BOOLEAN: {
1279 if ("true".equalsIgnoreCase(valueList.get(0))) {
1280 bundle.putBoolean(key, true);
1281 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1282 bundle.putBoolean(key, false);
1283 } else {
1284 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1285 return null;
1286 }
1287 break;
1288 }
1289 case DOUBLE: {
1290 try {
1291 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1292 } catch (NumberFormatException nfe) {
1293 // Not a valid double
1294 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1295 return null;
1296 }
1297 break;
1298 }
1299 case DOUBLE_ARRAY: {
1300 double[] valueDoubleArray = null;
1301 if (valueList.size() > 0) {
1302 valueDoubleArray = new double[valueList.size()];
1303 for (int i = 0; i < valueList.size(); i++) {
1304 try {
1305 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1306 } catch (NumberFormatException nfe) {
1307 // Not a valid double
1308 errPw.println(
1309 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1310 return null;
1311 }
1312 }
1313 }
1314 bundle.putDoubleArray(key, valueDoubleArray);
1315 break;
1316 }
1317 case INT: {
1318 try {
1319 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1320 } catch (NumberFormatException nfe) {
1321 // Not a valid integer
1322 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1323 return null;
1324 }
1325 break;
1326 }
1327 case INT_ARRAY: {
1328 int[] valueIntArray = null;
1329 if (valueList.size() > 0) {
1330 valueIntArray = new int[valueList.size()];
1331 for (int i = 0; i < valueList.size(); i++) {
1332 try {
1333 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1334 } catch (NumberFormatException nfe) {
1335 // Not a valid integer
1336 errPw.println(tag
1337 + "Unable to parse " + valueList.get(i) + " as an integer.");
1338 return null;
1339 }
1340 }
1341 }
1342 bundle.putIntArray(key, valueIntArray);
1343 break;
1344 }
1345 case LONG: {
1346 try {
1347 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1348 } catch (NumberFormatException nfe) {
1349 // Not a valid long
1350 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1351 return null;
1352 }
1353 break;
1354 }
1355 case LONG_ARRAY: {
1356 long[] valueLongArray = null;
1357 if (valueList.size() > 0) {
1358 valueLongArray = new long[valueList.size()];
1359 for (int i = 0; i < valueList.size(); i++) {
1360 try {
1361 valueLongArray[i] = Long.parseLong(valueList.get(i));
1362 } catch (NumberFormatException nfe) {
1363 // Not a valid long
1364 errPw.println(
1365 tag + "Unable to parse " + valueList.get(i) + " as a long");
1366 return null;
1367 }
1368 }
1369 }
1370 bundle.putLongArray(key, valueLongArray);
1371 break;
1372 }
1373 case STRING: {
1374 String value = null;
1375 if (valueList.size() > 0) {
1376 value = valueList.get(0);
1377 }
1378 bundle.putString(key, value);
1379 break;
1380 }
1381 case STRING_ARRAY: {
1382 String[] valueStringArray = null;
1383 if (valueList.size() > 0) {
1384 valueStringArray = new String[valueList.size()];
1385 valueList.toArray(valueStringArray);
1386 }
1387 bundle.putStringArray(key, valueStringArray);
1388 break;
1389 }
1390 }
1391 return bundle;
1392 }
Shuo Qian489d9282020-07-09 11:30:03 -07001393
1394 private int handleEndBlockSuppressionCommand() {
1395 if (!checkShellUid()) {
1396 return -1;
1397 }
1398
1399 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1400 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1401 }
1402 return 0;
1403 }
Hui Wang0866fcc2020-10-12 12:14:23 -07001404
1405 private int handleGbaCommand() {
1406 String arg = getNextArg();
1407 if (arg == null) {
1408 onHelpGba();
1409 return 0;
1410 }
1411
1412 switch (arg) {
1413 case GBA_SET_SERVICE: {
1414 return handleGbaSetServiceCommand();
1415 }
1416 case GBA_GET_SERVICE: {
1417 return handleGbaGetServiceCommand();
1418 }
1419 case GBA_SET_RELEASE_TIME: {
1420 return handleGbaSetReleaseCommand();
1421 }
1422 case GBA_GET_RELEASE_TIME: {
1423 return handleGbaGetReleaseCommand();
1424 }
1425 }
1426
1427 return -1;
1428 }
1429
1430 private int getSubId(String cmd) {
1431 int slotId = getDefaultSlot();
1432 String opt = getNextOption();
1433 if (opt != null && opt.equals("-s")) {
1434 try {
1435 slotId = Integer.parseInt(getNextArgRequired());
1436 } catch (NumberFormatException e) {
1437 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1438 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1439 }
1440 }
1441 int[] subIds = SubscriptionManager.getSubId(slotId);
1442 return subIds[0];
1443 }
1444
1445 private int handleGbaSetServiceCommand() {
1446 int subId = getSubId("gba set-service");
1447 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1448 return -1;
1449 }
1450
1451 String packageName = getNextArg();
1452 try {
1453 if (packageName == null) {
1454 packageName = "";
1455 }
1456 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1457 if (VDBG) {
1458 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1459 + packageName + ", result=" + result);
1460 }
1461 getOutPrintWriter().println(result);
1462 } catch (RemoteException e) {
1463 Log.w(LOG_TAG, "gba set-service " + subId + " "
1464 + packageName + ", error" + e.getMessage());
1465 getErrPrintWriter().println("Exception: " + e.getMessage());
1466 return -1;
1467 }
1468 return 0;
1469 }
1470
1471 private int handleGbaGetServiceCommand() {
1472 String result;
1473
1474 int subId = getSubId("gba get-service");
1475 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1476 return -1;
1477 }
1478
1479 try {
1480 result = mInterface.getBoundGbaService(subId);
1481 } catch (RemoteException e) {
1482 return -1;
1483 }
1484 if (VDBG) {
1485 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1486 }
1487 getOutPrintWriter().println(result);
1488 return 0;
1489 }
1490
1491 private int handleGbaSetReleaseCommand() {
1492 //the release time value could be -1
1493 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1494 : SubscriptionManager.getDefaultSubscriptionId();
1495 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1496 return -1;
1497 }
1498
1499 String intervalStr = getNextArg();
1500 if (intervalStr == null) {
1501 return -1;
1502 }
1503
1504 try {
1505 int interval = Integer.parseInt(intervalStr);
1506 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1507 if (VDBG) {
1508 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1509 + intervalStr + ", result=" + result);
1510 }
1511 getOutPrintWriter().println(result);
1512 } catch (NumberFormatException | RemoteException e) {
1513 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1514 + intervalStr + ", error" + e.getMessage());
1515 getErrPrintWriter().println("Exception: " + e.getMessage());
1516 return -1;
1517 }
1518 return 0;
1519 }
1520
1521 private int handleGbaGetReleaseCommand() {
1522 int subId = getSubId("gba get-release");
1523 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1524 return -1;
1525 }
1526
1527 int result = 0;
1528 try {
1529 result = mInterface.getGbaReleaseTime(subId);
1530 } catch (RemoteException e) {
1531 return -1;
1532 }
1533 if (VDBG) {
1534 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1535 }
1536 getOutPrintWriter().println(result);
1537 return 0;
1538 }
Hui Wang068ab862020-10-31 05:12:53 +00001539
1540 private int handleSingleRegistrationConfigCommand() {
1541 String arg = getNextArg();
1542 if (arg == null) {
1543 onHelpSrc();
1544 return 0;
1545 }
1546
1547 switch (arg) {
1548 case SRC_SET_DEVICE_ENABLED: {
1549 return handleSrcSetDeviceEnabledCommand();
1550 }
1551 case SRC_GET_DEVICE_ENABLED: {
1552 return handleSrcGetDeviceEnabledCommand();
1553 }
1554 case SRC_SET_CARRIER_ENABLED: {
1555 return handleSrcSetCarrierEnabledCommand();
1556 }
1557 case SRC_GET_CARRIER_ENABLED: {
1558 return handleSrcGetCarrierEnabledCommand();
1559 }
1560 }
1561
1562 return -1;
1563 }
1564
1565 private int handleSrcSetDeviceEnabledCommand() {
1566 String enabledStr = getNextArg();
1567 if (enabledStr == null) {
1568 return -1;
1569 }
1570
1571 try {
1572 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
1573 if (VDBG) {
1574 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
1575 }
1576 getOutPrintWriter().println("Done");
1577 } catch (NumberFormatException | RemoteException e) {
1578 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
1579 getErrPrintWriter().println("Exception: " + e.getMessage());
1580 return -1;
1581 }
1582 return 0;
1583 }
1584
1585 private int handleSrcGetDeviceEnabledCommand() {
1586 boolean result = false;
1587 try {
1588 result = mInterface.getDeviceSingleRegistrationEnabled();
1589 } catch (RemoteException e) {
1590 return -1;
1591 }
1592 if (VDBG) {
1593 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
1594 }
1595 getOutPrintWriter().println(result);
1596 return 0;
1597 }
1598
1599 private int handleSrcSetCarrierEnabledCommand() {
1600 //the release time value could be -1
1601 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
1602 : SubscriptionManager.getDefaultSubscriptionId();
1603 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1604 return -1;
1605 }
1606
1607 String enabledStr = getNextArg();
1608 if (enabledStr == null) {
1609 return -1;
1610 }
1611
1612 try {
1613 boolean result =
1614 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
1615 if (VDBG) {
1616 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1617 + enabledStr + ", result=" + result);
1618 }
1619 getOutPrintWriter().println(result);
1620 } catch (NumberFormatException | RemoteException e) {
1621 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1622 + enabledStr + ", error" + e.getMessage());
1623 getErrPrintWriter().println("Exception: " + e.getMessage());
1624 return -1;
1625 }
1626 return 0;
1627 }
1628
1629 private int handleSrcGetCarrierEnabledCommand() {
1630 int subId = getSubId("src get-carrier-enabled");
1631 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1632 return -1;
1633 }
1634
1635 boolean result = false;
1636 try {
1637 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
1638 } catch (RemoteException e) {
1639 return -1;
1640 }
1641 if (VDBG) {
1642 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
1643 }
1644 getOutPrintWriter().println(result);
1645 return 0;
1646 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001647}