blob: 5088424fd9fb5122c931f06193b4d61068bdd855 [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;
Michele Berionne54af4632020-12-28 20:23:16 +000032import android.telephony.TelephonyManager;
sqian9d4df8b2019-01-15 18:32:07 -080033import android.telephony.emergency.EmergencyNumber;
Brad Ebinger24c29992019-12-05 13:03:21 -080034import android.telephony.ims.feature.ImsFeature;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.util.Log;
36
37import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080038import com.android.internal.telephony.Phone;
39import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080040import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080041import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080042import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080043import com.android.modules.utils.BasicShellCommandHandler;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070044
45import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080046import java.util.ArrayList;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010047import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080048import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010049import java.util.Map;
50import java.util.TreeSet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051
52/**
53 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
54 * permission checks have been done before onCommand was called. Make sure any commands processed
55 * here also contain the appropriate permissions checks.
56 */
57
Hall Liua1548bd2019-12-24 14:14:12 -080058public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070059
60 private static final String LOG_TAG = "TelephonyShellCommand";
61 // Don't commit with this true.
62 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070063 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070064
65 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080066 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
sqian9d4df8b2019-01-15 18:32:07 -080067 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070068 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000069 private static final String RESTART_MODEM = "restart-modem";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010070 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080071 private static final String DATA_TEST_MODE = "data";
72 private static final String DATA_ENABLE = "enable";
73 private static final String DATA_DISABLE = "disable";
Hall Liud892bec2018-11-30 14:51:45 -080074
Brad Ebinger999d3302020-11-25 14:31:39 -080075 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
76 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
77 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070078 private static final String IMS_ENABLE = "enable";
79 private static final String IMS_DISABLE = "disable";
Tyler Gunn7bcdc742019-10-04 15:56:59 -070080 // Used to disable or enable processing of conference event package data from the network.
81 // This is handy for testing scenarios where CEP data does not exist on a network which does
82 // support CEP data.
83 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070084
Hall Liud892bec2018-11-30 14:51:45 -080085 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -080086 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -080087
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010088 private static final String CC_GET_VALUE = "get-value";
89 private static final String CC_SET_VALUE = "set-value";
90 private static final String CC_CLEAR_VALUES = "clear-values";
91
Hui Wang641e81c2020-10-12 12:14:23 -070092 private static final String GBA_SUBCOMMAND = "gba";
93 private static final String GBA_SET_SERVICE = "set-service";
94 private static final String GBA_GET_SERVICE = "get-service";
95 private static final String GBA_SET_RELEASE_TIME = "set-release";
96 private static final String GBA_GET_RELEASE_TIME = "get-release";
97
Hui Wang761a6682020-10-31 05:12:53 +000098 private static final String SINGLE_REGISTATION_CONFIG = "src";
99 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
100 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
101 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
102 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
103
Tyler Gunn92479152021-01-20 16:30:10 -0800104 private static final String D2D_SUBCOMMAND = "d2d";
105 private static final String D2D_SEND = "send";
106
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700107 // Take advantage of existing methods that already contain permissions checks when possible.
108 private final ITelephony mInterface;
109
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100110 private SubscriptionManager mSubscriptionManager;
111 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700112 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100113
114 private enum CcType {
115 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
116 STRING_ARRAY, UNKNOWN
117 }
118
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100119 private class CcOptionParseResult {
120 public int mSubId;
121 public boolean mPersistent;
122 }
123
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100124 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
125 // keys by looking at the end of the string which usually tells the type.
126 // For instance: "xxxx_string", "xxxx_string_array", etc.
127 // The carrier config keys in this map does not follow this convention. It is therefore not
128 // possible to infer the type for these keys by looking at the string.
129 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
130 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
131 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
132 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
133 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
134 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
135 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
136 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
137 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
138 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
139 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
140 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
141 CcType.STRING);
142 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
143 CcType.STRING_ARRAY);
144 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
145 CcType.STRING_ARRAY);
146 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
147 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
148 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
149 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
150 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
151 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
152 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
153 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
154 }
155 };
156
157 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700158 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100159 mCarrierConfigManager =
160 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
161 mSubscriptionManager = (SubscriptionManager)
162 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700163 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700164 }
165
166 @Override
167 public int onCommand(String cmd) {
168 if (cmd == null) {
169 return handleDefaultCommands(null);
170 }
171
172 switch (cmd) {
173 case IMS_SUBCOMMAND: {
174 return handleImsCommand();
175 }
Hall Liud892bec2018-11-30 14:51:45 -0800176 case NUMBER_VERIFICATION_SUBCOMMAND:
177 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800178 case EMERGENCY_NUMBER_TEST_MODE:
179 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100180 case CARRIER_CONFIG_SUBCOMMAND: {
181 return handleCcCommand();
182 }
Shuo Qianf5125122019-12-16 17:03:07 -0800183 case DATA_TEST_MODE:
184 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700185 case END_BLOCK_SUPPRESSION:
186 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700187 case GBA_SUBCOMMAND:
188 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800189 case D2D_SUBCOMMAND:
190 return handleD2dCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000191 case SINGLE_REGISTATION_CONFIG:
192 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000193 case RESTART_MODEM:
194 return handleRestartModemCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700195 default: {
196 return handleDefaultCommands(cmd);
197 }
198 }
199 }
200
201 @Override
202 public void onHelp() {
203 PrintWriter pw = getOutPrintWriter();
204 pw.println("Telephony Commands:");
205 pw.println(" help");
206 pw.println(" Print this help text.");
207 pw.println(" ims");
208 pw.println(" IMS Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800209 pw.println(" emergency-number-test-mode");
210 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700211 pw.println(" end-block-suppression");
212 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800213 pw.println(" data");
214 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100215 pw.println(" cc");
216 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700217 pw.println(" gba");
218 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000219 pw.println(" src");
220 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000221 pw.println(" restart-modem");
222 pw.println(" Restart modem command.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700223 onHelpIms();
sqian9d4df8b2019-01-15 18:32:07 -0800224 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700225 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800226 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100227 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700228 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000229 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800230 onHelpD2D();
231 }
232
233 private void onHelpD2D() {
234 PrintWriter pw = getOutPrintWriter();
235 pw.println("D2D Comms Commands:");
236 pw.println(" d2d send TYPE VALUE");
237 pw.println(" Sends a D2D message of specified type and value.");
238 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
239 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
240 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
241 MESSAGE_CALL_AUDIO_CODEC));
242 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
243 + Communicator.messageToString(
244 MESSAGE_DEVICE_BATTERY_STATE));
245 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
246 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700247 }
248
249 private void onHelpIms() {
250 PrintWriter pw = getOutPrintWriter();
251 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800252 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700253 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
254 pw.println(" ImsService. Options are:");
255 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
256 pw.println(" is specified, it will choose the default voice SIM slot.");
257 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
258 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800259 pw.println(" -f: Set the feature that this override if for, if no option is");
260 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700261 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
262 pw.println(" Gets the package name of the currently defined ImsService.");
263 pw.println(" Options are:");
264 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
265 pw.println(" is specified, it will choose the default voice SIM slot.");
266 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000267 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800268 pw.println(" -f: The feature type that the query will be requested for. If none is");
269 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800270 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
271 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
272 pw.println(" configuration overrides. Options are:");
273 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
274 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700275 pw.println(" ims enable [-s SLOT_ID]");
276 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
277 pw.println(" if none is specified.");
278 pw.println(" ims disable [-s SLOT_ID]");
279 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
280 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700281 pw.println(" ims conference-event-package [enable/disable]");
282 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700283 }
284
Hall Liud892bec2018-11-30 14:51:45 -0800285 private void onHelpNumberVerification() {
286 PrintWriter pw = getOutPrintWriter();
287 pw.println("Number verification commands");
288 pw.println(" numverify override-package PACKAGE_NAME;");
289 pw.println(" Set the authorized package for number verification.");
290 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800291 pw.println(" numverify fake-call NUMBER;");
292 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
293 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800294 }
295
Shuo Qianf5125122019-12-16 17:03:07 -0800296 private void onHelpDataTestMode() {
297 PrintWriter pw = getOutPrintWriter();
298 pw.println("Mobile Data Test Mode Commands:");
299 pw.println(" data enable: enable mobile data connectivity");
300 pw.println(" data disable: disable mobile data connectivity");
301 }
302
sqian9d4df8b2019-01-15 18:32:07 -0800303 private void onHelpEmergencyNumber() {
304 PrintWriter pw = getOutPrintWriter();
305 pw.println("Emergency Number Test Mode Commands:");
306 pw.println(" emergency-number-test-mode ");
307 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
308 + " the test mode");
309 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700310 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800311 pw.println(" -c: clear the emergency number list in the test mode.");
312 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700313 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800314 pw.println(" -p: get the full emergency number list in the test mode.");
315 }
316
Shuo Qian489d9282020-07-09 11:30:03 -0700317 private void onHelpEndBlockSupperssion() {
318 PrintWriter pw = getOutPrintWriter();
319 pw.println("End Block Suppression command:");
320 pw.println(" end-block-suppression: disable suppressing blocking by contact");
321 pw.println(" with emergency services.");
322 }
323
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100324 private void onHelpCc() {
325 PrintWriter pw = getOutPrintWriter();
326 pw.println("Carrier Config Commands:");
327 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
328 pw.println(" Print carrier config values.");
329 pw.println(" Options are:");
330 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
331 pw.println(" is specified, it will choose the default voice SIM slot.");
332 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
333 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100334 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100335 pw.println(" Set carrier config KEY to NEW_VALUE.");
336 pw.println(" Options are:");
337 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
338 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100339 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100340 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
341 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
342 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
343 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
344 pw.println(" cc clear-values [-s SLOT_ID]");
345 pw.println(" Clear all carrier override values that has previously been set");
346 pw.println(" with set-value");
347 pw.println(" Options are:");
348 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
349 pw.println(" is specified, it will choose the default voice SIM slot.");
350 }
351
Hui Wang641e81c2020-10-12 12:14:23 -0700352 private void onHelpGba() {
353 PrintWriter pw = getOutPrintWriter();
354 pw.println("Gba Commands:");
355 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
356 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
357 pw.println(" Options are:");
358 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
359 pw.println(" is specified, it will choose the default voice SIM slot.");
360 pw.println(" gba get-service [-s SLOT_ID]");
361 pw.println(" Gets the package name of the currently defined GbaService.");
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 set-release [-s SLOT_ID] n");
366 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
367 pw.println(" Do not release/unbind if n is -1.");
368 pw.println(" Options are:");
369 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
370 pw.println(" is specified, it will choose the default voice SIM slot.");
371 pw.println(" gba get-release [-s SLOT_ID]");
372 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
373 pw.println(" Options are:");
374 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
375 pw.println(" is specified, it will choose the default voice SIM slot.");
376 }
377
Hui Wang761a6682020-10-31 05:12:53 +0000378 private void onHelpSrc() {
379 PrintWriter pw = getOutPrintWriter();
380 pw.println("RCS VoLTE Single Registration Config Commands:");
381 pw.println(" src set-device-enabled true|false|null");
382 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
383 pw.println(" The value could be true, false, or null(undefined).");
384 pw.println(" src get-device-enabled");
385 pw.println(" Gets the device config for RCS VoLTE single registration.");
386 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
387 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
388 pw.println(" The value could be true, false, or null(undefined).");
389 pw.println(" Options are:");
390 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
391 pw.println(" is specified, it will choose the default voice SIM slot.");
392 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
393 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
394 pw.println(" Options are:");
395 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
396 pw.println(" is specified, it will choose the default voice SIM slot.");
397 }
398
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700399 private int handleImsCommand() {
400 String arg = getNextArg();
401 if (arg == null) {
402 onHelpIms();
403 return 0;
404 }
405
406 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800407 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700408 return handleImsSetServiceCommand();
409 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800410 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700411 return handleImsGetServiceCommand();
412 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800413 case IMS_CLEAR_SERVICE_OVERRIDE: {
414 return handleImsClearCarrierServiceCommand();
415 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700416 case IMS_ENABLE: {
417 return handleEnableIms();
418 }
419 case IMS_DISABLE: {
420 return handleDisableIms();
421 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700422 case IMS_CEP: {
423 return handleCepChange();
424 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700425 }
426
427 return -1;
428 }
429
Shuo Qianf5125122019-12-16 17:03:07 -0800430 private int handleDataTestModeCommand() {
431 PrintWriter errPw = getErrPrintWriter();
432 String arg = getNextArgRequired();
433 if (arg == null) {
434 onHelpDataTestMode();
435 return 0;
436 }
437 switch (arg) {
438 case DATA_ENABLE: {
439 try {
440 mInterface.enableDataConnectivity();
441 } catch (RemoteException ex) {
442 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
443 errPw.println("Exception: " + ex.getMessage());
444 return -1;
445 }
446 break;
447 }
448 case DATA_DISABLE: {
449 try {
450 mInterface.disableDataConnectivity();
451 } catch (RemoteException ex) {
452 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
453 errPw.println("Exception: " + ex.getMessage());
454 return -1;
455 }
456 break;
457 }
458 default:
459 onHelpDataTestMode();
460 break;
461 }
462 return 0;
463 }
464
sqian9d4df8b2019-01-15 18:32:07 -0800465 private int handleEmergencyNumberTestModeCommand() {
466 PrintWriter errPw = getErrPrintWriter();
467 String opt = getNextOption();
468 if (opt == null) {
469 onHelpEmergencyNumber();
470 return 0;
471 }
472
473 switch (opt) {
474 case "-a": {
475 String emergencyNumberCmd = getNextArgRequired();
476 if (emergencyNumberCmd == null
477 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700478 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800479 + " to be specified after -a in the command ");
480 return -1;
481 }
482 try {
483 mInterface.updateEmergencyNumberListTestMode(
484 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
485 new EmergencyNumber(emergencyNumberCmd, "", "",
486 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
487 new ArrayList<String>(),
488 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
489 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
490 } catch (RemoteException ex) {
491 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
492 + ", error " + ex.getMessage());
493 errPw.println("Exception: " + ex.getMessage());
494 return -1;
495 }
496 break;
497 }
498 case "-c": {
499 try {
500 mInterface.updateEmergencyNumberListTestMode(
501 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
502 } catch (RemoteException ex) {
503 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
504 errPw.println("Exception: " + ex.getMessage());
505 return -1;
506 }
507 break;
508 }
509 case "-r": {
510 String emergencyNumberCmd = getNextArgRequired();
511 if (emergencyNumberCmd == null
512 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700513 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800514 + " to be specified after -r in the command ");
515 return -1;
516 }
517 try {
518 mInterface.updateEmergencyNumberListTestMode(
519 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
520 new EmergencyNumber(emergencyNumberCmd, "", "",
521 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
522 new ArrayList<String>(),
523 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
524 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
525 } catch (RemoteException ex) {
526 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
527 + ", error " + ex.getMessage());
528 errPw.println("Exception: " + ex.getMessage());
529 return -1;
530 }
531 break;
532 }
533 case "-p": {
534 try {
535 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
536 } catch (RemoteException ex) {
537 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
538 errPw.println("Exception: " + ex.getMessage());
539 return -1;
540 }
541 break;
542 }
543 default:
544 onHelpEmergencyNumber();
545 break;
546 }
547 return 0;
548 }
549
Hall Liud892bec2018-11-30 14:51:45 -0800550 private int handleNumberVerificationCommand() {
551 String arg = getNextArg();
552 if (arg == null) {
553 onHelpNumberVerification();
554 return 0;
555 }
556
Hall Liuca5af3a2018-12-04 16:58:23 -0800557 if (!checkShellUid()) {
558 return -1;
559 }
560
Hall Liud892bec2018-11-30 14:51:45 -0800561 switch (arg) {
562 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800563 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
564 return 0;
565 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800566 case NUMBER_VERIFICATION_FAKE_CALL: {
567 boolean val = NumberVerificationManager.getInstance()
568 .checkIncomingCall(getNextArg());
569 getOutPrintWriter().println(val ? "1" : "0");
570 return 0;
571 }
Hall Liud892bec2018-11-30 14:51:45 -0800572 }
573
574 return -1;
575 }
576
Tyler Gunn92479152021-01-20 16:30:10 -0800577 private int handleD2dCommand() {
578 String arg = getNextArg();
579 if (arg == null) {
580 onHelpD2D();
581 return 0;
582 }
583
584 switch (arg) {
585 case D2D_SEND: {
586 return handleD2dSendCommand();
587 }
588 }
589
590 return -1;
591 }
592
593 private int handleD2dSendCommand() {
594 PrintWriter errPw = getErrPrintWriter();
595 String opt;
596 int messageType = -1;
597 int messageValue = -1;
598
599
600 String arg = getNextArg();
601 if (arg == null) {
602 onHelpD2D();
603 return 0;
604 }
605 try {
606 messageType = Integer.parseInt(arg);
607 } catch (NumberFormatException e) {
608 errPw.println("message type must be a valid integer");
609 return -1;
610 }
611
612 arg = getNextArg();
613 if (arg == null) {
614 onHelpD2D();
615 return 0;
616 }
617 try {
618 messageValue = Integer.parseInt(arg);
619 } catch (NumberFormatException e) {
620 errPw.println("message value must be a valid integer");
621 return -1;
622 }
623
624 try {
625 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
626 } catch (RemoteException e) {
627 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
628 errPw.println("Exception: " + e.getMessage());
629 return -1;
630 }
631
632 return 0;
633 }
634
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700635 // ims set-ims-service
636 private int handleImsSetServiceCommand() {
637 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700638 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700639 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800640 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700641
642 String opt;
643 while ((opt = getNextOption()) != null) {
644 switch (opt) {
645 case "-s": {
646 try {
647 slotId = Integer.parseInt(getNextArgRequired());
648 } catch (NumberFormatException e) {
649 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
650 return -1;
651 }
652 break;
653 }
654 case "-c": {
655 isCarrierService = true;
656 break;
657 }
658 case "-d": {
659 isCarrierService = false;
660 break;
661 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800662 case "-f": {
663 String featureString = getNextArgRequired();
664 String[] features = featureString.split(",");
665 for (int i = 0; i < features.length; i++) {
666 try {
667 Integer result = Integer.parseInt(features[i]);
668 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
669 || result >= ImsFeature.FEATURE_MAX) {
670 errPw.println("ims set-ims-service -f " + result
671 + " is an invalid feature.");
672 return -1;
673 }
674 featuresList.add(result);
675 } catch (NumberFormatException e) {
676 errPw.println("ims set-ims-service -f tried to parse " + features[i]
677 + " as an integer.");
678 return -1;
679 }
680 }
681 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700682 }
683 }
684 // Mandatory param, either -c or -d
685 if (isCarrierService == null) {
686 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
687 return -1;
688 }
689
690 String packageName = getNextArg();
691
692 try {
693 if (packageName == null) {
694 packageName = "";
695 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800696 int[] featureArray = new int[featuresList.size()];
697 for (int i = 0; i < featuresList.size(); i++) {
698 featureArray[i] = featuresList.get(i);
699 }
700 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
701 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700702 if (VDBG) {
703 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800704 + (isCarrierService ? "-c " : "-d ")
705 + "-f " + featuresList + " "
706 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700707 }
708 getOutPrintWriter().println(result);
709 } catch (RemoteException e) {
710 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800711 + (isCarrierService ? "-c " : "-d ")
712 + "-f " + featuresList + " "
713 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700714 errPw.println("Exception: " + e.getMessage());
715 return -1;
716 }
717 return 0;
718 }
719
Brad Ebinger999d3302020-11-25 14:31:39 -0800720 // ims clear-ims-service-override
721 private int handleImsClearCarrierServiceCommand() {
722 PrintWriter errPw = getErrPrintWriter();
723 int slotId = getDefaultSlot();
724
725 String opt;
726 while ((opt = getNextOption()) != null) {
727 switch (opt) {
728 case "-s": {
729 try {
730 slotId = Integer.parseInt(getNextArgRequired());
731 } catch (NumberFormatException e) {
732 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
733 return -1;
734 }
735 break;
736 }
737 }
738 }
739
740 try {
741 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
742 if (VDBG) {
743 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
744 + ", result=" + result);
745 }
746 getOutPrintWriter().println(result);
747 } catch (RemoteException e) {
748 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
749 + ", error" + e.getMessage());
750 errPw.println("Exception: " + e.getMessage());
751 return -1;
752 }
753 return 0;
754 }
755
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700756 // ims get-ims-service
757 private int handleImsGetServiceCommand() {
758 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700759 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700760 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800761 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700762
763 String opt;
764 while ((opt = getNextOption()) != null) {
765 switch (opt) {
766 case "-s": {
767 try {
768 slotId = Integer.parseInt(getNextArgRequired());
769 } catch (NumberFormatException e) {
770 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
771 return -1;
772 }
773 break;
774 }
775 case "-c": {
776 isCarrierService = true;
777 break;
778 }
779 case "-d": {
780 isCarrierService = false;
781 break;
782 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800783 case "-f": {
784 try {
785 featureType = Integer.parseInt(getNextArg());
786 } catch (NumberFormatException e) {
787 errPw.println("ims get-ims-service -f requires valid integer as feature.");
788 return -1;
789 }
790 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
791 || featureType >= ImsFeature.FEATURE_MAX) {
792 errPw.println("ims get-ims-service -f invalid feature.");
793 return -1;
794 }
795 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700796 }
797 }
798 // Mandatory param, either -c or -d
799 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800800 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700801 return -1;
802 }
803
804 String result;
805 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800806 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700807 } catch (RemoteException e) {
808 return -1;
809 }
810 if (VDBG) {
811 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800812 + (isCarrierService ? "-c " : "-d ")
813 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
814 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700815 }
816 getOutPrintWriter().println(result);
817 return 0;
818 }
819
820 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700821 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700822 String opt;
823 while ((opt = getNextOption()) != null) {
824 switch (opt) {
825 case "-s": {
826 try {
827 slotId = Integer.parseInt(getNextArgRequired());
828 } catch (NumberFormatException e) {
829 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
830 return -1;
831 }
832 break;
833 }
834 }
835 }
836 try {
837 mInterface.enableIms(slotId);
838 } catch (RemoteException e) {
839 return -1;
840 }
841 if (VDBG) {
842 Log.v(LOG_TAG, "ims enable -s " + slotId);
843 }
844 return 0;
845 }
846
847 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700848 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700849 String opt;
850 while ((opt = getNextOption()) != null) {
851 switch (opt) {
852 case "-s": {
853 try {
854 slotId = Integer.parseInt(getNextArgRequired());
855 } catch (NumberFormatException e) {
856 getErrPrintWriter().println(
857 "ims disable requires an integer as a SLOT_ID.");
858 return -1;
859 }
860 break;
861 }
862 }
863 }
864 try {
865 mInterface.disableIms(slotId);
866 } catch (RemoteException e) {
867 return -1;
868 }
869 if (VDBG) {
870 Log.v(LOG_TAG, "ims disable -s " + slotId);
871 }
872 return 0;
873 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700874
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700875 private int handleCepChange() {
876 Log.i(LOG_TAG, "handleCepChange");
877 String opt = getNextArg();
878 if (opt == null) {
879 return -1;
880 }
881 boolean isCepEnabled = opt.equals("enable");
882
883 try {
884 mInterface.setCepEnabled(isCepEnabled);
885 } catch (RemoteException e) {
886 return -1;
887 }
888 return 0;
889 }
890
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700891 private int getDefaultSlot() {
892 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
893 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
894 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
895 // If there is no default, default to slot 0.
896 slotId = DEFAULT_PHONE_ID;
897 }
898 return slotId;
899 }
sqian2fff4a32018-11-05 14:18:37 -0800900
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100901 // Parse options related to Carrier Config Commands.
902 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100903 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100904 CcOptionParseResult result = new CcOptionParseResult();
905 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
906 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100907
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100908 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100909 while ((opt = getNextOption()) != null) {
910 switch (opt) {
911 case "-s": {
912 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100913 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
914 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
915 errPw.println(tag + "No valid subscription found.");
916 return null;
917 }
918
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100919 } catch (IllegalArgumentException e) {
920 // Missing slot id
921 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100922 return null;
923 }
924 break;
925 }
926 case "-p": {
927 if (allowOptionPersistent) {
928 result.mPersistent = true;
929 } else {
930 errPw.println(tag + "Unexpected option " + opt);
931 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100932 }
933 break;
934 }
935 default: {
936 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100937 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100938 }
939 }
940 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100941 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100942 }
943
944 private int slotStringToSubId(String tag, String slotString) {
945 int slotId = -1;
946 try {
947 slotId = Integer.parseInt(slotString);
948 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +0800949 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
950 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
951 }
952
953 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100954 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
955 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
956 }
957
Qiong Liuf25799b2020-09-10 10:13:46 +0800958 Phone phone = PhoneFactory.getPhone(slotId);
959 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100960 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
961 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
962 }
Qiong Liuf25799b2020-09-10 10:13:46 +0800963 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100964 }
965
Hall Liud892bec2018-11-30 14:51:45 -0800966 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -0800967 // adb can run as root or as shell, depending on whether the device is rooted.
968 return Binder.getCallingUid() == Process.SHELL_UID
969 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -0800970 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100971
972 private int handleCcCommand() {
973 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
974 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -0800975 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100976 getErrPrintWriter().println("cc: Permission denied.");
977 return -1;
978 }
979
980 String arg = getNextArg();
981 if (arg == null) {
982 onHelpCc();
983 return 0;
984 }
985
986 switch (arg) {
987 case CC_GET_VALUE: {
988 return handleCcGetValue();
989 }
990 case CC_SET_VALUE: {
991 return handleCcSetValue();
992 }
993 case CC_CLEAR_VALUES: {
994 return handleCcClearValues();
995 }
996 default: {
997 getErrPrintWriter().println("cc: Unknown argument: " + arg);
998 }
999 }
1000 return -1;
1001 }
1002
1003 // cc get-value
1004 private int handleCcGetValue() {
1005 PrintWriter errPw = getErrPrintWriter();
1006 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1007 String key = null;
1008
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001009 // Parse all options
1010 CcOptionParseResult options = parseCcOptions(tag, false);
1011 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001012 return -1;
1013 }
1014
1015 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001016 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001017 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001018 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001019 return -1;
1020 }
1021
1022 // Get the key.
1023 key = getNextArg();
1024 if (key != null) {
1025 // A key was provided. Verify if it is a valid key
1026 if (!bundle.containsKey(key)) {
1027 errPw.println(tag + key + " is not a valid key.");
1028 return -1;
1029 }
1030
1031 // Print the carrier config value for key.
1032 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1033 } else {
1034 // No key provided. Show all values.
1035 // Iterate over a sorted list of all carrier config keys and print them.
1036 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1037 for (String k : sortedSet) {
1038 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1039 }
1040 }
1041 return 0;
1042 }
1043
1044 // cc set-value
1045 private int handleCcSetValue() {
1046 PrintWriter errPw = getErrPrintWriter();
1047 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1048
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001049 // Parse all options
1050 CcOptionParseResult options = parseCcOptions(tag, true);
1051 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001052 return -1;
1053 }
1054
1055 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001056 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001057 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001058 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001059 return -1;
1060 }
1061
1062 // Get the key.
1063 String key = getNextArg();
1064 if (key == null || key.equals("")) {
1065 errPw.println(tag + "KEY is missing");
1066 return -1;
1067 }
1068
1069 // Verify if the key is valid
1070 if (!originalValues.containsKey(key)) {
1071 errPw.println(tag + key + " is not a valid key.");
1072 return -1;
1073 }
1074
1075 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1076 ArrayList<String> valueList = new ArrayList<String>();
1077 while (peekNextArg() != null) {
1078 valueList.add(getNextArg());
1079 }
1080
1081 // Find the type of the carrier config value
1082 CcType type = getType(tag, key, originalValues);
1083 if (type == CcType.UNKNOWN) {
1084 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1085 return -1;
1086 }
1087
1088 // Create an override bundle containing the key and value that should be overriden.
1089 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1090 if (overrideBundle == null) {
1091 return -1;
1092 }
1093
1094 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001095 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001096
1097 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001098 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001099 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001100 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001101 return -1;
1102 }
1103
1104 // Print the original and new value.
1105 String originalValueString = ccValueToString(key, type, originalValues);
1106 String newValueString = ccValueToString(key, type, newValues);
1107 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1108 getOutPrintWriter().println("New value: \n" + newValueString);
1109
1110 return 0;
1111 }
1112
1113 // cc clear-values
1114 private int handleCcClearValues() {
1115 PrintWriter errPw = getErrPrintWriter();
1116 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1117
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001118 // Parse all options
1119 CcOptionParseResult options = parseCcOptions(tag, false);
1120 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001121 return -1;
1122 }
1123
1124 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001125 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001126 getOutPrintWriter()
1127 .println("All previously set carrier config override values has been cleared");
1128 return 0;
1129 }
1130
1131 private CcType getType(String tag, String key, PersistableBundle bundle) {
1132 // Find the type by checking the type of the current value stored in the bundle.
1133 Object value = bundle.get(key);
1134
1135 if (CC_TYPE_MAP.containsKey(key)) {
1136 return CC_TYPE_MAP.get(key);
1137 } else if (value != null) {
1138 if (value instanceof Boolean) {
1139 return CcType.BOOLEAN;
1140 } else if (value instanceof Double) {
1141 return CcType.DOUBLE;
1142 } else if (value instanceof double[]) {
1143 return CcType.DOUBLE_ARRAY;
1144 } else if (value instanceof Integer) {
1145 return CcType.INT;
1146 } else if (value instanceof int[]) {
1147 return CcType.INT_ARRAY;
1148 } else if (value instanceof Long) {
1149 return CcType.LONG;
1150 } else if (value instanceof long[]) {
1151 return CcType.LONG_ARRAY;
1152 } else if (value instanceof String) {
1153 return CcType.STRING;
1154 } else if (value instanceof String[]) {
1155 return CcType.STRING_ARRAY;
1156 }
1157 } else {
1158 // Current value was null and can therefore not be used in order to find the type.
1159 // Check the name of the key to infer the type. This check is not needed for primitive
1160 // data types (boolean, double, int and long), since they can not be null.
1161 if (key.endsWith("double_array")) {
1162 return CcType.DOUBLE_ARRAY;
1163 }
1164 if (key.endsWith("int_array")) {
1165 return CcType.INT_ARRAY;
1166 }
1167 if (key.endsWith("long_array")) {
1168 return CcType.LONG_ARRAY;
1169 }
1170 if (key.endsWith("string")) {
1171 return CcType.STRING;
1172 }
1173 if (key.endsWith("string_array") || key.endsWith("strings")) {
1174 return CcType.STRING_ARRAY;
1175 }
1176 }
1177
1178 // Not possible to infer the type by looking at the current value or the key.
1179 PrintWriter errPw = getErrPrintWriter();
1180 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1181 return CcType.UNKNOWN;
1182 }
1183
1184 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1185 String result;
1186 StringBuilder valueString = new StringBuilder();
1187 String typeString = type.toString();
1188 Object value = bundle.get(key);
1189
1190 if (value == null) {
1191 valueString.append("null");
1192 } else {
1193 switch (type) {
1194 case DOUBLE_ARRAY: {
1195 // Format the string representation of the int array as value1 value2......
1196 double[] valueArray = (double[]) value;
1197 for (int i = 0; i < valueArray.length; i++) {
1198 if (i != 0) {
1199 valueString.append(" ");
1200 }
1201 valueString.append(valueArray[i]);
1202 }
1203 break;
1204 }
1205 case INT_ARRAY: {
1206 // Format the string representation of the int array as value1 value2......
1207 int[] valueArray = (int[]) value;
1208 for (int i = 0; i < valueArray.length; i++) {
1209 if (i != 0) {
1210 valueString.append(" ");
1211 }
1212 valueString.append(valueArray[i]);
1213 }
1214 break;
1215 }
1216 case LONG_ARRAY: {
1217 // Format the string representation of the int array as value1 value2......
1218 long[] valueArray = (long[]) value;
1219 for (int i = 0; i < valueArray.length; i++) {
1220 if (i != 0) {
1221 valueString.append(" ");
1222 }
1223 valueString.append(valueArray[i]);
1224 }
1225 break;
1226 }
1227 case STRING: {
1228 valueString.append("\"" + value.toString() + "\"");
1229 break;
1230 }
1231 case STRING_ARRAY: {
1232 // Format the string representation of the string array as "value1" "value2"....
1233 String[] valueArray = (String[]) value;
1234 for (int i = 0; i < valueArray.length; i++) {
1235 if (i != 0) {
1236 valueString.append(" ");
1237 }
1238 if (valueArray[i] != null) {
1239 valueString.append("\"" + valueArray[i] + "\"");
1240 } else {
1241 valueString.append("null");
1242 }
1243 }
1244 break;
1245 }
1246 default: {
1247 valueString.append(value.toString());
1248 }
1249 }
1250 }
1251 return String.format("%-70s %-15s %s", key, typeString, valueString);
1252 }
1253
1254 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1255 ArrayList<String> valueList) {
1256 PrintWriter errPw = getErrPrintWriter();
1257 PersistableBundle bundle = new PersistableBundle();
1258
1259 // First verify that a valid number of values has been provided for the type.
1260 switch (type) {
1261 case BOOLEAN:
1262 case DOUBLE:
1263 case INT:
1264 case LONG: {
1265 if (valueList.size() != 1) {
1266 errPw.println(tag + "Expected 1 value for type " + type
1267 + ". Found: " + valueList.size());
1268 return null;
1269 }
1270 break;
1271 }
1272 case STRING: {
1273 if (valueList.size() > 1) {
1274 errPw.println(tag + "Expected 0 or 1 values for type " + type
1275 + ". Found: " + valueList.size());
1276 return null;
1277 }
1278 break;
1279 }
1280 }
1281
1282 // Parse the value according to type and add it to the Bundle.
1283 switch (type) {
1284 case BOOLEAN: {
1285 if ("true".equalsIgnoreCase(valueList.get(0))) {
1286 bundle.putBoolean(key, true);
1287 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1288 bundle.putBoolean(key, false);
1289 } else {
1290 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1291 return null;
1292 }
1293 break;
1294 }
1295 case DOUBLE: {
1296 try {
1297 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1298 } catch (NumberFormatException nfe) {
1299 // Not a valid double
1300 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1301 return null;
1302 }
1303 break;
1304 }
1305 case DOUBLE_ARRAY: {
1306 double[] valueDoubleArray = null;
1307 if (valueList.size() > 0) {
1308 valueDoubleArray = new double[valueList.size()];
1309 for (int i = 0; i < valueList.size(); i++) {
1310 try {
1311 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1312 } catch (NumberFormatException nfe) {
1313 // Not a valid double
1314 errPw.println(
1315 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1316 return null;
1317 }
1318 }
1319 }
1320 bundle.putDoubleArray(key, valueDoubleArray);
1321 break;
1322 }
1323 case INT: {
1324 try {
1325 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1326 } catch (NumberFormatException nfe) {
1327 // Not a valid integer
1328 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1329 return null;
1330 }
1331 break;
1332 }
1333 case INT_ARRAY: {
1334 int[] valueIntArray = null;
1335 if (valueList.size() > 0) {
1336 valueIntArray = new int[valueList.size()];
1337 for (int i = 0; i < valueList.size(); i++) {
1338 try {
1339 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1340 } catch (NumberFormatException nfe) {
1341 // Not a valid integer
1342 errPw.println(tag
1343 + "Unable to parse " + valueList.get(i) + " as an integer.");
1344 return null;
1345 }
1346 }
1347 }
1348 bundle.putIntArray(key, valueIntArray);
1349 break;
1350 }
1351 case LONG: {
1352 try {
1353 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1354 } catch (NumberFormatException nfe) {
1355 // Not a valid long
1356 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1357 return null;
1358 }
1359 break;
1360 }
1361 case LONG_ARRAY: {
1362 long[] valueLongArray = null;
1363 if (valueList.size() > 0) {
1364 valueLongArray = new long[valueList.size()];
1365 for (int i = 0; i < valueList.size(); i++) {
1366 try {
1367 valueLongArray[i] = Long.parseLong(valueList.get(i));
1368 } catch (NumberFormatException nfe) {
1369 // Not a valid long
1370 errPw.println(
1371 tag + "Unable to parse " + valueList.get(i) + " as a long");
1372 return null;
1373 }
1374 }
1375 }
1376 bundle.putLongArray(key, valueLongArray);
1377 break;
1378 }
1379 case STRING: {
1380 String value = null;
1381 if (valueList.size() > 0) {
1382 value = valueList.get(0);
1383 }
1384 bundle.putString(key, value);
1385 break;
1386 }
1387 case STRING_ARRAY: {
1388 String[] valueStringArray = null;
1389 if (valueList.size() > 0) {
1390 valueStringArray = new String[valueList.size()];
1391 valueList.toArray(valueStringArray);
1392 }
1393 bundle.putStringArray(key, valueStringArray);
1394 break;
1395 }
1396 }
1397 return bundle;
1398 }
Shuo Qian489d9282020-07-09 11:30:03 -07001399
1400 private int handleEndBlockSuppressionCommand() {
1401 if (!checkShellUid()) {
1402 return -1;
1403 }
1404
1405 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1406 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1407 }
1408 return 0;
1409 }
Hui Wang641e81c2020-10-12 12:14:23 -07001410
Michele Berionne54af4632020-12-28 20:23:16 +00001411 private int handleRestartModemCommand() {
1412 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1413 // non user build.
1414 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1415 getErrPrintWriter().println("RestartModem: Permission denied.");
1416 return -1;
1417 }
1418
1419 boolean result = TelephonyManager.getDefault().rebootRadio();
1420 getOutPrintWriter().println(result);
1421
1422 return result ? 0 : -1;
1423 }
1424
Hui Wang641e81c2020-10-12 12:14:23 -07001425 private int handleGbaCommand() {
1426 String arg = getNextArg();
1427 if (arg == null) {
1428 onHelpGba();
1429 return 0;
1430 }
1431
1432 switch (arg) {
1433 case GBA_SET_SERVICE: {
1434 return handleGbaSetServiceCommand();
1435 }
1436 case GBA_GET_SERVICE: {
1437 return handleGbaGetServiceCommand();
1438 }
1439 case GBA_SET_RELEASE_TIME: {
1440 return handleGbaSetReleaseCommand();
1441 }
1442 case GBA_GET_RELEASE_TIME: {
1443 return handleGbaGetReleaseCommand();
1444 }
1445 }
1446
1447 return -1;
1448 }
1449
1450 private int getSubId(String cmd) {
1451 int slotId = getDefaultSlot();
1452 String opt = getNextOption();
1453 if (opt != null && opt.equals("-s")) {
1454 try {
1455 slotId = Integer.parseInt(getNextArgRequired());
1456 } catch (NumberFormatException e) {
1457 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1458 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1459 }
1460 }
1461 int[] subIds = SubscriptionManager.getSubId(slotId);
1462 return subIds[0];
1463 }
1464
1465 private int handleGbaSetServiceCommand() {
1466 int subId = getSubId("gba set-service");
1467 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1468 return -1;
1469 }
1470
1471 String packageName = getNextArg();
1472 try {
1473 if (packageName == null) {
1474 packageName = "";
1475 }
1476 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1477 if (VDBG) {
1478 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1479 + packageName + ", result=" + result);
1480 }
1481 getOutPrintWriter().println(result);
1482 } catch (RemoteException e) {
1483 Log.w(LOG_TAG, "gba set-service " + subId + " "
1484 + packageName + ", error" + e.getMessage());
1485 getErrPrintWriter().println("Exception: " + e.getMessage());
1486 return -1;
1487 }
1488 return 0;
1489 }
1490
1491 private int handleGbaGetServiceCommand() {
1492 String result;
1493
1494 int subId = getSubId("gba get-service");
1495 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1496 return -1;
1497 }
1498
1499 try {
1500 result = mInterface.getBoundGbaService(subId);
1501 } catch (RemoteException e) {
1502 return -1;
1503 }
1504 if (VDBG) {
1505 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1506 }
1507 getOutPrintWriter().println(result);
1508 return 0;
1509 }
1510
1511 private int handleGbaSetReleaseCommand() {
1512 //the release time value could be -1
1513 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1514 : SubscriptionManager.getDefaultSubscriptionId();
1515 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1516 return -1;
1517 }
1518
1519 String intervalStr = getNextArg();
1520 if (intervalStr == null) {
1521 return -1;
1522 }
1523
1524 try {
1525 int interval = Integer.parseInt(intervalStr);
1526 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1527 if (VDBG) {
1528 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1529 + intervalStr + ", result=" + result);
1530 }
1531 getOutPrintWriter().println(result);
1532 } catch (NumberFormatException | RemoteException e) {
1533 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1534 + intervalStr + ", error" + e.getMessage());
1535 getErrPrintWriter().println("Exception: " + e.getMessage());
1536 return -1;
1537 }
1538 return 0;
1539 }
1540
1541 private int handleGbaGetReleaseCommand() {
1542 int subId = getSubId("gba get-release");
1543 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1544 return -1;
1545 }
1546
1547 int result = 0;
1548 try {
1549 result = mInterface.getGbaReleaseTime(subId);
1550 } catch (RemoteException e) {
1551 return -1;
1552 }
1553 if (VDBG) {
1554 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1555 }
1556 getOutPrintWriter().println(result);
1557 return 0;
1558 }
Hui Wang761a6682020-10-31 05:12:53 +00001559
1560 private int handleSingleRegistrationConfigCommand() {
1561 String arg = getNextArg();
1562 if (arg == null) {
1563 onHelpSrc();
1564 return 0;
1565 }
1566
1567 switch (arg) {
1568 case SRC_SET_DEVICE_ENABLED: {
1569 return handleSrcSetDeviceEnabledCommand();
1570 }
1571 case SRC_GET_DEVICE_ENABLED: {
1572 return handleSrcGetDeviceEnabledCommand();
1573 }
1574 case SRC_SET_CARRIER_ENABLED: {
1575 return handleSrcSetCarrierEnabledCommand();
1576 }
1577 case SRC_GET_CARRIER_ENABLED: {
1578 return handleSrcGetCarrierEnabledCommand();
1579 }
1580 }
1581
1582 return -1;
1583 }
1584
1585 private int handleSrcSetDeviceEnabledCommand() {
1586 String enabledStr = getNextArg();
1587 if (enabledStr == null) {
1588 return -1;
1589 }
1590
1591 try {
1592 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
1593 if (VDBG) {
1594 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
1595 }
1596 getOutPrintWriter().println("Done");
1597 } catch (NumberFormatException | RemoteException e) {
1598 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
1599 getErrPrintWriter().println("Exception: " + e.getMessage());
1600 return -1;
1601 }
1602 return 0;
1603 }
1604
1605 private int handleSrcGetDeviceEnabledCommand() {
1606 boolean result = false;
1607 try {
1608 result = mInterface.getDeviceSingleRegistrationEnabled();
1609 } catch (RemoteException e) {
1610 return -1;
1611 }
1612 if (VDBG) {
1613 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
1614 }
1615 getOutPrintWriter().println(result);
1616 return 0;
1617 }
1618
1619 private int handleSrcSetCarrierEnabledCommand() {
1620 //the release time value could be -1
1621 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
1622 : SubscriptionManager.getDefaultSubscriptionId();
1623 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1624 return -1;
1625 }
1626
1627 String enabledStr = getNextArg();
1628 if (enabledStr == null) {
1629 return -1;
1630 }
1631
1632 try {
1633 boolean result =
1634 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
1635 if (VDBG) {
1636 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1637 + enabledStr + ", result=" + result);
1638 }
1639 getOutPrintWriter().println(result);
1640 } catch (NumberFormatException | RemoteException e) {
1641 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1642 + enabledStr + ", error" + e.getMessage());
1643 getErrPrintWriter().println("Exception: " + e.getMessage());
1644 return -1;
1645 }
1646 return 0;
1647 }
1648
1649 private int handleSrcGetCarrierEnabledCommand() {
1650 int subId = getSubId("src get-carrier-enabled");
1651 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1652 return -1;
1653 }
1654
1655 boolean result = false;
1656 try {
1657 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
1658 } catch (RemoteException e) {
1659 return -1;
1660 }
1661 if (VDBG) {
1662 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
1663 }
1664 getOutPrintWriter().println(result);
1665 return 0;
1666 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001667}