blob: b2e1a996747ac3b7d2d92d18608d5342cb285370 [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 Wang068ab862020-10-31 05:12:53 +0000116
Tyler Gunn92479152021-01-20 16:30:10 -0800117 private static final String D2D_SUBCOMMAND = "d2d";
118 private static final String D2D_SEND = "send";
119
James.cf Linbcdf8b32021-01-14 16:44:13 +0800120 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800121 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800122 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800123 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
124 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000125 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
126 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800127
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800128 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
129 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
130
Jack Nudelman644b91a2021-03-12 14:09:48 -0800131 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
132 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
133 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
134
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700135 // Take advantage of existing methods that already contain permissions checks when possible.
136 private final ITelephony mInterface;
137
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100138 private SubscriptionManager mSubscriptionManager;
139 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700140 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100141
142 private enum CcType {
143 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
144 STRING_ARRAY, UNKNOWN
145 }
146
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100147 private class CcOptionParseResult {
148 public int mSubId;
149 public boolean mPersistent;
150 }
151
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100152 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
153 // keys by looking at the end of the string which usually tells the type.
154 // For instance: "xxxx_string", "xxxx_string_array", etc.
155 // The carrier config keys in this map does not follow this convention. It is therefore not
156 // possible to infer the type for these keys by looking at the string.
157 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
158 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
159 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
160 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
161 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
162 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
163 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
164 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
165 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
166 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
167 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
168 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
169 CcType.STRING);
170 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
171 CcType.STRING_ARRAY);
172 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
173 CcType.STRING_ARRAY);
174 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
175 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
176 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
177 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
178 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
179 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
180 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
181 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
182 }
183 };
184
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000185 /**
186 * Map from a shorthand string to the feature tags required in registration required in order
187 * for the RCS feature to be considered "capable".
188 */
189 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
190 static {
191 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
192 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
193 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
194 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
195 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
196 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
197 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
198 FeatureTags.FEATURE_TAG_VIDEO)));
199 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
200 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
201 map.put("call_comp",
202 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
203 map.put("call_comp_mmtel",
204 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
205 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
206 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
207 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
208 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
209 // version
210 map.put("chatbot", new ArraySet<>(Arrays.asList(
211 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
212 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
213 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
214 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
215 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
216 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
217 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
218 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
219 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
220 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
221 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
222 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
223 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
224 }
225
226
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100227 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700228 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100229 mCarrierConfigManager =
230 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
231 mSubscriptionManager = (SubscriptionManager)
232 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700233 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700234 }
235
236 @Override
237 public int onCommand(String cmd) {
238 if (cmd == null) {
239 return handleDefaultCommands(null);
240 }
241
242 switch (cmd) {
243 case IMS_SUBCOMMAND: {
244 return handleImsCommand();
245 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800246 case RCS_UCE_COMMAND:
247 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800248 case NUMBER_VERIFICATION_SUBCOMMAND:
249 return handleNumberVerificationCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800250 case EMERGENCY_NUMBER_TEST_MODE:
251 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100252 case CARRIER_CONFIG_SUBCOMMAND: {
253 return handleCcCommand();
254 }
Shuo Qianf5125122019-12-16 17:03:07 -0800255 case DATA_TEST_MODE:
256 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700257 case END_BLOCK_SUPPRESSION:
258 return handleEndBlockSuppressionCommand();
Hui Wang0866fcc2020-10-12 12:14:23 -0700259 case GBA_SUBCOMMAND:
260 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800261 case D2D_SUBCOMMAND:
262 return handleD2dCommand();
Hui Wang068ab862020-10-31 05:12:53 +0000263 case SINGLE_REGISTATION_CONFIG:
264 return handleSingleRegistrationConfigCommand();
Michele Berionne38c1afa2020-12-28 20:23:16 +0000265 case RESTART_MODEM:
266 return handleRestartModemCommand();
Michele Berionned9fbae52020-11-13 02:36:59 +0000267 case UNATTENDED_REBOOT:
268 return handleUnattendedReboot();
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800269 case HAS_CARRIER_PRIVILEGES_COMMAND:
270 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800271 case THERMAL_MITIGATION_COMMAND:
272 return handleThermalMitigationCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700273 default: {
274 return handleDefaultCommands(cmd);
275 }
276 }
277 }
278
279 @Override
280 public void onHelp() {
281 PrintWriter pw = getOutPrintWriter();
282 pw.println("Telephony Commands:");
283 pw.println(" help");
284 pw.println(" Print this help text.");
285 pw.println(" ims");
286 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800287 pw.println(" uce");
288 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800289 pw.println(" emergency-number-test-mode");
290 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700291 pw.println(" end-block-suppression");
292 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800293 pw.println(" data");
294 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100295 pw.println(" cc");
296 pw.println(" Carrier Config Commands.");
Hui Wang0866fcc2020-10-12 12:14:23 -0700297 pw.println(" gba");
298 pw.println(" GBA Commands.");
Hui Wang068ab862020-10-31 05:12:53 +0000299 pw.println(" src");
300 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne38c1afa2020-12-28 20:23:16 +0000301 pw.println(" restart-modem");
302 pw.println(" Restart modem command.");
Michele Berionned9fbae52020-11-13 02:36:59 +0000303 pw.println(" unattended-reboot");
304 pw.println(" Prepare for unattended reboot.");
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800305 pw.println(" has-carrier-privileges [package]");
306 pw.println(" Query carrier privilege status for a package. Prints true or false.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700307 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800308 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800309 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700310 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800311 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100312 onHelpCc();
Hui Wang0866fcc2020-10-12 12:14:23 -0700313 onHelpGba();
Hui Wang068ab862020-10-31 05:12:53 +0000314 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800315 onHelpD2D();
316 }
317
318 private void onHelpD2D() {
319 PrintWriter pw = getOutPrintWriter();
320 pw.println("D2D Comms Commands:");
321 pw.println(" d2d send TYPE VALUE");
322 pw.println(" Sends a D2D message of specified type and value.");
323 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
324 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
325 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
326 MESSAGE_CALL_AUDIO_CODEC));
327 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
328 + Communicator.messageToString(
329 MESSAGE_DEVICE_BATTERY_STATE));
330 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
331 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700332 }
333
334 private void onHelpIms() {
335 PrintWriter pw = getOutPrintWriter();
336 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800337 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700338 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
339 pw.println(" ImsService. Options are:");
340 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
341 pw.println(" is specified, it will choose the default voice SIM slot.");
342 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
343 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800344 pw.println(" -f: Set the feature that this override if for, if no option is");
345 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700346 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
347 pw.println(" Gets the package name of the currently defined ImsService.");
348 pw.println(" Options are:");
349 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
350 pw.println(" is specified, it will choose the default voice SIM slot.");
351 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000352 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800353 pw.println(" -f: The feature type that the query will be requested for. If none is");
354 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800355 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
356 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
357 pw.println(" configuration overrides. Options are:");
358 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
359 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700360 pw.println(" ims enable [-s SLOT_ID]");
361 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
362 pw.println(" if none is specified.");
363 pw.println(" ims disable [-s SLOT_ID]");
364 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
365 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700366 pw.println(" ims conference-event-package [enable/disable]");
367 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700368 }
369
James.cf Linbcdf8b32021-01-14 16:44:13 +0800370 private void onHelpUce() {
371 PrintWriter pw = getOutPrintWriter();
372 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800373 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
374 pw.println(" Get the EAB contacts from the EAB database.");
375 pw.println(" Options are:");
376 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
377 pw.println(" Expected output format :");
378 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800379 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
380 pw.println(" Remove the EAB contacts from the EAB database.");
381 pw.println(" Options are:");
382 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
383 pw.println(" is specified, it will choose the default voice SIM slot.");
384 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800385 pw.println(" uce get-device-enabled");
386 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
387 pw.println(" uce set-device-enabled true|false");
388 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
389 pw.println(" The value could be true, false.");
Brad Ebingerd4c5bde2021-02-12 06:18:28 +0000390 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
391 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
392 pw.println(" Options are:");
393 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
394 pw.println(" is specified, it will choose the default voice SIM slot.");
395 pw.println(" add [CAPABILITY]: add a new capability");
396 pw.println(" remove [CAPABILITY]: remove a capability");
397 pw.println(" clear: clear all capability overrides");
398 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
399 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
400 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
401 pw.println(" chatbot_sa, chatbot_role] as well as full length");
402 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
403 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
404 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
405 pw.println(" PUBLISH is active");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800406 }
407
Hall Liud892bec2018-11-30 14:51:45 -0800408 private void onHelpNumberVerification() {
409 PrintWriter pw = getOutPrintWriter();
410 pw.println("Number verification commands");
411 pw.println(" numverify override-package PACKAGE_NAME;");
412 pw.println(" Set the authorized package for number verification.");
413 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800414 pw.println(" numverify fake-call NUMBER;");
415 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
416 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800417 }
418
Jack Nudelman644b91a2021-03-12 14:09:48 -0800419 private void onHelpThermalMitigation() {
420 PrintWriter pw = getOutPrintWriter();
421 pw.println("Thermal mitigation commands");
422 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
423 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
424 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
425 pw.println(" Remove the package from one of the authorized packages for thermal "
426 + "mitigation.");
427 }
428
Shuo Qianf5125122019-12-16 17:03:07 -0800429 private void onHelpDataTestMode() {
430 PrintWriter pw = getOutPrintWriter();
431 pw.println("Mobile Data Test Mode Commands:");
432 pw.println(" data enable: enable mobile data connectivity");
433 pw.println(" data disable: disable mobile data connectivity");
434 }
435
sqian9d4df8b2019-01-15 18:32:07 -0800436 private void onHelpEmergencyNumber() {
437 PrintWriter pw = getOutPrintWriter();
438 pw.println("Emergency Number Test Mode Commands:");
439 pw.println(" emergency-number-test-mode ");
440 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
441 + " the test mode");
442 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700443 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800444 pw.println(" -c: clear the emergency number list in the test mode.");
445 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700446 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800447 pw.println(" -p: get the full emergency number list in the test mode.");
448 }
449
Shuo Qian489d9282020-07-09 11:30:03 -0700450 private void onHelpEndBlockSupperssion() {
451 PrintWriter pw = getOutPrintWriter();
452 pw.println("End Block Suppression command:");
453 pw.println(" end-block-suppression: disable suppressing blocking by contact");
454 pw.println(" with emergency services.");
455 }
456
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100457 private void onHelpCc() {
458 PrintWriter pw = getOutPrintWriter();
459 pw.println("Carrier Config Commands:");
460 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
461 pw.println(" Print carrier config values.");
462 pw.println(" Options are:");
463 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
464 pw.println(" is specified, it will choose the default voice SIM slot.");
465 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
466 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100467 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100468 pw.println(" Set carrier config KEY to NEW_VALUE.");
469 pw.println(" Options are:");
470 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
471 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100472 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100473 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
474 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
475 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
476 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
477 pw.println(" cc clear-values [-s SLOT_ID]");
478 pw.println(" Clear all carrier override values that has previously been set");
479 pw.println(" with set-value");
480 pw.println(" Options are:");
481 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
482 pw.println(" is specified, it will choose the default voice SIM slot.");
483 }
484
Hui Wang0866fcc2020-10-12 12:14:23 -0700485 private void onHelpGba() {
486 PrintWriter pw = getOutPrintWriter();
487 pw.println("Gba Commands:");
488 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
489 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
490 pw.println(" Options are:");
491 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
492 pw.println(" is specified, it will choose the default voice SIM slot.");
493 pw.println(" gba get-service [-s SLOT_ID]");
494 pw.println(" Gets the package name of the currently defined GbaService.");
495 pw.println(" Options are:");
496 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
497 pw.println(" is specified, it will choose the default voice SIM slot.");
498 pw.println(" gba set-release [-s SLOT_ID] n");
499 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
500 pw.println(" Do not release/unbind if n is -1.");
501 pw.println(" Options are:");
502 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
503 pw.println(" is specified, it will choose the default voice SIM slot.");
504 pw.println(" gba get-release [-s SLOT_ID]");
505 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
506 pw.println(" Options are:");
507 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
508 pw.println(" is specified, it will choose the default voice SIM slot.");
509 }
510
Hui Wang068ab862020-10-31 05:12:53 +0000511 private void onHelpSrc() {
512 PrintWriter pw = getOutPrintWriter();
513 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wang19a21872021-02-19 20:45:36 -0800514 pw.println(" src set-test-enabled true|false");
515 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
516 pw.println(" The value could be true, false, or null(undefined).");
517 pw.println(" src get-test-enabled");
518 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang068ab862020-10-31 05:12:53 +0000519 pw.println(" src set-device-enabled true|false|null");
520 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
521 pw.println(" The value could be true, false, or null(undefined).");
522 pw.println(" src get-device-enabled");
523 pw.println(" Gets the device config for RCS VoLTE single registration.");
524 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
525 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
526 pw.println(" The value could be true, false, or null(undefined).");
527 pw.println(" Options are:");
528 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
529 pw.println(" is specified, it will choose the default voice SIM slot.");
530 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
531 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
532 pw.println(" Options are:");
533 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
534 pw.println(" is specified, it will choose the default voice SIM slot.");
535 }
536
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700537 private int handleImsCommand() {
538 String arg = getNextArg();
539 if (arg == null) {
540 onHelpIms();
541 return 0;
542 }
543
544 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800545 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700546 return handleImsSetServiceCommand();
547 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800548 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700549 return handleImsGetServiceCommand();
550 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800551 case IMS_CLEAR_SERVICE_OVERRIDE: {
552 return handleImsClearCarrierServiceCommand();
553 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700554 case IMS_ENABLE: {
555 return handleEnableIms();
556 }
557 case IMS_DISABLE: {
558 return handleDisableIms();
559 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700560 case IMS_CEP: {
561 return handleCepChange();
562 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700563 }
564
565 return -1;
566 }
567
Shuo Qianf5125122019-12-16 17:03:07 -0800568 private int handleDataTestModeCommand() {
569 PrintWriter errPw = getErrPrintWriter();
570 String arg = getNextArgRequired();
571 if (arg == null) {
572 onHelpDataTestMode();
573 return 0;
574 }
575 switch (arg) {
576 case DATA_ENABLE: {
577 try {
578 mInterface.enableDataConnectivity();
579 } catch (RemoteException ex) {
580 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
581 errPw.println("Exception: " + ex.getMessage());
582 return -1;
583 }
584 break;
585 }
586 case DATA_DISABLE: {
587 try {
588 mInterface.disableDataConnectivity();
589 } catch (RemoteException ex) {
590 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
591 errPw.println("Exception: " + ex.getMessage());
592 return -1;
593 }
594 break;
595 }
596 default:
597 onHelpDataTestMode();
598 break;
599 }
600 return 0;
601 }
602
sqian9d4df8b2019-01-15 18:32:07 -0800603 private int handleEmergencyNumberTestModeCommand() {
604 PrintWriter errPw = getErrPrintWriter();
605 String opt = getNextOption();
606 if (opt == null) {
607 onHelpEmergencyNumber();
608 return 0;
609 }
610
611 switch (opt) {
612 case "-a": {
613 String emergencyNumberCmd = getNextArgRequired();
614 if (emergencyNumberCmd == null
615 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700616 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800617 + " to be specified after -a in the command ");
618 return -1;
619 }
620 try {
621 mInterface.updateEmergencyNumberListTestMode(
622 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
623 new EmergencyNumber(emergencyNumberCmd, "", "",
624 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
625 new ArrayList<String>(),
626 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
627 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
628 } catch (RemoteException ex) {
629 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
630 + ", error " + ex.getMessage());
631 errPw.println("Exception: " + ex.getMessage());
632 return -1;
633 }
634 break;
635 }
636 case "-c": {
637 try {
638 mInterface.updateEmergencyNumberListTestMode(
639 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
640 } catch (RemoteException ex) {
641 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
642 errPw.println("Exception: " + ex.getMessage());
643 return -1;
644 }
645 break;
646 }
647 case "-r": {
648 String emergencyNumberCmd = getNextArgRequired();
649 if (emergencyNumberCmd == null
650 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700651 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800652 + " to be specified after -r in the command ");
653 return -1;
654 }
655 try {
656 mInterface.updateEmergencyNumberListTestMode(
657 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
658 new EmergencyNumber(emergencyNumberCmd, "", "",
659 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
660 new ArrayList<String>(),
661 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
662 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
663 } catch (RemoteException ex) {
664 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
665 + ", error " + ex.getMessage());
666 errPw.println("Exception: " + ex.getMessage());
667 return -1;
668 }
669 break;
670 }
671 case "-p": {
672 try {
673 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
674 } catch (RemoteException ex) {
675 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
676 errPw.println("Exception: " + ex.getMessage());
677 return -1;
678 }
679 break;
680 }
681 default:
682 onHelpEmergencyNumber();
683 break;
684 }
685 return 0;
686 }
687
Hall Liud892bec2018-11-30 14:51:45 -0800688 private int handleNumberVerificationCommand() {
689 String arg = getNextArg();
690 if (arg == null) {
691 onHelpNumberVerification();
692 return 0;
693 }
694
Hall Liuca5af3a2018-12-04 16:58:23 -0800695 if (!checkShellUid()) {
696 return -1;
697 }
698
Hall Liud892bec2018-11-30 14:51:45 -0800699 switch (arg) {
700 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800701 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
702 return 0;
703 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800704 case NUMBER_VERIFICATION_FAKE_CALL: {
705 boolean val = NumberVerificationManager.getInstance()
706 .checkIncomingCall(getNextArg());
707 getOutPrintWriter().println(val ? "1" : "0");
708 return 0;
709 }
Hall Liud892bec2018-11-30 14:51:45 -0800710 }
711
712 return -1;
713 }
714
Jack Nudelman644b91a2021-03-12 14:09:48 -0800715 private int handleThermalMitigationCommand() {
716 String arg = getNextArg();
717 String packageName = getNextArg();
718 if (arg == null || packageName == null) {
719 onHelpThermalMitigation();
720 return 0;
721 }
722
723 if (!checkShellUid()) {
724 return -1;
725 }
726
727 switch (arg) {
728 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
729 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
730 return 0;
731 }
732 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
733 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
734 mContext);
735 return 0;
736 }
737 default:
738 onHelpThermalMitigation();
739 }
740
741 return -1;
742
743 }
744
Tyler Gunn92479152021-01-20 16:30:10 -0800745 private int handleD2dCommand() {
746 String arg = getNextArg();
747 if (arg == null) {
748 onHelpD2D();
749 return 0;
750 }
751
752 switch (arg) {
753 case D2D_SEND: {
754 return handleD2dSendCommand();
755 }
756 }
757
758 return -1;
759 }
760
761 private int handleD2dSendCommand() {
762 PrintWriter errPw = getErrPrintWriter();
763 String opt;
764 int messageType = -1;
765 int messageValue = -1;
766
767
768 String arg = getNextArg();
769 if (arg == null) {
770 onHelpD2D();
771 return 0;
772 }
773 try {
774 messageType = Integer.parseInt(arg);
775 } catch (NumberFormatException e) {
776 errPw.println("message type must be a valid integer");
777 return -1;
778 }
779
780 arg = getNextArg();
781 if (arg == null) {
782 onHelpD2D();
783 return 0;
784 }
785 try {
786 messageValue = Integer.parseInt(arg);
787 } catch (NumberFormatException e) {
788 errPw.println("message value must be a valid integer");
789 return -1;
790 }
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -0800791
Tyler Gunn92479152021-01-20 16:30:10 -0800792 try {
793 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
794 } catch (RemoteException e) {
795 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
796 errPw.println("Exception: " + e.getMessage());
797 return -1;
798 }
799
800 return 0;
801 }
802
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700803 // ims set-ims-service
804 private int handleImsSetServiceCommand() {
805 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700806 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700807 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800808 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700809
810 String opt;
811 while ((opt = getNextOption()) != null) {
812 switch (opt) {
813 case "-s": {
814 try {
815 slotId = Integer.parseInt(getNextArgRequired());
816 } catch (NumberFormatException e) {
817 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
818 return -1;
819 }
820 break;
821 }
822 case "-c": {
823 isCarrierService = true;
824 break;
825 }
826 case "-d": {
827 isCarrierService = false;
828 break;
829 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800830 case "-f": {
831 String featureString = getNextArgRequired();
832 String[] features = featureString.split(",");
833 for (int i = 0; i < features.length; i++) {
834 try {
835 Integer result = Integer.parseInt(features[i]);
836 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
837 || result >= ImsFeature.FEATURE_MAX) {
838 errPw.println("ims set-ims-service -f " + result
839 + " is an invalid feature.");
840 return -1;
841 }
842 featuresList.add(result);
843 } catch (NumberFormatException e) {
844 errPw.println("ims set-ims-service -f tried to parse " + features[i]
845 + " as an integer.");
846 return -1;
847 }
848 }
849 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700850 }
851 }
852 // Mandatory param, either -c or -d
853 if (isCarrierService == null) {
854 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
855 return -1;
856 }
857
858 String packageName = getNextArg();
859
860 try {
861 if (packageName == null) {
862 packageName = "";
863 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800864 int[] featureArray = new int[featuresList.size()];
865 for (int i = 0; i < featuresList.size(); i++) {
866 featureArray[i] = featuresList.get(i);
867 }
868 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
869 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700870 if (VDBG) {
871 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800872 + (isCarrierService ? "-c " : "-d ")
873 + "-f " + featuresList + " "
874 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700875 }
876 getOutPrintWriter().println(result);
877 } catch (RemoteException e) {
878 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800879 + (isCarrierService ? "-c " : "-d ")
880 + "-f " + featuresList + " "
881 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700882 errPw.println("Exception: " + e.getMessage());
883 return -1;
884 }
885 return 0;
886 }
887
Brad Ebinger999d3302020-11-25 14:31:39 -0800888 // ims clear-ims-service-override
889 private int handleImsClearCarrierServiceCommand() {
890 PrintWriter errPw = getErrPrintWriter();
891 int slotId = getDefaultSlot();
892
893 String opt;
894 while ((opt = getNextOption()) != null) {
895 switch (opt) {
896 case "-s": {
897 try {
898 slotId = Integer.parseInt(getNextArgRequired());
899 } catch (NumberFormatException e) {
900 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
901 return -1;
902 }
903 break;
904 }
905 }
906 }
907
908 try {
909 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
910 if (VDBG) {
911 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
912 + ", result=" + result);
913 }
914 getOutPrintWriter().println(result);
915 } catch (RemoteException e) {
916 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
917 + ", error" + e.getMessage());
918 errPw.println("Exception: " + e.getMessage());
919 return -1;
920 }
921 return 0;
922 }
923
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700924 // ims get-ims-service
925 private int handleImsGetServiceCommand() {
926 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700927 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700928 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800929 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700930
931 String opt;
932 while ((opt = getNextOption()) != null) {
933 switch (opt) {
934 case "-s": {
935 try {
936 slotId = Integer.parseInt(getNextArgRequired());
937 } catch (NumberFormatException e) {
938 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
939 return -1;
940 }
941 break;
942 }
943 case "-c": {
944 isCarrierService = true;
945 break;
946 }
947 case "-d": {
948 isCarrierService = false;
949 break;
950 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800951 case "-f": {
952 try {
953 featureType = Integer.parseInt(getNextArg());
954 } catch (NumberFormatException e) {
955 errPw.println("ims get-ims-service -f requires valid integer as feature.");
956 return -1;
957 }
958 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
959 || featureType >= ImsFeature.FEATURE_MAX) {
960 errPw.println("ims get-ims-service -f invalid feature.");
961 return -1;
962 }
963 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700964 }
965 }
966 // Mandatory param, either -c or -d
967 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -0800968 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700969 return -1;
970 }
971
972 String result;
973 try {
Brad Ebinger24c29992019-12-05 13:03:21 -0800974 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700975 } catch (RemoteException e) {
976 return -1;
977 }
978 if (VDBG) {
979 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -0800980 + (isCarrierService ? "-c " : "-d ")
981 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
982 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700983 }
984 getOutPrintWriter().println(result);
985 return 0;
986 }
987
988 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700989 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700990 String opt;
991 while ((opt = getNextOption()) != null) {
992 switch (opt) {
993 case "-s": {
994 try {
995 slotId = Integer.parseInt(getNextArgRequired());
996 } catch (NumberFormatException e) {
997 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
998 return -1;
999 }
1000 break;
1001 }
1002 }
1003 }
1004 try {
1005 mInterface.enableIms(slotId);
1006 } catch (RemoteException e) {
1007 return -1;
1008 }
1009 if (VDBG) {
1010 Log.v(LOG_TAG, "ims enable -s " + slotId);
1011 }
1012 return 0;
1013 }
1014
1015 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001016 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001017 String opt;
1018 while ((opt = getNextOption()) != null) {
1019 switch (opt) {
1020 case "-s": {
1021 try {
1022 slotId = Integer.parseInt(getNextArgRequired());
1023 } catch (NumberFormatException e) {
1024 getErrPrintWriter().println(
1025 "ims disable requires an integer as a SLOT_ID.");
1026 return -1;
1027 }
1028 break;
1029 }
1030 }
1031 }
1032 try {
1033 mInterface.disableIms(slotId);
1034 } catch (RemoteException e) {
1035 return -1;
1036 }
1037 if (VDBG) {
1038 Log.v(LOG_TAG, "ims disable -s " + slotId);
1039 }
1040 return 0;
1041 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001042
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001043 private int handleCepChange() {
1044 Log.i(LOG_TAG, "handleCepChange");
1045 String opt = getNextArg();
1046 if (opt == null) {
1047 return -1;
1048 }
1049 boolean isCepEnabled = opt.equals("enable");
1050
1051 try {
1052 mInterface.setCepEnabled(isCepEnabled);
1053 } catch (RemoteException e) {
1054 return -1;
1055 }
1056 return 0;
1057 }
1058
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001059 private int getDefaultSlot() {
1060 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1061 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1062 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1063 // If there is no default, default to slot 0.
1064 slotId = DEFAULT_PHONE_ID;
1065 }
1066 return slotId;
1067 }
sqian2fff4a32018-11-05 14:18:37 -08001068
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001069 // Parse options related to Carrier Config Commands.
1070 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001071 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001072 CcOptionParseResult result = new CcOptionParseResult();
1073 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1074 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001075
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001076 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001077 while ((opt = getNextOption()) != null) {
1078 switch (opt) {
1079 case "-s": {
1080 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001081 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1082 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1083 errPw.println(tag + "No valid subscription found.");
1084 return null;
1085 }
1086
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001087 } catch (IllegalArgumentException e) {
1088 // Missing slot id
1089 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001090 return null;
1091 }
1092 break;
1093 }
1094 case "-p": {
1095 if (allowOptionPersistent) {
1096 result.mPersistent = true;
1097 } else {
1098 errPw.println(tag + "Unexpected option " + opt);
1099 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001100 }
1101 break;
1102 }
1103 default: {
1104 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001105 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001106 }
1107 }
1108 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001109 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001110 }
1111
1112 private int slotStringToSubId(String tag, String slotString) {
1113 int slotId = -1;
1114 try {
1115 slotId = Integer.parseInt(slotString);
1116 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001117 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1118 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1119 }
1120
1121 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001122 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1123 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1124 }
1125
Qiong Liuf25799b2020-09-10 10:13:46 +08001126 Phone phone = PhoneFactory.getPhone(slotId);
1127 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001128 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1129 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1130 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001131 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001132 }
1133
Hall Liud892bec2018-11-30 14:51:45 -08001134 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001135 // adb can run as root or as shell, depending on whether the device is rooted.
1136 return Binder.getCallingUid() == Process.SHELL_UID
1137 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001138 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001139
1140 private int handleCcCommand() {
1141 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1142 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001143 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001144 getErrPrintWriter().println("cc: Permission denied.");
1145 return -1;
1146 }
1147
1148 String arg = getNextArg();
1149 if (arg == null) {
1150 onHelpCc();
1151 return 0;
1152 }
1153
1154 switch (arg) {
1155 case CC_GET_VALUE: {
1156 return handleCcGetValue();
1157 }
1158 case CC_SET_VALUE: {
1159 return handleCcSetValue();
1160 }
1161 case CC_CLEAR_VALUES: {
1162 return handleCcClearValues();
1163 }
1164 default: {
1165 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1166 }
1167 }
1168 return -1;
1169 }
1170
1171 // cc get-value
1172 private int handleCcGetValue() {
1173 PrintWriter errPw = getErrPrintWriter();
1174 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1175 String key = null;
1176
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001177 // Parse all options
1178 CcOptionParseResult options = parseCcOptions(tag, false);
1179 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001180 return -1;
1181 }
1182
1183 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001184 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001185 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001186 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001187 return -1;
1188 }
1189
1190 // Get the key.
1191 key = getNextArg();
1192 if (key != null) {
1193 // A key was provided. Verify if it is a valid key
1194 if (!bundle.containsKey(key)) {
1195 errPw.println(tag + key + " is not a valid key.");
1196 return -1;
1197 }
1198
1199 // Print the carrier config value for key.
1200 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1201 } else {
1202 // No key provided. Show all values.
1203 // Iterate over a sorted list of all carrier config keys and print them.
1204 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1205 for (String k : sortedSet) {
1206 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1207 }
1208 }
1209 return 0;
1210 }
1211
1212 // cc set-value
1213 private int handleCcSetValue() {
1214 PrintWriter errPw = getErrPrintWriter();
1215 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1216
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001217 // Parse all options
1218 CcOptionParseResult options = parseCcOptions(tag, true);
1219 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001220 return -1;
1221 }
1222
1223 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001224 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001225 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001226 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001227 return -1;
1228 }
1229
1230 // Get the key.
1231 String key = getNextArg();
1232 if (key == null || key.equals("")) {
1233 errPw.println(tag + "KEY is missing");
1234 return -1;
1235 }
1236
1237 // Verify if the key is valid
1238 if (!originalValues.containsKey(key)) {
1239 errPw.println(tag + key + " is not a valid key.");
1240 return -1;
1241 }
1242
1243 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1244 ArrayList<String> valueList = new ArrayList<String>();
1245 while (peekNextArg() != null) {
1246 valueList.add(getNextArg());
1247 }
1248
1249 // Find the type of the carrier config value
1250 CcType type = getType(tag, key, originalValues);
1251 if (type == CcType.UNKNOWN) {
1252 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1253 return -1;
1254 }
1255
1256 // Create an override bundle containing the key and value that should be overriden.
1257 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1258 if (overrideBundle == null) {
1259 return -1;
1260 }
1261
1262 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001263 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001264
1265 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001266 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001267 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001268 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001269 return -1;
1270 }
1271
1272 // Print the original and new value.
1273 String originalValueString = ccValueToString(key, type, originalValues);
1274 String newValueString = ccValueToString(key, type, newValues);
1275 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1276 getOutPrintWriter().println("New value: \n" + newValueString);
1277
1278 return 0;
1279 }
1280
1281 // cc clear-values
1282 private int handleCcClearValues() {
1283 PrintWriter errPw = getErrPrintWriter();
1284 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1285
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001286 // Parse all options
1287 CcOptionParseResult options = parseCcOptions(tag, false);
1288 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001289 return -1;
1290 }
1291
1292 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001293 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001294 getOutPrintWriter()
1295 .println("All previously set carrier config override values has been cleared");
1296 return 0;
1297 }
1298
1299 private CcType getType(String tag, String key, PersistableBundle bundle) {
1300 // Find the type by checking the type of the current value stored in the bundle.
1301 Object value = bundle.get(key);
1302
1303 if (CC_TYPE_MAP.containsKey(key)) {
1304 return CC_TYPE_MAP.get(key);
1305 } else if (value != null) {
1306 if (value instanceof Boolean) {
1307 return CcType.BOOLEAN;
1308 } else if (value instanceof Double) {
1309 return CcType.DOUBLE;
1310 } else if (value instanceof double[]) {
1311 return CcType.DOUBLE_ARRAY;
1312 } else if (value instanceof Integer) {
1313 return CcType.INT;
1314 } else if (value instanceof int[]) {
1315 return CcType.INT_ARRAY;
1316 } else if (value instanceof Long) {
1317 return CcType.LONG;
1318 } else if (value instanceof long[]) {
1319 return CcType.LONG_ARRAY;
1320 } else if (value instanceof String) {
1321 return CcType.STRING;
1322 } else if (value instanceof String[]) {
1323 return CcType.STRING_ARRAY;
1324 }
1325 } else {
1326 // Current value was null and can therefore not be used in order to find the type.
1327 // Check the name of the key to infer the type. This check is not needed for primitive
1328 // data types (boolean, double, int and long), since they can not be null.
1329 if (key.endsWith("double_array")) {
1330 return CcType.DOUBLE_ARRAY;
1331 }
1332 if (key.endsWith("int_array")) {
1333 return CcType.INT_ARRAY;
1334 }
1335 if (key.endsWith("long_array")) {
1336 return CcType.LONG_ARRAY;
1337 }
1338 if (key.endsWith("string")) {
1339 return CcType.STRING;
1340 }
1341 if (key.endsWith("string_array") || key.endsWith("strings")) {
1342 return CcType.STRING_ARRAY;
1343 }
1344 }
1345
1346 // Not possible to infer the type by looking at the current value or the key.
1347 PrintWriter errPw = getErrPrintWriter();
1348 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1349 return CcType.UNKNOWN;
1350 }
1351
1352 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1353 String result;
1354 StringBuilder valueString = new StringBuilder();
1355 String typeString = type.toString();
1356 Object value = bundle.get(key);
1357
1358 if (value == null) {
1359 valueString.append("null");
1360 } else {
1361 switch (type) {
1362 case DOUBLE_ARRAY: {
1363 // Format the string representation of the int array as value1 value2......
1364 double[] valueArray = (double[]) value;
1365 for (int i = 0; i < valueArray.length; i++) {
1366 if (i != 0) {
1367 valueString.append(" ");
1368 }
1369 valueString.append(valueArray[i]);
1370 }
1371 break;
1372 }
1373 case INT_ARRAY: {
1374 // Format the string representation of the int array as value1 value2......
1375 int[] valueArray = (int[]) value;
1376 for (int i = 0; i < valueArray.length; i++) {
1377 if (i != 0) {
1378 valueString.append(" ");
1379 }
1380 valueString.append(valueArray[i]);
1381 }
1382 break;
1383 }
1384 case LONG_ARRAY: {
1385 // Format the string representation of the int array as value1 value2......
1386 long[] valueArray = (long[]) value;
1387 for (int i = 0; i < valueArray.length; i++) {
1388 if (i != 0) {
1389 valueString.append(" ");
1390 }
1391 valueString.append(valueArray[i]);
1392 }
1393 break;
1394 }
1395 case STRING: {
1396 valueString.append("\"" + value.toString() + "\"");
1397 break;
1398 }
1399 case STRING_ARRAY: {
1400 // Format the string representation of the string array as "value1" "value2"....
1401 String[] valueArray = (String[]) value;
1402 for (int i = 0; i < valueArray.length; i++) {
1403 if (i != 0) {
1404 valueString.append(" ");
1405 }
1406 if (valueArray[i] != null) {
1407 valueString.append("\"" + valueArray[i] + "\"");
1408 } else {
1409 valueString.append("null");
1410 }
1411 }
1412 break;
1413 }
1414 default: {
1415 valueString.append(value.toString());
1416 }
1417 }
1418 }
1419 return String.format("%-70s %-15s %s", key, typeString, valueString);
1420 }
1421
1422 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1423 ArrayList<String> valueList) {
1424 PrintWriter errPw = getErrPrintWriter();
1425 PersistableBundle bundle = new PersistableBundle();
1426
1427 // First verify that a valid number of values has been provided for the type.
1428 switch (type) {
1429 case BOOLEAN:
1430 case DOUBLE:
1431 case INT:
1432 case LONG: {
1433 if (valueList.size() != 1) {
1434 errPw.println(tag + "Expected 1 value for type " + type
1435 + ". Found: " + valueList.size());
1436 return null;
1437 }
1438 break;
1439 }
1440 case STRING: {
1441 if (valueList.size() > 1) {
1442 errPw.println(tag + "Expected 0 or 1 values for type " + type
1443 + ". Found: " + valueList.size());
1444 return null;
1445 }
1446 break;
1447 }
1448 }
1449
1450 // Parse the value according to type and add it to the Bundle.
1451 switch (type) {
1452 case BOOLEAN: {
1453 if ("true".equalsIgnoreCase(valueList.get(0))) {
1454 bundle.putBoolean(key, true);
1455 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1456 bundle.putBoolean(key, false);
1457 } else {
1458 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1459 return null;
1460 }
1461 break;
1462 }
1463 case DOUBLE: {
1464 try {
1465 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1466 } catch (NumberFormatException nfe) {
1467 // Not a valid double
1468 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1469 return null;
1470 }
1471 break;
1472 }
1473 case DOUBLE_ARRAY: {
1474 double[] valueDoubleArray = null;
1475 if (valueList.size() > 0) {
1476 valueDoubleArray = new double[valueList.size()];
1477 for (int i = 0; i < valueList.size(); i++) {
1478 try {
1479 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1480 } catch (NumberFormatException nfe) {
1481 // Not a valid double
1482 errPw.println(
1483 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1484 return null;
1485 }
1486 }
1487 }
1488 bundle.putDoubleArray(key, valueDoubleArray);
1489 break;
1490 }
1491 case INT: {
1492 try {
1493 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1494 } catch (NumberFormatException nfe) {
1495 // Not a valid integer
1496 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1497 return null;
1498 }
1499 break;
1500 }
1501 case INT_ARRAY: {
1502 int[] valueIntArray = null;
1503 if (valueList.size() > 0) {
1504 valueIntArray = new int[valueList.size()];
1505 for (int i = 0; i < valueList.size(); i++) {
1506 try {
1507 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1508 } catch (NumberFormatException nfe) {
1509 // Not a valid integer
1510 errPw.println(tag
1511 + "Unable to parse " + valueList.get(i) + " as an integer.");
1512 return null;
1513 }
1514 }
1515 }
1516 bundle.putIntArray(key, valueIntArray);
1517 break;
1518 }
1519 case LONG: {
1520 try {
1521 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1522 } catch (NumberFormatException nfe) {
1523 // Not a valid long
1524 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1525 return null;
1526 }
1527 break;
1528 }
1529 case LONG_ARRAY: {
1530 long[] valueLongArray = null;
1531 if (valueList.size() > 0) {
1532 valueLongArray = new long[valueList.size()];
1533 for (int i = 0; i < valueList.size(); i++) {
1534 try {
1535 valueLongArray[i] = Long.parseLong(valueList.get(i));
1536 } catch (NumberFormatException nfe) {
1537 // Not a valid long
1538 errPw.println(
1539 tag + "Unable to parse " + valueList.get(i) + " as a long");
1540 return null;
1541 }
1542 }
1543 }
1544 bundle.putLongArray(key, valueLongArray);
1545 break;
1546 }
1547 case STRING: {
1548 String value = null;
1549 if (valueList.size() > 0) {
1550 value = valueList.get(0);
1551 }
1552 bundle.putString(key, value);
1553 break;
1554 }
1555 case STRING_ARRAY: {
1556 String[] valueStringArray = null;
1557 if (valueList.size() > 0) {
1558 valueStringArray = new String[valueList.size()];
1559 valueList.toArray(valueStringArray);
1560 }
1561 bundle.putStringArray(key, valueStringArray);
1562 break;
1563 }
1564 }
1565 return bundle;
1566 }
Shuo Qian489d9282020-07-09 11:30:03 -07001567
1568 private int handleEndBlockSuppressionCommand() {
1569 if (!checkShellUid()) {
1570 return -1;
1571 }
1572
1573 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1574 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1575 }
1576 return 0;
1577 }
Hui Wang0866fcc2020-10-12 12:14:23 -07001578
Michele Berionne38c1afa2020-12-28 20:23:16 +00001579 private int handleRestartModemCommand() {
1580 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1581 // non user build.
1582 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1583 getErrPrintWriter().println("RestartModem: Permission denied.");
1584 return -1;
1585 }
1586
1587 boolean result = TelephonyManager.getDefault().rebootRadio();
1588 getOutPrintWriter().println(result);
1589
1590 return result ? 0 : -1;
1591 }
1592
Michele Berionned9fbae52020-11-13 02:36:59 +00001593 private int handleUnattendedReboot() {
1594 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1595 // non user build.
1596 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1597 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
1598 return -1;
1599 }
1600
1601 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
1602 getOutPrintWriter().println("result: " + result);
1603
1604 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
1605 }
1606
Hui Wang0866fcc2020-10-12 12:14:23 -07001607 private int handleGbaCommand() {
1608 String arg = getNextArg();
1609 if (arg == null) {
1610 onHelpGba();
1611 return 0;
1612 }
1613
1614 switch (arg) {
1615 case GBA_SET_SERVICE: {
1616 return handleGbaSetServiceCommand();
1617 }
1618 case GBA_GET_SERVICE: {
1619 return handleGbaGetServiceCommand();
1620 }
1621 case GBA_SET_RELEASE_TIME: {
1622 return handleGbaSetReleaseCommand();
1623 }
1624 case GBA_GET_RELEASE_TIME: {
1625 return handleGbaGetReleaseCommand();
1626 }
1627 }
1628
1629 return -1;
1630 }
1631
1632 private int getSubId(String cmd) {
1633 int slotId = getDefaultSlot();
1634 String opt = getNextOption();
1635 if (opt != null && opt.equals("-s")) {
1636 try {
1637 slotId = Integer.parseInt(getNextArgRequired());
1638 } catch (NumberFormatException e) {
1639 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1640 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1641 }
1642 }
1643 int[] subIds = SubscriptionManager.getSubId(slotId);
1644 return subIds[0];
1645 }
1646
1647 private int handleGbaSetServiceCommand() {
1648 int subId = getSubId("gba set-service");
1649 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1650 return -1;
1651 }
1652
1653 String packageName = getNextArg();
1654 try {
1655 if (packageName == null) {
1656 packageName = "";
1657 }
1658 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1659 if (VDBG) {
1660 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1661 + packageName + ", result=" + result);
1662 }
1663 getOutPrintWriter().println(result);
1664 } catch (RemoteException e) {
1665 Log.w(LOG_TAG, "gba set-service " + subId + " "
1666 + packageName + ", error" + e.getMessage());
1667 getErrPrintWriter().println("Exception: " + e.getMessage());
1668 return -1;
1669 }
1670 return 0;
1671 }
1672
1673 private int handleGbaGetServiceCommand() {
1674 String result;
1675
1676 int subId = getSubId("gba get-service");
1677 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1678 return -1;
1679 }
1680
1681 try {
1682 result = mInterface.getBoundGbaService(subId);
1683 } catch (RemoteException e) {
1684 return -1;
1685 }
1686 if (VDBG) {
1687 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1688 }
1689 getOutPrintWriter().println(result);
1690 return 0;
1691 }
1692
1693 private int handleGbaSetReleaseCommand() {
1694 //the release time value could be -1
1695 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1696 : SubscriptionManager.getDefaultSubscriptionId();
1697 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1698 return -1;
1699 }
1700
1701 String intervalStr = getNextArg();
1702 if (intervalStr == null) {
1703 return -1;
1704 }
1705
1706 try {
1707 int interval = Integer.parseInt(intervalStr);
1708 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1709 if (VDBG) {
1710 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1711 + intervalStr + ", result=" + result);
1712 }
1713 getOutPrintWriter().println(result);
1714 } catch (NumberFormatException | RemoteException e) {
1715 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1716 + intervalStr + ", error" + e.getMessage());
1717 getErrPrintWriter().println("Exception: " + e.getMessage());
1718 return -1;
1719 }
1720 return 0;
1721 }
1722
1723 private int handleGbaGetReleaseCommand() {
1724 int subId = getSubId("gba get-release");
1725 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1726 return -1;
1727 }
1728
1729 int result = 0;
1730 try {
1731 result = mInterface.getGbaReleaseTime(subId);
1732 } catch (RemoteException e) {
1733 return -1;
1734 }
1735 if (VDBG) {
1736 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1737 }
1738 getOutPrintWriter().println(result);
1739 return 0;
1740 }
Hui Wang068ab862020-10-31 05:12:53 +00001741
1742 private int handleSingleRegistrationConfigCommand() {
1743 String arg = getNextArg();
1744 if (arg == null) {
1745 onHelpSrc();
1746 return 0;
1747 }
1748
1749 switch (arg) {
Hui Wang19a21872021-02-19 20:45:36 -08001750 case SRC_SET_TEST_ENABLED: {
1751 return handleSrcSetTestEnabledCommand();
1752 }
1753 case SRC_GET_TEST_ENABLED: {
1754 return handleSrcGetTestEnabledCommand();
1755 }
Hui Wang068ab862020-10-31 05:12:53 +00001756 case SRC_SET_DEVICE_ENABLED: {
1757 return handleSrcSetDeviceEnabledCommand();
1758 }
1759 case SRC_GET_DEVICE_ENABLED: {
1760 return handleSrcGetDeviceEnabledCommand();
1761 }
1762 case SRC_SET_CARRIER_ENABLED: {
1763 return handleSrcSetCarrierEnabledCommand();
1764 }
1765 case SRC_GET_CARRIER_ENABLED: {
1766 return handleSrcGetCarrierEnabledCommand();
1767 }
1768 }
1769
1770 return -1;
1771 }
1772
James.cf Linbcdf8b32021-01-14 16:44:13 +08001773 private int handleRcsUceCommand() {
1774 String arg = getNextArg();
1775 if (arg == null) {
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001776 onHelpUce();
1777 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001778 }
1779
1780 switch (arg) {
1781 case UCE_REMOVE_EAB_CONTACT:
1782 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08001783 case UCE_GET_EAB_CONTACT:
1784 return handleGettingEabContactCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08001785 case UCE_GET_DEVICE_ENABLED:
1786 return handleUceGetDeviceEnabledCommand();
1787 case UCE_SET_DEVICE_ENABLED:
1788 return handleUceSetDeviceEnabledCommand();
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001789 case UCE_OVERRIDE_PUBLISH_CAPS:
1790 return handleUceOverridePublishCaps();
1791 case UCE_GET_LAST_PIDF_XML:
1792 return handleUceGetPidfXml();
James.cf Linbcdf8b32021-01-14 16:44:13 +08001793 }
1794 return -1;
1795 }
1796
1797 private int handleRemovingEabContactCommand() {
1798 int subId = getSubId("uce remove-eab-contact");
1799 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1800 return -1;
1801 }
1802
1803 String phoneNumber = getNextArgRequired();
1804 if (TextUtils.isEmpty(phoneNumber)) {
1805 return -1;
1806 }
1807 int result = 0;
1808 try {
1809 result = mInterface.removeContactFromEab(subId, phoneNumber);
1810 } catch (RemoteException e) {
1811 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
1812 getErrPrintWriter().println("Exception: " + e.getMessage());
1813 return -1;
1814 }
1815
1816 if (VDBG) {
1817 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
1818 }
calvinpan293ea1b2021-02-04 17:52:13 +08001819 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001820 }
1821
calvinpane4a8a1d2021-01-25 13:51:18 +08001822 private int handleGettingEabContactCommand() {
1823 String phoneNumber = getNextArgRequired();
1824 if (TextUtils.isEmpty(phoneNumber)) {
1825 return -1;
1826 }
1827 String result = "";
1828 try {
1829 result = mInterface.getContactFromEab(phoneNumber);
1830
1831 } catch (RemoteException e) {
1832 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
1833 getErrPrintWriter().println("Exception: " + e.getMessage());
1834 return -1;
1835 }
1836
1837 if (VDBG) {
1838 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
1839 }
calvinpan293ea1b2021-02-04 17:52:13 +08001840 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08001841 return 0;
1842 }
1843
1844 private int handleUceGetDeviceEnabledCommand() {
1845 boolean result = false;
1846 try {
1847 result = mInterface.getDeviceUceEnabled();
1848 } catch (RemoteException e) {
1849 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
1850 return -1;
1851 }
1852 if (VDBG) {
1853 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
1854 }
calvinpane4a8a1d2021-01-25 13:51:18 +08001855 getOutPrintWriter().println(result);
1856 return 0;
1857 }
1858
James.cf Lin4b784aa2021-01-31 03:25:15 +08001859 private int handleUceSetDeviceEnabledCommand() {
1860 String enabledStr = getNextArg();
1861 if (TextUtils.isEmpty(enabledStr)) {
1862 return -1;
1863 }
1864
1865 try {
1866 boolean isEnabled = Boolean.parseBoolean(enabledStr);
1867 mInterface.setDeviceUceEnabled(isEnabled);
1868 if (VDBG) {
1869 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
1870 }
1871 } catch (NumberFormatException | RemoteException e) {
1872 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
1873 getErrPrintWriter().println("Exception: " + e.getMessage());
1874 return -1;
1875 }
1876 return 0;
1877 }
1878
Hui Wang19a21872021-02-19 20:45:36 -08001879 private int handleSrcSetTestEnabledCommand() {
1880 String enabledStr = getNextArg();
1881 if (enabledStr == null) {
1882 return -1;
1883 }
1884
1885 try {
1886 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
1887 if (VDBG) {
1888 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
1889 }
1890 getOutPrintWriter().println("Done");
1891 } catch (NumberFormatException | RemoteException e) {
1892 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
1893 getErrPrintWriter().println("Exception: " + e.getMessage());
1894 return -1;
1895 }
1896 return 0;
1897 }
1898
1899 private int handleSrcGetTestEnabledCommand() {
1900 boolean result = false;
1901 try {
1902 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
1903 } catch (RemoteException e) {
1904 return -1;
1905 }
1906 if (VDBG) {
1907 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
1908 }
1909 getOutPrintWriter().println(result);
1910 return 0;
1911 }
1912
Brad Ebingerd4c5bde2021-02-12 06:18:28 +00001913 private int handleUceOverridePublishCaps() {
1914 int subId = getSubId("uce override-published-caps");
1915 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1916 return -1;
1917 }
1918 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
1919 String operation = getNextArgRequired();
1920 String caps = getNextArg();
1921 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
1922 && !"list".equals(operation)) {
1923 getErrPrintWriter().println("Invalid operation: " + operation);
1924 return -1;
1925 }
1926
1927 // add/remove requires capabilities to be specified.
1928 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
1929 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
1930 + "specified");
1931 return -1;
1932 }
1933
1934 ArraySet<String> capSet = new ArraySet<>();
1935 if (!TextUtils.isEmpty(caps)) {
1936 String[] capArray = caps.split(":");
1937 for (String cap : capArray) {
1938 // Allow unknown tags to be passed in as well.
1939 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
1940 }
1941 }
1942
1943 RcsContactUceCapability result = null;
1944 try {
1945 switch (operation) {
1946 case "add":
1947 result = mInterface.addUceRegistrationOverrideShell(subId,
1948 new ArrayList<>(capSet));
1949 break;
1950 case "remove":
1951 result = mInterface.removeUceRegistrationOverrideShell(subId,
1952 new ArrayList<>(capSet));
1953 break;
1954 case "clear":
1955 result = mInterface.clearUceRegistrationOverrideShell(subId);
1956 break;
1957 case "list":
1958 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
1959 break;
1960 }
1961 } catch (RemoteException e) {
1962 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
1963 getErrPrintWriter().println("Exception: " + e.getMessage());
1964 return -1;
1965 } catch (ServiceSpecificException sse) {
1966 // Reconstruct ImsException
1967 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
1968 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
1969 getErrPrintWriter().println("Exception: " + imsException);
1970 return -1;
1971 }
1972 if (result == null) {
1973 getErrPrintWriter().println("Service not available");
1974 return -1;
1975 }
1976 getOutPrintWriter().println(result);
1977 return 0;
1978 }
1979
1980 private int handleUceGetPidfXml() {
1981 int subId = getSubId("uce get-last-publish-pidf");
1982 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1983 return -1;
1984 }
1985
1986 String result;
1987 try {
1988 result = mInterface.getLastUcePidfXmlShell(subId);
1989 } catch (RemoteException e) {
1990 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
1991 getErrPrintWriter().println("Exception: " + e.getMessage());
1992 return -1;
1993 } catch (ServiceSpecificException sse) {
1994 // Reconstruct ImsException
1995 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
1996 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
1997 getErrPrintWriter().println("Exception: " + imsException);
1998 return -1;
1999 }
2000 if (result == null) {
2001 getErrPrintWriter().println("Service not available");
2002 return -1;
2003 }
2004 getOutPrintWriter().println(result);
2005 return 0;
2006 }
2007
Hui Wang068ab862020-10-31 05:12:53 +00002008 private int handleSrcSetDeviceEnabledCommand() {
2009 String enabledStr = getNextArg();
2010 if (enabledStr == null) {
2011 return -1;
2012 }
2013
2014 try {
2015 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2016 if (VDBG) {
2017 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2018 }
2019 getOutPrintWriter().println("Done");
2020 } catch (NumberFormatException | RemoteException e) {
2021 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2022 getErrPrintWriter().println("Exception: " + e.getMessage());
2023 return -1;
2024 }
2025 return 0;
2026 }
2027
2028 private int handleSrcGetDeviceEnabledCommand() {
2029 boolean result = false;
2030 try {
2031 result = mInterface.getDeviceSingleRegistrationEnabled();
2032 } catch (RemoteException e) {
2033 return -1;
2034 }
2035 if (VDBG) {
2036 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2037 }
2038 getOutPrintWriter().println(result);
2039 return 0;
2040 }
2041
2042 private int handleSrcSetCarrierEnabledCommand() {
2043 //the release time value could be -1
2044 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2045 : SubscriptionManager.getDefaultSubscriptionId();
2046 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2047 return -1;
2048 }
2049
2050 String enabledStr = getNextArg();
2051 if (enabledStr == null) {
2052 return -1;
2053 }
2054
2055 try {
2056 boolean result =
2057 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2058 if (VDBG) {
2059 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2060 + enabledStr + ", result=" + result);
2061 }
2062 getOutPrintWriter().println(result);
2063 } catch (NumberFormatException | RemoteException e) {
2064 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2065 + enabledStr + ", error" + e.getMessage());
2066 getErrPrintWriter().println("Exception: " + e.getMessage());
2067 return -1;
2068 }
2069 return 0;
2070 }
2071
2072 private int handleSrcGetCarrierEnabledCommand() {
2073 int subId = getSubId("src get-carrier-enabled");
2074 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2075 return -1;
2076 }
2077
2078 boolean result = false;
2079 try {
2080 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2081 } catch (RemoteException e) {
2082 return -1;
2083 }
2084 if (VDBG) {
2085 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2086 }
2087 getOutPrintWriter().println(result);
2088 return 0;
2089 }
Hunter Knepshield18d0a6b2021-03-02 13:07:53 -08002090
2091 private int handleHasCarrierPrivilegesCommand() {
2092 String packageName = getNextArgRequired();
2093
2094 boolean hasCarrierPrivileges;
2095 try {
2096 hasCarrierPrivileges =
2097 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2098 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2099 } catch (RemoteException e) {
2100 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2101 getErrPrintWriter().println("Exception: " + e.getMessage());
2102 return -1;
2103 }
2104
2105 getOutPrintWriter().println(hasCarrierPrivileges);
2106 return 0;
2107 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07002108}