blob: 9cfb804cb153a807947c190d6584ffff5e653780 [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010024import android.content.Context;
Hall Liud892bec2018-11-30 14:51:45 -080025import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010026import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080027import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070028import android.os.RemoteException;
Shuo Qian489d9282020-07-09 11:30:03 -070029import android.provider.BlockedNumberContract;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.telephony.CarrierConfigManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070031import android.telephony.SubscriptionManager;
sqian9d4df8b2019-01-15 18:32:07 -080032import android.telephony.emergency.EmergencyNumber;
Brad Ebinger24c29992019-12-05 13:03:21 -080033import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080034import android.text.TextUtils;
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";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010069 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080070 private static final String DATA_TEST_MODE = "data";
71 private static final String DATA_ENABLE = "enable";
72 private static final String DATA_DISABLE = "disable";
Hall Liud892bec2018-11-30 14:51:45 -080073
Brad Ebinger999d3302020-11-25 14:31:39 -080074 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
75 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
76 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070077 private static final String IMS_ENABLE = "enable";
78 private static final String IMS_DISABLE = "disable";
Tyler Gunn7bcdc742019-10-04 15:56:59 -070079 // Used to disable or enable processing of conference event package data from the network.
80 // This is handy for testing scenarios where CEP data does not exist on a network which does
81 // support CEP data.
82 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070083
Hall Liud892bec2018-11-30 14:51:45 -080084 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -080085 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -080086
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010087 private static final String CC_GET_VALUE = "get-value";
88 private static final String CC_SET_VALUE = "set-value";
89 private static final String CC_CLEAR_VALUES = "clear-values";
90
Hui Wang0866fcc2020-10-12 12:14:23 -070091 private static final String GBA_SUBCOMMAND = "gba";
92 private static final String GBA_SET_SERVICE = "set-service";
93 private static final String GBA_GET_SERVICE = "get-service";
94 private static final String GBA_SET_RELEASE_TIME = "set-release";
95 private static final String GBA_GET_RELEASE_TIME = "get-release";
96
Hui Wang068ab862020-10-31 05:12:53 +000097 private static final String SINGLE_REGISTATION_CONFIG = "src";
98 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
99 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
100 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
101 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
102
Tyler Gunn92479152021-01-20 16:30:10 -0800103 private static final String D2D_SUBCOMMAND = "d2d";
104 private static final String D2D_SEND = "send";
105
James.cf Linbcdf8b32021-01-14 16:44:13 +0800106 private static final String RCS_UCE_COMMAND = "uce";
107 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
108
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700109 // Take advantage of existing methods that already contain permissions checks when possible.
110 private final ITelephony mInterface;
111
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100112 private SubscriptionManager mSubscriptionManager;
113 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700114 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100115
116 private enum CcType {
117 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
118 STRING_ARRAY, UNKNOWN
119 }
120
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100121 private class CcOptionParseResult {
122 public int mSubId;
123 public boolean mPersistent;
124 }
125
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100126 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
127 // keys by looking at the end of the string which usually tells the type.
128 // For instance: "xxxx_string", "xxxx_string_array", etc.
129 // The carrier config keys in this map does not follow this convention. It is therefore not
130 // possible to infer the type for these keys by looking at the string.
131 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
132 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
133 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
134 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
135 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
136 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
137 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
138 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
139 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
140 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
141 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
142 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
143 CcType.STRING);
144 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
145 CcType.STRING_ARRAY);
146 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
147 CcType.STRING_ARRAY);
148 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
149 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
150 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
151 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
152 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
153 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
154 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
155 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
156 }
157 };
158
159 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700160 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100161 mCarrierConfigManager =
162 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
163 mSubscriptionManager = (SubscriptionManager)
164 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700165 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700166 }
167
168 @Override
169 public int onCommand(String cmd) {
170 if (cmd == null) {
171 return handleDefaultCommands(null);
172 }
173
174 switch (cmd) {
175 case IMS_SUBCOMMAND: {
176 return handleImsCommand();
177 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800178 case RCS_UCE_COMMAND:
179 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800180 case NUMBER_VERIFICATION_SUBCOMMAND:
181 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800182 case EMERGENCY_NUMBER_TEST_MODE:
183 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100184 case CARRIER_CONFIG_SUBCOMMAND: {
185 return handleCcCommand();
186 }
Shuo Qianf5125122019-12-16 17:03:07 -0800187 case DATA_TEST_MODE:
188 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700189 case END_BLOCK_SUPPRESSION:
190 return handleEndBlockSuppressionCommand();
Hui Wang0866fcc2020-10-12 12:14:23 -0700191 case GBA_SUBCOMMAND:
192 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800193 case D2D_SUBCOMMAND:
194 return handleD2dCommand();
Hui Wang068ab862020-10-31 05:12:53 +0000195 case SINGLE_REGISTATION_CONFIG:
196 return handleSingleRegistrationConfigCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700197 default: {
198 return handleDefaultCommands(cmd);
199 }
200 }
201 }
202
203 @Override
204 public void onHelp() {
205 PrintWriter pw = getOutPrintWriter();
206 pw.println("Telephony Commands:");
207 pw.println(" help");
208 pw.println(" Print this help text.");
209 pw.println(" ims");
210 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800211 pw.println(" uce");
212 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800213 pw.println(" emergency-number-test-mode");
214 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700215 pw.println(" end-block-suppression");
216 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800217 pw.println(" data");
218 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100219 pw.println(" cc");
220 pw.println(" Carrier Config Commands.");
Hui Wang0866fcc2020-10-12 12:14:23 -0700221 pw.println(" gba");
222 pw.println(" GBA Commands.");
Hui Wang068ab862020-10-31 05:12:53 +0000223 pw.println(" src");
224 pw.println(" RCS VoLTE Single Registration Config Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700225 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800226 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800227 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700228 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800229 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100230 onHelpCc();
Hui Wang0866fcc2020-10-12 12:14:23 -0700231 onHelpGba();
Hui Wang068ab862020-10-31 05:12:53 +0000232 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800233 onHelpD2D();
234 }
235
236 private void onHelpD2D() {
237 PrintWriter pw = getOutPrintWriter();
238 pw.println("D2D Comms Commands:");
239 pw.println(" d2d send TYPE VALUE");
240 pw.println(" Sends a D2D message of specified type and value.");
241 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
242 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
243 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
244 MESSAGE_CALL_AUDIO_CODEC));
245 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
246 + Communicator.messageToString(
247 MESSAGE_DEVICE_BATTERY_STATE));
248 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
249 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700250 }
251
252 private void onHelpIms() {
253 PrintWriter pw = getOutPrintWriter();
254 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800255 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700256 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
257 pw.println(" ImsService. Options are:");
258 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
259 pw.println(" is specified, it will choose the default voice SIM slot.");
260 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
261 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800262 pw.println(" -f: Set the feature that this override if for, if no option is");
263 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700264 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
265 pw.println(" Gets the package name of the currently defined ImsService.");
266 pw.println(" Options are:");
267 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
268 pw.println(" is specified, it will choose the default voice SIM slot.");
269 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000270 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800271 pw.println(" -f: The feature type that the query will be requested for. If none is");
272 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800273 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
274 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
275 pw.println(" configuration overrides. 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.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700278 pw.println(" ims enable [-s SLOT_ID]");
279 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
280 pw.println(" if none is specified.");
281 pw.println(" ims disable [-s SLOT_ID]");
282 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
283 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700284 pw.println(" ims conference-event-package [enable/disable]");
285 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700286 }
287
James.cf Linbcdf8b32021-01-14 16:44:13 +0800288 private void onHelpUce() {
289 PrintWriter pw = getOutPrintWriter();
290 pw.println("User Capability Exchange Commands:");
291 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
292 pw.println(" Remove the EAB contacts from the EAB database.");
293 pw.println(" Options are:");
294 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
295 pw.println(" is specified, it will choose the default voice SIM slot.");
296 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
297 }
298
Hall Liud892bec2018-11-30 14:51:45 -0800299 private void onHelpNumberVerification() {
300 PrintWriter pw = getOutPrintWriter();
301 pw.println("Number verification commands");
302 pw.println(" numverify override-package PACKAGE_NAME;");
303 pw.println(" Set the authorized package for number verification.");
304 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800305 pw.println(" numverify fake-call NUMBER;");
306 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
307 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800308 }
309
Shuo Qianf5125122019-12-16 17:03:07 -0800310 private void onHelpDataTestMode() {
311 PrintWriter pw = getOutPrintWriter();
312 pw.println("Mobile Data Test Mode Commands:");
313 pw.println(" data enable: enable mobile data connectivity");
314 pw.println(" data disable: disable mobile data connectivity");
315 }
316
sqian9d4df8b2019-01-15 18:32:07 -0800317 private void onHelpEmergencyNumber() {
318 PrintWriter pw = getOutPrintWriter();
319 pw.println("Emergency Number Test Mode Commands:");
320 pw.println(" emergency-number-test-mode ");
321 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
322 + " the test mode");
323 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700324 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800325 pw.println(" -c: clear the emergency number list in the test mode.");
326 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700327 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800328 pw.println(" -p: get the full emergency number list in the test mode.");
329 }
330
Shuo Qian489d9282020-07-09 11:30:03 -0700331 private void onHelpEndBlockSupperssion() {
332 PrintWriter pw = getOutPrintWriter();
333 pw.println("End Block Suppression command:");
334 pw.println(" end-block-suppression: disable suppressing blocking by contact");
335 pw.println(" with emergency services.");
336 }
337
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100338 private void onHelpCc() {
339 PrintWriter pw = getOutPrintWriter();
340 pw.println("Carrier Config Commands:");
341 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
342 pw.println(" Print carrier config values.");
343 pw.println(" Options are:");
344 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
345 pw.println(" is specified, it will choose the default voice SIM slot.");
346 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
347 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100348 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100349 pw.println(" Set carrier config KEY to NEW_VALUE.");
350 pw.println(" Options are:");
351 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
352 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100353 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100354 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
355 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
356 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
357 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
358 pw.println(" cc clear-values [-s SLOT_ID]");
359 pw.println(" Clear all carrier override values that has previously been set");
360 pw.println(" with set-value");
361 pw.println(" Options are:");
362 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
363 pw.println(" is specified, it will choose the default voice SIM slot.");
364 }
365
Hui Wang0866fcc2020-10-12 12:14:23 -0700366 private void onHelpGba() {
367 PrintWriter pw = getOutPrintWriter();
368 pw.println("Gba Commands:");
369 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
370 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
371 pw.println(" Options are:");
372 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
373 pw.println(" is specified, it will choose the default voice SIM slot.");
374 pw.println(" gba get-service [-s SLOT_ID]");
375 pw.println(" Gets the package name of the currently defined GbaService.");
376 pw.println(" Options are:");
377 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
378 pw.println(" is specified, it will choose the default voice SIM slot.");
379 pw.println(" gba set-release [-s SLOT_ID] n");
380 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
381 pw.println(" Do not release/unbind if n is -1.");
382 pw.println(" Options are:");
383 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
384 pw.println(" is specified, it will choose the default voice SIM slot.");
385 pw.println(" gba get-release [-s SLOT_ID]");
386 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
387 pw.println(" Options are:");
388 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
389 pw.println(" is specified, it will choose the default voice SIM slot.");
390 }
391
Hui Wang068ab862020-10-31 05:12:53 +0000392 private void onHelpSrc() {
393 PrintWriter pw = getOutPrintWriter();
394 pw.println("RCS VoLTE Single Registration Config Commands:");
395 pw.println(" src set-device-enabled true|false|null");
396 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
397 pw.println(" The value could be true, false, or null(undefined).");
398 pw.println(" src get-device-enabled");
399 pw.println(" Gets the device config for RCS VoLTE single registration.");
400 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
401 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
402 pw.println(" The value could be true, false, or null(undefined).");
403 pw.println(" Options are:");
404 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
405 pw.println(" is specified, it will choose the default voice SIM slot.");
406 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
407 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
408 pw.println(" Options are:");
409 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
410 pw.println(" is specified, it will choose the default voice SIM slot.");
411 }
412
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700413 private int handleImsCommand() {
414 String arg = getNextArg();
415 if (arg == null) {
416 onHelpIms();
417 return 0;
418 }
419
420 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800421 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700422 return handleImsSetServiceCommand();
423 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800424 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700425 return handleImsGetServiceCommand();
426 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800427 case IMS_CLEAR_SERVICE_OVERRIDE: {
428 return handleImsClearCarrierServiceCommand();
429 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700430 case IMS_ENABLE: {
431 return handleEnableIms();
432 }
433 case IMS_DISABLE: {
434 return handleDisableIms();
435 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700436 case IMS_CEP: {
437 return handleCepChange();
438 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700439 }
440
441 return -1;
442 }
443
Shuo Qianf5125122019-12-16 17:03:07 -0800444 private int handleDataTestModeCommand() {
445 PrintWriter errPw = getErrPrintWriter();
446 String arg = getNextArgRequired();
447 if (arg == null) {
448 onHelpDataTestMode();
449 return 0;
450 }
451 switch (arg) {
452 case DATA_ENABLE: {
453 try {
454 mInterface.enableDataConnectivity();
455 } catch (RemoteException ex) {
456 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
457 errPw.println("Exception: " + ex.getMessage());
458 return -1;
459 }
460 break;
461 }
462 case DATA_DISABLE: {
463 try {
464 mInterface.disableDataConnectivity();
465 } catch (RemoteException ex) {
466 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
467 errPw.println("Exception: " + ex.getMessage());
468 return -1;
469 }
470 break;
471 }
472 default:
473 onHelpDataTestMode();
474 break;
475 }
476 return 0;
477 }
478
sqian9d4df8b2019-01-15 18:32:07 -0800479 private int handleEmergencyNumberTestModeCommand() {
480 PrintWriter errPw = getErrPrintWriter();
481 String opt = getNextOption();
482 if (opt == null) {
483 onHelpEmergencyNumber();
484 return 0;
485 }
486
487 switch (opt) {
488 case "-a": {
489 String emergencyNumberCmd = getNextArgRequired();
490 if (emergencyNumberCmd == null
491 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700492 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800493 + " to be specified after -a in the command ");
494 return -1;
495 }
496 try {
497 mInterface.updateEmergencyNumberListTestMode(
498 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
499 new EmergencyNumber(emergencyNumberCmd, "", "",
500 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
501 new ArrayList<String>(),
502 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
503 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
504 } catch (RemoteException ex) {
505 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
506 + ", error " + ex.getMessage());
507 errPw.println("Exception: " + ex.getMessage());
508 return -1;
509 }
510 break;
511 }
512 case "-c": {
513 try {
514 mInterface.updateEmergencyNumberListTestMode(
515 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
516 } catch (RemoteException ex) {
517 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
518 errPw.println("Exception: " + ex.getMessage());
519 return -1;
520 }
521 break;
522 }
523 case "-r": {
524 String emergencyNumberCmd = getNextArgRequired();
525 if (emergencyNumberCmd == null
526 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700527 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800528 + " to be specified after -r in the command ");
529 return -1;
530 }
531 try {
532 mInterface.updateEmergencyNumberListTestMode(
533 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
534 new EmergencyNumber(emergencyNumberCmd, "", "",
535 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
536 new ArrayList<String>(),
537 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
538 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
539 } catch (RemoteException ex) {
540 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
541 + ", error " + ex.getMessage());
542 errPw.println("Exception: " + ex.getMessage());
543 return -1;
544 }
545 break;
546 }
547 case "-p": {
548 try {
549 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
550 } catch (RemoteException ex) {
551 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
552 errPw.println("Exception: " + ex.getMessage());
553 return -1;
554 }
555 break;
556 }
557 default:
558 onHelpEmergencyNumber();
559 break;
560 }
561 return 0;
562 }
563
Hall Liud892bec2018-11-30 14:51:45 -0800564 private int handleNumberVerificationCommand() {
565 String arg = getNextArg();
566 if (arg == null) {
567 onHelpNumberVerification();
568 return 0;
569 }
570
Hall Liuca5af3a2018-12-04 16:58:23 -0800571 if (!checkShellUid()) {
572 return -1;
573 }
574
Hall Liud892bec2018-11-30 14:51:45 -0800575 switch (arg) {
576 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800577 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
578 return 0;
579 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800580 case NUMBER_VERIFICATION_FAKE_CALL: {
581 boolean val = NumberVerificationManager.getInstance()
582 .checkIncomingCall(getNextArg());
583 getOutPrintWriter().println(val ? "1" : "0");
584 return 0;
585 }
Hall Liud892bec2018-11-30 14:51:45 -0800586 }
587
588 return -1;
589 }
590
Tyler Gunn92479152021-01-20 16:30:10 -0800591 private int handleD2dCommand() {
592 String arg = getNextArg();
593 if (arg == null) {
594 onHelpD2D();
595 return 0;
596 }
597
598 switch (arg) {
599 case D2D_SEND: {
600 return handleD2dSendCommand();
601 }
602 }
603
604 return -1;
605 }
606
607 private int handleD2dSendCommand() {
608 PrintWriter errPw = getErrPrintWriter();
609 String opt;
610 int messageType = -1;
611 int messageValue = -1;
612
613
614 String arg = getNextArg();
615 if (arg == null) {
616 onHelpD2D();
617 return 0;
618 }
619 try {
620 messageType = Integer.parseInt(arg);
621 } catch (NumberFormatException e) {
622 errPw.println("message type must be a valid integer");
623 return -1;
624 }
625
626 arg = getNextArg();
627 if (arg == null) {
628 onHelpD2D();
629 return 0;
630 }
631 try {
632 messageValue = Integer.parseInt(arg);
633 } catch (NumberFormatException e) {
634 errPw.println("message value must be a valid integer");
635 return -1;
636 }
637
638 try {
639 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
640 } catch (RemoteException e) {
641 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
642 errPw.println("Exception: " + e.getMessage());
643 return -1;
644 }
645
646 return 0;
647 }
648
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700649 // ims set-ims-service
650 private int handleImsSetServiceCommand() {
651 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700652 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700653 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800654 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700655
656 String opt;
657 while ((opt = getNextOption()) != null) {
658 switch (opt) {
659 case "-s": {
660 try {
661 slotId = Integer.parseInt(getNextArgRequired());
662 } catch (NumberFormatException e) {
663 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
664 return -1;
665 }
666 break;
667 }
668 case "-c": {
669 isCarrierService = true;
670 break;
671 }
672 case "-d": {
673 isCarrierService = false;
674 break;
675 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800676 case "-f": {
677 String featureString = getNextArgRequired();
678 String[] features = featureString.split(",");
679 for (int i = 0; i < features.length; i++) {
680 try {
681 Integer result = Integer.parseInt(features[i]);
682 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
683 || result >= ImsFeature.FEATURE_MAX) {
684 errPw.println("ims set-ims-service -f " + result
685 + " is an invalid feature.");
686 return -1;
687 }
688 featuresList.add(result);
689 } catch (NumberFormatException e) {
690 errPw.println("ims set-ims-service -f tried to parse " + features[i]
691 + " as an integer.");
692 return -1;
693 }
694 }
695 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700696 }
697 }
698 // Mandatory param, either -c or -d
699 if (isCarrierService == null) {
700 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
701 return -1;
702 }
703
704 String packageName = getNextArg();
705
706 try {
707 if (packageName == null) {
708 packageName = "";
709 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800710 int[] featureArray = new int[featuresList.size()];
711 for (int i = 0; i < featuresList.size(); i++) {
712 featureArray[i] = featuresList.get(i);
713 }
714 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
715 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700716 if (VDBG) {
717 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800718 + (isCarrierService ? "-c " : "-d ")
719 + "-f " + featuresList + " "
720 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700721 }
722 getOutPrintWriter().println(result);
723 } catch (RemoteException e) {
724 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800725 + (isCarrierService ? "-c " : "-d ")
726 + "-f " + featuresList + " "
727 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700728 errPw.println("Exception: " + e.getMessage());
729 return -1;
730 }
731 return 0;
732 }
733
Brad Ebinger999d3302020-11-25 14:31:39 -0800734 // ims clear-ims-service-override
735 private int handleImsClearCarrierServiceCommand() {
736 PrintWriter errPw = getErrPrintWriter();
737 int slotId = getDefaultSlot();
738
739 String opt;
740 while ((opt = getNextOption()) != null) {
741 switch (opt) {
742 case "-s": {
743 try {
744 slotId = Integer.parseInt(getNextArgRequired());
745 } catch (NumberFormatException e) {
746 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
747 return -1;
748 }
749 break;
750 }
751 }
752 }
753
754 try {
755 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
756 if (VDBG) {
757 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
758 + ", result=" + result);
759 }
760 getOutPrintWriter().println(result);
761 } catch (RemoteException e) {
762 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
763 + ", error" + e.getMessage());
764 errPw.println("Exception: " + e.getMessage());
765 return -1;
766 }
767 return 0;
768 }
769
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700770 // ims get-ims-service
771 private int handleImsGetServiceCommand() {
772 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700773 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700774 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800775 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700776
777 String opt;
778 while ((opt = getNextOption()) != null) {
779 switch (opt) {
780 case "-s": {
781 try {
782 slotId = Integer.parseInt(getNextArgRequired());
783 } catch (NumberFormatException e) {
784 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
785 return -1;
786 }
787 break;
788 }
789 case "-c": {
790 isCarrierService = true;
791 break;
792 }
793 case "-d": {
794 isCarrierService = false;
795 break;
796 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800797 case "-f": {
798 try {
799 featureType = Integer.parseInt(getNextArg());
800 } catch (NumberFormatException e) {
801 errPw.println("ims get-ims-service -f requires valid integer as feature.");
802 return -1;
803 }
804 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
805 || featureType >= ImsFeature.FEATURE_MAX) {
806 errPw.println("ims get-ims-service -f invalid feature.");
807 return -1;
808 }
809 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700810 }
811 }
812 // Mandatory param, either -c or -d
813 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800814 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700815 return -1;
816 }
817
818 String result;
819 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800820 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700821 } catch (RemoteException e) {
822 return -1;
823 }
824 if (VDBG) {
825 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800826 + (isCarrierService ? "-c " : "-d ")
827 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
828 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700829 }
830 getOutPrintWriter().println(result);
831 return 0;
832 }
833
834 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700835 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700836 String opt;
837 while ((opt = getNextOption()) != null) {
838 switch (opt) {
839 case "-s": {
840 try {
841 slotId = Integer.parseInt(getNextArgRequired());
842 } catch (NumberFormatException e) {
843 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
844 return -1;
845 }
846 break;
847 }
848 }
849 }
850 try {
851 mInterface.enableIms(slotId);
852 } catch (RemoteException e) {
853 return -1;
854 }
855 if (VDBG) {
856 Log.v(LOG_TAG, "ims enable -s " + slotId);
857 }
858 return 0;
859 }
860
861 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700862 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700863 String opt;
864 while ((opt = getNextOption()) != null) {
865 switch (opt) {
866 case "-s": {
867 try {
868 slotId = Integer.parseInt(getNextArgRequired());
869 } catch (NumberFormatException e) {
870 getErrPrintWriter().println(
871 "ims disable requires an integer as a SLOT_ID.");
872 return -1;
873 }
874 break;
875 }
876 }
877 }
878 try {
879 mInterface.disableIms(slotId);
880 } catch (RemoteException e) {
881 return -1;
882 }
883 if (VDBG) {
884 Log.v(LOG_TAG, "ims disable -s " + slotId);
885 }
886 return 0;
887 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700888
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700889 private int handleCepChange() {
890 Log.i(LOG_TAG, "handleCepChange");
891 String opt = getNextArg();
892 if (opt == null) {
893 return -1;
894 }
895 boolean isCepEnabled = opt.equals("enable");
896
897 try {
898 mInterface.setCepEnabled(isCepEnabled);
899 } catch (RemoteException e) {
900 return -1;
901 }
902 return 0;
903 }
904
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700905 private int getDefaultSlot() {
906 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
907 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
908 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
909 // If there is no default, default to slot 0.
910 slotId = DEFAULT_PHONE_ID;
911 }
912 return slotId;
913 }
sqian2fff4a32018-11-05 14:18:37 -0800914
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100915 // Parse options related to Carrier Config Commands.
916 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100917 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100918 CcOptionParseResult result = new CcOptionParseResult();
919 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
920 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100921
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100922 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100923 while ((opt = getNextOption()) != null) {
924 switch (opt) {
925 case "-s": {
926 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100927 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
928 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
929 errPw.println(tag + "No valid subscription found.");
930 return null;
931 }
932
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100933 } catch (IllegalArgumentException e) {
934 // Missing slot id
935 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100936 return null;
937 }
938 break;
939 }
940 case "-p": {
941 if (allowOptionPersistent) {
942 result.mPersistent = true;
943 } else {
944 errPw.println(tag + "Unexpected option " + opt);
945 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100946 }
947 break;
948 }
949 default: {
950 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100951 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100952 }
953 }
954 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100955 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100956 }
957
958 private int slotStringToSubId(String tag, String slotString) {
959 int slotId = -1;
960 try {
961 slotId = Integer.parseInt(slotString);
962 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +0800963 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
964 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
965 }
966
967 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100968 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
969 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
970 }
971
Qiong Liuf25799b2020-09-10 10:13:46 +0800972 Phone phone = PhoneFactory.getPhone(slotId);
973 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100974 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
975 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
976 }
Qiong Liuf25799b2020-09-10 10:13:46 +0800977 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100978 }
979
Hall Liud892bec2018-11-30 14:51:45 -0800980 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -0800981 // adb can run as root or as shell, depending on whether the device is rooted.
982 return Binder.getCallingUid() == Process.SHELL_UID
983 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -0800984 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100985
986 private int handleCcCommand() {
987 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
988 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -0800989 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100990 getErrPrintWriter().println("cc: Permission denied.");
991 return -1;
992 }
993
994 String arg = getNextArg();
995 if (arg == null) {
996 onHelpCc();
997 return 0;
998 }
999
1000 switch (arg) {
1001 case CC_GET_VALUE: {
1002 return handleCcGetValue();
1003 }
1004 case CC_SET_VALUE: {
1005 return handleCcSetValue();
1006 }
1007 case CC_CLEAR_VALUES: {
1008 return handleCcClearValues();
1009 }
1010 default: {
1011 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1012 }
1013 }
1014 return -1;
1015 }
1016
1017 // cc get-value
1018 private int handleCcGetValue() {
1019 PrintWriter errPw = getErrPrintWriter();
1020 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1021 String key = null;
1022
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001023 // Parse all options
1024 CcOptionParseResult options = parseCcOptions(tag, false);
1025 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001026 return -1;
1027 }
1028
1029 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001030 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001031 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001032 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001033 return -1;
1034 }
1035
1036 // Get the key.
1037 key = getNextArg();
1038 if (key != null) {
1039 // A key was provided. Verify if it is a valid key
1040 if (!bundle.containsKey(key)) {
1041 errPw.println(tag + key + " is not a valid key.");
1042 return -1;
1043 }
1044
1045 // Print the carrier config value for key.
1046 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1047 } else {
1048 // No key provided. Show all values.
1049 // Iterate over a sorted list of all carrier config keys and print them.
1050 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1051 for (String k : sortedSet) {
1052 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1053 }
1054 }
1055 return 0;
1056 }
1057
1058 // cc set-value
1059 private int handleCcSetValue() {
1060 PrintWriter errPw = getErrPrintWriter();
1061 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1062
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001063 // Parse all options
1064 CcOptionParseResult options = parseCcOptions(tag, true);
1065 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001066 return -1;
1067 }
1068
1069 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001070 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001071 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001072 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001073 return -1;
1074 }
1075
1076 // Get the key.
1077 String key = getNextArg();
1078 if (key == null || key.equals("")) {
1079 errPw.println(tag + "KEY is missing");
1080 return -1;
1081 }
1082
1083 // Verify if the key is valid
1084 if (!originalValues.containsKey(key)) {
1085 errPw.println(tag + key + " is not a valid key.");
1086 return -1;
1087 }
1088
1089 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1090 ArrayList<String> valueList = new ArrayList<String>();
1091 while (peekNextArg() != null) {
1092 valueList.add(getNextArg());
1093 }
1094
1095 // Find the type of the carrier config value
1096 CcType type = getType(tag, key, originalValues);
1097 if (type == CcType.UNKNOWN) {
1098 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1099 return -1;
1100 }
1101
1102 // Create an override bundle containing the key and value that should be overriden.
1103 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1104 if (overrideBundle == null) {
1105 return -1;
1106 }
1107
1108 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001109 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001110
1111 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001112 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001113 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001114 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001115 return -1;
1116 }
1117
1118 // Print the original and new value.
1119 String originalValueString = ccValueToString(key, type, originalValues);
1120 String newValueString = ccValueToString(key, type, newValues);
1121 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1122 getOutPrintWriter().println("New value: \n" + newValueString);
1123
1124 return 0;
1125 }
1126
1127 // cc clear-values
1128 private int handleCcClearValues() {
1129 PrintWriter errPw = getErrPrintWriter();
1130 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1131
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001132 // Parse all options
1133 CcOptionParseResult options = parseCcOptions(tag, false);
1134 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001135 return -1;
1136 }
1137
1138 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001139 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001140 getOutPrintWriter()
1141 .println("All previously set carrier config override values has been cleared");
1142 return 0;
1143 }
1144
1145 private CcType getType(String tag, String key, PersistableBundle bundle) {
1146 // Find the type by checking the type of the current value stored in the bundle.
1147 Object value = bundle.get(key);
1148
1149 if (CC_TYPE_MAP.containsKey(key)) {
1150 return CC_TYPE_MAP.get(key);
1151 } else if (value != null) {
1152 if (value instanceof Boolean) {
1153 return CcType.BOOLEAN;
1154 } else if (value instanceof Double) {
1155 return CcType.DOUBLE;
1156 } else if (value instanceof double[]) {
1157 return CcType.DOUBLE_ARRAY;
1158 } else if (value instanceof Integer) {
1159 return CcType.INT;
1160 } else if (value instanceof int[]) {
1161 return CcType.INT_ARRAY;
1162 } else if (value instanceof Long) {
1163 return CcType.LONG;
1164 } else if (value instanceof long[]) {
1165 return CcType.LONG_ARRAY;
1166 } else if (value instanceof String) {
1167 return CcType.STRING;
1168 } else if (value instanceof String[]) {
1169 return CcType.STRING_ARRAY;
1170 }
1171 } else {
1172 // Current value was null and can therefore not be used in order to find the type.
1173 // Check the name of the key to infer the type. This check is not needed for primitive
1174 // data types (boolean, double, int and long), since they can not be null.
1175 if (key.endsWith("double_array")) {
1176 return CcType.DOUBLE_ARRAY;
1177 }
1178 if (key.endsWith("int_array")) {
1179 return CcType.INT_ARRAY;
1180 }
1181 if (key.endsWith("long_array")) {
1182 return CcType.LONG_ARRAY;
1183 }
1184 if (key.endsWith("string")) {
1185 return CcType.STRING;
1186 }
1187 if (key.endsWith("string_array") || key.endsWith("strings")) {
1188 return CcType.STRING_ARRAY;
1189 }
1190 }
1191
1192 // Not possible to infer the type by looking at the current value or the key.
1193 PrintWriter errPw = getErrPrintWriter();
1194 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1195 return CcType.UNKNOWN;
1196 }
1197
1198 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1199 String result;
1200 StringBuilder valueString = new StringBuilder();
1201 String typeString = type.toString();
1202 Object value = bundle.get(key);
1203
1204 if (value == null) {
1205 valueString.append("null");
1206 } else {
1207 switch (type) {
1208 case DOUBLE_ARRAY: {
1209 // Format the string representation of the int array as value1 value2......
1210 double[] valueArray = (double[]) value;
1211 for (int i = 0; i < valueArray.length; i++) {
1212 if (i != 0) {
1213 valueString.append(" ");
1214 }
1215 valueString.append(valueArray[i]);
1216 }
1217 break;
1218 }
1219 case INT_ARRAY: {
1220 // Format the string representation of the int array as value1 value2......
1221 int[] valueArray = (int[]) value;
1222 for (int i = 0; i < valueArray.length; i++) {
1223 if (i != 0) {
1224 valueString.append(" ");
1225 }
1226 valueString.append(valueArray[i]);
1227 }
1228 break;
1229 }
1230 case LONG_ARRAY: {
1231 // Format the string representation of the int array as value1 value2......
1232 long[] valueArray = (long[]) value;
1233 for (int i = 0; i < valueArray.length; i++) {
1234 if (i != 0) {
1235 valueString.append(" ");
1236 }
1237 valueString.append(valueArray[i]);
1238 }
1239 break;
1240 }
1241 case STRING: {
1242 valueString.append("\"" + value.toString() + "\"");
1243 break;
1244 }
1245 case STRING_ARRAY: {
1246 // Format the string representation of the string array as "value1" "value2"....
1247 String[] valueArray = (String[]) value;
1248 for (int i = 0; i < valueArray.length; i++) {
1249 if (i != 0) {
1250 valueString.append(" ");
1251 }
1252 if (valueArray[i] != null) {
1253 valueString.append("\"" + valueArray[i] + "\"");
1254 } else {
1255 valueString.append("null");
1256 }
1257 }
1258 break;
1259 }
1260 default: {
1261 valueString.append(value.toString());
1262 }
1263 }
1264 }
1265 return String.format("%-70s %-15s %s", key, typeString, valueString);
1266 }
1267
1268 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1269 ArrayList<String> valueList) {
1270 PrintWriter errPw = getErrPrintWriter();
1271 PersistableBundle bundle = new PersistableBundle();
1272
1273 // First verify that a valid number of values has been provided for the type.
1274 switch (type) {
1275 case BOOLEAN:
1276 case DOUBLE:
1277 case INT:
1278 case LONG: {
1279 if (valueList.size() != 1) {
1280 errPw.println(tag + "Expected 1 value for type " + type
1281 + ". Found: " + valueList.size());
1282 return null;
1283 }
1284 break;
1285 }
1286 case STRING: {
1287 if (valueList.size() > 1) {
1288 errPw.println(tag + "Expected 0 or 1 values for type " + type
1289 + ". Found: " + valueList.size());
1290 return null;
1291 }
1292 break;
1293 }
1294 }
1295
1296 // Parse the value according to type and add it to the Bundle.
1297 switch (type) {
1298 case BOOLEAN: {
1299 if ("true".equalsIgnoreCase(valueList.get(0))) {
1300 bundle.putBoolean(key, true);
1301 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1302 bundle.putBoolean(key, false);
1303 } else {
1304 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1305 return null;
1306 }
1307 break;
1308 }
1309 case DOUBLE: {
1310 try {
1311 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1312 } catch (NumberFormatException nfe) {
1313 // Not a valid double
1314 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1315 return null;
1316 }
1317 break;
1318 }
1319 case DOUBLE_ARRAY: {
1320 double[] valueDoubleArray = null;
1321 if (valueList.size() > 0) {
1322 valueDoubleArray = new double[valueList.size()];
1323 for (int i = 0; i < valueList.size(); i++) {
1324 try {
1325 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1326 } catch (NumberFormatException nfe) {
1327 // Not a valid double
1328 errPw.println(
1329 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1330 return null;
1331 }
1332 }
1333 }
1334 bundle.putDoubleArray(key, valueDoubleArray);
1335 break;
1336 }
1337 case INT: {
1338 try {
1339 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1340 } catch (NumberFormatException nfe) {
1341 // Not a valid integer
1342 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1343 return null;
1344 }
1345 break;
1346 }
1347 case INT_ARRAY: {
1348 int[] valueIntArray = null;
1349 if (valueList.size() > 0) {
1350 valueIntArray = new int[valueList.size()];
1351 for (int i = 0; i < valueList.size(); i++) {
1352 try {
1353 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1354 } catch (NumberFormatException nfe) {
1355 // Not a valid integer
1356 errPw.println(tag
1357 + "Unable to parse " + valueList.get(i) + " as an integer.");
1358 return null;
1359 }
1360 }
1361 }
1362 bundle.putIntArray(key, valueIntArray);
1363 break;
1364 }
1365 case LONG: {
1366 try {
1367 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1368 } catch (NumberFormatException nfe) {
1369 // Not a valid long
1370 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1371 return null;
1372 }
1373 break;
1374 }
1375 case LONG_ARRAY: {
1376 long[] valueLongArray = null;
1377 if (valueList.size() > 0) {
1378 valueLongArray = new long[valueList.size()];
1379 for (int i = 0; i < valueList.size(); i++) {
1380 try {
1381 valueLongArray[i] = Long.parseLong(valueList.get(i));
1382 } catch (NumberFormatException nfe) {
1383 // Not a valid long
1384 errPw.println(
1385 tag + "Unable to parse " + valueList.get(i) + " as a long");
1386 return null;
1387 }
1388 }
1389 }
1390 bundle.putLongArray(key, valueLongArray);
1391 break;
1392 }
1393 case STRING: {
1394 String value = null;
1395 if (valueList.size() > 0) {
1396 value = valueList.get(0);
1397 }
1398 bundle.putString(key, value);
1399 break;
1400 }
1401 case STRING_ARRAY: {
1402 String[] valueStringArray = null;
1403 if (valueList.size() > 0) {
1404 valueStringArray = new String[valueList.size()];
1405 valueList.toArray(valueStringArray);
1406 }
1407 bundle.putStringArray(key, valueStringArray);
1408 break;
1409 }
1410 }
1411 return bundle;
1412 }
Shuo Qian489d9282020-07-09 11:30:03 -07001413
1414 private int handleEndBlockSuppressionCommand() {
1415 if (!checkShellUid()) {
1416 return -1;
1417 }
1418
1419 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1420 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1421 }
1422 return 0;
1423 }
Hui Wang0866fcc2020-10-12 12:14:23 -07001424
1425 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 Wang068ab862020-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
James.cf Linbcdf8b32021-01-14 16:44:13 +08001585 private int handleRcsUceCommand() {
1586 String arg = getNextArg();
1587 if (arg == null) {
1588 Log.w(LOG_TAG, "cannot get uce parameter");
1589 return -1;
1590 }
1591
1592 switch (arg) {
1593 case UCE_REMOVE_EAB_CONTACT:
1594 return handleRemovingEabContactCommand();
1595 }
1596 return -1;
1597 }
1598
1599 private int handleRemovingEabContactCommand() {
1600 int subId = getSubId("uce remove-eab-contact");
1601 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1602 return -1;
1603 }
1604
1605 String phoneNumber = getNextArgRequired();
1606 if (TextUtils.isEmpty(phoneNumber)) {
1607 return -1;
1608 }
1609 int result = 0;
1610 try {
1611 result = mInterface.removeContactFromEab(subId, phoneNumber);
1612 } catch (RemoteException e) {
1613 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
1614 getErrPrintWriter().println("Exception: " + e.getMessage());
1615 return -1;
1616 }
1617
1618 if (VDBG) {
1619 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
1620 }
1621 return result;
1622 }
1623
Hui Wang068ab862020-10-31 05:12:53 +00001624 private int handleSrcSetDeviceEnabledCommand() {
1625 String enabledStr = getNextArg();
1626 if (enabledStr == null) {
1627 return -1;
1628 }
1629
1630 try {
1631 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
1632 if (VDBG) {
1633 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
1634 }
1635 getOutPrintWriter().println("Done");
1636 } catch (NumberFormatException | RemoteException e) {
1637 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
1638 getErrPrintWriter().println("Exception: " + e.getMessage());
1639 return -1;
1640 }
1641 return 0;
1642 }
1643
1644 private int handleSrcGetDeviceEnabledCommand() {
1645 boolean result = false;
1646 try {
1647 result = mInterface.getDeviceSingleRegistrationEnabled();
1648 } catch (RemoteException e) {
1649 return -1;
1650 }
1651 if (VDBG) {
1652 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
1653 }
1654 getOutPrintWriter().println(result);
1655 return 0;
1656 }
1657
1658 private int handleSrcSetCarrierEnabledCommand() {
1659 //the release time value could be -1
1660 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
1661 : SubscriptionManager.getDefaultSubscriptionId();
1662 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1663 return -1;
1664 }
1665
1666 String enabledStr = getNextArg();
1667 if (enabledStr == null) {
1668 return -1;
1669 }
1670
1671 try {
1672 boolean result =
1673 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
1674 if (VDBG) {
1675 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1676 + enabledStr + ", result=" + result);
1677 }
1678 getOutPrintWriter().println(result);
1679 } catch (NumberFormatException | RemoteException e) {
1680 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
1681 + enabledStr + ", error" + e.getMessage());
1682 getErrPrintWriter().println("Exception: " + e.getMessage());
1683 return -1;
1684 }
1685 return 0;
1686 }
1687
1688 private int handleSrcGetCarrierEnabledCommand() {
1689 int subId = getSubId("src get-carrier-enabled");
1690 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1691 return -1;
1692 }
1693
1694 boolean result = false;
1695 try {
1696 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
1697 } catch (RemoteException e) {
1698 return -1;
1699 }
1700 if (VDBG) {
1701 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
1702 }
1703 getOutPrintWriter().println(result);
1704 return 0;
1705 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001706}