blob: 36d539a9a3f472d9412624d50fef344ee18b7faf [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;
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000029import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070030import android.provider.BlockedNumberContract;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010031import android.telephony.CarrierConfigManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070032import android.telephony.SubscriptionManager;
Michele Berionne38c1afa2020-12-28 20:23:16 +000033import android.telephony.TelephonyManager;
sqian9d4df8b2019-01-15 18:32:07 -080034import android.telephony.emergency.EmergencyNumber;
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000035import android.telephony.ims.ImsException;
36import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080037import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080038import android.text.TextUtils;
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000039import android.util.ArrayMap;
40import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070041import android.util.Log;
42
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000043import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070044import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080045import com.android.internal.telephony.Phone;
46import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080047import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080048import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080049import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080050import com.android.modules.utils.BasicShellCommandHandler;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051
52import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080053import java.util.ArrayList;
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000054import java.util.Arrays;
55import java.util.Collections;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010056import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080057import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010058import java.util.Map;
Brad Ebingerd4c5bde2021-02-12 06:18:28 +000059import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010060import java.util.TreeSet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070061
62/**
63 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
64 * permission checks have been done before onCommand was called. Make sure any commands processed
65 * here also contain the appropriate permissions checks.
66 */
67
Hall Liua1548bd2019-12-24 14:14:12 -080068public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070069
70 private static final String LOG_TAG = "TelephonyShellCommand";
71 // Don't commit with this true.
72 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070073 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070074
75 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080076 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
sqian9d4df8b2019-01-15 18:32:07 -080077 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070078 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne38c1afa2020-12-28 20:23:16 +000079 private static final String RESTART_MODEM = "restart-modem";
Michele Berionned9fbae52020-11-13 02:36:59 +000080 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010081 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080082 private static final String DATA_TEST_MODE = "data";
83 private static final String DATA_ENABLE = "enable";
84 private static final String DATA_DISABLE = "disable";
Hall Liud892bec2018-11-30 14:51:45 -080085
Brad Ebinger999d3302020-11-25 14:31:39 -080086 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
87 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
88 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070089 private static final String IMS_ENABLE = "enable";
90 private static final String IMS_DISABLE = "disable";
Tyler Gunn7bcdc742019-10-04 15:56:59 -070091 // Used to disable or enable processing of conference event package data from the network.
92 // This is handy for testing scenarios where CEP data does not exist on a network which does
93 // support CEP data.
94 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070095
Hall Liud892bec2018-11-30 14:51:45 -080096 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -080097 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -080098
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010099 private static final String CC_GET_VALUE = "get-value";
100 private static final String CC_SET_VALUE = "set-value";
101 private static final String CC_CLEAR_VALUES = "clear-values";
102
Hui Wang0866fcc2020-10-12 12:14:23 -0700103 private static final String GBA_SUBCOMMAND = "gba";
104 private static final String GBA_SET_SERVICE = "set-service";
105 private static final String GBA_GET_SERVICE = "get-service";
106 private static final String GBA_SET_RELEASE_TIME = "set-release";
107 private static final String GBA_GET_RELEASE_TIME = "get-release";
108
Hui Wang068ab862020-10-31 05:12:53 +0000109 private static final String SINGLE_REGISTATION_CONFIG = "src";
110 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
111 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
112 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
113 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wang19a21872021-02-19 20:45:36 -0800114 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
115 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangeadb2562021-02-26 09:33:38 -0800116 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
117 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang068ab862020-10-31 05:12:53 +0000118
Tyler Gunn92479152021-01-20 16:30:10 -0800119 private static final String D2D_SUBCOMMAND = "d2d";
120 private static final String D2D_SEND = "send";
121
James.cf Linbcdf8b32021-01-14 16:44:13 +0800122 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800123 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800124 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800125 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
126 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000127 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
128 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800129
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800130 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
131 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
132
Jack Nudelman644b91a2021-03-12 14:09:48 -0800133 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
134 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
135 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
136
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700137 // Take advantage of existing methods that already contain permissions checks when possible.
138 private final ITelephony mInterface;
139
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100140 private SubscriptionManager mSubscriptionManager;
141 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700142 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100143
144 private enum CcType {
145 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
146 STRING_ARRAY, UNKNOWN
147 }
148
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100149 private class CcOptionParseResult {
150 public int mSubId;
151 public boolean mPersistent;
152 }
153
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100154 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
155 // keys by looking at the end of the string which usually tells the type.
156 // For instance: "xxxx_string", "xxxx_string_array", etc.
157 // The carrier config keys in this map does not follow this convention. It is therefore not
158 // possible to infer the type for these keys by looking at the string.
159 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
160 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
161 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
162 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
163 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
164 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
165 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
166 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
167 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
168 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
169 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
170 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
171 CcType.STRING);
172 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
173 CcType.STRING_ARRAY);
174 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
175 CcType.STRING_ARRAY);
176 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
177 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
178 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
179 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
180 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
181 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
182 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
183 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
184 }
185 };
186
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000187 /**
188 * Map from a shorthand string to the feature tags required in registration required in order
189 * for the RCS feature to be considered "capable".
190 */
191 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
192 static {
193 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
194 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
195 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
196 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
197 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
198 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
199 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
200 FeatureTags.FEATURE_TAG_VIDEO)));
201 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
202 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
203 map.put("call_comp",
204 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
205 map.put("call_comp_mmtel",
206 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
207 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
208 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
209 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
210 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
211 // version
212 map.put("chatbot", new ArraySet<>(Arrays.asList(
213 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
214 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
215 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
216 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
217 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
218 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
219 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
220 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
221 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
222 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
223 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
224 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
225 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
226 }
227
228
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100229 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700230 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100231 mCarrierConfigManager =
232 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
233 mSubscriptionManager = (SubscriptionManager)
234 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700235 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700236 }
237
238 @Override
239 public int onCommand(String cmd) {
240 if (cmd == null) {
241 return handleDefaultCommands(null);
242 }
243
244 switch (cmd) {
245 case IMS_SUBCOMMAND: {
246 return handleImsCommand();
247 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800248 case RCS_UCE_COMMAND:
249 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800250 case NUMBER_VERIFICATION_SUBCOMMAND:
251 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800252 case EMERGENCY_NUMBER_TEST_MODE:
253 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100254 case CARRIER_CONFIG_SUBCOMMAND: {
255 return handleCcCommand();
256 }
Shuo Qianf5125122019-12-16 17:03:07 -0800257 case DATA_TEST_MODE:
258 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700259 case END_BLOCK_SUPPRESSION:
260 return handleEndBlockSuppressionCommand();
Hui Wang0866fcc2020-10-12 12:14:23 -0700261 case GBA_SUBCOMMAND:
262 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800263 case D2D_SUBCOMMAND:
264 return handleD2dCommand();
Hui Wang068ab862020-10-31 05:12:53 +0000265 case SINGLE_REGISTATION_CONFIG:
266 return handleSingleRegistrationConfigCommand();
Michele Berionne38c1afa2020-12-28 20:23:16 +0000267 case RESTART_MODEM:
268 return handleRestartModemCommand();
Michele Berionned9fbae52020-11-13 02:36:59 +0000269 case UNATTENDED_REBOOT:
270 return handleUnattendedReboot();
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800271 case HAS_CARRIER_PRIVILEGES_COMMAND:
272 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800273 case THERMAL_MITIGATION_COMMAND:
274 return handleThermalMitigationCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700275 default: {
276 return handleDefaultCommands(cmd);
277 }
278 }
279 }
280
281 @Override
282 public void onHelp() {
283 PrintWriter pw = getOutPrintWriter();
284 pw.println("Telephony Commands:");
285 pw.println(" help");
286 pw.println(" Print this help text.");
287 pw.println(" ims");
288 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800289 pw.println(" uce");
290 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800291 pw.println(" emergency-number-test-mode");
292 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700293 pw.println(" end-block-suppression");
294 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800295 pw.println(" data");
296 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100297 pw.println(" cc");
298 pw.println(" Carrier Config Commands.");
Hui Wang0866fcc2020-10-12 12:14:23 -0700299 pw.println(" gba");
300 pw.println(" GBA Commands.");
Hui Wang068ab862020-10-31 05:12:53 +0000301 pw.println(" src");
302 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne38c1afa2020-12-28 20:23:16 +0000303 pw.println(" restart-modem");
304 pw.println(" Restart modem command.");
Michele Berionned9fbae52020-11-13 02:36:59 +0000305 pw.println(" unattended-reboot");
306 pw.println(" Prepare for unattended reboot.");
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800307 pw.println(" has-carrier-privileges [package]");
308 pw.println(" Query carrier privilege status for a package. Prints true or false.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700309 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800310 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800311 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700312 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800313 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100314 onHelpCc();
Hui Wang0866fcc2020-10-12 12:14:23 -0700315 onHelpGba();
Hui Wang068ab862020-10-31 05:12:53 +0000316 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800317 onHelpD2D();
318 }
319
320 private void onHelpD2D() {
321 PrintWriter pw = getOutPrintWriter();
322 pw.println("D2D Comms Commands:");
323 pw.println(" d2d send TYPE VALUE");
324 pw.println(" Sends a D2D message of specified type and value.");
325 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
326 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
327 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
328 MESSAGE_CALL_AUDIO_CODEC));
329 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
330 + Communicator.messageToString(
331 MESSAGE_DEVICE_BATTERY_STATE));
332 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
333 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700334 }
335
336 private void onHelpIms() {
337 PrintWriter pw = getOutPrintWriter();
338 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800339 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700340 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
341 pw.println(" ImsService. Options are:");
342 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
343 pw.println(" is specified, it will choose the default voice SIM slot.");
344 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
345 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800346 pw.println(" -f: Set the feature that this override if for, if no option is");
347 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700348 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
349 pw.println(" Gets the package name of the currently defined ImsService.");
350 pw.println(" Options are:");
351 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
352 pw.println(" is specified, it will choose the default voice SIM slot.");
353 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000354 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800355 pw.println(" -f: The feature type that the query will be requested for. If none is");
356 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800357 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
358 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
359 pw.println(" configuration overrides. Options are:");
360 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
361 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700362 pw.println(" ims enable [-s SLOT_ID]");
363 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
364 pw.println(" if none is specified.");
365 pw.println(" ims disable [-s SLOT_ID]");
366 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
367 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700368 pw.println(" ims conference-event-package [enable/disable]");
369 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700370 }
371
James.cf Linbcdf8b32021-01-14 16:44:13 +0800372 private void onHelpUce() {
373 PrintWriter pw = getOutPrintWriter();
374 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800375 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
376 pw.println(" Get the EAB contacts from the EAB database.");
377 pw.println(" Options are:");
378 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
379 pw.println(" Expected output format :");
380 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800381 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
382 pw.println(" Remove the EAB contacts from the EAB database.");
383 pw.println(" Options are:");
384 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
385 pw.println(" is specified, it will choose the default voice SIM slot.");
386 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800387 pw.println(" uce get-device-enabled");
388 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
389 pw.println(" uce set-device-enabled true|false");
390 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
391 pw.println(" The value could be true, false.");
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000392 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
393 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
394 pw.println(" Options are:");
395 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
396 pw.println(" is specified, it will choose the default voice SIM slot.");
397 pw.println(" add [CAPABILITY]: add a new capability");
398 pw.println(" remove [CAPABILITY]: remove a capability");
399 pw.println(" clear: clear all capability overrides");
400 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
401 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
402 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
403 pw.println(" chatbot_sa, chatbot_role] as well as full length");
404 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
405 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
406 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
407 pw.println(" PUBLISH is active");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800408 }
409
Hall Liud892bec2018-11-30 14:51:45 -0800410 private void onHelpNumberVerification() {
411 PrintWriter pw = getOutPrintWriter();
412 pw.println("Number verification commands");
413 pw.println(" numverify override-package PACKAGE_NAME;");
414 pw.println(" Set the authorized package for number verification.");
415 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800416 pw.println(" numverify fake-call NUMBER;");
417 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
418 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800419 }
420
Jack Nudelman644b91a2021-03-12 14:09:48 -0800421 private void onHelpThermalMitigation() {
422 PrintWriter pw = getOutPrintWriter();
423 pw.println("Thermal mitigation commands");
424 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
425 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
426 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
427 pw.println(" Remove the package from one of the authorized packages for thermal "
428 + "mitigation.");
429 }
430
Shuo Qianf5125122019-12-16 17:03:07 -0800431 private void onHelpDataTestMode() {
432 PrintWriter pw = getOutPrintWriter();
433 pw.println("Mobile Data Test Mode Commands:");
434 pw.println(" data enable: enable mobile data connectivity");
435 pw.println(" data disable: disable mobile data connectivity");
436 }
437
sqian9d4df8b2019-01-15 18:32:07 -0800438 private void onHelpEmergencyNumber() {
439 PrintWriter pw = getOutPrintWriter();
440 pw.println("Emergency Number Test Mode Commands:");
441 pw.println(" emergency-number-test-mode ");
442 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
443 + " the test mode");
444 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700445 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800446 pw.println(" -c: clear the emergency number list in the test mode.");
447 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700448 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800449 pw.println(" -p: get the full emergency number list in the test mode.");
450 }
451
Shuo Qian489d9282020-07-09 11:30:03 -0700452 private void onHelpEndBlockSupperssion() {
453 PrintWriter pw = getOutPrintWriter();
454 pw.println("End Block Suppression command:");
455 pw.println(" end-block-suppression: disable suppressing blocking by contact");
456 pw.println(" with emergency services.");
457 }
458
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100459 private void onHelpCc() {
460 PrintWriter pw = getOutPrintWriter();
461 pw.println("Carrier Config Commands:");
462 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
463 pw.println(" Print carrier config values.");
464 pw.println(" Options are:");
465 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
466 pw.println(" is specified, it will choose the default voice SIM slot.");
467 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
468 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100469 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100470 pw.println(" Set carrier config KEY to NEW_VALUE.");
471 pw.println(" Options are:");
472 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
473 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100474 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100475 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
476 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
477 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
478 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
479 pw.println(" cc clear-values [-s SLOT_ID]");
480 pw.println(" Clear all carrier override values that has previously been set");
481 pw.println(" with set-value");
482 pw.println(" Options are:");
483 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
484 pw.println(" is specified, it will choose the default voice SIM slot.");
485 }
486
Hui Wang0866fcc2020-10-12 12:14:23 -0700487 private void onHelpGba() {
488 PrintWriter pw = getOutPrintWriter();
489 pw.println("Gba Commands:");
490 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
491 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
492 pw.println(" Options are:");
493 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
494 pw.println(" is specified, it will choose the default voice SIM slot.");
495 pw.println(" gba get-service [-s SLOT_ID]");
496 pw.println(" Gets the package name of the currently defined GbaService.");
497 pw.println(" Options are:");
498 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
499 pw.println(" is specified, it will choose the default voice SIM slot.");
500 pw.println(" gba set-release [-s SLOT_ID] n");
501 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
502 pw.println(" Do not release/unbind if n is -1.");
503 pw.println(" Options are:");
504 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
505 pw.println(" is specified, it will choose the default voice SIM slot.");
506 pw.println(" gba get-release [-s SLOT_ID]");
507 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
508 pw.println(" Options are:");
509 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
510 pw.println(" is specified, it will choose the default voice SIM slot.");
511 }
512
Hui Wang068ab862020-10-31 05:12:53 +0000513 private void onHelpSrc() {
514 PrintWriter pw = getOutPrintWriter();
515 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wang19a21872021-02-19 20:45:36 -0800516 pw.println(" src set-test-enabled true|false");
517 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
518 pw.println(" The value could be true, false, or null(undefined).");
519 pw.println(" src get-test-enabled");
520 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang068ab862020-10-31 05:12:53 +0000521 pw.println(" src set-device-enabled true|false|null");
522 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
523 pw.println(" The value could be true, false, or null(undefined).");
524 pw.println(" src get-device-enabled");
525 pw.println(" Gets the device config for RCS VoLTE single registration.");
526 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
527 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
528 pw.println(" The value could be true, false, or null(undefined).");
529 pw.println(" Options are:");
530 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
531 pw.println(" is specified, it will choose the default voice SIM slot.");
532 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
533 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
534 pw.println(" Options are:");
535 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
536 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangeadb2562021-02-26 09:33:38 -0800537 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
538 pw.println(" Sets ims feature validation result.");
539 pw.println(" The value could be true, false, or null(undefined).");
540 pw.println(" Options are:");
541 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
543 pw.println(" src get-feature-validation [-s SLOT_ID]");
544 pw.println(" Gets ims feature validation override value.");
545 pw.println(" Options are:");
546 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
547 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang068ab862020-10-31 05:12:53 +0000548 }
549
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700550 private int handleImsCommand() {
551 String arg = getNextArg();
552 if (arg == null) {
553 onHelpIms();
554 return 0;
555 }
556
557 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800558 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700559 return handleImsSetServiceCommand();
560 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800561 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700562 return handleImsGetServiceCommand();
563 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800564 case IMS_CLEAR_SERVICE_OVERRIDE: {
565 return handleImsClearCarrierServiceCommand();
566 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700567 case IMS_ENABLE: {
568 return handleEnableIms();
569 }
570 case IMS_DISABLE: {
571 return handleDisableIms();
572 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700573 case IMS_CEP: {
574 return handleCepChange();
575 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700576 }
577
578 return -1;
579 }
580
Shuo Qianf5125122019-12-16 17:03:07 -0800581 private int handleDataTestModeCommand() {
582 PrintWriter errPw = getErrPrintWriter();
583 String arg = getNextArgRequired();
584 if (arg == null) {
585 onHelpDataTestMode();
586 return 0;
587 }
588 switch (arg) {
589 case DATA_ENABLE: {
590 try {
591 mInterface.enableDataConnectivity();
592 } catch (RemoteException ex) {
593 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
594 errPw.println("Exception: " + ex.getMessage());
595 return -1;
596 }
597 break;
598 }
599 case DATA_DISABLE: {
600 try {
601 mInterface.disableDataConnectivity();
602 } catch (RemoteException ex) {
603 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
604 errPw.println("Exception: " + ex.getMessage());
605 return -1;
606 }
607 break;
608 }
609 default:
610 onHelpDataTestMode();
611 break;
612 }
613 return 0;
614 }
615
sqian9d4df8b2019-01-15 18:32:07 -0800616 private int handleEmergencyNumberTestModeCommand() {
617 PrintWriter errPw = getErrPrintWriter();
618 String opt = getNextOption();
619 if (opt == null) {
620 onHelpEmergencyNumber();
621 return 0;
622 }
623
624 switch (opt) {
625 case "-a": {
626 String emergencyNumberCmd = getNextArgRequired();
627 if (emergencyNumberCmd == null
628 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700629 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800630 + " to be specified after -a in the command ");
631 return -1;
632 }
633 try {
634 mInterface.updateEmergencyNumberListTestMode(
635 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
636 new EmergencyNumber(emergencyNumberCmd, "", "",
637 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
638 new ArrayList<String>(),
639 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
640 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
641 } catch (RemoteException ex) {
642 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
643 + ", error " + ex.getMessage());
644 errPw.println("Exception: " + ex.getMessage());
645 return -1;
646 }
647 break;
648 }
649 case "-c": {
650 try {
651 mInterface.updateEmergencyNumberListTestMode(
652 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
653 } catch (RemoteException ex) {
654 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
655 errPw.println("Exception: " + ex.getMessage());
656 return -1;
657 }
658 break;
659 }
660 case "-r": {
661 String emergencyNumberCmd = getNextArgRequired();
662 if (emergencyNumberCmd == null
663 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700664 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800665 + " to be specified after -r in the command ");
666 return -1;
667 }
668 try {
669 mInterface.updateEmergencyNumberListTestMode(
670 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
671 new EmergencyNumber(emergencyNumberCmd, "", "",
672 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
673 new ArrayList<String>(),
674 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
675 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
676 } catch (RemoteException ex) {
677 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
678 + ", error " + ex.getMessage());
679 errPw.println("Exception: " + ex.getMessage());
680 return -1;
681 }
682 break;
683 }
684 case "-p": {
685 try {
686 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
687 } catch (RemoteException ex) {
688 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
689 errPw.println("Exception: " + ex.getMessage());
690 return -1;
691 }
692 break;
693 }
694 default:
695 onHelpEmergencyNumber();
696 break;
697 }
698 return 0;
699 }
700
Hall Liud892bec2018-11-30 14:51:45 -0800701 private int handleNumberVerificationCommand() {
702 String arg = getNextArg();
703 if (arg == null) {
704 onHelpNumberVerification();
705 return 0;
706 }
707
Hall Liuca5af3a2018-12-04 16:58:23 -0800708 if (!checkShellUid()) {
709 return -1;
710 }
711
Hall Liud892bec2018-11-30 14:51:45 -0800712 switch (arg) {
713 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800714 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
715 return 0;
716 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800717 case NUMBER_VERIFICATION_FAKE_CALL: {
718 boolean val = NumberVerificationManager.getInstance()
719 .checkIncomingCall(getNextArg());
720 getOutPrintWriter().println(val ? "1" : "0");
721 return 0;
722 }
Hall Liud892bec2018-11-30 14:51:45 -0800723 }
724
725 return -1;
726 }
727
Jack Nudelman644b91a2021-03-12 14:09:48 -0800728 private int handleThermalMitigationCommand() {
729 String arg = getNextArg();
730 String packageName = getNextArg();
731 if (arg == null || packageName == null) {
732 onHelpThermalMitigation();
733 return 0;
734 }
735
736 if (!checkShellUid()) {
737 return -1;
738 }
739
740 switch (arg) {
741 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
742 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
743 return 0;
744 }
745 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
746 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
747 mContext);
748 return 0;
749 }
750 default:
751 onHelpThermalMitigation();
752 }
753
754 return -1;
755
756 }
757
Tyler Gunn92479152021-01-20 16:30:10 -0800758 private int handleD2dCommand() {
759 String arg = getNextArg();
760 if (arg == null) {
761 onHelpD2D();
762 return 0;
763 }
764
765 switch (arg) {
766 case D2D_SEND: {
767 return handleD2dSendCommand();
768 }
769 }
770
771 return -1;
772 }
773
774 private int handleD2dSendCommand() {
775 PrintWriter errPw = getErrPrintWriter();
776 String opt;
777 int messageType = -1;
778 int messageValue = -1;
779
780
781 String arg = getNextArg();
782 if (arg == null) {
783 onHelpD2D();
784 return 0;
785 }
786 try {
787 messageType = Integer.parseInt(arg);
788 } catch (NumberFormatException e) {
789 errPw.println("message type must be a valid integer");
790 return -1;
791 }
792
793 arg = getNextArg();
794 if (arg == null) {
795 onHelpD2D();
796 return 0;
797 }
798 try {
799 messageValue = Integer.parseInt(arg);
800 } catch (NumberFormatException e) {
801 errPw.println("message value must be a valid integer");
802 return -1;
803 }
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800804
Tyler Gunn92479152021-01-20 16:30:10 -0800805 try {
806 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
807 } catch (RemoteException e) {
808 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
809 errPw.println("Exception: " + e.getMessage());
810 return -1;
811 }
812
813 return 0;
814 }
815
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700816 // ims set-ims-service
817 private int handleImsSetServiceCommand() {
818 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700819 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700820 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800821 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700822
823 String opt;
824 while ((opt = getNextOption()) != null) {
825 switch (opt) {
826 case "-s": {
827 try {
828 slotId = Integer.parseInt(getNextArgRequired());
829 } catch (NumberFormatException e) {
830 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
831 return -1;
832 }
833 break;
834 }
835 case "-c": {
836 isCarrierService = true;
837 break;
838 }
839 case "-d": {
840 isCarrierService = false;
841 break;
842 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800843 case "-f": {
844 String featureString = getNextArgRequired();
845 String[] features = featureString.split(",");
846 for (int i = 0; i < features.length; i++) {
847 try {
848 Integer result = Integer.parseInt(features[i]);
849 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
850 || result >= ImsFeature.FEATURE_MAX) {
851 errPw.println("ims set-ims-service -f " + result
852 + " is an invalid feature.");
853 return -1;
854 }
855 featuresList.add(result);
856 } catch (NumberFormatException e) {
857 errPw.println("ims set-ims-service -f tried to parse " + features[i]
858 + " as an integer.");
859 return -1;
860 }
861 }
862 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700863 }
864 }
865 // Mandatory param, either -c or -d
866 if (isCarrierService == null) {
867 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
868 return -1;
869 }
870
871 String packageName = getNextArg();
872
873 try {
874 if (packageName == null) {
875 packageName = "";
876 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800877 int[] featureArray = new int[featuresList.size()];
878 for (int i = 0; i < featuresList.size(); i++) {
879 featureArray[i] = featuresList.get(i);
880 }
881 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
882 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700883 if (VDBG) {
884 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800885 + (isCarrierService ? "-c " : "-d ")
886 + "-f " + featuresList + " "
887 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700888 }
889 getOutPrintWriter().println(result);
890 } catch (RemoteException e) {
891 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800892 + (isCarrierService ? "-c " : "-d ")
893 + "-f " + featuresList + " "
894 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700895 errPw.println("Exception: " + e.getMessage());
896 return -1;
897 }
898 return 0;
899 }
900
Brad Ebinger999d3302020-11-25 14:31:39 -0800901 // ims clear-ims-service-override
902 private int handleImsClearCarrierServiceCommand() {
903 PrintWriter errPw = getErrPrintWriter();
904 int slotId = getDefaultSlot();
905
906 String opt;
907 while ((opt = getNextOption()) != null) {
908 switch (opt) {
909 case "-s": {
910 try {
911 slotId = Integer.parseInt(getNextArgRequired());
912 } catch (NumberFormatException e) {
913 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
914 return -1;
915 }
916 break;
917 }
918 }
919 }
920
921 try {
922 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
923 if (VDBG) {
924 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
925 + ", result=" + result);
926 }
927 getOutPrintWriter().println(result);
928 } catch (RemoteException e) {
929 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
930 + ", error" + e.getMessage());
931 errPw.println("Exception: " + e.getMessage());
932 return -1;
933 }
934 return 0;
935 }
936
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700937 // ims get-ims-service
938 private int handleImsGetServiceCommand() {
939 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700940 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700941 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800942 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700943
944 String opt;
945 while ((opt = getNextOption()) != null) {
946 switch (opt) {
947 case "-s": {
948 try {
949 slotId = Integer.parseInt(getNextArgRequired());
950 } catch (NumberFormatException e) {
951 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
952 return -1;
953 }
954 break;
955 }
956 case "-c": {
957 isCarrierService = true;
958 break;
959 }
960 case "-d": {
961 isCarrierService = false;
962 break;
963 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800964 case "-f": {
965 try {
966 featureType = Integer.parseInt(getNextArg());
967 } catch (NumberFormatException e) {
968 errPw.println("ims get-ims-service -f requires valid integer as feature.");
969 return -1;
970 }
971 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
972 || featureType >= ImsFeature.FEATURE_MAX) {
973 errPw.println("ims get-ims-service -f invalid feature.");
974 return -1;
975 }
976 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700977 }
978 }
979 // Mandatory param, either -c or -d
980 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800981 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700982 return -1;
983 }
984
985 String result;
986 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800987 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700988 } catch (RemoteException e) {
989 return -1;
990 }
991 if (VDBG) {
992 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800993 + (isCarrierService ? "-c " : "-d ")
994 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
995 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700996 }
997 getOutPrintWriter().println(result);
998 return 0;
999 }
1000
1001 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001002 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001003 String opt;
1004 while ((opt = getNextOption()) != null) {
1005 switch (opt) {
1006 case "-s": {
1007 try {
1008 slotId = Integer.parseInt(getNextArgRequired());
1009 } catch (NumberFormatException e) {
1010 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1011 return -1;
1012 }
1013 break;
1014 }
1015 }
1016 }
1017 try {
1018 mInterface.enableIms(slotId);
1019 } catch (RemoteException e) {
1020 return -1;
1021 }
1022 if (VDBG) {
1023 Log.v(LOG_TAG, "ims enable -s " + slotId);
1024 }
1025 return 0;
1026 }
1027
1028 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001029 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001030 String opt;
1031 while ((opt = getNextOption()) != null) {
1032 switch (opt) {
1033 case "-s": {
1034 try {
1035 slotId = Integer.parseInt(getNextArgRequired());
1036 } catch (NumberFormatException e) {
1037 getErrPrintWriter().println(
1038 "ims disable requires an integer as a SLOT_ID.");
1039 return -1;
1040 }
1041 break;
1042 }
1043 }
1044 }
1045 try {
1046 mInterface.disableIms(slotId);
1047 } catch (RemoteException e) {
1048 return -1;
1049 }
1050 if (VDBG) {
1051 Log.v(LOG_TAG, "ims disable -s " + slotId);
1052 }
1053 return 0;
1054 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001055
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001056 private int handleCepChange() {
1057 Log.i(LOG_TAG, "handleCepChange");
1058 String opt = getNextArg();
1059 if (opt == null) {
1060 return -1;
1061 }
1062 boolean isCepEnabled = opt.equals("enable");
1063
1064 try {
1065 mInterface.setCepEnabled(isCepEnabled);
1066 } catch (RemoteException e) {
1067 return -1;
1068 }
1069 return 0;
1070 }
1071
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001072 private int getDefaultSlot() {
1073 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1074 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1075 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1076 // If there is no default, default to slot 0.
1077 slotId = DEFAULT_PHONE_ID;
1078 }
1079 return slotId;
1080 }
sqian2fff4a32018-11-05 14:18:37 -08001081
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001082 // Parse options related to Carrier Config Commands.
1083 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001084 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001085 CcOptionParseResult result = new CcOptionParseResult();
1086 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1087 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001088
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001089 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001090 while ((opt = getNextOption()) != null) {
1091 switch (opt) {
1092 case "-s": {
1093 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001094 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1095 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1096 errPw.println(tag + "No valid subscription found.");
1097 return null;
1098 }
1099
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001100 } catch (IllegalArgumentException e) {
1101 // Missing slot id
1102 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001103 return null;
1104 }
1105 break;
1106 }
1107 case "-p": {
1108 if (allowOptionPersistent) {
1109 result.mPersistent = true;
1110 } else {
1111 errPw.println(tag + "Unexpected option " + opt);
1112 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001113 }
1114 break;
1115 }
1116 default: {
1117 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001118 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001119 }
1120 }
1121 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001122 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001123 }
1124
1125 private int slotStringToSubId(String tag, String slotString) {
1126 int slotId = -1;
1127 try {
1128 slotId = Integer.parseInt(slotString);
1129 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001130 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1131 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1132 }
1133
1134 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001135 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1136 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1137 }
1138
Qiong Liuf25799b2020-09-10 10:13:46 +08001139 Phone phone = PhoneFactory.getPhone(slotId);
1140 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001141 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1142 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1143 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001144 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001145 }
1146
Hall Liud892bec2018-11-30 14:51:45 -08001147 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001148 // adb can run as root or as shell, depending on whether the device is rooted.
1149 return Binder.getCallingUid() == Process.SHELL_UID
1150 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001151 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001152
1153 private int handleCcCommand() {
1154 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1155 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001156 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001157 getErrPrintWriter().println("cc: Permission denied.");
1158 return -1;
1159 }
1160
1161 String arg = getNextArg();
1162 if (arg == null) {
1163 onHelpCc();
1164 return 0;
1165 }
1166
1167 switch (arg) {
1168 case CC_GET_VALUE: {
1169 return handleCcGetValue();
1170 }
1171 case CC_SET_VALUE: {
1172 return handleCcSetValue();
1173 }
1174 case CC_CLEAR_VALUES: {
1175 return handleCcClearValues();
1176 }
1177 default: {
1178 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1179 }
1180 }
1181 return -1;
1182 }
1183
1184 // cc get-value
1185 private int handleCcGetValue() {
1186 PrintWriter errPw = getErrPrintWriter();
1187 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1188 String key = null;
1189
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001190 // Parse all options
1191 CcOptionParseResult options = parseCcOptions(tag, false);
1192 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001193 return -1;
1194 }
1195
1196 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001197 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001198 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001199 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001200 return -1;
1201 }
1202
1203 // Get the key.
1204 key = getNextArg();
1205 if (key != null) {
1206 // A key was provided. Verify if it is a valid key
1207 if (!bundle.containsKey(key)) {
1208 errPw.println(tag + key + " is not a valid key.");
1209 return -1;
1210 }
1211
1212 // Print the carrier config value for key.
1213 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1214 } else {
1215 // No key provided. Show all values.
1216 // Iterate over a sorted list of all carrier config keys and print them.
1217 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1218 for (String k : sortedSet) {
1219 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1220 }
1221 }
1222 return 0;
1223 }
1224
1225 // cc set-value
1226 private int handleCcSetValue() {
1227 PrintWriter errPw = getErrPrintWriter();
1228 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1229
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001230 // Parse all options
1231 CcOptionParseResult options = parseCcOptions(tag, true);
1232 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001233 return -1;
1234 }
1235
1236 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001237 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001238 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001239 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001240 return -1;
1241 }
1242
1243 // Get the key.
1244 String key = getNextArg();
1245 if (key == null || key.equals("")) {
1246 errPw.println(tag + "KEY is missing");
1247 return -1;
1248 }
1249
1250 // Verify if the key is valid
1251 if (!originalValues.containsKey(key)) {
1252 errPw.println(tag + key + " is not a valid key.");
1253 return -1;
1254 }
1255
1256 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1257 ArrayList<String> valueList = new ArrayList<String>();
1258 while (peekNextArg() != null) {
1259 valueList.add(getNextArg());
1260 }
1261
1262 // Find the type of the carrier config value
1263 CcType type = getType(tag, key, originalValues);
1264 if (type == CcType.UNKNOWN) {
1265 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1266 return -1;
1267 }
1268
1269 // Create an override bundle containing the key and value that should be overriden.
1270 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1271 if (overrideBundle == null) {
1272 return -1;
1273 }
1274
1275 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001276 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001277
1278 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001279 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001280 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001281 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001282 return -1;
1283 }
1284
1285 // Print the original and new value.
1286 String originalValueString = ccValueToString(key, type, originalValues);
1287 String newValueString = ccValueToString(key, type, newValues);
1288 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1289 getOutPrintWriter().println("New value: \n" + newValueString);
1290
1291 return 0;
1292 }
1293
1294 // cc clear-values
1295 private int handleCcClearValues() {
1296 PrintWriter errPw = getErrPrintWriter();
1297 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1298
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001299 // Parse all options
1300 CcOptionParseResult options = parseCcOptions(tag, false);
1301 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001302 return -1;
1303 }
1304
1305 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001306 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001307 getOutPrintWriter()
1308 .println("All previously set carrier config override values has been cleared");
1309 return 0;
1310 }
1311
1312 private CcType getType(String tag, String key, PersistableBundle bundle) {
1313 // Find the type by checking the type of the current value stored in the bundle.
1314 Object value = bundle.get(key);
1315
1316 if (CC_TYPE_MAP.containsKey(key)) {
1317 return CC_TYPE_MAP.get(key);
1318 } else if (value != null) {
1319 if (value instanceof Boolean) {
1320 return CcType.BOOLEAN;
1321 } else if (value instanceof Double) {
1322 return CcType.DOUBLE;
1323 } else if (value instanceof double[]) {
1324 return CcType.DOUBLE_ARRAY;
1325 } else if (value instanceof Integer) {
1326 return CcType.INT;
1327 } else if (value instanceof int[]) {
1328 return CcType.INT_ARRAY;
1329 } else if (value instanceof Long) {
1330 return CcType.LONG;
1331 } else if (value instanceof long[]) {
1332 return CcType.LONG_ARRAY;
1333 } else if (value instanceof String) {
1334 return CcType.STRING;
1335 } else if (value instanceof String[]) {
1336 return CcType.STRING_ARRAY;
1337 }
1338 } else {
1339 // Current value was null and can therefore not be used in order to find the type.
1340 // Check the name of the key to infer the type. This check is not needed for primitive
1341 // data types (boolean, double, int and long), since they can not be null.
1342 if (key.endsWith("double_array")) {
1343 return CcType.DOUBLE_ARRAY;
1344 }
1345 if (key.endsWith("int_array")) {
1346 return CcType.INT_ARRAY;
1347 }
1348 if (key.endsWith("long_array")) {
1349 return CcType.LONG_ARRAY;
1350 }
1351 if (key.endsWith("string")) {
1352 return CcType.STRING;
1353 }
1354 if (key.endsWith("string_array") || key.endsWith("strings")) {
1355 return CcType.STRING_ARRAY;
1356 }
1357 }
1358
1359 // Not possible to infer the type by looking at the current value or the key.
1360 PrintWriter errPw = getErrPrintWriter();
1361 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1362 return CcType.UNKNOWN;
1363 }
1364
1365 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1366 String result;
1367 StringBuilder valueString = new StringBuilder();
1368 String typeString = type.toString();
1369 Object value = bundle.get(key);
1370
1371 if (value == null) {
1372 valueString.append("null");
1373 } else {
1374 switch (type) {
1375 case DOUBLE_ARRAY: {
1376 // Format the string representation of the int array as value1 value2......
1377 double[] valueArray = (double[]) value;
1378 for (int i = 0; i < valueArray.length; i++) {
1379 if (i != 0) {
1380 valueString.append(" ");
1381 }
1382 valueString.append(valueArray[i]);
1383 }
1384 break;
1385 }
1386 case INT_ARRAY: {
1387 // Format the string representation of the int array as value1 value2......
1388 int[] valueArray = (int[]) value;
1389 for (int i = 0; i < valueArray.length; i++) {
1390 if (i != 0) {
1391 valueString.append(" ");
1392 }
1393 valueString.append(valueArray[i]);
1394 }
1395 break;
1396 }
1397 case LONG_ARRAY: {
1398 // Format the string representation of the int array as value1 value2......
1399 long[] valueArray = (long[]) value;
1400 for (int i = 0; i < valueArray.length; i++) {
1401 if (i != 0) {
1402 valueString.append(" ");
1403 }
1404 valueString.append(valueArray[i]);
1405 }
1406 break;
1407 }
1408 case STRING: {
1409 valueString.append("\"" + value.toString() + "\"");
1410 break;
1411 }
1412 case STRING_ARRAY: {
1413 // Format the string representation of the string array as "value1" "value2"....
1414 String[] valueArray = (String[]) value;
1415 for (int i = 0; i < valueArray.length; i++) {
1416 if (i != 0) {
1417 valueString.append(" ");
1418 }
1419 if (valueArray[i] != null) {
1420 valueString.append("\"" + valueArray[i] + "\"");
1421 } else {
1422 valueString.append("null");
1423 }
1424 }
1425 break;
1426 }
1427 default: {
1428 valueString.append(value.toString());
1429 }
1430 }
1431 }
1432 return String.format("%-70s %-15s %s", key, typeString, valueString);
1433 }
1434
1435 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1436 ArrayList<String> valueList) {
1437 PrintWriter errPw = getErrPrintWriter();
1438 PersistableBundle bundle = new PersistableBundle();
1439
1440 // First verify that a valid number of values has been provided for the type.
1441 switch (type) {
1442 case BOOLEAN:
1443 case DOUBLE:
1444 case INT:
1445 case LONG: {
1446 if (valueList.size() != 1) {
1447 errPw.println(tag + "Expected 1 value for type " + type
1448 + ". Found: " + valueList.size());
1449 return null;
1450 }
1451 break;
1452 }
1453 case STRING: {
1454 if (valueList.size() > 1) {
1455 errPw.println(tag + "Expected 0 or 1 values for type " + type
1456 + ". Found: " + valueList.size());
1457 return null;
1458 }
1459 break;
1460 }
1461 }
1462
1463 // Parse the value according to type and add it to the Bundle.
1464 switch (type) {
1465 case BOOLEAN: {
1466 if ("true".equalsIgnoreCase(valueList.get(0))) {
1467 bundle.putBoolean(key, true);
1468 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1469 bundle.putBoolean(key, false);
1470 } else {
1471 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1472 return null;
1473 }
1474 break;
1475 }
1476 case DOUBLE: {
1477 try {
1478 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1479 } catch (NumberFormatException nfe) {
1480 // Not a valid double
1481 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1482 return null;
1483 }
1484 break;
1485 }
1486 case DOUBLE_ARRAY: {
1487 double[] valueDoubleArray = null;
1488 if (valueList.size() > 0) {
1489 valueDoubleArray = new double[valueList.size()];
1490 for (int i = 0; i < valueList.size(); i++) {
1491 try {
1492 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1493 } catch (NumberFormatException nfe) {
1494 // Not a valid double
1495 errPw.println(
1496 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1497 return null;
1498 }
1499 }
1500 }
1501 bundle.putDoubleArray(key, valueDoubleArray);
1502 break;
1503 }
1504 case INT: {
1505 try {
1506 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1507 } catch (NumberFormatException nfe) {
1508 // Not a valid integer
1509 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1510 return null;
1511 }
1512 break;
1513 }
1514 case INT_ARRAY: {
1515 int[] valueIntArray = null;
1516 if (valueList.size() > 0) {
1517 valueIntArray = new int[valueList.size()];
1518 for (int i = 0; i < valueList.size(); i++) {
1519 try {
1520 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1521 } catch (NumberFormatException nfe) {
1522 // Not a valid integer
1523 errPw.println(tag
1524 + "Unable to parse " + valueList.get(i) + " as an integer.");
1525 return null;
1526 }
1527 }
1528 }
1529 bundle.putIntArray(key, valueIntArray);
1530 break;
1531 }
1532 case LONG: {
1533 try {
1534 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1535 } catch (NumberFormatException nfe) {
1536 // Not a valid long
1537 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1538 return null;
1539 }
1540 break;
1541 }
1542 case LONG_ARRAY: {
1543 long[] valueLongArray = null;
1544 if (valueList.size() > 0) {
1545 valueLongArray = new long[valueList.size()];
1546 for (int i = 0; i < valueList.size(); i++) {
1547 try {
1548 valueLongArray[i] = Long.parseLong(valueList.get(i));
1549 } catch (NumberFormatException nfe) {
1550 // Not a valid long
1551 errPw.println(
1552 tag + "Unable to parse " + valueList.get(i) + " as a long");
1553 return null;
1554 }
1555 }
1556 }
1557 bundle.putLongArray(key, valueLongArray);
1558 break;
1559 }
1560 case STRING: {
1561 String value = null;
1562 if (valueList.size() > 0) {
1563 value = valueList.get(0);
1564 }
1565 bundle.putString(key, value);
1566 break;
1567 }
1568 case STRING_ARRAY: {
1569 String[] valueStringArray = null;
1570 if (valueList.size() > 0) {
1571 valueStringArray = new String[valueList.size()];
1572 valueList.toArray(valueStringArray);
1573 }
1574 bundle.putStringArray(key, valueStringArray);
1575 break;
1576 }
1577 }
1578 return bundle;
1579 }
Shuo Qian489d9282020-07-09 11:30:03 -07001580
1581 private int handleEndBlockSuppressionCommand() {
1582 if (!checkShellUid()) {
1583 return -1;
1584 }
1585
1586 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1587 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1588 }
1589 return 0;
1590 }
Hui Wang0866fcc2020-10-12 12:14:23 -07001591
Michele Berionne38c1afa2020-12-28 20:23:16 +00001592 private int handleRestartModemCommand() {
1593 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1594 // non user build.
1595 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1596 getErrPrintWriter().println("RestartModem: Permission denied.");
1597 return -1;
1598 }
1599
1600 boolean result = TelephonyManager.getDefault().rebootRadio();
1601 getOutPrintWriter().println(result);
1602
1603 return result ? 0 : -1;
1604 }
1605
Michele Berionned9fbae52020-11-13 02:36:59 +00001606 private int handleUnattendedReboot() {
1607 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1608 // non user build.
1609 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1610 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
1611 return -1;
1612 }
1613
1614 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
1615 getOutPrintWriter().println("result: " + result);
1616
1617 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
1618 }
1619
Hui Wang0866fcc2020-10-12 12:14:23 -07001620 private int handleGbaCommand() {
1621 String arg = getNextArg();
1622 if (arg == null) {
1623 onHelpGba();
1624 return 0;
1625 }
1626
1627 switch (arg) {
1628 case GBA_SET_SERVICE: {
1629 return handleGbaSetServiceCommand();
1630 }
1631 case GBA_GET_SERVICE: {
1632 return handleGbaGetServiceCommand();
1633 }
1634 case GBA_SET_RELEASE_TIME: {
1635 return handleGbaSetReleaseCommand();
1636 }
1637 case GBA_GET_RELEASE_TIME: {
1638 return handleGbaGetReleaseCommand();
1639 }
1640 }
1641
1642 return -1;
1643 }
1644
1645 private int getSubId(String cmd) {
1646 int slotId = getDefaultSlot();
1647 String opt = getNextOption();
1648 if (opt != null && opt.equals("-s")) {
1649 try {
1650 slotId = Integer.parseInt(getNextArgRequired());
1651 } catch (NumberFormatException e) {
1652 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1653 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1654 }
1655 }
1656 int[] subIds = SubscriptionManager.getSubId(slotId);
1657 return subIds[0];
1658 }
1659
1660 private int handleGbaSetServiceCommand() {
1661 int subId = getSubId("gba set-service");
1662 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1663 return -1;
1664 }
1665
1666 String packageName = getNextArg();
1667 try {
1668 if (packageName == null) {
1669 packageName = "";
1670 }
1671 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1672 if (VDBG) {
1673 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1674 + packageName + ", result=" + result);
1675 }
1676 getOutPrintWriter().println(result);
1677 } catch (RemoteException e) {
1678 Log.w(LOG_TAG, "gba set-service " + subId + " "
1679 + packageName + ", error" + e.getMessage());
1680 getErrPrintWriter().println("Exception: " + e.getMessage());
1681 return -1;
1682 }
1683 return 0;
1684 }
1685
1686 private int handleGbaGetServiceCommand() {
1687 String result;
1688
1689 int subId = getSubId("gba get-service");
1690 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1691 return -1;
1692 }
1693
1694 try {
1695 result = mInterface.getBoundGbaService(subId);
1696 } catch (RemoteException e) {
1697 return -1;
1698 }
1699 if (VDBG) {
1700 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1701 }
1702 getOutPrintWriter().println(result);
1703 return 0;
1704 }
1705
1706 private int handleGbaSetReleaseCommand() {
1707 //the release time value could be -1
1708 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1709 : SubscriptionManager.getDefaultSubscriptionId();
1710 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1711 return -1;
1712 }
1713
1714 String intervalStr = getNextArg();
1715 if (intervalStr == null) {
1716 return -1;
1717 }
1718
1719 try {
1720 int interval = Integer.parseInt(intervalStr);
1721 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1722 if (VDBG) {
1723 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1724 + intervalStr + ", result=" + result);
1725 }
1726 getOutPrintWriter().println(result);
1727 } catch (NumberFormatException | RemoteException e) {
1728 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1729 + intervalStr + ", error" + e.getMessage());
1730 getErrPrintWriter().println("Exception: " + e.getMessage());
1731 return -1;
1732 }
1733 return 0;
1734 }
1735
1736 private int handleGbaGetReleaseCommand() {
1737 int subId = getSubId("gba get-release");
1738 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1739 return -1;
1740 }
1741
1742 int result = 0;
1743 try {
1744 result = mInterface.getGbaReleaseTime(subId);
1745 } catch (RemoteException e) {
1746 return -1;
1747 }
1748 if (VDBG) {
1749 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1750 }
1751 getOutPrintWriter().println(result);
1752 return 0;
1753 }
Hui Wang068ab862020-10-31 05:12:53 +00001754
1755 private int handleSingleRegistrationConfigCommand() {
1756 String arg = getNextArg();
1757 if (arg == null) {
1758 onHelpSrc();
1759 return 0;
1760 }
1761
1762 switch (arg) {
Hui Wang19a21872021-02-19 20:45:36 -08001763 case SRC_SET_TEST_ENABLED: {
1764 return handleSrcSetTestEnabledCommand();
1765 }
1766 case SRC_GET_TEST_ENABLED: {
1767 return handleSrcGetTestEnabledCommand();
1768 }
Hui Wang068ab862020-10-31 05:12:53 +00001769 case SRC_SET_DEVICE_ENABLED: {
1770 return handleSrcSetDeviceEnabledCommand();
1771 }
1772 case SRC_GET_DEVICE_ENABLED: {
1773 return handleSrcGetDeviceEnabledCommand();
1774 }
1775 case SRC_SET_CARRIER_ENABLED: {
1776 return handleSrcSetCarrierEnabledCommand();
1777 }
1778 case SRC_GET_CARRIER_ENABLED: {
1779 return handleSrcGetCarrierEnabledCommand();
1780 }
Hui Wangeadb2562021-02-26 09:33:38 -08001781 case SRC_SET_FEATURE_ENABLED: {
1782 return handleSrcSetFeatureValidationCommand();
1783 }
1784 case SRC_GET_FEATURE_ENABLED: {
1785 return handleSrcGetFeatureValidationCommand();
1786 }
Hui Wang068ab862020-10-31 05:12:53 +00001787 }
1788
1789 return -1;
1790 }
1791
James.cf Linbcdf8b32021-01-14 16:44:13 +08001792 private int handleRcsUceCommand() {
1793 String arg = getNextArg();
1794 if (arg == null) {
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001795 onHelpUce();
1796 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001797 }
1798
1799 switch (arg) {
1800 case UCE_REMOVE_EAB_CONTACT:
1801 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08001802 case UCE_GET_EAB_CONTACT:
1803 return handleGettingEabContactCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08001804 case UCE_GET_DEVICE_ENABLED:
1805 return handleUceGetDeviceEnabledCommand();
1806 case UCE_SET_DEVICE_ENABLED:
1807 return handleUceSetDeviceEnabledCommand();
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001808 case UCE_OVERRIDE_PUBLISH_CAPS:
1809 return handleUceOverridePublishCaps();
1810 case UCE_GET_LAST_PIDF_XML:
1811 return handleUceGetPidfXml();
James.cf Linbcdf8b32021-01-14 16:44:13 +08001812 }
1813 return -1;
1814 }
1815
1816 private int handleRemovingEabContactCommand() {
1817 int subId = getSubId("uce remove-eab-contact");
1818 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1819 return -1;
1820 }
1821
1822 String phoneNumber = getNextArgRequired();
1823 if (TextUtils.isEmpty(phoneNumber)) {
1824 return -1;
1825 }
1826 int result = 0;
1827 try {
1828 result = mInterface.removeContactFromEab(subId, phoneNumber);
1829 } catch (RemoteException e) {
1830 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
1831 getErrPrintWriter().println("Exception: " + e.getMessage());
1832 return -1;
1833 }
1834
1835 if (VDBG) {
1836 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
1837 }
calvinpan293ea1b2021-02-04 17:52:13 +08001838 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001839 }
1840
calvinpane4a8a1d2021-01-25 13:51:18 +08001841 private int handleGettingEabContactCommand() {
1842 String phoneNumber = getNextArgRequired();
1843 if (TextUtils.isEmpty(phoneNumber)) {
1844 return -1;
1845 }
1846 String result = "";
1847 try {
1848 result = mInterface.getContactFromEab(phoneNumber);
1849
1850 } catch (RemoteException e) {
1851 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
1852 getErrPrintWriter().println("Exception: " + e.getMessage());
1853 return -1;
1854 }
1855
1856 if (VDBG) {
1857 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
1858 }
calvinpan293ea1b2021-02-04 17:52:13 +08001859 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08001860 return 0;
1861 }
1862
1863 private int handleUceGetDeviceEnabledCommand() {
1864 boolean result = false;
1865 try {
1866 result = mInterface.getDeviceUceEnabled();
1867 } catch (RemoteException e) {
1868 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
1869 return -1;
1870 }
1871 if (VDBG) {
1872 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
1873 }
calvinpane4a8a1d2021-01-25 13:51:18 +08001874 getOutPrintWriter().println(result);
1875 return 0;
1876 }
1877
James.cf Lin4b784aa2021-01-31 03:25:15 +08001878 private int handleUceSetDeviceEnabledCommand() {
1879 String enabledStr = getNextArg();
1880 if (TextUtils.isEmpty(enabledStr)) {
1881 return -1;
1882 }
1883
1884 try {
1885 boolean isEnabled = Boolean.parseBoolean(enabledStr);
1886 mInterface.setDeviceUceEnabled(isEnabled);
1887 if (VDBG) {
1888 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
1889 }
1890 } catch (NumberFormatException | RemoteException e) {
1891 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
1892 getErrPrintWriter().println("Exception: " + e.getMessage());
1893 return -1;
1894 }
1895 return 0;
1896 }
1897
Hui Wang19a21872021-02-19 20:45:36 -08001898 private int handleSrcSetTestEnabledCommand() {
1899 String enabledStr = getNextArg();
1900 if (enabledStr == null) {
1901 return -1;
1902 }
1903
1904 try {
1905 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
1906 if (VDBG) {
1907 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
1908 }
1909 getOutPrintWriter().println("Done");
1910 } catch (NumberFormatException | RemoteException e) {
1911 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
1912 getErrPrintWriter().println("Exception: " + e.getMessage());
1913 return -1;
1914 }
1915 return 0;
1916 }
1917
1918 private int handleSrcGetTestEnabledCommand() {
1919 boolean result = false;
1920 try {
1921 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
1922 } catch (RemoteException e) {
1923 return -1;
1924 }
1925 if (VDBG) {
1926 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
1927 }
1928 getOutPrintWriter().println(result);
1929 return 0;
1930 }
1931
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001932 private int handleUceOverridePublishCaps() {
1933 int subId = getSubId("uce override-published-caps");
1934 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1935 return -1;
1936 }
1937 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
1938 String operation = getNextArgRequired();
1939 String caps = getNextArg();
1940 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
1941 && !"list".equals(operation)) {
1942 getErrPrintWriter().println("Invalid operation: " + operation);
1943 return -1;
1944 }
1945
1946 // add/remove requires capabilities to be specified.
1947 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
1948 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
1949 + "specified");
1950 return -1;
1951 }
1952
1953 ArraySet<String> capSet = new ArraySet<>();
1954 if (!TextUtils.isEmpty(caps)) {
1955 String[] capArray = caps.split(":");
1956 for (String cap : capArray) {
1957 // Allow unknown tags to be passed in as well.
1958 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
1959 }
1960 }
1961
1962 RcsContactUceCapability result = null;
1963 try {
1964 switch (operation) {
1965 case "add":
1966 result = mInterface.addUceRegistrationOverrideShell(subId,
1967 new ArrayList<>(capSet));
1968 break;
1969 case "remove":
1970 result = mInterface.removeUceRegistrationOverrideShell(subId,
1971 new ArrayList<>(capSet));
1972 break;
1973 case "clear":
1974 result = mInterface.clearUceRegistrationOverrideShell(subId);
1975 break;
1976 case "list":
1977 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
1978 break;
1979 }
1980 } catch (RemoteException e) {
1981 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
1982 getErrPrintWriter().println("Exception: " + e.getMessage());
1983 return -1;
1984 } catch (ServiceSpecificException sse) {
1985 // Reconstruct ImsException
1986 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
1987 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
1988 getErrPrintWriter().println("Exception: " + imsException);
1989 return -1;
1990 }
1991 if (result == null) {
1992 getErrPrintWriter().println("Service not available");
1993 return -1;
1994 }
1995 getOutPrintWriter().println(result);
1996 return 0;
1997 }
1998
1999 private int handleUceGetPidfXml() {
2000 int subId = getSubId("uce get-last-publish-pidf");
2001 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2002 return -1;
2003 }
2004
2005 String result;
2006 try {
2007 result = mInterface.getLastUcePidfXmlShell(subId);
2008 } catch (RemoteException e) {
2009 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2010 getErrPrintWriter().println("Exception: " + e.getMessage());
2011 return -1;
2012 } catch (ServiceSpecificException sse) {
2013 // Reconstruct ImsException
2014 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2015 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2016 getErrPrintWriter().println("Exception: " + imsException);
2017 return -1;
2018 }
2019 if (result == null) {
2020 getErrPrintWriter().println("Service not available");
2021 return -1;
2022 }
2023 getOutPrintWriter().println(result);
2024 return 0;
2025 }
2026
Hui Wang068ab862020-10-31 05:12:53 +00002027 private int handleSrcSetDeviceEnabledCommand() {
2028 String enabledStr = getNextArg();
2029 if (enabledStr == null) {
2030 return -1;
2031 }
2032
2033 try {
2034 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2035 if (VDBG) {
2036 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2037 }
2038 getOutPrintWriter().println("Done");
2039 } catch (NumberFormatException | RemoteException e) {
2040 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2041 getErrPrintWriter().println("Exception: " + e.getMessage());
2042 return -1;
2043 }
2044 return 0;
2045 }
2046
2047 private int handleSrcGetDeviceEnabledCommand() {
2048 boolean result = false;
2049 try {
2050 result = mInterface.getDeviceSingleRegistrationEnabled();
2051 } catch (RemoteException e) {
2052 return -1;
2053 }
2054 if (VDBG) {
2055 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2056 }
2057 getOutPrintWriter().println(result);
2058 return 0;
2059 }
2060
2061 private int handleSrcSetCarrierEnabledCommand() {
2062 //the release time value could be -1
2063 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2064 : SubscriptionManager.getDefaultSubscriptionId();
2065 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2066 return -1;
2067 }
2068
2069 String enabledStr = getNextArg();
2070 if (enabledStr == null) {
2071 return -1;
2072 }
2073
2074 try {
2075 boolean result =
2076 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2077 if (VDBG) {
2078 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2079 + enabledStr + ", result=" + result);
2080 }
2081 getOutPrintWriter().println(result);
2082 } catch (NumberFormatException | RemoteException e) {
2083 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2084 + enabledStr + ", error" + e.getMessage());
2085 getErrPrintWriter().println("Exception: " + e.getMessage());
2086 return -1;
2087 }
2088 return 0;
2089 }
2090
2091 private int handleSrcGetCarrierEnabledCommand() {
2092 int subId = getSubId("src get-carrier-enabled");
2093 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2094 return -1;
2095 }
2096
2097 boolean result = false;
2098 try {
2099 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2100 } catch (RemoteException e) {
2101 return -1;
2102 }
2103 if (VDBG) {
2104 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2105 }
2106 getOutPrintWriter().println(result);
2107 return 0;
2108 }
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -08002109
Hui Wangeadb2562021-02-26 09:33:38 -08002110 private int handleSrcSetFeatureValidationCommand() {
2111 //the release time value could be -1
2112 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2113 : SubscriptionManager.getDefaultSubscriptionId();
2114 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2115 return -1;
2116 }
2117
2118 String enabledStr = getNextArg();
2119 if (enabledStr == null) {
2120 return -1;
2121 }
2122
2123 try {
2124 boolean result =
2125 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2126 if (VDBG) {
2127 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2128 + enabledStr + ", result=" + result);
2129 }
2130 getOutPrintWriter().println(result);
2131 } catch (NumberFormatException | RemoteException e) {
2132 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2133 + enabledStr + ", error" + e.getMessage());
2134 getErrPrintWriter().println("Exception: " + e.getMessage());
2135 return -1;
2136 }
2137 return 0;
2138 }
2139
2140 private int handleSrcGetFeatureValidationCommand() {
2141 int subId = getSubId("src get-feature-validation");
2142 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2143 return -1;
2144 }
2145
2146 Boolean result = false;
2147 try {
2148 result = mInterface.getImsFeatureValidationOverride(subId);
2149 } catch (RemoteException e) {
2150 return -1;
2151 }
2152 if (VDBG) {
2153 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2154 }
2155 getOutPrintWriter().println(result);
2156 return 0;
2157 }
2158
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -08002159 private int handleHasCarrierPrivilegesCommand() {
2160 String packageName = getNextArgRequired();
2161
2162 boolean hasCarrierPrivileges;
2163 try {
2164 hasCarrierPrivileges =
2165 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2166 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2167 } catch (RemoteException e) {
2168 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2169 getErrPrintWriter().println("Exception: " + e.getMessage());
2170 return -1;
2171 }
2172
2173 getOutPrintWriter().println(hasCarrierPrivileges);
2174 return 0;
2175 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07002176}