blob: af293ce7fa5ee8c27b4f84599392a61f002be318 [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 Berionne38c1afa2020-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;
James.cf Linbcdf8b32021-01-14 16:44:13 +080035import android.text.TextUtils;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070036import android.util.Log;
37
38import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080039import com.android.internal.telephony.Phone;
40import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080041import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080042import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080043import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080044import com.android.modules.utils.BasicShellCommandHandler;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070045
46import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080047import java.util.ArrayList;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010048import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080049import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010050import java.util.Map;
51import java.util.TreeSet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052
53/**
54 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
55 * permission checks have been done before onCommand was called. Make sure any commands processed
56 * here also contain the appropriate permissions checks.
57 */
58
Hall Liua1548bd2019-12-24 14:14:12 -080059public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070060
61 private static final String LOG_TAG = "TelephonyShellCommand";
62 // Don't commit with this true.
63 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070064 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070065
66 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080067 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
sqian9d4df8b2019-01-15 18:32:07 -080068 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070069 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne38c1afa2020-12-28 20:23:16 +000070 private static final String RESTART_MODEM = "restart-modem";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010071 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080072 private static final String DATA_TEST_MODE = "data";
73 private static final String DATA_ENABLE = "enable";
74 private static final String DATA_DISABLE = "disable";
Hall Liud892bec2018-11-30 14:51:45 -080075
Brad Ebinger999d3302020-11-25 14:31:39 -080076 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
77 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
78 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070079 private static final String IMS_ENABLE = "enable";
80 private static final String IMS_DISABLE = "disable";
Tyler Gunn7bcdc742019-10-04 15:56:59 -070081 // Used to disable or enable processing of conference event package data from the network.
82 // This is handy for testing scenarios where CEP data does not exist on a network which does
83 // support CEP data.
84 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070085
Hall Liud892bec2018-11-30 14:51:45 -080086 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -080087 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -080088
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010089 private static final String CC_GET_VALUE = "get-value";
90 private static final String CC_SET_VALUE = "set-value";
91 private static final String CC_CLEAR_VALUES = "clear-values";
92
Hui Wang0866fcc2020-10-12 12:14:23 -070093 private static final String GBA_SUBCOMMAND = "gba";
94 private static final String GBA_SET_SERVICE = "set-service";
95 private static final String GBA_GET_SERVICE = "get-service";
96 private static final String GBA_SET_RELEASE_TIME = "set-release";
97 private static final String GBA_GET_RELEASE_TIME = "get-release";
98
Hui Wang068ab862020-10-31 05:12:53 +000099 private static final String SINGLE_REGISTATION_CONFIG = "src";
100 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
101 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
102 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
103 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
104
Tyler Gunn92479152021-01-20 16:30:10 -0800105 private static final String D2D_SUBCOMMAND = "d2d";
106 private static final String D2D_SEND = "send";
107
James.cf Linbcdf8b32021-01-14 16:44:13 +0800108 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800109 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800110 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800111 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
112 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800113
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700114 // Take advantage of existing methods that already contain permissions checks when possible.
115 private final ITelephony mInterface;
116
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100117 private SubscriptionManager mSubscriptionManager;
118 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700119 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100120
121 private enum CcType {
122 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
123 STRING_ARRAY, UNKNOWN
124 }
125
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100126 private class CcOptionParseResult {
127 public int mSubId;
128 public boolean mPersistent;
129 }
130
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100131 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
132 // keys by looking at the end of the string which usually tells the type.
133 // For instance: "xxxx_string", "xxxx_string_array", etc.
134 // The carrier config keys in this map does not follow this convention. It is therefore not
135 // possible to infer the type for these keys by looking at the string.
136 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
137 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
138 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
139 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
140 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
141 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
142 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
143 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
144 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
145 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
146 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
147 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
148 CcType.STRING);
149 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
150 CcType.STRING_ARRAY);
151 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
152 CcType.STRING_ARRAY);
153 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
154 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
155 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
156 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
157 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
158 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
159 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
160 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
161 }
162 };
163
164 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700165 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100166 mCarrierConfigManager =
167 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
168 mSubscriptionManager = (SubscriptionManager)
169 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700170 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700171 }
172
173 @Override
174 public int onCommand(String cmd) {
175 if (cmd == null) {
176 return handleDefaultCommands(null);
177 }
178
179 switch (cmd) {
180 case IMS_SUBCOMMAND: {
181 return handleImsCommand();
182 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800183 case RCS_UCE_COMMAND:
184 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800185 case NUMBER_VERIFICATION_SUBCOMMAND:
186 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800187 case EMERGENCY_NUMBER_TEST_MODE:
188 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100189 case CARRIER_CONFIG_SUBCOMMAND: {
190 return handleCcCommand();
191 }
Shuo Qianf5125122019-12-16 17:03:07 -0800192 case DATA_TEST_MODE:
193 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700194 case END_BLOCK_SUPPRESSION:
195 return handleEndBlockSuppressionCommand();
Hui Wang0866fcc2020-10-12 12:14:23 -0700196 case GBA_SUBCOMMAND:
197 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800198 case D2D_SUBCOMMAND:
199 return handleD2dCommand();
Hui Wang068ab862020-10-31 05:12:53 +0000200 case SINGLE_REGISTATION_CONFIG:
201 return handleSingleRegistrationConfigCommand();
Michele Berionne38c1afa2020-12-28 20:23:16 +0000202 case RESTART_MODEM:
203 return handleRestartModemCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700204 default: {
205 return handleDefaultCommands(cmd);
206 }
207 }
208 }
209
210 @Override
211 public void onHelp() {
212 PrintWriter pw = getOutPrintWriter();
213 pw.println("Telephony Commands:");
214 pw.println(" help");
215 pw.println(" Print this help text.");
216 pw.println(" ims");
217 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800218 pw.println(" uce");
219 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800220 pw.println(" emergency-number-test-mode");
221 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700222 pw.println(" end-block-suppression");
223 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800224 pw.println(" data");
225 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100226 pw.println(" cc");
227 pw.println(" Carrier Config Commands.");
Hui Wang0866fcc2020-10-12 12:14:23 -0700228 pw.println(" gba");
229 pw.println(" GBA Commands.");
Hui Wang068ab862020-10-31 05:12:53 +0000230 pw.println(" src");
231 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne38c1afa2020-12-28 20:23:16 +0000232 pw.println(" restart-modem");
233 pw.println(" Restart modem command.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700234 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800235 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800236 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700237 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800238 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100239 onHelpCc();
Hui Wang0866fcc2020-10-12 12:14:23 -0700240 onHelpGba();
Hui Wang068ab862020-10-31 05:12:53 +0000241 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800242 onHelpD2D();
243 }
244
245 private void onHelpD2D() {
246 PrintWriter pw = getOutPrintWriter();
247 pw.println("D2D Comms Commands:");
248 pw.println(" d2d send TYPE VALUE");
249 pw.println(" Sends a D2D message of specified type and value.");
250 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
251 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
252 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
253 MESSAGE_CALL_AUDIO_CODEC));
254 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
255 + Communicator.messageToString(
256 MESSAGE_DEVICE_BATTERY_STATE));
257 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
258 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700259 }
260
261 private void onHelpIms() {
262 PrintWriter pw = getOutPrintWriter();
263 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800264 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700265 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
266 pw.println(" ImsService. Options are:");
267 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
268 pw.println(" is specified, it will choose the default voice SIM slot.");
269 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
270 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800271 pw.println(" -f: Set the feature that this override if for, if no option is");
272 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700273 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
274 pw.println(" Gets the package name of the currently defined ImsService.");
275 pw.println(" Options are:");
276 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
277 pw.println(" is specified, it will choose the default voice SIM slot.");
278 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000279 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800280 pw.println(" -f: The feature type that the query will be requested for. If none is");
281 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800282 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
283 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
284 pw.println(" configuration overrides. Options are:");
285 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
286 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700287 pw.println(" ims enable [-s SLOT_ID]");
288 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
289 pw.println(" if none is specified.");
290 pw.println(" ims disable [-s SLOT_ID]");
291 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
292 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700293 pw.println(" ims conference-event-package [enable/disable]");
294 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700295 }
296
James.cf Linbcdf8b32021-01-14 16:44:13 +0800297 private void onHelpUce() {
298 PrintWriter pw = getOutPrintWriter();
299 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800300 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
301 pw.println(" Get the EAB contacts from the EAB database.");
302 pw.println(" Options are:");
303 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
304 pw.println(" Expected output format :");
305 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800306 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
307 pw.println(" Remove the EAB contacts from the EAB database.");
308 pw.println(" Options are:");
309 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
310 pw.println(" is specified, it will choose the default voice SIM slot.");
311 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800312 pw.println(" uce get-device-enabled");
313 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
314 pw.println(" uce set-device-enabled true|false");
315 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
316 pw.println(" The value could be true, false.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800317 }
318
Hall Liud892bec2018-11-30 14:51:45 -0800319 private void onHelpNumberVerification() {
320 PrintWriter pw = getOutPrintWriter();
321 pw.println("Number verification commands");
322 pw.println(" numverify override-package PACKAGE_NAME;");
323 pw.println(" Set the authorized package for number verification.");
324 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800325 pw.println(" numverify fake-call NUMBER;");
326 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
327 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800328 }
329
Shuo Qianf5125122019-12-16 17:03:07 -0800330 private void onHelpDataTestMode() {
331 PrintWriter pw = getOutPrintWriter();
332 pw.println("Mobile Data Test Mode Commands:");
333 pw.println(" data enable: enable mobile data connectivity");
334 pw.println(" data disable: disable mobile data connectivity");
335 }
336
sqian9d4df8b2019-01-15 18:32:07 -0800337 private void onHelpEmergencyNumber() {
338 PrintWriter pw = getOutPrintWriter();
339 pw.println("Emergency Number Test Mode Commands:");
340 pw.println(" emergency-number-test-mode ");
341 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
342 + " the test mode");
343 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700344 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800345 pw.println(" -c: clear the emergency number list in the test mode.");
346 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700347 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800348 pw.println(" -p: get the full emergency number list in the test mode.");
349 }
350
Shuo Qian489d9282020-07-09 11:30:03 -0700351 private void onHelpEndBlockSupperssion() {
352 PrintWriter pw = getOutPrintWriter();
353 pw.println("End Block Suppression command:");
354 pw.println(" end-block-suppression: disable suppressing blocking by contact");
355 pw.println(" with emergency services.");
356 }
357
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100358 private void onHelpCc() {
359 PrintWriter pw = getOutPrintWriter();
360 pw.println("Carrier Config Commands:");
361 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
362 pw.println(" Print carrier config values.");
363 pw.println(" Options are:");
364 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
365 pw.println(" is specified, it will choose the default voice SIM slot.");
366 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
367 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100368 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100369 pw.println(" Set carrier config KEY to NEW_VALUE.");
370 pw.println(" Options are:");
371 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
372 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100373 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100374 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
375 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
376 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
377 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
378 pw.println(" cc clear-values [-s SLOT_ID]");
379 pw.println(" Clear all carrier override values that has previously been set");
380 pw.println(" with set-value");
381 pw.println(" Options are:");
382 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
383 pw.println(" is specified, it will choose the default voice SIM slot.");
384 }
385
Hui Wang0866fcc2020-10-12 12:14:23 -0700386 private void onHelpGba() {
387 PrintWriter pw = getOutPrintWriter();
388 pw.println("Gba Commands:");
389 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
390 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
391 pw.println(" Options are:");
392 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
393 pw.println(" is specified, it will choose the default voice SIM slot.");
394 pw.println(" gba get-service [-s SLOT_ID]");
395 pw.println(" Gets the package name of the currently defined GbaService.");
396 pw.println(" Options are:");
397 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
398 pw.println(" is specified, it will choose the default voice SIM slot.");
399 pw.println(" gba set-release [-s SLOT_ID] n");
400 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
401 pw.println(" Do not release/unbind if n is -1.");
402 pw.println(" Options are:");
403 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
404 pw.println(" is specified, it will choose the default voice SIM slot.");
405 pw.println(" gba get-release [-s SLOT_ID]");
406 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
407 pw.println(" Options are:");
408 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
409 pw.println(" is specified, it will choose the default voice SIM slot.");
410 }
411
Hui Wang068ab862020-10-31 05:12:53 +0000412 private void onHelpSrc() {
413 PrintWriter pw = getOutPrintWriter();
414 pw.println("RCS VoLTE Single Registration Config Commands:");
415 pw.println(" src set-device-enabled true|false|null");
416 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
417 pw.println(" The value could be true, false, or null(undefined).");
418 pw.println(" src get-device-enabled");
419 pw.println(" Gets the device config for RCS VoLTE single registration.");
420 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
421 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
422 pw.println(" The value could be true, false, or null(undefined).");
423 pw.println(" Options are:");
424 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
425 pw.println(" is specified, it will choose the default voice SIM slot.");
426 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
427 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
428 pw.println(" Options are:");
429 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
430 pw.println(" is specified, it will choose the default voice SIM slot.");
431 }
432
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700433 private int handleImsCommand() {
434 String arg = getNextArg();
435 if (arg == null) {
436 onHelpIms();
437 return 0;
438 }
439
440 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800441 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700442 return handleImsSetServiceCommand();
443 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800444 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700445 return handleImsGetServiceCommand();
446 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800447 case IMS_CLEAR_SERVICE_OVERRIDE: {
448 return handleImsClearCarrierServiceCommand();
449 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700450 case IMS_ENABLE: {
451 return handleEnableIms();
452 }
453 case IMS_DISABLE: {
454 return handleDisableIms();
455 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700456 case IMS_CEP: {
457 return handleCepChange();
458 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700459 }
460
461 return -1;
462 }
463
Shuo Qianf5125122019-12-16 17:03:07 -0800464 private int handleDataTestModeCommand() {
465 PrintWriter errPw = getErrPrintWriter();
466 String arg = getNextArgRequired();
467 if (arg == null) {
468 onHelpDataTestMode();
469 return 0;
470 }
471 switch (arg) {
472 case DATA_ENABLE: {
473 try {
474 mInterface.enableDataConnectivity();
475 } catch (RemoteException ex) {
476 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
477 errPw.println("Exception: " + ex.getMessage());
478 return -1;
479 }
480 break;
481 }
482 case DATA_DISABLE: {
483 try {
484 mInterface.disableDataConnectivity();
485 } catch (RemoteException ex) {
486 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
487 errPw.println("Exception: " + ex.getMessage());
488 return -1;
489 }
490 break;
491 }
492 default:
493 onHelpDataTestMode();
494 break;
495 }
496 return 0;
497 }
498
sqian9d4df8b2019-01-15 18:32:07 -0800499 private int handleEmergencyNumberTestModeCommand() {
500 PrintWriter errPw = getErrPrintWriter();
501 String opt = getNextOption();
502 if (opt == null) {
503 onHelpEmergencyNumber();
504 return 0;
505 }
506
507 switch (opt) {
508 case "-a": {
509 String emergencyNumberCmd = getNextArgRequired();
510 if (emergencyNumberCmd == null
511 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700512 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800513 + " to be specified after -a in the command ");
514 return -1;
515 }
516 try {
517 mInterface.updateEmergencyNumberListTestMode(
518 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
519 new EmergencyNumber(emergencyNumberCmd, "", "",
520 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
521 new ArrayList<String>(),
522 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
523 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
524 } catch (RemoteException ex) {
525 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
526 + ", error " + ex.getMessage());
527 errPw.println("Exception: " + ex.getMessage());
528 return -1;
529 }
530 break;
531 }
532 case "-c": {
533 try {
534 mInterface.updateEmergencyNumberListTestMode(
535 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
536 } catch (RemoteException ex) {
537 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
538 errPw.println("Exception: " + ex.getMessage());
539 return -1;
540 }
541 break;
542 }
543 case "-r": {
544 String emergencyNumberCmd = getNextArgRequired();
545 if (emergencyNumberCmd == null
546 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700547 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800548 + " to be specified after -r in the command ");
549 return -1;
550 }
551 try {
552 mInterface.updateEmergencyNumberListTestMode(
553 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
554 new EmergencyNumber(emergencyNumberCmd, "", "",
555 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
556 new ArrayList<String>(),
557 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
558 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
559 } catch (RemoteException ex) {
560 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
561 + ", error " + ex.getMessage());
562 errPw.println("Exception: " + ex.getMessage());
563 return -1;
564 }
565 break;
566 }
567 case "-p": {
568 try {
569 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
570 } catch (RemoteException ex) {
571 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
572 errPw.println("Exception: " + ex.getMessage());
573 return -1;
574 }
575 break;
576 }
577 default:
578 onHelpEmergencyNumber();
579 break;
580 }
581 return 0;
582 }
583
Hall Liud892bec2018-11-30 14:51:45 -0800584 private int handleNumberVerificationCommand() {
585 String arg = getNextArg();
586 if (arg == null) {
587 onHelpNumberVerification();
588 return 0;
589 }
590
Hall Liuca5af3a2018-12-04 16:58:23 -0800591 if (!checkShellUid()) {
592 return -1;
593 }
594
Hall Liud892bec2018-11-30 14:51:45 -0800595 switch (arg) {
596 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800597 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
598 return 0;
599 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800600 case NUMBER_VERIFICATION_FAKE_CALL: {
601 boolean val = NumberVerificationManager.getInstance()
602 .checkIncomingCall(getNextArg());
603 getOutPrintWriter().println(val ? "1" : "0");
604 return 0;
605 }
Hall Liud892bec2018-11-30 14:51:45 -0800606 }
607
608 return -1;
609 }
610
Tyler Gunn92479152021-01-20 16:30:10 -0800611 private int handleD2dCommand() {
612 String arg = getNextArg();
613 if (arg == null) {
614 onHelpD2D();
615 return 0;
616 }
617
618 switch (arg) {
619 case D2D_SEND: {
620 return handleD2dSendCommand();
621 }
622 }
623
624 return -1;
625 }
626
627 private int handleD2dSendCommand() {
628 PrintWriter errPw = getErrPrintWriter();
629 String opt;
630 int messageType = -1;
631 int messageValue = -1;
632
633
634 String arg = getNextArg();
635 if (arg == null) {
636 onHelpD2D();
637 return 0;
638 }
639 try {
640 messageType = Integer.parseInt(arg);
641 } catch (NumberFormatException e) {
642 errPw.println("message type must be a valid integer");
643 return -1;
644 }
645
646 arg = getNextArg();
647 if (arg == null) {
648 onHelpD2D();
649 return 0;
650 }
651 try {
652 messageValue = Integer.parseInt(arg);
653 } catch (NumberFormatException e) {
654 errPw.println("message value must be a valid integer");
655 return -1;
656 }
657
658 try {
659 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
660 } catch (RemoteException e) {
661 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
662 errPw.println("Exception: " + e.getMessage());
663 return -1;
664 }
665
666 return 0;
667 }
668
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700669 // ims set-ims-service
670 private int handleImsSetServiceCommand() {
671 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700672 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700673 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800674 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700675
676 String opt;
677 while ((opt = getNextOption()) != null) {
678 switch (opt) {
679 case "-s": {
680 try {
681 slotId = Integer.parseInt(getNextArgRequired());
682 } catch (NumberFormatException e) {
683 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
684 return -1;
685 }
686 break;
687 }
688 case "-c": {
689 isCarrierService = true;
690 break;
691 }
692 case "-d": {
693 isCarrierService = false;
694 break;
695 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800696 case "-f": {
697 String featureString = getNextArgRequired();
698 String[] features = featureString.split(",");
699 for (int i = 0; i < features.length; i++) {
700 try {
701 Integer result = Integer.parseInt(features[i]);
702 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
703 || result >= ImsFeature.FEATURE_MAX) {
704 errPw.println("ims set-ims-service -f " + result
705 + " is an invalid feature.");
706 return -1;
707 }
708 featuresList.add(result);
709 } catch (NumberFormatException e) {
710 errPw.println("ims set-ims-service -f tried to parse " + features[i]
711 + " as an integer.");
712 return -1;
713 }
714 }
715 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700716 }
717 }
718 // Mandatory param, either -c or -d
719 if (isCarrierService == null) {
720 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
721 return -1;
722 }
723
724 String packageName = getNextArg();
725
726 try {
727 if (packageName == null) {
728 packageName = "";
729 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800730 int[] featureArray = new int[featuresList.size()];
731 for (int i = 0; i < featuresList.size(); i++) {
732 featureArray[i] = featuresList.get(i);
733 }
734 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
735 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700736 if (VDBG) {
737 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800738 + (isCarrierService ? "-c " : "-d ")
739 + "-f " + featuresList + " "
740 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700741 }
742 getOutPrintWriter().println(result);
743 } catch (RemoteException e) {
744 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800745 + (isCarrierService ? "-c " : "-d ")
746 + "-f " + featuresList + " "
747 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700748 errPw.println("Exception: " + e.getMessage());
749 return -1;
750 }
751 return 0;
752 }
753
Brad Ebinger999d3302020-11-25 14:31:39 -0800754 // ims clear-ims-service-override
755 private int handleImsClearCarrierServiceCommand() {
756 PrintWriter errPw = getErrPrintWriter();
757 int slotId = getDefaultSlot();
758
759 String opt;
760 while ((opt = getNextOption()) != null) {
761 switch (opt) {
762 case "-s": {
763 try {
764 slotId = Integer.parseInt(getNextArgRequired());
765 } catch (NumberFormatException e) {
766 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
767 return -1;
768 }
769 break;
770 }
771 }
772 }
773
774 try {
775 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
776 if (VDBG) {
777 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
778 + ", result=" + result);
779 }
780 getOutPrintWriter().println(result);
781 } catch (RemoteException e) {
782 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
783 + ", error" + e.getMessage());
784 errPw.println("Exception: " + e.getMessage());
785 return -1;
786 }
787 return 0;
788 }
789
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700790 // ims get-ims-service
791 private int handleImsGetServiceCommand() {
792 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700793 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700794 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800795 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700796
797 String opt;
798 while ((opt = getNextOption()) != null) {
799 switch (opt) {
800 case "-s": {
801 try {
802 slotId = Integer.parseInt(getNextArgRequired());
803 } catch (NumberFormatException e) {
804 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
805 return -1;
806 }
807 break;
808 }
809 case "-c": {
810 isCarrierService = true;
811 break;
812 }
813 case "-d": {
814 isCarrierService = false;
815 break;
816 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800817 case "-f": {
818 try {
819 featureType = Integer.parseInt(getNextArg());
820 } catch (NumberFormatException e) {
821 errPw.println("ims get-ims-service -f requires valid integer as feature.");
822 return -1;
823 }
824 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
825 || featureType >= ImsFeature.FEATURE_MAX) {
826 errPw.println("ims get-ims-service -f invalid feature.");
827 return -1;
828 }
829 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700830 }
831 }
832 // Mandatory param, either -c or -d
833 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800834 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700835 return -1;
836 }
837
838 String result;
839 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800840 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700841 } catch (RemoteException e) {
842 return -1;
843 }
844 if (VDBG) {
845 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800846 + (isCarrierService ? "-c " : "-d ")
847 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
848 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700849 }
850 getOutPrintWriter().println(result);
851 return 0;
852 }
853
854 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700855 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700856 String opt;
857 while ((opt = getNextOption()) != null) {
858 switch (opt) {
859 case "-s": {
860 try {
861 slotId = Integer.parseInt(getNextArgRequired());
862 } catch (NumberFormatException e) {
863 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
864 return -1;
865 }
866 break;
867 }
868 }
869 }
870 try {
871 mInterface.enableIms(slotId);
872 } catch (RemoteException e) {
873 return -1;
874 }
875 if (VDBG) {
876 Log.v(LOG_TAG, "ims enable -s " + slotId);
877 }
878 return 0;
879 }
880
881 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700882 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700883 String opt;
884 while ((opt = getNextOption()) != null) {
885 switch (opt) {
886 case "-s": {
887 try {
888 slotId = Integer.parseInt(getNextArgRequired());
889 } catch (NumberFormatException e) {
890 getErrPrintWriter().println(
891 "ims disable requires an integer as a SLOT_ID.");
892 return -1;
893 }
894 break;
895 }
896 }
897 }
898 try {
899 mInterface.disableIms(slotId);
900 } catch (RemoteException e) {
901 return -1;
902 }
903 if (VDBG) {
904 Log.v(LOG_TAG, "ims disable -s " + slotId);
905 }
906 return 0;
907 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700908
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700909 private int handleCepChange() {
910 Log.i(LOG_TAG, "handleCepChange");
911 String opt = getNextArg();
912 if (opt == null) {
913 return -1;
914 }
915 boolean isCepEnabled = opt.equals("enable");
916
917 try {
918 mInterface.setCepEnabled(isCepEnabled);
919 } catch (RemoteException e) {
920 return -1;
921 }
922 return 0;
923 }
924
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700925 private int getDefaultSlot() {
926 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
927 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
928 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
929 // If there is no default, default to slot 0.
930 slotId = DEFAULT_PHONE_ID;
931 }
932 return slotId;
933 }
sqian2fff4a32018-11-05 14:18:37 -0800934
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100935 // Parse options related to Carrier Config Commands.
936 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100937 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100938 CcOptionParseResult result = new CcOptionParseResult();
939 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
940 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100941
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100942 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100943 while ((opt = getNextOption()) != null) {
944 switch (opt) {
945 case "-s": {
946 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100947 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
948 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
949 errPw.println(tag + "No valid subscription found.");
950 return null;
951 }
952
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100953 } catch (IllegalArgumentException e) {
954 // Missing slot id
955 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100956 return null;
957 }
958 break;
959 }
960 case "-p": {
961 if (allowOptionPersistent) {
962 result.mPersistent = true;
963 } else {
964 errPw.println(tag + "Unexpected option " + opt);
965 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100966 }
967 break;
968 }
969 default: {
970 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100971 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100972 }
973 }
974 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100975 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100976 }
977
978 private int slotStringToSubId(String tag, String slotString) {
979 int slotId = -1;
980 try {
981 slotId = Integer.parseInt(slotString);
982 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +0800983 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
984 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
985 }
986
987 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100988 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
989 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
990 }
991
Qiong Liuf25799b2020-09-10 10:13:46 +0800992 Phone phone = PhoneFactory.getPhone(slotId);
993 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100994 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
995 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
996 }
Qiong Liuf25799b2020-09-10 10:13:46 +0800997 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100998 }
999
Hall Liud892bec2018-11-30 14:51:45 -08001000 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001001 // adb can run as root or as shell, depending on whether the device is rooted.
1002 return Binder.getCallingUid() == Process.SHELL_UID
1003 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001004 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001005
1006 private int handleCcCommand() {
1007 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1008 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001009 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001010 getErrPrintWriter().println("cc: Permission denied.");
1011 return -1;
1012 }
1013
1014 String arg = getNextArg();
1015 if (arg == null) {
1016 onHelpCc();
1017 return 0;
1018 }
1019
1020 switch (arg) {
1021 case CC_GET_VALUE: {
1022 return handleCcGetValue();
1023 }
1024 case CC_SET_VALUE: {
1025 return handleCcSetValue();
1026 }
1027 case CC_CLEAR_VALUES: {
1028 return handleCcClearValues();
1029 }
1030 default: {
1031 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1032 }
1033 }
1034 return -1;
1035 }
1036
1037 // cc get-value
1038 private int handleCcGetValue() {
1039 PrintWriter errPw = getErrPrintWriter();
1040 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1041 String key = null;
1042
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001043 // Parse all options
1044 CcOptionParseResult options = parseCcOptions(tag, false);
1045 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001046 return -1;
1047 }
1048
1049 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001050 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001051 if (bundle == 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 key = getNextArg();
1058 if (key != null) {
1059 // A key was provided. Verify if it is a valid key
1060 if (!bundle.containsKey(key)) {
1061 errPw.println(tag + key + " is not a valid key.");
1062 return -1;
1063 }
1064
1065 // Print the carrier config value for key.
1066 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1067 } else {
1068 // No key provided. Show all values.
1069 // Iterate over a sorted list of all carrier config keys and print them.
1070 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1071 for (String k : sortedSet) {
1072 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1073 }
1074 }
1075 return 0;
1076 }
1077
1078 // cc set-value
1079 private int handleCcSetValue() {
1080 PrintWriter errPw = getErrPrintWriter();
1081 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1082
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001083 // Parse all options
1084 CcOptionParseResult options = parseCcOptions(tag, true);
1085 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001086 return -1;
1087 }
1088
1089 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001090 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001091 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001092 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001093 return -1;
1094 }
1095
1096 // Get the key.
1097 String key = getNextArg();
1098 if (key == null || key.equals("")) {
1099 errPw.println(tag + "KEY is missing");
1100 return -1;
1101 }
1102
1103 // Verify if the key is valid
1104 if (!originalValues.containsKey(key)) {
1105 errPw.println(tag + key + " is not a valid key.");
1106 return -1;
1107 }
1108
1109 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1110 ArrayList<String> valueList = new ArrayList<String>();
1111 while (peekNextArg() != null) {
1112 valueList.add(getNextArg());
1113 }
1114
1115 // Find the type of the carrier config value
1116 CcType type = getType(tag, key, originalValues);
1117 if (type == CcType.UNKNOWN) {
1118 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1119 return -1;
1120 }
1121
1122 // Create an override bundle containing the key and value that should be overriden.
1123 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1124 if (overrideBundle == null) {
1125 return -1;
1126 }
1127
1128 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001129 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001130
1131 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001132 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001133 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001134 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001135 return -1;
1136 }
1137
1138 // Print the original and new value.
1139 String originalValueString = ccValueToString(key, type, originalValues);
1140 String newValueString = ccValueToString(key, type, newValues);
1141 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1142 getOutPrintWriter().println("New value: \n" + newValueString);
1143
1144 return 0;
1145 }
1146
1147 // cc clear-values
1148 private int handleCcClearValues() {
1149 PrintWriter errPw = getErrPrintWriter();
1150 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1151
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001152 // Parse all options
1153 CcOptionParseResult options = parseCcOptions(tag, false);
1154 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001155 return -1;
1156 }
1157
1158 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001159 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001160 getOutPrintWriter()
1161 .println("All previously set carrier config override values has been cleared");
1162 return 0;
1163 }
1164
1165 private CcType getType(String tag, String key, PersistableBundle bundle) {
1166 // Find the type by checking the type of the current value stored in the bundle.
1167 Object value = bundle.get(key);
1168
1169 if (CC_TYPE_MAP.containsKey(key)) {
1170 return CC_TYPE_MAP.get(key);
1171 } else if (value != null) {
1172 if (value instanceof Boolean) {
1173 return CcType.BOOLEAN;
1174 } else if (value instanceof Double) {
1175 return CcType.DOUBLE;
1176 } else if (value instanceof double[]) {
1177 return CcType.DOUBLE_ARRAY;
1178 } else if (value instanceof Integer) {
1179 return CcType.INT;
1180 } else if (value instanceof int[]) {
1181 return CcType.INT_ARRAY;
1182 } else if (value instanceof Long) {
1183 return CcType.LONG;
1184 } else if (value instanceof long[]) {
1185 return CcType.LONG_ARRAY;
1186 } else if (value instanceof String) {
1187 return CcType.STRING;
1188 } else if (value instanceof String[]) {
1189 return CcType.STRING_ARRAY;
1190 }
1191 } else {
1192 // Current value was null and can therefore not be used in order to find the type.
1193 // Check the name of the key to infer the type. This check is not needed for primitive
1194 // data types (boolean, double, int and long), since they can not be null.
1195 if (key.endsWith("double_array")) {
1196 return CcType.DOUBLE_ARRAY;
1197 }
1198 if (key.endsWith("int_array")) {
1199 return CcType.INT_ARRAY;
1200 }
1201 if (key.endsWith("long_array")) {
1202 return CcType.LONG_ARRAY;
1203 }
1204 if (key.endsWith("string")) {
1205 return CcType.STRING;
1206 }
1207 if (key.endsWith("string_array") || key.endsWith("strings")) {
1208 return CcType.STRING_ARRAY;
1209 }
1210 }
1211
1212 // Not possible to infer the type by looking at the current value or the key.
1213 PrintWriter errPw = getErrPrintWriter();
1214 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1215 return CcType.UNKNOWN;
1216 }
1217
1218 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1219 String result;
1220 StringBuilder valueString = new StringBuilder();
1221 String typeString = type.toString();
1222 Object value = bundle.get(key);
1223
1224 if (value == null) {
1225 valueString.append("null");
1226 } else {
1227 switch (type) {
1228 case DOUBLE_ARRAY: {
1229 // Format the string representation of the int array as value1 value2......
1230 double[] valueArray = (double[]) value;
1231 for (int i = 0; i < valueArray.length; i++) {
1232 if (i != 0) {
1233 valueString.append(" ");
1234 }
1235 valueString.append(valueArray[i]);
1236 }
1237 break;
1238 }
1239 case INT_ARRAY: {
1240 // Format the string representation of the int array as value1 value2......
1241 int[] valueArray = (int[]) value;
1242 for (int i = 0; i < valueArray.length; i++) {
1243 if (i != 0) {
1244 valueString.append(" ");
1245 }
1246 valueString.append(valueArray[i]);
1247 }
1248 break;
1249 }
1250 case LONG_ARRAY: {
1251 // Format the string representation of the int array as value1 value2......
1252 long[] valueArray = (long[]) value;
1253 for (int i = 0; i < valueArray.length; i++) {
1254 if (i != 0) {
1255 valueString.append(" ");
1256 }
1257 valueString.append(valueArray[i]);
1258 }
1259 break;
1260 }
1261 case STRING: {
1262 valueString.append("\"" + value.toString() + "\"");
1263 break;
1264 }
1265 case STRING_ARRAY: {
1266 // Format the string representation of the string array as "value1" "value2"....
1267 String[] valueArray = (String[]) value;
1268 for (int i = 0; i < valueArray.length; i++) {
1269 if (i != 0) {
1270 valueString.append(" ");
1271 }
1272 if (valueArray[i] != null) {
1273 valueString.append("\"" + valueArray[i] + "\"");
1274 } else {
1275 valueString.append("null");
1276 }
1277 }
1278 break;
1279 }
1280 default: {
1281 valueString.append(value.toString());
1282 }
1283 }
1284 }
1285 return String.format("%-70s %-15s %s", key, typeString, valueString);
1286 }
1287
1288 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1289 ArrayList<String> valueList) {
1290 PrintWriter errPw = getErrPrintWriter();
1291 PersistableBundle bundle = new PersistableBundle();
1292
1293 // First verify that a valid number of values has been provided for the type.
1294 switch (type) {
1295 case BOOLEAN:
1296 case DOUBLE:
1297 case INT:
1298 case LONG: {
1299 if (valueList.size() != 1) {
1300 errPw.println(tag + "Expected 1 value for type " + type
1301 + ". Found: " + valueList.size());
1302 return null;
1303 }
1304 break;
1305 }
1306 case STRING: {
1307 if (valueList.size() > 1) {
1308 errPw.println(tag + "Expected 0 or 1 values for type " + type
1309 + ". Found: " + valueList.size());
1310 return null;
1311 }
1312 break;
1313 }
1314 }
1315
1316 // Parse the value according to type and add it to the Bundle.
1317 switch (type) {
1318 case BOOLEAN: {
1319 if ("true".equalsIgnoreCase(valueList.get(0))) {
1320 bundle.putBoolean(key, true);
1321 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1322 bundle.putBoolean(key, false);
1323 } else {
1324 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1325 return null;
1326 }
1327 break;
1328 }
1329 case DOUBLE: {
1330 try {
1331 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1332 } catch (NumberFormatException nfe) {
1333 // Not a valid double
1334 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1335 return null;
1336 }
1337 break;
1338 }
1339 case DOUBLE_ARRAY: {
1340 double[] valueDoubleArray = null;
1341 if (valueList.size() > 0) {
1342 valueDoubleArray = new double[valueList.size()];
1343 for (int i = 0; i < valueList.size(); i++) {
1344 try {
1345 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1346 } catch (NumberFormatException nfe) {
1347 // Not a valid double
1348 errPw.println(
1349 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1350 return null;
1351 }
1352 }
1353 }
1354 bundle.putDoubleArray(key, valueDoubleArray);
1355 break;
1356 }
1357 case INT: {
1358 try {
1359 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1360 } catch (NumberFormatException nfe) {
1361 // Not a valid integer
1362 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1363 return null;
1364 }
1365 break;
1366 }
1367 case INT_ARRAY: {
1368 int[] valueIntArray = null;
1369 if (valueList.size() > 0) {
1370 valueIntArray = new int[valueList.size()];
1371 for (int i = 0; i < valueList.size(); i++) {
1372 try {
1373 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1374 } catch (NumberFormatException nfe) {
1375 // Not a valid integer
1376 errPw.println(tag
1377 + "Unable to parse " + valueList.get(i) + " as an integer.");
1378 return null;
1379 }
1380 }
1381 }
1382 bundle.putIntArray(key, valueIntArray);
1383 break;
1384 }
1385 case LONG: {
1386 try {
1387 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1388 } catch (NumberFormatException nfe) {
1389 // Not a valid long
1390 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1391 return null;
1392 }
1393 break;
1394 }
1395 case LONG_ARRAY: {
1396 long[] valueLongArray = null;
1397 if (valueList.size() > 0) {
1398 valueLongArray = new long[valueList.size()];
1399 for (int i = 0; i < valueList.size(); i++) {
1400 try {
1401 valueLongArray[i] = Long.parseLong(valueList.get(i));
1402 } catch (NumberFormatException nfe) {
1403 // Not a valid long
1404 errPw.println(
1405 tag + "Unable to parse " + valueList.get(i) + " as a long");
1406 return null;
1407 }
1408 }
1409 }
1410 bundle.putLongArray(key, valueLongArray);
1411 break;
1412 }
1413 case STRING: {
1414 String value = null;
1415 if (valueList.size() > 0) {
1416 value = valueList.get(0);
1417 }
1418 bundle.putString(key, value);
1419 break;
1420 }
1421 case STRING_ARRAY: {
1422 String[] valueStringArray = null;
1423 if (valueList.size() > 0) {
1424 valueStringArray = new String[valueList.size()];
1425 valueList.toArray(valueStringArray);
1426 }
1427 bundle.putStringArray(key, valueStringArray);
1428 break;
1429 }
1430 }
1431 return bundle;
1432 }
Shuo Qian489d9282020-07-09 11:30:03 -07001433
1434 private int handleEndBlockSuppressionCommand() {
1435 if (!checkShellUid()) {
1436 return -1;
1437 }
1438
1439 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1440 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1441 }
1442 return 0;
1443 }
Hui Wang0866fcc2020-10-12 12:14:23 -07001444
Michele Berionne38c1afa2020-12-28 20:23:16 +00001445 private int handleRestartModemCommand() {
1446 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1447 // non user build.
1448 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1449 getErrPrintWriter().println("RestartModem: Permission denied.");
1450 return -1;
1451 }
1452
1453 boolean result = TelephonyManager.getDefault().rebootRadio();
1454 getOutPrintWriter().println(result);
1455
1456 return result ? 0 : -1;
1457 }
1458
Hui Wang0866fcc2020-10-12 12:14:23 -07001459 private int handleGbaCommand() {
1460 String arg = getNextArg();
1461 if (arg == null) {
1462 onHelpGba();
1463 return 0;
1464 }
1465
1466 switch (arg) {
1467 case GBA_SET_SERVICE: {
1468 return handleGbaSetServiceCommand();
1469 }
1470 case GBA_GET_SERVICE: {
1471 return handleGbaGetServiceCommand();
1472 }
1473 case GBA_SET_RELEASE_TIME: {
1474 return handleGbaSetReleaseCommand();
1475 }
1476 case GBA_GET_RELEASE_TIME: {
1477 return handleGbaGetReleaseCommand();
1478 }
1479 }
1480
1481 return -1;
1482 }
1483
1484 private int getSubId(String cmd) {
1485 int slotId = getDefaultSlot();
1486 String opt = getNextOption();
1487 if (opt != null && opt.equals("-s")) {
1488 try {
1489 slotId = Integer.parseInt(getNextArgRequired());
1490 } catch (NumberFormatException e) {
1491 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1492 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1493 }
1494 }
1495 int[] subIds = SubscriptionManager.getSubId(slotId);
1496 return subIds[0];
1497 }
1498
1499 private int handleGbaSetServiceCommand() {
1500 int subId = getSubId("gba set-service");
1501 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1502 return -1;
1503 }
1504
1505 String packageName = getNextArg();
1506 try {
1507 if (packageName == null) {
1508 packageName = "";
1509 }
1510 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1511 if (VDBG) {
1512 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1513 + packageName + ", result=" + result);
1514 }
1515 getOutPrintWriter().println(result);
1516 } catch (RemoteException e) {
1517 Log.w(LOG_TAG, "gba set-service " + subId + " "
1518 + packageName + ", error" + e.getMessage());
1519 getErrPrintWriter().println("Exception: " + e.getMessage());
1520 return -1;
1521 }
1522 return 0;
1523 }
1524
1525 private int handleGbaGetServiceCommand() {
1526 String result;
1527
1528 int subId = getSubId("gba get-service");
1529 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1530 return -1;
1531 }
1532
1533 try {
1534 result = mInterface.getBoundGbaService(subId);
1535 } catch (RemoteException e) {
1536 return -1;
1537 }
1538 if (VDBG) {
1539 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1540 }
1541 getOutPrintWriter().println(result);
1542 return 0;
1543 }
1544
1545 private int handleGbaSetReleaseCommand() {
1546 //the release time value could be -1
1547 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1548 : SubscriptionManager.getDefaultSubscriptionId();
1549 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1550 return -1;
1551 }
1552
1553 String intervalStr = getNextArg();
1554 if (intervalStr == null) {
1555 return -1;
1556 }
1557
1558 try {
1559 int interval = Integer.parseInt(intervalStr);
1560 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1561 if (VDBG) {
1562 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1563 + intervalStr + ", result=" + result);
1564 }
1565 getOutPrintWriter().println(result);
1566 } catch (NumberFormatException | RemoteException e) {
1567 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1568 + intervalStr + ", error" + e.getMessage());
1569 getErrPrintWriter().println("Exception: " + e.getMessage());
1570 return -1;
1571 }
1572 return 0;
1573 }
1574
1575 private int handleGbaGetReleaseCommand() {
1576 int subId = getSubId("gba get-release");
1577 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1578 return -1;
1579 }
1580
1581 int result = 0;
1582 try {
1583 result = mInterface.getGbaReleaseTime(subId);
1584 } catch (RemoteException e) {
1585 return -1;
1586 }
1587 if (VDBG) {
1588 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1589 }
1590 getOutPrintWriter().println(result);
1591 return 0;
1592 }
Hui Wang068ab862020-10-31 05:12:53 +00001593
1594 private int handleSingleRegistrationConfigCommand() {
1595 String arg = getNextArg();
1596 if (arg == null) {
1597 onHelpSrc();
1598 return 0;
1599 }
1600
1601 switch (arg) {
1602 case SRC_SET_DEVICE_ENABLED: {
1603 return handleSrcSetDeviceEnabledCommand();
1604 }
1605 case SRC_GET_DEVICE_ENABLED: {
1606 return handleSrcGetDeviceEnabledCommand();
1607 }
1608 case SRC_SET_CARRIER_ENABLED: {
1609 return handleSrcSetCarrierEnabledCommand();
1610 }
1611 case SRC_GET_CARRIER_ENABLED: {
1612 return handleSrcGetCarrierEnabledCommand();
1613 }
1614 }
1615
1616 return -1;
1617 }
1618
James.cf Linbcdf8b32021-01-14 16:44:13 +08001619 private int handleRcsUceCommand() {
1620 String arg = getNextArg();
1621 if (arg == null) {
1622 Log.w(LOG_TAG, "cannot get uce parameter");
1623 return -1;
1624 }
1625
1626 switch (arg) {
1627 case UCE_REMOVE_EAB_CONTACT:
1628 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08001629 case UCE_GET_EAB_CONTACT:
1630 return handleGettingEabContactCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08001631 case UCE_GET_DEVICE_ENABLED:
1632 return handleUceGetDeviceEnabledCommand();
1633 case UCE_SET_DEVICE_ENABLED:
1634 return handleUceSetDeviceEnabledCommand();
James.cf Linbcdf8b32021-01-14 16:44:13 +08001635 }
1636 return -1;
1637 }
1638
1639 private int handleRemovingEabContactCommand() {
1640 int subId = getSubId("uce remove-eab-contact");
1641 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1642 return -1;
1643 }
1644
1645 String phoneNumber = getNextArgRequired();
1646 if (TextUtils.isEmpty(phoneNumber)) {
1647 return -1;
1648 }
1649 int result = 0;
1650 try {
1651 result = mInterface.removeContactFromEab(subId, phoneNumber);
1652 } catch (RemoteException e) {
1653 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
1654 getErrPrintWriter().println("Exception: " + e.getMessage());
1655 return -1;
1656 }
1657
1658 if (VDBG) {
1659 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
1660 }
calvinpan293ea1b2021-02-04 17:52:13 +08001661 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001662 }
1663
calvinpane4a8a1d2021-01-25 13:51:18 +08001664 private int handleGettingEabContactCommand() {
1665 String phoneNumber = getNextArgRequired();
1666 if (TextUtils.isEmpty(phoneNumber)) {
1667 return -1;
1668 }
1669 String result = "";
1670 try {
1671 result = mInterface.getContactFromEab(phoneNumber);
1672
1673 } catch (RemoteException e) {
1674 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
1675 getErrPrintWriter().println("Exception: " + e.getMessage());
1676 return -1;
1677 }
1678
1679 if (VDBG) {
1680 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
1681 }
calvinpan293ea1b2021-02-04 17:52:13 +08001682 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08001683 return 0;
1684 }
1685
1686 private int handleUceGetDeviceEnabledCommand() {
1687 boolean result = false;
1688 try {
1689 result = mInterface.getDeviceUceEnabled();
1690 } catch (RemoteException e) {
1691 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
1692 return -1;
1693 }
1694 if (VDBG) {
1695 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
1696 }
calvinpane4a8a1d2021-01-25 13:51:18 +08001697 getOutPrintWriter().println(result);
1698 return 0;
1699 }
1700
James.cf Lin4b784aa2021-01-31 03:25:15 +08001701 private int handleUceSetDeviceEnabledCommand() {
1702 String enabledStr = getNextArg();
1703 if (TextUtils.isEmpty(enabledStr)) {
1704 return -1;
1705 }
1706
1707 try {
1708 boolean isEnabled = Boolean.parseBoolean(enabledStr);
1709 mInterface.setDeviceUceEnabled(isEnabled);
1710 if (VDBG) {
1711 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
1712 }
1713 } catch (NumberFormatException | RemoteException e) {
1714 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
1715 getErrPrintWriter().println("Exception: " + e.getMessage());
1716 return -1;
1717 }
1718 return 0;
1719 }
1720
Hui Wang068ab862020-10-31 05:12:53 +00001721 private int handleSrcSetDeviceEnabledCommand() {
1722 String enabledStr = getNextArg();
1723 if (enabledStr == null) {
1724 return -1;
1725 }
1726
1727 try {
1728 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
1729 if (VDBG) {
1730 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
1731 }
1732 getOutPrintWriter().println("Done");
1733 } catch (NumberFormatException | RemoteException e) {
1734 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
1735 getErrPrintWriter().println("Exception: " + e.getMessage());
1736 return -1;
1737 }
1738 return 0;
1739 }
1740
1741 private int handleSrcGetDeviceEnabledCommand() {
1742 boolean result = false;
1743 try {
1744 result = mInterface.getDeviceSingleRegistrationEnabled();
1745 } catch (RemoteException e) {
1746 return -1;
1747 }
1748 if (VDBG) {
1749 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
1750 }
1751 getOutPrintWriter().println(result);
1752 return 0;
1753 }
1754
1755 private int handleSrcSetCarrierEnabledCommand() {
1756 //the release time value could be -1
1757 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
1758 : SubscriptionManager.getDefaultSubscriptionId();
1759 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1760 return -1;
1761 }
1762
1763 String enabledStr = getNextArg();
1764 if (enabledStr == null) {
1765 return -1;
1766 }
1767
1768 try {
1769 boolean result =
1770 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
1771 if (VDBG) {
1772 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1773 + enabledStr + ", result=" + result);
1774 }
1775 getOutPrintWriter().println(result);
1776 } catch (NumberFormatException | RemoteException e) {
1777 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1778 + enabledStr + ", error" + e.getMessage());
1779 getErrPrintWriter().println("Exception: " + e.getMessage());
1780 return -1;
1781 }
1782 return 0;
1783 }
1784
1785 private int handleSrcGetCarrierEnabledCommand() {
1786 int subId = getSubId("src get-carrier-enabled");
1787 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1788 return -1;
1789 }
1790
1791 boolean result = false;
1792 try {
1793 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
1794 } catch (RemoteException e) {
1795 return -1;
1796 }
1797 if (VDBG) {
1798 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
1799 }
1800 getOutPrintWriter().println(result);
1801 return 0;
1802 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001803}