1 /* 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 17 package com.android.phone; 18 19 import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC; 20 import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE; 21 import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE; 22 import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE; 23 24 import static java.util.Map.entry; 25 26 import android.Manifest; 27 import android.annotation.NonNull; 28 import android.annotation.Nullable; 29 import android.content.ComponentName; 30 import android.content.Context; 31 import android.net.Uri; 32 import android.os.Binder; 33 import android.os.PersistableBundle; 34 import android.os.Process; 35 import android.os.RemoteException; 36 import android.os.ServiceSpecificException; 37 import android.provider.BlockedNumberContract; 38 import android.telephony.BarringInfo; 39 import android.telephony.CarrierConfigManager; 40 import android.telephony.SubscriptionInfo; 41 import android.telephony.SubscriptionManager; 42 import android.telephony.TelephonyManager; 43 import android.telephony.TelephonyRegistryManager; 44 import android.telephony.emergency.EmergencyNumber; 45 import android.telephony.ims.ImsException; 46 import android.telephony.ims.RcsContactUceCapability; 47 import android.telephony.ims.feature.ImsFeature; 48 import android.text.TextUtils; 49 import android.util.ArrayMap; 50 import android.util.ArraySet; 51 import android.util.Log; 52 import android.util.SparseArray; 53 54 import com.android.ims.rcs.uce.util.FeatureTags; 55 import com.android.internal.telephony.ITelephony; 56 import com.android.internal.telephony.Phone; 57 import com.android.internal.telephony.PhoneFactory; 58 import com.android.internal.telephony.d2d.Communicator; 59 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 60 import com.android.internal.telephony.util.TelephonyUtils; 61 import com.android.modules.utils.BasicShellCommandHandler; 62 import com.android.phone.callcomposer.CallComposerPictureManager; 63 import com.android.phone.euicc.EuiccUiDispatcherActivity; 64 import com.android.phone.utils.CarrierAllowListInfo; 65 66 import java.io.IOException; 67 import java.io.PrintWriter; 68 import java.util.ArrayList; 69 import java.util.Arrays; 70 import java.util.Collections; 71 import java.util.HashMap; 72 import java.util.List; 73 import java.util.Locale; 74 import java.util.Map; 75 import java.util.Set; 76 import java.util.TreeSet; 77 import java.util.UUID; 78 import java.util.concurrent.CompletableFuture; 79 80 /** 81 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no 82 * permission checks have been done before onCommand was called. Make sure any commands processed 83 * here also contain the appropriate permissions checks. 84 */ 85 86 public class TelephonyShellCommand extends BasicShellCommandHandler { 87 88 private static final String LOG_TAG = "TelephonyShellCommand"; 89 // Don't commit with this true. 90 private static final boolean VDBG = true; 91 private static final int DEFAULT_PHONE_ID = 0; 92 93 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer"; 94 private static final String IMS_SUBCOMMAND = "ims"; 95 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify"; 96 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode"; 97 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode"; 98 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression"; 99 private static final String RESTART_MODEM = "restart-modem"; 100 private static final String UNATTENDED_REBOOT = "unattended-reboot"; 101 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc"; 102 private static final String DATA_TEST_MODE = "data"; 103 private static final String ENABLE = "enable"; 104 private static final String DISABLE = "disable"; 105 private static final String QUERY = "query"; 106 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test"; 107 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE = 108 "set-carrier-service-package-override"; 109 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE = 110 "clear-carrier-service-package-override"; 111 private final String QUOTES = "\""; 112 113 private static final String CALL_COMPOSER_TEST_MODE = "test-mode"; 114 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call"; 115 private static final String CALL_COMPOSER_USER_SETTING = "user-setting"; 116 117 private static final String IMS_SET_IMS_SERVICE = "set-ims-service"; 118 private static final String IMS_GET_IMS_SERVICE = "get-ims-service"; 119 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override"; 120 // Used to disable or enable processing of conference event package data from the network. 121 // This is handy for testing scenarios where CEP data does not exist on a network which does 122 // support CEP data. 123 private static final String IMS_CEP = "conference-event-package"; 124 125 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package"; 126 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call"; 127 128 private static final String CC_GET_VALUE = "get-value"; 129 private static final String CC_SET_VALUE = "set-value"; 130 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml"; 131 private static final String CC_CLEAR_VALUES = "clear-values"; 132 133 private static final String EUICC_SUBCOMMAND = "euicc"; 134 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent"; 135 136 private static final String GBA_SUBCOMMAND = "gba"; 137 private static final String GBA_SET_SERVICE = "set-service"; 138 private static final String GBA_GET_SERVICE = "get-service"; 139 private static final String GBA_SET_RELEASE_TIME = "set-release"; 140 private static final String GBA_GET_RELEASE_TIME = "get-release"; 141 142 private static final String SINGLE_REGISTATION_CONFIG = "src"; 143 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled"; 144 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled"; 145 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled"; 146 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled"; 147 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled"; 148 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled"; 149 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation"; 150 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation"; 151 152 private static final String D2D_SUBCOMMAND = "d2d"; 153 private static final String D2D_SEND = "send"; 154 private static final String D2D_TRANSPORT = "transport"; 155 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support"; 156 157 private static final String BARRING_SUBCOMMAND = "barring"; 158 private static final String BARRING_SEND_INFO = "send"; 159 160 private static final String RCS_UCE_COMMAND = "uce"; 161 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact"; 162 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability"; 163 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact"; 164 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled"; 165 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled"; 166 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps"; 167 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf"; 168 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS = 169 "remove-request-disallowed-status"; 170 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT = 171 "set-capabilities-request-timeout"; 172 173 private static final String RADIO_SUBCOMMAND = "radio"; 174 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service"; 175 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service"; 176 177 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId. 178 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges"; 179 180 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription"; 181 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription"; 182 183 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation"; 184 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package"; 185 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package"; 186 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME = 187 "set-satellite-service-package-name"; 188 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME = 189 "set-satellite-gateway-service-package-name"; 190 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION = 191 "set-satellite-listening-timeout-duration"; 192 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME = 193 "set-satellite-pointing-ui-class-name"; 194 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION = 195 "set-datagram-controller-timeout-duration"; 196 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG = 197 "set-datagram-controller-boolean-config"; 198 199 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION = 200 "set-satellite-controller-timeout-duration"; 201 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE = 202 "set-emergency-call-to-satellite-handover-type"; 203 private static final String SET_COUNTRY_CODES = "set-country-codes"; 204 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS = 205 "set-satellite-access-control-overlay-configs"; 206 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS = 207 "set-oem-enabled-satellite-provision-status"; 208 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE = 209 "set-should-send-datagram-to-modem-in-demo-mode"; 210 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE = 211 "set-is-satellite-communication-allowed-for-current-location-cache"; 212 213 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection"; 214 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override"; 215 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override"; 216 217 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', " 218 + "'*', '#' or '+') needs to be specified after -a in the command "; 219 220 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN, 221 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY, 222 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL}; 223 224 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER = 225 "get-allowed-network-types-for-users"; 226 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER = 227 "set-allowed-network-types-for-users"; 228 private static final String GET_IMEI = "get-imei"; 229 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping"; 230 // Take advantage of existing methods that already contain permissions checks when possible. 231 private final ITelephony mInterface; 232 233 private SubscriptionManager mSubscriptionManager; 234 private CarrierConfigManager mCarrierConfigManager; 235 private TelephonyRegistryManager mTelephonyRegistryManager; 236 private Context mContext; 237 238 private enum CcType { 239 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING, 240 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN 241 } 242 243 private class CcOptionParseResult { 244 public int mSubId; 245 public boolean mPersistent; 246 } 247 248 // Maps carrier config keys to type. It is possible to infer the type for most carrier config 249 // keys by looking at the end of the string which usually tells the type. 250 // For instance: "xxxx_string", "xxxx_string_array", etc. 251 // The carrier config keys in this map does not follow this convention. It is therefore not 252 // possible to infer the type for these keys by looking at the string. 253 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries( 254 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, 255 CcType.STRING), 256 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING), 257 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING), 258 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING), 259 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING), 260 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING), 261 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING), 262 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING), 263 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING), 264 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING), 265 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING, 266 CcType.STRING), 267 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, 268 CcType.STRING_ARRAY), 269 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY, 270 CcType.STRING_ARRAY), 271 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING), 272 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING), 273 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING), 274 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING), 275 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING), 276 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING), 277 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING), 278 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY)); 279 280 /** 281 * Map from a shorthand string to the feature tags required in registration required in order 282 * for the RCS feature to be considered "capable". 283 */ 284 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP; 285 static { 286 ArrayMap<String, Set<String>> map = new ArrayMap<>(18); 287 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM)); 288 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION)); 289 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER)); 290 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS)); 291 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL)); 292 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL, 293 FeatureTags.FEATURE_TAG_VIDEO))); 294 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH)); 295 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS)); 296 map.put("call_comp", 297 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING)); 298 map.put("call_comp_mmtel", 299 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY)); 300 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL)); 301 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP)); 302 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH)); 303 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot 304 // version 305 map.put("chatbot", new ArraySet<>(Arrays.asList( 306 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION, 307 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED))); 308 map.put("chatbot_v2", new ArraySet<>(Arrays.asList( 309 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION, 310 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED))); 311 map.put("chatbot_sa", new ArraySet<>(Arrays.asList( 312 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG, 313 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED))); 314 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList( 315 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG, 316 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED))); 317 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE)); 318 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map); 319 } 320 321 TelephonyShellCommand(ITelephony binder, Context context)322 public TelephonyShellCommand(ITelephony binder, Context context) { 323 mInterface = binder; 324 mCarrierConfigManager = 325 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); 326 mSubscriptionManager = (SubscriptionManager) 327 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 328 mTelephonyRegistryManager = (TelephonyRegistryManager) 329 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 330 mContext = context; 331 } 332 333 @Override onCommand(String cmd)334 public int onCommand(String cmd) { 335 if (cmd == null) { 336 return handleDefaultCommands(null); 337 } 338 339 switch (cmd) { 340 case IMS_SUBCOMMAND: { 341 return handleImsCommand(); 342 } 343 case RCS_UCE_COMMAND: 344 return handleRcsUceCommand(); 345 case NUMBER_VERIFICATION_SUBCOMMAND: 346 return handleNumberVerificationCommand(); 347 case EMERGENCY_CALLBACK_MODE: 348 return handleEmergencyCallbackModeCommand(); 349 case EMERGENCY_NUMBER_TEST_MODE: 350 return handleEmergencyNumberTestModeCommand(); 351 case CARRIER_CONFIG_SUBCOMMAND: { 352 return handleCcCommand(); 353 } 354 case DATA_TEST_MODE: 355 return handleDataTestModeCommand(); 356 case END_BLOCK_SUPPRESSION: 357 return handleEndBlockSuppressionCommand(); 358 case EUICC_SUBCOMMAND: 359 return handleEuiccCommand(); 360 case GBA_SUBCOMMAND: 361 return handleGbaCommand(); 362 case D2D_SUBCOMMAND: 363 return handleD2dCommand(); 364 case BARRING_SUBCOMMAND: 365 return handleBarringCommand(); 366 case SINGLE_REGISTATION_CONFIG: 367 return handleSingleRegistrationConfigCommand(); 368 case RESTART_MODEM: 369 return handleRestartModemCommand(); 370 case CALL_COMPOSER_SUBCOMMAND: 371 return handleCallComposerCommand(); 372 case UNATTENDED_REBOOT: 373 return handleUnattendedReboot(); 374 case HAS_CARRIER_PRIVILEGES_COMMAND: 375 return handleHasCarrierPrivilegesCommand(); 376 case THERMAL_MITIGATION_COMMAND: 377 return handleThermalMitigationCommand(); 378 case DISABLE_PHYSICAL_SUBSCRIPTION: 379 return handleEnablePhysicalSubscription(false); 380 case ENABLE_PHYSICAL_SUBSCRIPTION: 381 return handleEnablePhysicalSubscription(true); 382 case GET_ALLOWED_NETWORK_TYPES_FOR_USER: 383 case SET_ALLOWED_NETWORK_TYPES_FOR_USER: 384 return handleAllowedNetworkTypesCommand(cmd); 385 case GET_IMEI: 386 return handleGetImei(); 387 case GET_SIM_SLOTS_MAPPING: 388 return handleGetSimSlotsMapping(); 389 case RADIO_SUBCOMMAND: 390 return handleRadioCommand(); 391 case CARRIER_RESTRICTION_STATUS_TEST: 392 return handleCarrierRestrictionStatusCommand(); 393 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE: 394 return setCarrierServicePackageOverride(); 395 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE: 396 return clearCarrierServicePackageOverride(); 397 case DOMAIN_SELECTION_SUBCOMMAND: 398 return handleDomainSelectionCommand(); 399 case SET_SATELLITE_SERVICE_PACKAGE_NAME: 400 return handleSetSatelliteServicePackageNameCommand(); 401 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME: 402 return handleSetSatelliteGatewayServicePackageNameCommand(); 403 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION: 404 return handleSetSatelliteListeningTimeoutDuration(); 405 case SET_SATELLITE_POINTING_UI_CLASS_NAME: 406 return handleSetSatellitePointingUiClassNameCommand(); 407 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION: 408 return handleSetDatagramControllerTimeoutDuration(); 409 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG: 410 return handleSetDatagramControllerBooleanConfig(); 411 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION: 412 return handleSetSatelliteControllerTimeoutDuration(); 413 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE: 414 return handleSetEmergencyCallToSatelliteHandoverType(); 415 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE: 416 return handleSetShouldSendDatagramToModemInDemoMode(); 417 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS: 418 return handleSetSatelliteAccessControlOverlayConfigs(); 419 case SET_COUNTRY_CODES: 420 return handleSetCountryCodes(); 421 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS: 422 return handleSetOemEnabledSatelliteProvisionStatus(); 423 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE: 424 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache(); 425 default: { 426 return handleDefaultCommands(cmd); 427 } 428 } 429 } 430 431 @Override onHelp()432 public void onHelp() { 433 PrintWriter pw = getOutPrintWriter(); 434 pw.println("Telephony Commands:"); 435 pw.println(" help"); 436 pw.println(" Print this help text."); 437 pw.println(" ims"); 438 pw.println(" IMS Commands."); 439 pw.println(" uce"); 440 pw.println(" RCS User Capability Exchange Commands."); 441 pw.println(" emergency-number-test-mode"); 442 pw.println(" Emergency Number Test Mode Commands."); 443 pw.println(" end-block-suppression"); 444 pw.println(" End Block Suppression command."); 445 pw.println(" data"); 446 pw.println(" Data Test Mode Commands."); 447 pw.println(" cc"); 448 pw.println(" Carrier Config Commands."); 449 pw.println(" gba"); 450 pw.println(" GBA Commands."); 451 pw.println(" src"); 452 pw.println(" RCS VoLTE Single Registration Config Commands."); 453 pw.println(" restart-modem"); 454 pw.println(" Restart modem command."); 455 pw.println(" unattended-reboot"); 456 pw.println(" Prepare for unattended reboot."); 457 pw.println(" has-carrier-privileges [package]"); 458 pw.println(" Query carrier privilege status for a package. Prints true or false."); 459 pw.println(" get-allowed-network-types-for-users"); 460 pw.println(" Get the Allowed Network Types."); 461 pw.println(" set-allowed-network-types-for-users"); 462 pw.println(" Set the Allowed Network Types."); 463 pw.println(" radio"); 464 pw.println(" Radio Commands."); 465 onHelpIms(); 466 onHelpUce(); 467 onHelpEmergencyNumber(); 468 onHelpEndBlockSupperssion(); 469 onHelpDataTestMode(); 470 onHelpCc(); 471 onHelpGba(); 472 onHelpSrc(); 473 onHelpD2D(); 474 onHelpDisableOrEnablePhysicalSubscription(); 475 onHelpAllowedNetworkTypes(); 476 onHelpRadio(); 477 onHelpImei(); 478 onHelpSatellite(); 479 onHelpDomainSelection(); 480 } 481 onHelpD2D()482 private void onHelpD2D() { 483 PrintWriter pw = getOutPrintWriter(); 484 pw.println("D2D Comms Commands:"); 485 pw.println(" d2d send TYPE VALUE"); 486 pw.println(" Sends a D2D message of specified type and value."); 487 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - " 488 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE)); 489 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString( 490 MESSAGE_CALL_AUDIO_CODEC)); 491 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - " 492 + Communicator.messageToString( 493 MESSAGE_DEVICE_BATTERY_STATE)); 494 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - " 495 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE)); 496 pw.println(" d2d transport TYPE"); 497 pw.println(" Forces the specified D2D transport TYPE to be active. Use the"); 498 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport."); 499 pw.println(" d2d set-device-support true/default"); 500 pw.println(" true - forces device support to be enabled for D2D."); 501 pw.println(" default - clear any previously set force-enable of D2D, reverting to "); 502 pw.println(" the current device's configuration."); 503 } 504 onHelpBarring()505 private void onHelpBarring() { 506 PrintWriter pw = getOutPrintWriter(); 507 pw.println("Barring Commands:"); 508 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED" 509 + " -t CONDITIONAL_BARRING_TIME_SECS"); 510 pw.println(" Notifies of a barring info change for the specified slot id."); 511 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE"); 512 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL"); 513 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL"); 514 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN"); 515 } 516 onHelpIms()517 private void onHelpIms() { 518 PrintWriter pw = getOutPrintWriter(); 519 pw.println("IMS Commands:"); 520 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME"); 521 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound"); 522 pw.println(" ImsService. Options are:"); 523 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option"); 524 pw.println(" is specified, it will choose the default voice SIM slot."); 525 pw.println(" -c: Override the ImsService defined in the carrier configuration."); 526 pw.println(" -d: Override the ImsService defined in the device overlay."); 527 pw.println(" -f: Set the feature that this override if for, if no option is"); 528 pw.println(" specified, the new package name will be used for all features."); 529 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]"); 530 pw.println(" Gets the package name of the currently defined ImsService."); 531 pw.println(" Options are:"); 532 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option"); 533 pw.println(" is specified, it will choose the default voice SIM slot."); 534 pw.println(" -c: The ImsService defined as the carrier configured ImsService."); 535 pw.println(" -d: The ImsService defined as the device default ImsService."); 536 pw.println(" -f: The feature type that the query will be requested for. If none is"); 537 pw.println(" specified, the returned package name will correspond to MMTEL."); 538 pw.println(" ims clear-ims-service-override [-s SLOT_ID]"); 539 pw.println(" Clear all carrier ImsService overrides. This does not work for device "); 540 pw.println(" configuration overrides. Options are:"); 541 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option"); 542 pw.println(" is specified, it will choose the default voice SIM slot."); 543 pw.println(" ims enable [-s SLOT_ID]"); 544 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot"); 545 pw.println(" if none is specified."); 546 pw.println(" ims disable [-s SLOT_ID]"); 547 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM"); 548 pw.println(" slot if none is specified."); 549 pw.println(" ims conference-event-package [enable/disable]"); 550 pw.println(" enables or disables handling or network conference event package data."); 551 } 552 onHelpUce()553 private void onHelpUce() { 554 PrintWriter pw = getOutPrintWriter(); 555 pw.println("User Capability Exchange Commands:"); 556 pw.println(" uce get-eab-contact [PHONE_NUMBER]"); 557 pw.println(" Get the EAB contacts from the EAB database."); 558 pw.println(" Options are:"); 559 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases"); 560 pw.println(" Expected output format :"); 561 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]"); 562 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]"); 563 pw.println(" Remove the EAB contacts from the EAB database."); 564 pw.println(" Options are:"); 565 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 566 pw.println(" is specified, it will choose the default voice SIM slot."); 567 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases"); 568 pw.println(" uce get-device-enabled"); 569 pw.println(" Get the config to check whether the device supports RCS UCE or not."); 570 pw.println(" uce set-device-enabled true|false"); 571 pw.println(" Set the device config for RCS User Capability Exchange to the value."); 572 pw.println(" The value could be true, false."); 573 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]"); 574 pw.println(" Override the existing SIP PUBLISH with different capabilities."); 575 pw.println(" Options are:"); 576 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 577 pw.println(" is specified, it will choose the default voice SIM slot."); 578 pw.println(" add [CAPABILITY]: add a new capability"); 579 pw.println(" remove [CAPABILITY]: remove a capability"); 580 pw.println(" clear: clear all capability overrides"); 581 pw.println(" CAPABILITY: \":\" separated list of capabilities."); 582 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,"); 583 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,"); 584 pw.println(" chatbot_sa, chatbot_role] as well as full length"); 585 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here."); 586 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]"); 587 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no "); 588 pw.println(" PUBLISH is active"); 589 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]"); 590 pw.println(" Remove the UCE is disallowed to execute UCE requests status"); 591 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]"); 592 pw.println(" Set the timeout for contact capabilities request."); 593 } 594 onHelpNumberVerification()595 private void onHelpNumberVerification() { 596 PrintWriter pw = getOutPrintWriter(); 597 pw.println("Number verification commands"); 598 pw.println(" numverify override-package PACKAGE_NAME;"); 599 pw.println(" Set the authorized package for number verification."); 600 pw.println(" Leave the package name blank to reset."); 601 pw.println(" numverify fake-call NUMBER;"); 602 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be"); 603 pw.println(" 1 if the call would have been intercepted, 0 otherwise."); 604 } 605 onHelpThermalMitigation()606 private void onHelpThermalMitigation() { 607 PrintWriter pw = getOutPrintWriter(); 608 pw.println("Thermal mitigation commands"); 609 pw.println(" thermal-mitigation allow-package PACKAGE_NAME"); 610 pw.println(" Set the package as one of authorized packages for thermal mitigation."); 611 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME"); 612 pw.println(" Remove the package from one of the authorized packages for thermal " 613 + "mitigation."); 614 } 615 onHelpDisableOrEnablePhysicalSubscription()616 private void onHelpDisableOrEnablePhysicalSubscription() { 617 PrintWriter pw = getOutPrintWriter(); 618 pw.println("Disable or enable a physical subscription"); 619 pw.println(" disable-physical-subscription SUB_ID"); 620 pw.println(" Disable the physical subscription with the provided subId, if allowed."); 621 pw.println(" enable-physical-subscription SUB_ID"); 622 pw.println(" Enable the physical subscription with the provided subId, if allowed."); 623 } 624 onHelpDataTestMode()625 private void onHelpDataTestMode() { 626 PrintWriter pw = getOutPrintWriter(); 627 pw.println("Mobile Data Test Mode Commands:"); 628 pw.println(" data enable: enable mobile data connectivity"); 629 pw.println(" data disable: disable mobile data connectivity"); 630 } 631 onHelpEmergencyNumber()632 private void onHelpEmergencyNumber() { 633 PrintWriter pw = getOutPrintWriter(); 634 pw.println("Emergency Number Test Mode Commands:"); 635 pw.println(" emergency-number-test-mode "); 636 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in" 637 + " the test mode"); 638 pw.println(" -a <emergency number address>: add an emergency number address for the" 639 + " test mode, only allows '0'-'9', '*', '#' or '+'."); 640 pw.println(" -c: clear the emergency number list in the test mode."); 641 pw.println(" -r <emergency number address>: remove an existing emergency number" 642 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'."); 643 pw.println(" -p: get the full emergency number list in the test mode."); 644 } 645 onHelpEndBlockSupperssion()646 private void onHelpEndBlockSupperssion() { 647 PrintWriter pw = getOutPrintWriter(); 648 pw.println("End Block Suppression command:"); 649 pw.println(" end-block-suppression: disable suppressing blocking by contact"); 650 pw.println(" with emergency services."); 651 } 652 onHelpCc()653 private void onHelpCc() { 654 PrintWriter pw = getOutPrintWriter(); 655 pw.println("Carrier Config Commands:"); 656 pw.println(" cc get-value [-s SLOT_ID] [KEY]"); 657 pw.println(" Print carrier config values."); 658 pw.println(" Options are:"); 659 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 660 pw.println(" is specified, it will choose the default voice SIM slot."); 661 pw.println(" KEY: The key to the carrier config value to print. All values are printed"); 662 pw.println(" if KEY is not specified."); 663 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]"); 664 pw.println(" Set carrier config KEY to NEW_VALUE."); 665 pw.println(" Options are:"); 666 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option"); 667 pw.println(" is specified, it will choose the default voice SIM slot."); 668 pw.println(" -p: Value will be stored persistent"); 669 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be"); 670 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with"); 671 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\""); 672 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\""); 673 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH"); 674 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be"); 675 pw.println(" provided through standard input and follow CarrierConfig XML format."); 676 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml"); 677 pw.println(" Options are:"); 678 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option"); 679 pw.println(" is specified, it will choose the default voice SIM slot."); 680 pw.println(" -p: Value will be stored persistent"); 681 pw.println(" cc clear-values [-s SLOT_ID]"); 682 pw.println(" Clear all carrier override values that has previously been set"); 683 pw.println(" with set-value or set-values-from-xml"); 684 pw.println(" Options are:"); 685 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option"); 686 pw.println(" is specified, it will choose the default voice SIM slot."); 687 } 688 onHelpEuicc()689 private void onHelpEuicc() { 690 PrintWriter pw = getOutPrintWriter(); 691 pw.println("Euicc Commands:"); 692 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME"); 693 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions."); 694 pw.println(" COMPONENT_NAME: The component name which handles UI Actions."); 695 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs."); 696 } 697 onHelpGba()698 private void onHelpGba() { 699 PrintWriter pw = getOutPrintWriter(); 700 pw.println("Gba Commands:"); 701 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME"); 702 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound."); 703 pw.println(" Options are:"); 704 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 705 pw.println(" is specified, it will choose the default voice SIM slot."); 706 pw.println(" gba get-service [-s SLOT_ID]"); 707 pw.println(" Gets the package name of the currently defined GbaService."); 708 pw.println(" Options are:"); 709 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 710 pw.println(" is specified, it will choose the default voice SIM slot."); 711 pw.println(" gba set-release [-s SLOT_ID] n"); 712 pw.println(" Sets the time to release/unbind GbaService in n milli-second."); 713 pw.println(" Do not release/unbind if n is -1."); 714 pw.println(" Options are:"); 715 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 716 pw.println(" is specified, it will choose the default voice SIM slot."); 717 pw.println(" gba get-release [-s SLOT_ID]"); 718 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond."); 719 pw.println(" Options are:"); 720 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 721 pw.println(" is specified, it will choose the default voice SIM slot."); 722 } 723 onHelpSrc()724 private void onHelpSrc() { 725 PrintWriter pw = getOutPrintWriter(); 726 pw.println("RCS VoLTE Single Registration Config Commands:"); 727 pw.println(" src set-test-enabled true|false"); 728 pw.println(" Sets the test mode enabled for RCS VoLTE single registration."); 729 pw.println(" The value could be true, false, or null(undefined)."); 730 pw.println(" src get-test-enabled"); 731 pw.println(" Gets the test mode for RCS VoLTE single registration."); 732 pw.println(" src set-device-enabled true|false|null"); 733 pw.println(" Sets the device config for RCS VoLTE single registration to the value."); 734 pw.println(" The value could be true, false, or null(undefined)."); 735 pw.println(" src get-device-enabled"); 736 pw.println(" Gets the device config for RCS VoLTE single registration."); 737 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null"); 738 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value."); 739 pw.println(" The value could be true, false, or null(undefined)."); 740 pw.println(" Options are:"); 741 pw.println(" -s: The SIM slot ID to set the config value for. If no option"); 742 pw.println(" is specified, it will choose the default voice SIM slot."); 743 pw.println(" src get-carrier-enabled [-s SLOT_ID]"); 744 pw.println(" Gets the carrier config for RCS VoLTE single registration."); 745 pw.println(" Options are:"); 746 pw.println(" -s: The SIM slot ID to read the config value for. If no option"); 747 pw.println(" is specified, it will choose the default voice SIM slot."); 748 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null"); 749 pw.println(" Sets ims feature validation result."); 750 pw.println(" The value could be true, false, or null(undefined)."); 751 pw.println(" Options are:"); 752 pw.println(" -s: The SIM slot ID to set the config value for. If no option"); 753 pw.println(" is specified, it will choose the default voice SIM slot."); 754 pw.println(" src get-feature-validation [-s SLOT_ID]"); 755 pw.println(" Gets ims feature validation override value."); 756 pw.println(" Options are:"); 757 pw.println(" -s: The SIM slot ID to read the config value for. If no option"); 758 pw.println(" is specified, it will choose the default voice SIM slot."); 759 } 760 onHelpAllowedNetworkTypes()761 private void onHelpAllowedNetworkTypes() { 762 PrintWriter pw = getOutPrintWriter(); 763 pw.println("Allowed Network Types Commands:"); 764 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]"); 765 pw.println(" Print allowed network types value."); 766 pw.println(" Options are:"); 767 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no"); 768 pw.println(" option is specified, it will choose the default voice SIM slot."); 769 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]"); 770 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK."); 771 pw.println(" Options are:"); 772 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no"); 773 pw.println(" option is specified, it will choose the default voice SIM slot."); 774 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type"); 775 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask"); 776 pw.println(" at TelephonyManager.java"); 777 pw.println(" For example:"); 778 pw.println(" NR only : 10000000000000000000"); 779 pw.println(" NR|LTE : 11000001000000000000"); 780 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111"); 781 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111"); 782 pw.println(" LTE only : 01000001000000000000"); 783 } 784 onHelpRadio()785 private void onHelpRadio() { 786 PrintWriter pw = getOutPrintWriter(); 787 pw.println("Radio Commands:"); 788 pw.println(" radio set-modem-service [-s SERVICE_NAME]"); 789 pw.println(" Sets the class name of modem service defined in SERVICE_NAME"); 790 pw.println(" to be the bound. Options are:"); 791 pw.println(" -s: the service name that the modem service should be bound for."); 792 pw.println(" If no option is specified, it will bind to the default."); 793 pw.println(" radio get-modem-service"); 794 pw.println(" Gets the service name of the currently defined modem service."); 795 pw.println(" If it is binding to default, 'default' returns."); 796 pw.println(" If it doesn't bind to any modem service for some reasons,"); 797 pw.println(" the result would be 'unknown'."); 798 } 799 onHelpSatellite()800 private void onHelpSatellite() { 801 PrintWriter pw = getOutPrintWriter(); 802 pw.println("Satellite Commands:"); 803 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]"); 804 pw.println(" Sets the package name of satellite service defined in"); 805 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:"); 806 pw.println(" -s: the satellite service package name that Telephony will bind to."); 807 pw.println(" If no option is specified, it will bind to the default."); 808 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]"); 809 pw.println(" Sets the package name of satellite gateway service defined in"); 810 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:"); 811 pw.println(" -s: the satellite gateway service package name that Telephony will bind"); 812 pw.println(" to. If no option is specified, it will bind to the default."); 813 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]"); 814 pw.println(" Sets the timeout duration in millis that satellite will stay at listening"); 815 pw.println(" mode. Options are:"); 816 pw.println(" -t: the timeout duration in milliseconds."); 817 pw.println(" If no option is specified, it will use the default values."); 818 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]"); 819 pw.println(" Sets the package and class name of satellite pointing UI app defined in"); 820 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:"); 821 pw.println(" -p: the satellite pointing UI app package name that Telephony will"); 822 pw.println(" launch. If no option is specified, it will launch the default."); 823 pw.println(" -c: the satellite pointing UI app class name that Telephony will"); 824 pw.println(" launch."); 825 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE "); 826 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency "); 827 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer."); 828 pw.println(" Options are:"); 829 pw.println(" -t: the emergency call to satellite handover type."); 830 pw.println(" If no option is specified, override is disabled."); 831 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE."); 832 pw.println(" If no option is specified, there is no delay in sending the event."); 833 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE "); 834 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay"); 835 pw.println(" configs of satellite access controller."); 836 pw.println(" Options are:"); 837 pw.println(" -r: clear the overriding. Absent means enable overriding."); 838 pw.println(" -a: the country codes is an allowed list. Absent means disallowed."); 839 pw.println(" -f: the satellite s2 file."); 840 pw.println(" -d: the location fresh duration nanos."); 841 pw.println(" -c: the list of satellite country codes separated by comma."); 842 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c"); 843 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t"); 844 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] "); 845 pw.println(" Override the cached location country code and its update timestamp. "); 846 pw.println(" Options are:"); 847 pw.println(" -r: clear the overriding. Absent means enable overriding."); 848 pw.println(" -n: the current network country code ISOs."); 849 pw.println(" -c: the cached network country code ISOs."); 850 pw.println(" -l: the location country code ISO."); 851 pw.println(" -t: the update timestamp nanos of the location country code."); 852 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]"); 853 pw.println(" Sets the OEM-enabled satellite provision status. Options are:"); 854 pw.println(" -p: the overriding satellite provision status. If no option is "); 855 pw.println(" specified, reset the overridden provision status."); 856 } 857 onHelpImei()858 private void onHelpImei() { 859 PrintWriter pw = getOutPrintWriter(); 860 pw.println("IMEI Commands:"); 861 pw.println(" get-imei [-s SLOT_ID]"); 862 pw.println(" Gets the device IMEI. Options are:"); 863 pw.println(" -s: the slot ID to get the IMEI. If no option"); 864 pw.println(" is specified, it will choose the default voice SIM slot."); 865 } 866 onHelpDomainSelection()867 private void onHelpDomainSelection() { 868 PrintWriter pw = getOutPrintWriter(); 869 pw.println("Domain Selection Commands:"); 870 pw.println(" domainselection set-dss-override COMPONENT_NAME"); 871 pw.println(" Sets the service defined in COMPONENT_NAME to be bound"); 872 pw.println(" domainselection clear-dss-override"); 873 pw.println(" Clears DomainSelectionService override."); 874 } 875 handleImsCommand()876 private int handleImsCommand() { 877 String arg = getNextArg(); 878 if (arg == null) { 879 onHelpIms(); 880 return 0; 881 } 882 883 switch (arg) { 884 case IMS_SET_IMS_SERVICE: { 885 return handleImsSetServiceCommand(); 886 } 887 case IMS_GET_IMS_SERVICE: { 888 return handleImsGetServiceCommand(); 889 } 890 case IMS_CLEAR_SERVICE_OVERRIDE: { 891 return handleImsClearCarrierServiceCommand(); 892 } 893 case ENABLE: { 894 return handleEnableIms(); 895 } 896 case DISABLE: { 897 return handleDisableIms(); 898 } 899 case IMS_CEP: { 900 return handleCepChange(); 901 } 902 } 903 904 return -1; 905 } 906 handleDataTestModeCommand()907 private int handleDataTestModeCommand() { 908 PrintWriter errPw = getErrPrintWriter(); 909 String arg = getNextArgRequired(); 910 if (arg == null) { 911 onHelpDataTestMode(); 912 return 0; 913 } 914 switch (arg) { 915 case ENABLE: { 916 try { 917 mInterface.enableDataConnectivity(mContext.getOpPackageName()); 918 } catch (RemoteException ex) { 919 Log.w(LOG_TAG, "data enable, error " + ex.getMessage()); 920 errPw.println("Exception: " + ex.getMessage()); 921 return -1; 922 } 923 break; 924 } 925 case DISABLE: { 926 try { 927 mInterface.disableDataConnectivity(mContext.getOpPackageName()); 928 } catch (RemoteException ex) { 929 Log.w(LOG_TAG, "data disable, error " + ex.getMessage()); 930 errPw.println("Exception: " + ex.getMessage()); 931 return -1; 932 } 933 break; 934 } 935 default: 936 onHelpDataTestMode(); 937 break; 938 } 939 return 0; 940 } 941 handleEmergencyCallbackModeCommand()942 private int handleEmergencyCallbackModeCommand() { 943 PrintWriter errPw = getErrPrintWriter(); 944 try { 945 mInterface.startEmergencyCallbackMode(); 946 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered"); 947 } catch (RemoteException ex) { 948 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage()); 949 errPw.println("Exception: " + ex.getMessage()); 950 return -1; 951 } 952 return 0; 953 } 954 removeEmergencyNumberTestMode(String emergencyNumber)955 private void removeEmergencyNumberTestMode(String emergencyNumber) { 956 PrintWriter errPw = getErrPrintWriter(); 957 for (int routingType : ROUTING_TYPES) { 958 try { 959 mInterface.updateEmergencyNumberListTestMode( 960 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE, 961 new EmergencyNumber(emergencyNumber, "", "", 962 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 963 new ArrayList<String>(), 964 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST, 965 routingType)); 966 } catch (RemoteException ex) { 967 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage()); 968 errPw.println("Exception: " + ex.getMessage()); 969 } 970 } 971 } 972 handleEmergencyNumberTestModeCommand()973 private int handleEmergencyNumberTestModeCommand() { 974 PrintWriter errPw = getErrPrintWriter(); 975 String opt = getNextOption(); 976 if (opt == null) { 977 onHelpEmergencyNumber(); 978 return 0; 979 } 980 switch (opt) { 981 case "-a": { 982 String emergencyNumberCmd = getNextArgRequired(); 983 if (emergencyNumberCmd == null){ 984 errPw.println(INVALID_ENTRY_ERROR); 985 return -1; 986 } 987 String[] params = emergencyNumberCmd.split(":"); 988 String emergencyNumber; 989 if (params[0] == null || 990 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){ 991 errPw.println(INVALID_ENTRY_ERROR); 992 return -1; 993 } else { 994 emergencyNumber = params[0]; 995 } 996 removeEmergencyNumberTestMode(emergencyNumber); 997 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN; 998 if (params.length > 1) { 999 switch (params[1].toLowerCase(Locale.ROOT)) { 1000 case "emergency": 1001 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY; 1002 break; 1003 case "normal": 1004 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL; 1005 break; 1006 case "unknown": 1007 break; 1008 default: 1009 errPw.println("\"" + params[1] + "\" is not a valid specification for " 1010 + "emergency call routing. Please enter either \"normal\", " 1011 + "\"unknown\", or \"emergency\" for call routing. " 1012 + "(-a 1234:normal)"); 1013 return -1; 1014 } 1015 } 1016 try { 1017 mInterface.updateEmergencyNumberListTestMode( 1018 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE, 1019 new EmergencyNumber(emergencyNumber, "", "", 1020 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 1021 new ArrayList<String>(), 1022 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST, 1023 emergencyCallRouting)); 1024 } catch (RemoteException ex) { 1025 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber 1026 + ", error " + ex.getMessage()); 1027 errPw.println("Exception: " + ex.getMessage()); 1028 return -1; 1029 } 1030 break; 1031 } 1032 case "-c": { 1033 try { 1034 mInterface.updateEmergencyNumberListTestMode( 1035 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null); 1036 } catch (RemoteException ex) { 1037 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage()); 1038 errPw.println("Exception: " + ex.getMessage()); 1039 return -1; 1040 } 1041 break; 1042 } 1043 case "-r": { 1044 String emergencyNumberCmd = getNextArgRequired(); 1045 if (emergencyNumberCmd == null 1046 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) { 1047 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs" 1048 + " to be specified after -r in the command "); 1049 return -1; 1050 } 1051 removeEmergencyNumberTestMode(emergencyNumberCmd); 1052 break; 1053 } 1054 case "-p": { 1055 try { 1056 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode()); 1057 } catch (RemoteException ex) { 1058 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage()); 1059 errPw.println("Exception: " + ex.getMessage()); 1060 return -1; 1061 } 1062 break; 1063 } 1064 default: 1065 onHelpEmergencyNumber(); 1066 break; 1067 } 1068 return 0; 1069 } 1070 handleNumberVerificationCommand()1071 private int handleNumberVerificationCommand() { 1072 String arg = getNextArg(); 1073 if (arg == null) { 1074 onHelpNumberVerification(); 1075 return 0; 1076 } 1077 1078 if (!checkShellUid()) { 1079 return -1; 1080 } 1081 1082 switch (arg) { 1083 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: { 1084 NumberVerificationManager.overrideAuthorizedPackage(getNextArg()); 1085 return 0; 1086 } 1087 case NUMBER_VERIFICATION_FAKE_CALL: { 1088 boolean val = NumberVerificationManager.getInstance() 1089 .checkIncomingCall(getNextArg()); 1090 getOutPrintWriter().println(val ? "1" : "0"); 1091 return 0; 1092 } 1093 } 1094 1095 return -1; 1096 } 1097 subIsEsim(int subId)1098 private boolean subIsEsim(int subId) { 1099 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId); 1100 if (info != null) { 1101 return info.isEmbedded(); 1102 } 1103 return false; 1104 } 1105 handleEnablePhysicalSubscription(boolean enable)1106 private int handleEnablePhysicalSubscription(boolean enable) { 1107 PrintWriter errPw = getErrPrintWriter(); 1108 int subId = 0; 1109 try { 1110 subId = Integer.parseInt(getNextArgRequired()); 1111 } catch (NumberFormatException e) { 1112 errPw.println((enable ? "enable" : "disable") 1113 + "-physical-subscription requires an integer as a subId."); 1114 return -1; 1115 } 1116 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 1117 // non user build. 1118 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 1119 errPw.println("cc: Permission denied."); 1120 return -1; 1121 } 1122 // Verify that the subId represents a physical sub 1123 if (subIsEsim(subId)) { 1124 errPw.println("SubId " + subId + " is not for a physical subscription"); 1125 return -1; 1126 } 1127 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling") 1128 + " physical subscription with subId=" + subId); 1129 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable); 1130 return 0; 1131 } 1132 handleThermalMitigationCommand()1133 private int handleThermalMitigationCommand() { 1134 String arg = getNextArg(); 1135 String packageName = getNextArg(); 1136 if (arg == null || packageName == null) { 1137 onHelpThermalMitigation(); 1138 return 0; 1139 } 1140 1141 if (!checkShellUid()) { 1142 return -1; 1143 } 1144 1145 switch (arg) { 1146 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: { 1147 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext); 1148 return 0; 1149 } 1150 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: { 1151 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName, 1152 mContext); 1153 return 0; 1154 } 1155 default: 1156 onHelpThermalMitigation(); 1157 } 1158 1159 return -1; 1160 1161 } 1162 handleD2dCommand()1163 private int handleD2dCommand() { 1164 String arg = getNextArg(); 1165 if (arg == null) { 1166 onHelpD2D(); 1167 return 0; 1168 } 1169 1170 switch (arg) { 1171 case D2D_SEND: { 1172 return handleD2dSendCommand(); 1173 } 1174 case D2D_TRANSPORT: { 1175 return handleD2dTransportCommand(); 1176 } 1177 case D2D_SET_DEVICE_SUPPORT: { 1178 return handleD2dDeviceSupportedCommand(); 1179 } 1180 } 1181 1182 return -1; 1183 } 1184 handleD2dSendCommand()1185 private int handleD2dSendCommand() { 1186 PrintWriter errPw = getErrPrintWriter(); 1187 int messageType = -1; 1188 int messageValue = -1; 1189 1190 String arg = getNextArg(); 1191 if (arg == null) { 1192 onHelpD2D(); 1193 return 0; 1194 } 1195 try { 1196 messageType = Integer.parseInt(arg); 1197 } catch (NumberFormatException e) { 1198 errPw.println("message type must be a valid integer"); 1199 return -1; 1200 } 1201 1202 arg = getNextArg(); 1203 if (arg == null) { 1204 onHelpD2D(); 1205 return 0; 1206 } 1207 try { 1208 messageValue = Integer.parseInt(arg); 1209 } catch (NumberFormatException e) { 1210 errPw.println("message value must be a valid integer"); 1211 return -1; 1212 } 1213 1214 try { 1215 mInterface.sendDeviceToDeviceMessage(messageType, messageValue); 1216 } catch (RemoteException e) { 1217 Log.w(LOG_TAG, "d2d send error: " + e.getMessage()); 1218 errPw.println("Exception: " + e.getMessage()); 1219 return -1; 1220 } 1221 1222 return 0; 1223 } 1224 handleD2dTransportCommand()1225 private int handleD2dTransportCommand() { 1226 PrintWriter errPw = getErrPrintWriter(); 1227 1228 String arg = getNextArg(); 1229 if (arg == null) { 1230 onHelpD2D(); 1231 return 0; 1232 } 1233 1234 try { 1235 mInterface.setActiveDeviceToDeviceTransport(arg); 1236 } catch (RemoteException e) { 1237 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage()); 1238 errPw.println("Exception: " + e.getMessage()); 1239 return -1; 1240 } 1241 return 0; 1242 } handleBarringCommand()1243 private int handleBarringCommand() { 1244 String arg = getNextArg(); 1245 if (arg == null) { 1246 onHelpBarring(); 1247 return 0; 1248 } 1249 1250 switch (arg) { 1251 case BARRING_SEND_INFO: { 1252 return handleBarringSendCommand(); 1253 } 1254 } 1255 return -1; 1256 } 1257 handleBarringSendCommand()1258 private int handleBarringSendCommand() { 1259 PrintWriter errPw = getErrPrintWriter(); 1260 int slotId = getDefaultSlot(); 1261 int subId = SubscriptionManager.getSubscriptionId(slotId); 1262 @BarringInfo.BarringServiceInfo.BarringType int barringType = 1263 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL; 1264 boolean isConditionallyBarred = false; 1265 int conditionalBarringTimeSeconds = 0; 1266 1267 String opt; 1268 while ((opt = getNextOption()) != null) { 1269 switch (opt) { 1270 case "-s": { 1271 try { 1272 slotId = Integer.parseInt(getNextArgRequired()); 1273 subId = SubscriptionManager.getSubscriptionId(slotId); 1274 } catch (NumberFormatException e) { 1275 errPw.println("barring send requires an integer as a SLOT_ID."); 1276 return -1; 1277 } 1278 break; 1279 } 1280 case "-b": { 1281 try { 1282 barringType = Integer.parseInt(getNextArgRequired()); 1283 if (barringType < -1 || barringType > 2) { 1284 throw new NumberFormatException(); 1285 } 1286 1287 } catch (NumberFormatException e) { 1288 errPw.println("barring send requires an integer in range [-1,2] as " 1289 + "a BARRING_TYPE."); 1290 return -1; 1291 } 1292 break; 1293 } 1294 case "-c": { 1295 try { 1296 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired()); 1297 } catch (Exception e) { 1298 errPw.println("barring send requires a boolean after -c indicating" 1299 + " conditional barring"); 1300 return -1; 1301 } 1302 break; 1303 } 1304 case "-t": { 1305 try { 1306 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired()); 1307 } catch (NumberFormatException e) { 1308 errPw.println("barring send requires an integer for time of barring" 1309 + " in seconds after -t for conditional barring"); 1310 return -1; 1311 } 1312 break; 1313 } 1314 } 1315 } 1316 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>(); 1317 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo( 1318 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds); 1319 barringServiceInfos.append(0, bsi); 1320 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos); 1321 try { 1322 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo); 1323 } catch (Exception e) { 1324 Log.w(LOG_TAG, "barring send error: " + e.getMessage()); 1325 errPw.println("Exception: " + e.getMessage()); 1326 return -1; 1327 } 1328 return 0; 1329 } 1330 handleD2dDeviceSupportedCommand()1331 private int handleD2dDeviceSupportedCommand() { 1332 PrintWriter errPw = getErrPrintWriter(); 1333 1334 String arg = getNextArg(); 1335 if (arg == null) { 1336 onHelpD2D(); 1337 return 0; 1338 } 1339 1340 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT)); 1341 try { 1342 mInterface.setDeviceToDeviceForceEnabled(isEnabled); 1343 } catch (RemoteException e) { 1344 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage()); 1345 errPw.println("Exception: " + e.getMessage()); 1346 return -1; 1347 } 1348 return 0; 1349 } 1350 1351 // ims set-ims-service handleImsSetServiceCommand()1352 private int handleImsSetServiceCommand() { 1353 PrintWriter errPw = getErrPrintWriter(); 1354 int slotId = getDefaultSlot(); 1355 Boolean isCarrierService = null; 1356 List<Integer> featuresList = new ArrayList<>(); 1357 1358 String opt; 1359 while ((opt = getNextOption()) != null) { 1360 switch (opt) { 1361 case "-s": { 1362 try { 1363 slotId = Integer.parseInt(getNextArgRequired()); 1364 } catch (NumberFormatException e) { 1365 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1366 return -1; 1367 } 1368 break; 1369 } 1370 case "-c": { 1371 isCarrierService = true; 1372 break; 1373 } 1374 case "-d": { 1375 isCarrierService = false; 1376 break; 1377 } 1378 case "-f": { 1379 String featureString = getNextArgRequired(); 1380 String[] features = featureString.split(","); 1381 for (int i = 0; i < features.length; i++) { 1382 try { 1383 Integer result = Integer.parseInt(features[i]); 1384 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL 1385 || result >= ImsFeature.FEATURE_MAX) { 1386 errPw.println("ims set-ims-service -f " + result 1387 + " is an invalid feature."); 1388 return -1; 1389 } 1390 featuresList.add(result); 1391 } catch (NumberFormatException e) { 1392 errPw.println("ims set-ims-service -f tried to parse " + features[i] 1393 + " as an integer."); 1394 return -1; 1395 } 1396 } 1397 } 1398 } 1399 } 1400 // Mandatory param, either -c or -d 1401 if (isCarrierService == null) { 1402 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set."); 1403 return -1; 1404 } 1405 1406 String packageName = getNextArg(); 1407 1408 try { 1409 if (packageName == null) { 1410 packageName = ""; 1411 } 1412 int[] featureArray = new int[featuresList.size()]; 1413 for (int i = 0; i < featuresList.size(); i++) { 1414 featureArray[i] = featuresList.get(i); 1415 } 1416 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService, 1417 featureArray, packageName); 1418 if (VDBG) { 1419 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " " 1420 + (isCarrierService ? "-c " : "-d ") 1421 + "-f " + featuresList + " " 1422 + packageName + ", result=" + result); 1423 } 1424 getOutPrintWriter().println(result); 1425 } catch (RemoteException e) { 1426 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " " 1427 + (isCarrierService ? "-c " : "-d ") 1428 + "-f " + featuresList + " " 1429 + packageName + ", error" + e.getMessage()); 1430 errPw.println("Exception: " + e.getMessage()); 1431 return -1; 1432 } 1433 return 0; 1434 } 1435 1436 // ims clear-ims-service-override handleImsClearCarrierServiceCommand()1437 private int handleImsClearCarrierServiceCommand() { 1438 PrintWriter errPw = getErrPrintWriter(); 1439 int slotId = getDefaultSlot(); 1440 1441 String opt; 1442 while ((opt = getNextOption()) != null) { 1443 switch (opt) { 1444 case "-s": { 1445 try { 1446 slotId = Integer.parseInt(getNextArgRequired()); 1447 } catch (NumberFormatException e) { 1448 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1449 return -1; 1450 } 1451 break; 1452 } 1453 } 1454 } 1455 1456 try { 1457 boolean result = mInterface.clearCarrierImsServiceOverride(slotId); 1458 if (VDBG) { 1459 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId 1460 + ", result=" + result); 1461 } 1462 getOutPrintWriter().println(result); 1463 } catch (RemoteException e) { 1464 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId 1465 + ", error" + e.getMessage()); 1466 errPw.println("Exception: " + e.getMessage()); 1467 return -1; 1468 } 1469 return 0; 1470 } 1471 1472 // ims get-ims-service handleImsGetServiceCommand()1473 private int handleImsGetServiceCommand() { 1474 PrintWriter errPw = getErrPrintWriter(); 1475 int slotId = getDefaultSlot(); 1476 Boolean isCarrierService = null; 1477 Integer featureType = ImsFeature.FEATURE_MMTEL; 1478 1479 String opt; 1480 while ((opt = getNextOption()) != null) { 1481 switch (opt) { 1482 case "-s": { 1483 try { 1484 slotId = Integer.parseInt(getNextArgRequired()); 1485 } catch (NumberFormatException e) { 1486 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1487 return -1; 1488 } 1489 break; 1490 } 1491 case "-c": { 1492 isCarrierService = true; 1493 break; 1494 } 1495 case "-d": { 1496 isCarrierService = false; 1497 break; 1498 } 1499 case "-f": { 1500 try { 1501 featureType = Integer.parseInt(getNextArg()); 1502 } catch (NumberFormatException e) { 1503 errPw.println("ims get-ims-service -f requires valid integer as feature."); 1504 return -1; 1505 } 1506 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL 1507 || featureType >= ImsFeature.FEATURE_MAX) { 1508 errPw.println("ims get-ims-service -f invalid feature."); 1509 return -1; 1510 } 1511 } 1512 } 1513 } 1514 // Mandatory param, either -c or -d 1515 if (isCarrierService == null) { 1516 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set."); 1517 return -1; 1518 } 1519 1520 String result; 1521 try { 1522 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType); 1523 } catch (RemoteException e) { 1524 return -1; 1525 } 1526 if (VDBG) { 1527 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " " 1528 + (isCarrierService ? "-c " : "-d ") 1529 + (featureType != null ? ("-f " + featureType) : "") + " , returned: " 1530 + result); 1531 } 1532 getOutPrintWriter().println(result); 1533 return 0; 1534 } 1535 handleEnableIms()1536 private int handleEnableIms() { 1537 int slotId = getDefaultSlot(); 1538 String opt; 1539 while ((opt = getNextOption()) != null) { 1540 switch (opt) { 1541 case "-s": { 1542 try { 1543 slotId = Integer.parseInt(getNextArgRequired()); 1544 } catch (NumberFormatException e) { 1545 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID."); 1546 return -1; 1547 } 1548 break; 1549 } 1550 } 1551 } 1552 try { 1553 mInterface.enableIms(slotId); 1554 } catch (RemoteException e) { 1555 return -1; 1556 } 1557 if (VDBG) { 1558 Log.v(LOG_TAG, "ims enable -s " + slotId); 1559 } 1560 return 0; 1561 } 1562 handleDisableIms()1563 private int handleDisableIms() { 1564 int slotId = getDefaultSlot(); 1565 String opt; 1566 while ((opt = getNextOption()) != null) { 1567 switch (opt) { 1568 case "-s": { 1569 try { 1570 slotId = Integer.parseInt(getNextArgRequired()); 1571 } catch (NumberFormatException e) { 1572 getErrPrintWriter().println( 1573 "ims disable requires an integer as a SLOT_ID."); 1574 return -1; 1575 } 1576 break; 1577 } 1578 } 1579 } 1580 try { 1581 mInterface.disableIms(slotId); 1582 } catch (RemoteException e) { 1583 return -1; 1584 } 1585 if (VDBG) { 1586 Log.v(LOG_TAG, "ims disable -s " + slotId); 1587 } 1588 return 0; 1589 } 1590 handleCepChange()1591 private int handleCepChange() { 1592 Log.i(LOG_TAG, "handleCepChange"); 1593 String opt = getNextArg(); 1594 if (opt == null) { 1595 return -1; 1596 } 1597 boolean isCepEnabled = opt.equals("enable"); 1598 1599 try { 1600 mInterface.setCepEnabled(isCepEnabled); 1601 } catch (RemoteException e) { 1602 return -1; 1603 } 1604 return 0; 1605 } 1606 getDefaultSlot()1607 private int getDefaultSlot() { 1608 int slotId = SubscriptionManager.getDefaultVoicePhoneId(); 1609 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX 1610 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 1611 // If there is no default, default to slot 0. 1612 slotId = DEFAULT_PHONE_ID; 1613 } 1614 return slotId; 1615 } 1616 1617 // Parse options related to Carrier Config Commands. parseCcOptions(String tag, boolean allowOptionPersistent)1618 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) { 1619 PrintWriter errPw = getErrPrintWriter(); 1620 CcOptionParseResult result = new CcOptionParseResult(); 1621 result.mSubId = SubscriptionManager.getDefaultSubscriptionId(); 1622 result.mPersistent = false; 1623 1624 String opt; 1625 while ((opt = getNextOption()) != null) { 1626 switch (opt) { 1627 case "-s": { 1628 try { 1629 result.mSubId = slotStringToSubId(tag, getNextArgRequired()); 1630 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) { 1631 errPw.println(tag + "No valid subscription found."); 1632 return null; 1633 } 1634 1635 } catch (IllegalArgumentException e) { 1636 // Missing slot id 1637 errPw.println(tag + "SLOT_ID expected after -s."); 1638 return null; 1639 } 1640 break; 1641 } 1642 case "-p": { 1643 if (allowOptionPersistent) { 1644 result.mPersistent = true; 1645 } else { 1646 errPw.println(tag + "Unexpected option " + opt); 1647 return null; 1648 } 1649 break; 1650 } 1651 default: { 1652 errPw.println(tag + "Unknown option " + opt); 1653 return null; 1654 } 1655 } 1656 } 1657 return result; 1658 } 1659 slotStringToSubId(String tag, String slotString)1660 private int slotStringToSubId(String tag, String slotString) { 1661 int slotId = -1; 1662 try { 1663 slotId = Integer.parseInt(slotString); 1664 } catch (NumberFormatException e) { 1665 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID."); 1666 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1667 } 1668 1669 if (!SubscriptionManager.isValidPhoneId(slotId)) { 1670 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID."); 1671 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1672 } 1673 1674 Phone phone = PhoneFactory.getPhone(slotId); 1675 if (phone == null) { 1676 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + "."); 1677 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1678 } 1679 return phone.getSubId(); 1680 } 1681 checkShellUid()1682 private boolean checkShellUid() { 1683 // adb can run as root or as shell, depending on whether the device is rooted. 1684 return Binder.getCallingUid() == Process.SHELL_UID 1685 || Binder.getCallingUid() == Process.ROOT_UID; 1686 } 1687 handleCcCommand()1688 private int handleCcCommand() { 1689 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 1690 // non user build. 1691 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 1692 getErrPrintWriter().println("cc: Permission denied."); 1693 return -1; 1694 } 1695 1696 String arg = getNextArg(); 1697 if (arg == null) { 1698 onHelpCc(); 1699 return 0; 1700 } 1701 1702 switch (arg) { 1703 case CC_GET_VALUE: { 1704 return handleCcGetValue(); 1705 } 1706 case CC_SET_VALUE: { 1707 return handleCcSetValue(); 1708 } 1709 case CC_SET_VALUES_FROM_XML: { 1710 return handleCcSetValuesFromXml(); 1711 } 1712 case CC_CLEAR_VALUES: { 1713 return handleCcClearValues(); 1714 } 1715 default: { 1716 getErrPrintWriter().println("cc: Unknown argument: " + arg); 1717 } 1718 } 1719 return -1; 1720 } 1721 1722 // cc get-value handleCcGetValue()1723 private int handleCcGetValue() { 1724 PrintWriter errPw = getErrPrintWriter(); 1725 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": "; 1726 String key = null; 1727 1728 // Parse all options 1729 CcOptionParseResult options = parseCcOptions(tag, false); 1730 if (options == null) { 1731 return -1; 1732 } 1733 1734 // Get bundle containing all carrier configuration values. 1735 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1736 if (bundle == null) { 1737 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1738 return -1; 1739 } 1740 1741 // Get the key. 1742 key = getNextArg(); 1743 if (key != null) { 1744 // A key was provided. Verify if it is a valid key 1745 if (!bundle.containsKey(key)) { 1746 errPw.println(tag + key + " is not a valid key."); 1747 return -1; 1748 } 1749 1750 // Print the carrier config value for key. 1751 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle)); 1752 } else { 1753 // No key provided. Show all values. 1754 // Iterate over a sorted list of all carrier config keys and print them. 1755 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet()); 1756 for (String k : sortedSet) { 1757 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle)); 1758 } 1759 } 1760 return 0; 1761 } 1762 1763 // cc set-value handleCcSetValue()1764 private int handleCcSetValue() { 1765 PrintWriter errPw = getErrPrintWriter(); 1766 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": "; 1767 1768 // Parse all options 1769 CcOptionParseResult options = parseCcOptions(tag, true); 1770 if (options == null) { 1771 return -1; 1772 } 1773 1774 // Get bundle containing all current carrier configuration values. 1775 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1776 if (originalValues == null) { 1777 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1778 return -1; 1779 } 1780 1781 // Get the key. 1782 String key = getNextArg(); 1783 if (key == null || key.equals("")) { 1784 errPw.println(tag + "KEY is missing"); 1785 return -1; 1786 } 1787 1788 // Verify if the key is valid 1789 if (!originalValues.containsKey(key)) { 1790 errPw.println(tag + key + " is not a valid key."); 1791 return -1; 1792 } 1793 1794 // Remaining arguments is a list of new values. Add them all into an ArrayList. 1795 ArrayList<String> valueList = new ArrayList<String>(); 1796 while (peekNextArg() != null) { 1797 valueList.add(getNextArg()); 1798 } 1799 1800 // Find the type of the carrier config value 1801 CcType type = getType(tag, key, originalValues); 1802 if (type == CcType.UNKNOWN) { 1803 errPw.println(tag + "ERROR: Not possible to override key with unknown type."); 1804 return -1; 1805 } 1806 if (type == CcType.PERSISTABLE_BUNDLE) { 1807 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. " 1808 + "Use set-values-from-xml instead."); 1809 return -1; 1810 } 1811 1812 // Create an override bundle containing the key and value that should be overriden. 1813 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList); 1814 if (overrideBundle == null) { 1815 return -1; 1816 } 1817 1818 // Override the value 1819 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent); 1820 1821 // Find bundle containing all new carrier configuration values after the override. 1822 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1823 if (newValues == null) { 1824 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1825 return -1; 1826 } 1827 1828 // Print the original and new value. 1829 String originalValueString = ccValueToString(key, type, originalValues); 1830 String newValueString = ccValueToString(key, type, newValues); 1831 getOutPrintWriter().println("Previous value: \n" + originalValueString); 1832 getOutPrintWriter().println("New value: \n" + newValueString); 1833 1834 return 0; 1835 } 1836 1837 // cc set-values-from-xml handleCcSetValuesFromXml()1838 private int handleCcSetValuesFromXml() { 1839 PrintWriter errPw = getErrPrintWriter(); 1840 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": "; 1841 1842 // Parse all options 1843 CcOptionParseResult options = parseCcOptions(tag, true); 1844 if (options == null) { 1845 return -1; 1846 } 1847 1848 // Get bundle containing all current carrier configuration values. 1849 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1850 if (originalValues == null) { 1851 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1852 return -1; 1853 } 1854 1855 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag); 1856 if (overrideBundle == null) { 1857 return -1; 1858 } 1859 1860 // Verify all values are valid types 1861 for (String key : overrideBundle.keySet()) { 1862 CcType type = getType(tag, key, originalValues); 1863 if (type == CcType.UNKNOWN) { 1864 errPw.println(tag + "ERROR: Not possible to override key with unknown type."); 1865 return -1; 1866 } 1867 } 1868 1869 // Override the value 1870 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent); 1871 1872 // Find bundle containing all new carrier configuration values after the override. 1873 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1874 if (newValues == null) { 1875 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1876 return -1; 1877 } 1878 1879 // Print the original and new values 1880 overrideBundle.keySet().forEach(key -> { 1881 CcType type = getType(tag, key, originalValues); 1882 String originalValueString = ccValueToString(key, type, originalValues); 1883 String newValueString = ccValueToString(key, type, newValues); 1884 getOutPrintWriter().println("Previous value: \n" + originalValueString); 1885 getOutPrintWriter().println("New value: \n" + newValueString); 1886 }); 1887 1888 return 0; 1889 } 1890 readPersistableBundleFromXml(String tag)1891 private PersistableBundle readPersistableBundleFromXml(String tag) { 1892 PersistableBundle subIdBundles; 1893 try { 1894 subIdBundles = PersistableBundle.readFromStream(getRawInputStream()); 1895 } catch (IOException | RuntimeException e) { 1896 PrintWriter errPw = getErrPrintWriter(); 1897 errPw.println(tag + e); 1898 return null; 1899 } 1900 1901 return subIdBundles; 1902 } 1903 1904 // cc clear-values handleCcClearValues()1905 private int handleCcClearValues() { 1906 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": "; 1907 1908 // Parse all options 1909 CcOptionParseResult options = parseCcOptions(tag, false); 1910 if (options == null) { 1911 return -1; 1912 } 1913 1914 // Clear all values that has previously been set. 1915 mCarrierConfigManager.overrideConfig(options.mSubId, null, true); 1916 getOutPrintWriter() 1917 .println("All previously set carrier config override values has been cleared"); 1918 return 0; 1919 } 1920 getType(String tag, String key, PersistableBundle bundle)1921 private CcType getType(String tag, String key, PersistableBundle bundle) { 1922 // Find the type by checking the type of the current value stored in the bundle. 1923 Object value = bundle.get(key); 1924 1925 if (CC_TYPE_MAP.containsKey(key)) { 1926 return CC_TYPE_MAP.get(key); 1927 } else if (value != null) { 1928 if (value instanceof Boolean) { 1929 return CcType.BOOLEAN; 1930 } 1931 if (value instanceof Double) { 1932 return CcType.DOUBLE; 1933 } 1934 if (value instanceof double[]) { 1935 return CcType.DOUBLE_ARRAY; 1936 } 1937 if (value instanceof Integer) { 1938 return CcType.INT; 1939 } 1940 if (value instanceof int[]) { 1941 return CcType.INT_ARRAY; 1942 } 1943 if (value instanceof Long) { 1944 return CcType.LONG; 1945 } 1946 if (value instanceof long[]) { 1947 return CcType.LONG_ARRAY; 1948 } 1949 if (value instanceof String) { 1950 return CcType.STRING; 1951 } 1952 if (value instanceof String[]) { 1953 return CcType.STRING_ARRAY; 1954 } 1955 if (value instanceof PersistableBundle) { 1956 return CcType.PERSISTABLE_BUNDLE; 1957 } 1958 } else { 1959 // Current value was null and can therefore not be used in order to find the type. 1960 // Check the name of the key to infer the type. This check is not needed for primitive 1961 // data types (boolean, double, int and long), since they can not be null. 1962 if (key.endsWith("double_array")) { 1963 return CcType.DOUBLE_ARRAY; 1964 } 1965 if (key.endsWith("int_array")) { 1966 return CcType.INT_ARRAY; 1967 } 1968 if (key.endsWith("long_array")) { 1969 return CcType.LONG_ARRAY; 1970 } 1971 if (key.endsWith("string")) { 1972 return CcType.STRING; 1973 } 1974 if (key.endsWith("string_array") || key.endsWith("strings")) { 1975 return CcType.STRING_ARRAY; 1976 } 1977 if (key.endsWith("bundle")) { 1978 return CcType.PERSISTABLE_BUNDLE; 1979 } 1980 } 1981 1982 // Not possible to infer the type by looking at the current value or the key. 1983 PrintWriter errPw = getErrPrintWriter(); 1984 errPw.println(tag + "ERROR: " + key + " has unknown type."); 1985 return CcType.UNKNOWN; 1986 } 1987 ccValueToString(String key, CcType type, PersistableBundle bundle)1988 private String ccValueToString(String key, CcType type, PersistableBundle bundle) { 1989 String result; 1990 StringBuilder valueString = new StringBuilder(); 1991 String typeString = type.toString(); 1992 Object value = bundle.get(key); 1993 1994 if (value == null) { 1995 valueString.append("null"); 1996 } else { 1997 switch (type) { 1998 case DOUBLE_ARRAY: { 1999 // Format the string representation of the int array as value1 value2...... 2000 double[] valueArray = (double[]) value; 2001 for (int i = 0; i < valueArray.length; i++) { 2002 if (i != 0) { 2003 valueString.append(" "); 2004 } 2005 valueString.append(valueArray[i]); 2006 } 2007 break; 2008 } 2009 case INT_ARRAY: { 2010 // Format the string representation of the int array as value1 value2...... 2011 int[] valueArray = (int[]) value; 2012 for (int i = 0; i < valueArray.length; i++) { 2013 if (i != 0) { 2014 valueString.append(" "); 2015 } 2016 valueString.append(valueArray[i]); 2017 } 2018 break; 2019 } 2020 case LONG_ARRAY: { 2021 // Format the string representation of the int array as value1 value2...... 2022 long[] valueArray = (long[]) value; 2023 for (int i = 0; i < valueArray.length; i++) { 2024 if (i != 0) { 2025 valueString.append(" "); 2026 } 2027 valueString.append(valueArray[i]); 2028 } 2029 break; 2030 } 2031 case STRING: { 2032 valueString.append("\"" + value.toString() + "\""); 2033 break; 2034 } 2035 case STRING_ARRAY: { 2036 // Format the string representation of the string array as "value1" "value2".... 2037 String[] valueArray = (String[]) value; 2038 for (int i = 0; i < valueArray.length; i++) { 2039 if (i != 0) { 2040 valueString.append(" "); 2041 } 2042 if (valueArray[i] != null) { 2043 valueString.append("\"" + valueArray[i] + "\""); 2044 } else { 2045 valueString.append("null"); 2046 } 2047 } 2048 break; 2049 } 2050 default: { 2051 valueString.append(value.toString()); 2052 } 2053 } 2054 } 2055 return String.format("%-70s %-15s %s", key, typeString, valueString); 2056 } 2057 getOverrideBundle(String tag, CcType type, String key, ArrayList<String> valueList)2058 private PersistableBundle getOverrideBundle(String tag, CcType type, String key, 2059 ArrayList<String> valueList) { 2060 PrintWriter errPw = getErrPrintWriter(); 2061 PersistableBundle bundle = new PersistableBundle(); 2062 2063 // First verify that a valid number of values has been provided for the type. 2064 switch (type) { 2065 case BOOLEAN: 2066 case DOUBLE: 2067 case INT: 2068 case LONG: { 2069 if (valueList.size() != 1) { 2070 errPw.println(tag + "Expected 1 value for type " + type 2071 + ". Found: " + valueList.size()); 2072 return null; 2073 } 2074 break; 2075 } 2076 case STRING: { 2077 if (valueList.size() > 1) { 2078 errPw.println(tag + "Expected 0 or 1 values for type " + type 2079 + ". Found: " + valueList.size()); 2080 return null; 2081 } 2082 break; 2083 } 2084 } 2085 2086 // Parse the value according to type and add it to the Bundle. 2087 switch (type) { 2088 case BOOLEAN: { 2089 if ("true".equalsIgnoreCase(valueList.get(0))) { 2090 bundle.putBoolean(key, true); 2091 } else if ("false".equalsIgnoreCase(valueList.get(0))) { 2092 bundle.putBoolean(key, false); 2093 } else { 2094 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 2095 return null; 2096 } 2097 break; 2098 } 2099 case DOUBLE: { 2100 try { 2101 bundle.putDouble(key, Double.parseDouble(valueList.get(0))); 2102 } catch (NumberFormatException nfe) { 2103 // Not a valid double 2104 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 2105 return null; 2106 } 2107 break; 2108 } 2109 case DOUBLE_ARRAY: { 2110 double[] valueDoubleArray = null; 2111 if (valueList.size() > 0) { 2112 valueDoubleArray = new double[valueList.size()]; 2113 for (int i = 0; i < valueList.size(); i++) { 2114 try { 2115 valueDoubleArray[i] = Double.parseDouble(valueList.get(i)); 2116 } catch (NumberFormatException nfe) { 2117 // Not a valid double 2118 errPw.println( 2119 tag + "Unable to parse " + valueList.get(i) + " as a double."); 2120 return null; 2121 } 2122 } 2123 } 2124 bundle.putDoubleArray(key, valueDoubleArray); 2125 break; 2126 } 2127 case INT: { 2128 try { 2129 bundle.putInt(key, Integer.parseInt(valueList.get(0))); 2130 } catch (NumberFormatException nfe) { 2131 // Not a valid integer 2132 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type); 2133 return null; 2134 } 2135 break; 2136 } 2137 case INT_ARRAY: { 2138 int[] valueIntArray = null; 2139 if (valueList.size() > 0) { 2140 valueIntArray = new int[valueList.size()]; 2141 for (int i = 0; i < valueList.size(); i++) { 2142 try { 2143 valueIntArray[i] = Integer.parseInt(valueList.get(i)); 2144 } catch (NumberFormatException nfe) { 2145 // Not a valid integer 2146 errPw.println(tag 2147 + "Unable to parse " + valueList.get(i) + " as an integer."); 2148 return null; 2149 } 2150 } 2151 } 2152 bundle.putIntArray(key, valueIntArray); 2153 break; 2154 } 2155 case LONG: { 2156 try { 2157 bundle.putLong(key, Long.parseLong(valueList.get(0))); 2158 } catch (NumberFormatException nfe) { 2159 // Not a valid long 2160 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 2161 return null; 2162 } 2163 break; 2164 } 2165 case LONG_ARRAY: { 2166 long[] valueLongArray = null; 2167 if (valueList.size() > 0) { 2168 valueLongArray = new long[valueList.size()]; 2169 for (int i = 0; i < valueList.size(); i++) { 2170 try { 2171 valueLongArray[i] = Long.parseLong(valueList.get(i)); 2172 } catch (NumberFormatException nfe) { 2173 // Not a valid long 2174 errPw.println( 2175 tag + "Unable to parse " + valueList.get(i) + " as a long"); 2176 return null; 2177 } 2178 } 2179 } 2180 bundle.putLongArray(key, valueLongArray); 2181 break; 2182 } 2183 case STRING: { 2184 String value = null; 2185 if (valueList.size() > 0) { 2186 value = valueList.get(0); 2187 } 2188 bundle.putString(key, value); 2189 break; 2190 } 2191 case STRING_ARRAY: { 2192 String[] valueStringArray = null; 2193 if (valueList.size() > 0) { 2194 valueStringArray = new String[valueList.size()]; 2195 valueList.toArray(valueStringArray); 2196 } 2197 bundle.putStringArray(key, valueStringArray); 2198 break; 2199 } 2200 } 2201 return bundle; 2202 } 2203 handleEndBlockSuppressionCommand()2204 private int handleEndBlockSuppressionCommand() { 2205 if (!checkShellUid()) { 2206 return -1; 2207 } 2208 2209 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) { 2210 BlockedNumberContract.SystemContract.endBlockSuppression(mContext); 2211 } 2212 return 0; 2213 } 2214 handleEuiccCommand()2215 private int handleEuiccCommand() { 2216 String arg = getNextArg(); 2217 if (arg == null) { 2218 onHelpEuicc(); 2219 return 0; 2220 } 2221 2222 switch (arg) { 2223 case EUICC_SET_UI_COMPONENT: { 2224 return handleEuiccServiceCommand(); 2225 } 2226 } 2227 return -1; 2228 } 2229 handleEuiccServiceCommand()2230 private int handleEuiccServiceCommand() { 2231 String uiComponent = getNextArg(); 2232 String packageName = getNextArg(); 2233 if (packageName == null || uiComponent == null) { 2234 return -1; 2235 } 2236 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent); 2237 if (VDBG) { 2238 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" " 2239 + packageName); 2240 } 2241 return 0; 2242 } 2243 handleRestartModemCommand()2244 private int handleRestartModemCommand() { 2245 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2246 // non user build. 2247 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2248 getErrPrintWriter().println("RestartModem: Permission denied."); 2249 return -1; 2250 } 2251 2252 boolean result = TelephonyManager.getDefault().rebootRadio(); 2253 getOutPrintWriter().println(result); 2254 2255 return result ? 0 : -1; 2256 } 2257 handleGetImei()2258 private int handleGetImei() { 2259 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2260 // non user build. 2261 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2262 getErrPrintWriter().println("Device IMEI: Permission denied."); 2263 return -1; 2264 } 2265 2266 final long identity = Binder.clearCallingIdentity(); 2267 2268 String imei = null; 2269 String arg = getNextArg(); 2270 if (arg != null) { 2271 try { 2272 int specifiedSlotIndex = Integer.parseInt(arg); 2273 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex); 2274 } catch (NumberFormatException exception) { 2275 PrintWriter errPw = getErrPrintWriter(); 2276 errPw.println("-s requires an integer as slot index."); 2277 return -1; 2278 } 2279 2280 } else { 2281 imei = TelephonyManager.from(mContext).getImei(); 2282 } 2283 getOutPrintWriter().println("Device IMEI: " + imei); 2284 2285 Binder.restoreCallingIdentity(identity); 2286 return 0; 2287 } 2288 handleUnattendedReboot()2289 private int handleUnattendedReboot() { 2290 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2291 // non user build. 2292 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2293 getErrPrintWriter().println("UnattendedReboot: Permission denied."); 2294 return -1; 2295 } 2296 2297 int result = TelephonyManager.getDefault().prepareForUnattendedReboot(); 2298 getOutPrintWriter().println("result: " + result); 2299 2300 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1; 2301 } 2302 handleGetSimSlotsMapping()2303 private int handleGetSimSlotsMapping() { 2304 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2305 // non user build. 2306 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2307 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied."); 2308 return -1; 2309 } 2310 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); 2311 String result = telephonyManager.getSimSlotMapping().toString(); 2312 getOutPrintWriter().println("simSlotsMapping: " + result); 2313 2314 return 0; 2315 } 2316 handleGbaCommand()2317 private int handleGbaCommand() { 2318 String arg = getNextArg(); 2319 if (arg == null) { 2320 onHelpGba(); 2321 return 0; 2322 } 2323 2324 switch (arg) { 2325 case GBA_SET_SERVICE: { 2326 return handleGbaSetServiceCommand(); 2327 } 2328 case GBA_GET_SERVICE: { 2329 return handleGbaGetServiceCommand(); 2330 } 2331 case GBA_SET_RELEASE_TIME: { 2332 return handleGbaSetReleaseCommand(); 2333 } 2334 case GBA_GET_RELEASE_TIME: { 2335 return handleGbaGetReleaseCommand(); 2336 } 2337 } 2338 2339 return -1; 2340 } 2341 getSubId(String cmd)2342 private int getSubId(String cmd) { 2343 int slotId = getDefaultSlot(); 2344 String opt = getNextOption(); 2345 if (opt != null && opt.equals("-s")) { 2346 try { 2347 slotId = Integer.parseInt(getNextArgRequired()); 2348 } catch (NumberFormatException e) { 2349 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID."); 2350 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2351 } 2352 } 2353 return SubscriptionManager.getSubscriptionId(slotId); 2354 } 2355 handleGbaSetServiceCommand()2356 private int handleGbaSetServiceCommand() { 2357 int subId = getSubId("gba set-service"); 2358 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2359 return -1; 2360 } 2361 2362 String packageName = getNextArg(); 2363 try { 2364 if (packageName == null) { 2365 packageName = ""; 2366 } 2367 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName); 2368 if (VDBG) { 2369 Log.v(LOG_TAG, "gba set-service -s " + subId + " " 2370 + packageName + ", result=" + result); 2371 } 2372 getOutPrintWriter().println(result); 2373 } catch (RemoteException e) { 2374 Log.w(LOG_TAG, "gba set-service " + subId + " " 2375 + packageName + ", error" + e.getMessage()); 2376 getErrPrintWriter().println("Exception: " + e.getMessage()); 2377 return -1; 2378 } 2379 return 0; 2380 } 2381 handleGbaGetServiceCommand()2382 private int handleGbaGetServiceCommand() { 2383 String result; 2384 2385 int subId = getSubId("gba get-service"); 2386 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2387 return -1; 2388 } 2389 2390 try { 2391 result = mInterface.getBoundGbaService(subId); 2392 } catch (RemoteException e) { 2393 return -1; 2394 } 2395 if (VDBG) { 2396 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result); 2397 } 2398 getOutPrintWriter().println(result); 2399 return 0; 2400 } 2401 handleGbaSetReleaseCommand()2402 private int handleGbaSetReleaseCommand() { 2403 //the release time value could be -1 2404 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release") 2405 : SubscriptionManager.getDefaultSubscriptionId(); 2406 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2407 return -1; 2408 } 2409 2410 String intervalStr = getNextArg(); 2411 if (intervalStr == null) { 2412 return -1; 2413 } 2414 2415 try { 2416 int interval = Integer.parseInt(intervalStr); 2417 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval); 2418 if (VDBG) { 2419 Log.v(LOG_TAG, "gba set-release -s " + subId + " " 2420 + intervalStr + ", result=" + result); 2421 } 2422 getOutPrintWriter().println(result); 2423 } catch (NumberFormatException | RemoteException e) { 2424 Log.w(LOG_TAG, "gba set-release -s " + subId + " " 2425 + intervalStr + ", error" + e.getMessage()); 2426 getErrPrintWriter().println("Exception: " + e.getMessage()); 2427 return -1; 2428 } 2429 return 0; 2430 } 2431 handleGbaGetReleaseCommand()2432 private int handleGbaGetReleaseCommand() { 2433 int subId = getSubId("gba get-release"); 2434 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2435 return -1; 2436 } 2437 2438 int result = 0; 2439 try { 2440 result = mInterface.getGbaReleaseTime(subId); 2441 } catch (RemoteException e) { 2442 return -1; 2443 } 2444 if (VDBG) { 2445 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result); 2446 } 2447 getOutPrintWriter().println(result); 2448 return 0; 2449 } 2450 handleSingleRegistrationConfigCommand()2451 private int handleSingleRegistrationConfigCommand() { 2452 String arg = getNextArg(); 2453 if (arg == null) { 2454 onHelpSrc(); 2455 return 0; 2456 } 2457 2458 switch (arg) { 2459 case SRC_SET_TEST_ENABLED: { 2460 return handleSrcSetTestEnabledCommand(); 2461 } 2462 case SRC_GET_TEST_ENABLED: { 2463 return handleSrcGetTestEnabledCommand(); 2464 } 2465 case SRC_SET_DEVICE_ENABLED: { 2466 return handleSrcSetDeviceEnabledCommand(); 2467 } 2468 case SRC_GET_DEVICE_ENABLED: { 2469 return handleSrcGetDeviceEnabledCommand(); 2470 } 2471 case SRC_SET_CARRIER_ENABLED: { 2472 return handleSrcSetCarrierEnabledCommand(); 2473 } 2474 case SRC_GET_CARRIER_ENABLED: { 2475 return handleSrcGetCarrierEnabledCommand(); 2476 } 2477 case SRC_SET_FEATURE_ENABLED: { 2478 return handleSrcSetFeatureValidationCommand(); 2479 } 2480 case SRC_GET_FEATURE_ENABLED: { 2481 return handleSrcGetFeatureValidationCommand(); 2482 } 2483 } 2484 2485 return -1; 2486 } 2487 handleRcsUceCommand()2488 private int handleRcsUceCommand() { 2489 String arg = getNextArg(); 2490 if (arg == null) { 2491 onHelpUce(); 2492 return 0; 2493 } 2494 2495 switch (arg) { 2496 case UCE_REMOVE_EAB_CONTACT: 2497 return handleRemovingEabContactCommand(); 2498 case UCE_GET_EAB_CONTACT: 2499 return handleGettingEabContactCommand(); 2500 case UCE_GET_EAB_CAPABILITY: 2501 return handleGettingEabCapabilityCommand(); 2502 case UCE_GET_DEVICE_ENABLED: 2503 return handleUceGetDeviceEnabledCommand(); 2504 case UCE_SET_DEVICE_ENABLED: 2505 return handleUceSetDeviceEnabledCommand(); 2506 case UCE_OVERRIDE_PUBLISH_CAPS: 2507 return handleUceOverridePublishCaps(); 2508 case UCE_GET_LAST_PIDF_XML: 2509 return handleUceGetPidfXml(); 2510 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS: 2511 return handleUceRemoveRequestDisallowedStatus(); 2512 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT: 2513 return handleUceSetCapRequestTimeout(); 2514 } 2515 return -1; 2516 } 2517 handleRemovingEabContactCommand()2518 private int handleRemovingEabContactCommand() { 2519 int subId = getSubId("uce remove-eab-contact"); 2520 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2521 return -1; 2522 } 2523 2524 String phoneNumber = getNextArgRequired(); 2525 if (TextUtils.isEmpty(phoneNumber)) { 2526 return -1; 2527 } 2528 int result = 0; 2529 try { 2530 result = mInterface.removeContactFromEab(subId, phoneNumber); 2531 } catch (RemoteException e) { 2532 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage()); 2533 getErrPrintWriter().println("Exception: " + e.getMessage()); 2534 return -1; 2535 } 2536 2537 if (VDBG) { 2538 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result); 2539 } 2540 return 0; 2541 } 2542 handleGettingEabContactCommand()2543 private int handleGettingEabContactCommand() { 2544 String phoneNumber = getNextArgRequired(); 2545 if (TextUtils.isEmpty(phoneNumber)) { 2546 return -1; 2547 } 2548 String result = ""; 2549 try { 2550 result = mInterface.getContactFromEab(phoneNumber); 2551 } catch (RemoteException e) { 2552 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage()); 2553 getErrPrintWriter().println("Exception: " + e.getMessage()); 2554 return -1; 2555 } 2556 2557 if (VDBG) { 2558 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result); 2559 } 2560 getOutPrintWriter().println(result); 2561 return 0; 2562 } 2563 handleGettingEabCapabilityCommand()2564 private int handleGettingEabCapabilityCommand() { 2565 String phoneNumber = getNextArgRequired(); 2566 if (TextUtils.isEmpty(phoneNumber)) { 2567 return -1; 2568 } 2569 String result = ""; 2570 try { 2571 result = mInterface.getCapabilityFromEab(phoneNumber); 2572 } catch (RemoteException e) { 2573 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage()); 2574 getErrPrintWriter().println("Exception: " + e.getMessage()); 2575 return -1; 2576 } 2577 2578 if (VDBG) { 2579 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result); 2580 } 2581 getOutPrintWriter().println(result); 2582 return 0; 2583 } 2584 handleUceGetDeviceEnabledCommand()2585 private int handleUceGetDeviceEnabledCommand() { 2586 boolean result = false; 2587 try { 2588 result = mInterface.getDeviceUceEnabled(); 2589 } catch (RemoteException e) { 2590 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage()); 2591 return -1; 2592 } 2593 if (VDBG) { 2594 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result); 2595 } 2596 getOutPrintWriter().println(result); 2597 return 0; 2598 } 2599 handleUceSetDeviceEnabledCommand()2600 private int handleUceSetDeviceEnabledCommand() { 2601 String enabledStr = getNextArg(); 2602 if (TextUtils.isEmpty(enabledStr)) { 2603 return -1; 2604 } 2605 2606 try { 2607 boolean isEnabled = Boolean.parseBoolean(enabledStr); 2608 mInterface.setDeviceUceEnabled(isEnabled); 2609 if (VDBG) { 2610 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done"); 2611 } 2612 } catch (NumberFormatException | RemoteException e) { 2613 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage()); 2614 getErrPrintWriter().println("Exception: " + e.getMessage()); 2615 return -1; 2616 } 2617 return 0; 2618 } 2619 handleUceRemoveRequestDisallowedStatus()2620 private int handleUceRemoveRequestDisallowedStatus() { 2621 int subId = getSubId("uce remove-request-disallowed-status"); 2622 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2623 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID"); 2624 return -1; 2625 } 2626 boolean result; 2627 try { 2628 result = mInterface.removeUceRequestDisallowedStatus(subId); 2629 } catch (RemoteException e) { 2630 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage()); 2631 return -1; 2632 } 2633 if (VDBG) { 2634 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result); 2635 } 2636 getOutPrintWriter().println(result); 2637 return 0; 2638 } 2639 handleUceSetCapRequestTimeout()2640 private int handleUceSetCapRequestTimeout() { 2641 int subId = getSubId("uce set-capabilities-request-timeout"); 2642 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2643 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID"); 2644 return -1; 2645 } 2646 long timeoutAfterMs = Long.valueOf(getNextArg()); 2647 boolean result; 2648 try { 2649 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs); 2650 } catch (RemoteException e) { 2651 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage()); 2652 return -1; 2653 } 2654 if (VDBG) { 2655 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result); 2656 } 2657 getOutPrintWriter().println(result); 2658 return 0; 2659 } 2660 handleSrcSetTestEnabledCommand()2661 private int handleSrcSetTestEnabledCommand() { 2662 String enabledStr = getNextArg(); 2663 if (enabledStr == null) { 2664 return -1; 2665 } 2666 2667 try { 2668 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr)); 2669 if (VDBG) { 2670 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done"); 2671 } 2672 getOutPrintWriter().println("Done"); 2673 } catch (NumberFormatException | RemoteException e) { 2674 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage()); 2675 getErrPrintWriter().println("Exception: " + e.getMessage()); 2676 return -1; 2677 } 2678 return 0; 2679 } 2680 handleSrcGetTestEnabledCommand()2681 private int handleSrcGetTestEnabledCommand() { 2682 boolean result = false; 2683 try { 2684 result = mInterface.getRcsSingleRegistrationTestModeEnabled(); 2685 } catch (RemoteException e) { 2686 return -1; 2687 } 2688 if (VDBG) { 2689 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result); 2690 } 2691 getOutPrintWriter().println(result); 2692 return 0; 2693 } 2694 handleUceOverridePublishCaps()2695 private int handleUceOverridePublishCaps() { 2696 int subId = getSubId("uce override-published-caps"); 2697 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2698 return -1; 2699 } 2700 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES] 2701 String operation = getNextArgRequired(); 2702 String caps = getNextArg(); 2703 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation) 2704 && !"list".equals(operation)) { 2705 getErrPrintWriter().println("Invalid operation: " + operation); 2706 return -1; 2707 } 2708 2709 // add/remove requires capabilities to be specified. 2710 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) { 2711 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be " 2712 + "specified"); 2713 return -1; 2714 } 2715 2716 ArraySet<String> capSet = new ArraySet<>(); 2717 if (!TextUtils.isEmpty(caps)) { 2718 String[] capArray = caps.split(":"); 2719 for (String cap : capArray) { 2720 // Allow unknown tags to be passed in as well. 2721 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap))); 2722 } 2723 } 2724 2725 RcsContactUceCapability result = null; 2726 try { 2727 switch (operation) { 2728 case "add": 2729 result = mInterface.addUceRegistrationOverrideShell(subId, 2730 new ArrayList<>(capSet)); 2731 break; 2732 case "remove": 2733 result = mInterface.removeUceRegistrationOverrideShell(subId, 2734 new ArrayList<>(capSet)); 2735 break; 2736 case "clear": 2737 result = mInterface.clearUceRegistrationOverrideShell(subId); 2738 break; 2739 case "list": 2740 result = mInterface.getLatestRcsContactUceCapabilityShell(subId); 2741 break; 2742 } 2743 } catch (RemoteException e) { 2744 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage()); 2745 getErrPrintWriter().println("Exception: " + e.getMessage()); 2746 return -1; 2747 } catch (ServiceSpecificException sse) { 2748 // Reconstruct ImsException 2749 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode); 2750 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException); 2751 getErrPrintWriter().println("Exception: " + imsException); 2752 return -1; 2753 } 2754 if (result == null) { 2755 getErrPrintWriter().println("Service not available"); 2756 return -1; 2757 } 2758 getOutPrintWriter().println(result); 2759 return 0; 2760 } 2761 handleUceGetPidfXml()2762 private int handleUceGetPidfXml() { 2763 int subId = getSubId("uce get-last-publish-pidf"); 2764 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2765 return -1; 2766 } 2767 2768 String result; 2769 try { 2770 result = mInterface.getLastUcePidfXmlShell(subId); 2771 } catch (RemoteException e) { 2772 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage()); 2773 getErrPrintWriter().println("Exception: " + e.getMessage()); 2774 return -1; 2775 } catch (ServiceSpecificException sse) { 2776 // Reconstruct ImsException 2777 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode); 2778 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException); 2779 getErrPrintWriter().println("Exception: " + imsException); 2780 return -1; 2781 } 2782 if (result == null) { 2783 getErrPrintWriter().println("Service not available"); 2784 return -1; 2785 } 2786 getOutPrintWriter().println(result); 2787 return 0; 2788 } 2789 handleSrcSetDeviceEnabledCommand()2790 private int handleSrcSetDeviceEnabledCommand() { 2791 String enabledStr = getNextArg(); 2792 if (enabledStr == null) { 2793 return -1; 2794 } 2795 2796 try { 2797 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr); 2798 if (VDBG) { 2799 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done"); 2800 } 2801 getOutPrintWriter().println("Done"); 2802 } catch (NumberFormatException | RemoteException e) { 2803 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage()); 2804 getErrPrintWriter().println("Exception: " + e.getMessage()); 2805 return -1; 2806 } 2807 return 0; 2808 } 2809 handleSrcGetDeviceEnabledCommand()2810 private int handleSrcGetDeviceEnabledCommand() { 2811 boolean result = false; 2812 try { 2813 result = mInterface.getDeviceSingleRegistrationEnabled(); 2814 } catch (RemoteException e) { 2815 return -1; 2816 } 2817 if (VDBG) { 2818 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result); 2819 } 2820 getOutPrintWriter().println(result); 2821 return 0; 2822 } 2823 handleSrcSetCarrierEnabledCommand()2824 private int handleSrcSetCarrierEnabledCommand() { 2825 //the release time value could be -1 2826 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled") 2827 : SubscriptionManager.getDefaultSubscriptionId(); 2828 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2829 return -1; 2830 } 2831 2832 String enabledStr = getNextArg(); 2833 if (enabledStr == null) { 2834 return -1; 2835 } 2836 2837 try { 2838 boolean result = 2839 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr); 2840 if (VDBG) { 2841 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " " 2842 + enabledStr + ", result=" + result); 2843 } 2844 getOutPrintWriter().println(result); 2845 } catch (NumberFormatException | RemoteException e) { 2846 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " " 2847 + enabledStr + ", error" + e.getMessage()); 2848 getErrPrintWriter().println("Exception: " + e.getMessage()); 2849 return -1; 2850 } 2851 return 0; 2852 } 2853 handleSrcGetCarrierEnabledCommand()2854 private int handleSrcGetCarrierEnabledCommand() { 2855 int subId = getSubId("src get-carrier-enabled"); 2856 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2857 return -1; 2858 } 2859 2860 boolean result = false; 2861 try { 2862 result = mInterface.getCarrierSingleRegistrationEnabled(subId); 2863 } catch (RemoteException e) { 2864 return -1; 2865 } 2866 if (VDBG) { 2867 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result); 2868 } 2869 getOutPrintWriter().println(result); 2870 return 0; 2871 } 2872 handleSrcSetFeatureValidationCommand()2873 private int handleSrcSetFeatureValidationCommand() { 2874 //the release time value could be -1 2875 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation") 2876 : SubscriptionManager.getDefaultSubscriptionId(); 2877 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2878 return -1; 2879 } 2880 2881 String enabledStr = getNextArg(); 2882 if (enabledStr == null) { 2883 return -1; 2884 } 2885 2886 try { 2887 boolean result = 2888 mInterface.setImsFeatureValidationOverride(subId, enabledStr); 2889 if (VDBG) { 2890 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " " 2891 + enabledStr + ", result=" + result); 2892 } 2893 getOutPrintWriter().println(result); 2894 } catch (NumberFormatException | RemoteException e) { 2895 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " " 2896 + enabledStr + ", error" + e.getMessage()); 2897 getErrPrintWriter().println("Exception: " + e.getMessage()); 2898 return -1; 2899 } 2900 return 0; 2901 } 2902 handleSrcGetFeatureValidationCommand()2903 private int handleSrcGetFeatureValidationCommand() { 2904 int subId = getSubId("src get-feature-validation"); 2905 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2906 return -1; 2907 } 2908 2909 Boolean result = false; 2910 try { 2911 result = mInterface.getImsFeatureValidationOverride(subId); 2912 } catch (RemoteException e) { 2913 return -1; 2914 } 2915 if (VDBG) { 2916 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result); 2917 } 2918 getOutPrintWriter().println(result); 2919 return 0; 2920 } 2921 2922 onHelpCallComposer()2923 private void onHelpCallComposer() { 2924 PrintWriter pw = getOutPrintWriter(); 2925 pw.println("Call composer commands"); 2926 pw.println(" callcomposer test-mode enable|disable|query"); 2927 pw.println(" Enables or disables test mode for call composer. In test mode, picture"); 2928 pw.println(" upload/download from carrier servers is disabled, and operations are"); 2929 pw.println(" performed using emulated local files instead."); 2930 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]"); 2931 pw.println(" Simulates an outgoing call being placed with the picture ID as"); 2932 pw.println(" the provided UUID. This triggers storage to the call log."); 2933 pw.println(" callcomposer user-setting [subId] enable|disable|query"); 2934 pw.println(" Enables or disables the user setting for call composer, as set by"); 2935 pw.println(" TelephonyManager#setCallComposerStatus."); 2936 } 2937 handleCallComposerCommand()2938 private int handleCallComposerCommand() { 2939 String arg = getNextArg(); 2940 if (arg == null) { 2941 onHelpCallComposer(); 2942 return 0; 2943 } 2944 2945 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE, 2946 "MODIFY_PHONE_STATE required for call composer shell cmds"); 2947 switch (arg) { 2948 case CALL_COMPOSER_TEST_MODE: { 2949 String enabledStr = getNextArg(); 2950 if (ENABLE.equals(enabledStr)) { 2951 CallComposerPictureManager.sTestMode = true; 2952 } else if (DISABLE.equals(enabledStr)) { 2953 CallComposerPictureManager.sTestMode = false; 2954 } else if (QUERY.equals(enabledStr)) { 2955 getOutPrintWriter().println(CallComposerPictureManager.sTestMode); 2956 } else { 2957 onHelpCallComposer(); 2958 return 1; 2959 } 2960 break; 2961 } 2962 case CALL_COMPOSER_SIMULATE_CALL: { 2963 int subscriptionId = Integer.valueOf(getNextArg()); 2964 String uuidString = getNextArg(); 2965 UUID uuid = UUID.fromString(uuidString); 2966 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>(); 2967 Binder.withCleanCallingIdentity(() -> { 2968 CallComposerPictureManager.getInstance(mContext, subscriptionId) 2969 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete); 2970 }); 2971 try { 2972 Uri uri = storageUriFuture.get(); 2973 getOutPrintWriter().println(String.valueOf(uri)); 2974 } catch (Exception e) { 2975 throw new RuntimeException(e); 2976 } 2977 break; 2978 } 2979 case CALL_COMPOSER_USER_SETTING: { 2980 try { 2981 int subscriptionId = Integer.valueOf(getNextArg()); 2982 String enabledStr = getNextArg(); 2983 if (ENABLE.equals(enabledStr)) { 2984 mInterface.setCallComposerStatus(subscriptionId, 2985 TelephonyManager.CALL_COMPOSER_STATUS_ON); 2986 } else if (DISABLE.equals(enabledStr)) { 2987 mInterface.setCallComposerStatus(subscriptionId, 2988 TelephonyManager.CALL_COMPOSER_STATUS_OFF); 2989 } else if (QUERY.equals(enabledStr)) { 2990 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId) 2991 == TelephonyManager.CALL_COMPOSER_STATUS_ON); 2992 } else { 2993 onHelpCallComposer(); 2994 return 1; 2995 } 2996 } catch (RemoteException e) { 2997 e.printStackTrace(getOutPrintWriter()); 2998 return 1; 2999 } 3000 break; 3001 } 3002 } 3003 return 0; 3004 } 3005 handleHasCarrierPrivilegesCommand()3006 private int handleHasCarrierPrivilegesCommand() { 3007 String packageName = getNextArgRequired(); 3008 3009 boolean hasCarrierPrivileges; 3010 final long token = Binder.clearCallingIdentity(); 3011 try { 3012 hasCarrierPrivileges = 3013 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName) 3014 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 3015 } catch (RemoteException e) { 3016 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e); 3017 getErrPrintWriter().println("Exception: " + e.getMessage()); 3018 return -1; 3019 } finally { 3020 Binder.restoreCallingIdentity(token); 3021 } 3022 3023 getOutPrintWriter().println(hasCarrierPrivileges); 3024 return 0; 3025 } 3026 handleAllowedNetworkTypesCommand(String command)3027 private int handleAllowedNetworkTypesCommand(String command) { 3028 if (!checkShellUid()) { 3029 return -1; 3030 } 3031 3032 PrintWriter errPw = getErrPrintWriter(); 3033 String tag = command + ": "; 3034 String opt; 3035 int subId = -1; 3036 Log.v(LOG_TAG, command + " start"); 3037 3038 while ((opt = getNextOption()) != null) { 3039 if (opt.equals("-s")) { 3040 try { 3041 subId = slotStringToSubId(tag, getNextArgRequired()); 3042 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 3043 errPw.println(tag + "No valid subscription found."); 3044 return -1; 3045 } 3046 } catch (IllegalArgumentException e) { 3047 // Missing slot id 3048 errPw.println(tag + "SLOT_ID expected after -s."); 3049 return -1; 3050 } 3051 } else { 3052 errPw.println(tag + "Unknown option " + opt); 3053 return -1; 3054 } 3055 } 3056 3057 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) { 3058 return handleGetAllowedNetworkTypesCommand(subId); 3059 } 3060 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) { 3061 return handleSetAllowedNetworkTypesCommand(subId); 3062 } 3063 return -1; 3064 } 3065 handleGetAllowedNetworkTypesCommand(int subId)3066 private int handleGetAllowedNetworkTypesCommand(int subId) { 3067 PrintWriter errPw = getErrPrintWriter(); 3068 3069 long result = -1; 3070 try { 3071 if (mInterface != null) { 3072 result = mInterface.getAllowedNetworkTypesForReason(subId, 3073 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER); 3074 } else { 3075 throw new IllegalStateException("telephony service is null."); 3076 } 3077 } catch (RemoteException e) { 3078 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e); 3079 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e); 3080 return -1; 3081 } 3082 3083 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result)); 3084 return 0; 3085 } 3086 handleSetAllowedNetworkTypesCommand(int subId)3087 private int handleSetAllowedNetworkTypesCommand(int subId) { 3088 PrintWriter errPw = getErrPrintWriter(); 3089 3090 String bitmaskString = getNextArg(); 3091 if (TextUtils.isEmpty(bitmaskString)) { 3092 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK"); 3093 return -1; 3094 } 3095 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString); 3096 if (allowedNetworkTypes < 0) { 3097 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK"); 3098 return -1; 3099 } 3100 boolean result = false; 3101 try { 3102 if (mInterface != null) { 3103 result = mInterface.setAllowedNetworkTypesForReason(subId, 3104 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes); 3105 } else { 3106 throw new IllegalStateException("telephony service is null."); 3107 } 3108 } catch (RemoteException e) { 3109 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e); 3110 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e); 3111 return -1; 3112 } 3113 3114 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed"; 3115 if (result) { 3116 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed"; 3117 } 3118 getOutPrintWriter().println(resultMessage); 3119 return 0; 3120 } 3121 convertNetworkTypeBitmaskFromStringToLong(String bitmaskString)3122 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) { 3123 if (TextUtils.isEmpty(bitmaskString)) { 3124 return -1; 3125 } 3126 if (VDBG) { 3127 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString 3128 + ", length: " + bitmaskString.length()); 3129 } 3130 try { 3131 return Long.parseLong(bitmaskString, 2); 3132 } catch (NumberFormatException e) { 3133 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e); 3134 return -1; 3135 } 3136 } 3137 handleRadioSetModemServiceCommand()3138 private int handleRadioSetModemServiceCommand() { 3139 PrintWriter errPw = getErrPrintWriter(); 3140 String serviceName = null; 3141 3142 String opt; 3143 while ((opt = getNextOption()) != null) { 3144 switch (opt) { 3145 case "-s": { 3146 serviceName = getNextArgRequired(); 3147 break; 3148 } 3149 } 3150 } 3151 3152 try { 3153 boolean result = mInterface.setModemService(serviceName); 3154 if (VDBG) { 3155 Log.v(LOG_TAG, 3156 "RadioSetModemService " + serviceName + ", result = " + result); 3157 } 3158 getOutPrintWriter().println(result); 3159 } catch (RemoteException e) { 3160 Log.w(LOG_TAG, 3161 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage()); 3162 errPw.println("Exception: " + e.getMessage()); 3163 return -1; 3164 } 3165 return 0; 3166 } 3167 handleRadioGetModemServiceCommand()3168 private int handleRadioGetModemServiceCommand() { 3169 PrintWriter errPw = getErrPrintWriter(); 3170 String result; 3171 3172 try { 3173 result = mInterface.getModemService(); 3174 getOutPrintWriter().println(result); 3175 } catch (RemoteException e) { 3176 errPw.println("Exception: " + e.getMessage()); 3177 return -1; 3178 } 3179 if (VDBG) { 3180 Log.v(LOG_TAG, "RadioGetModemService, result = " + result); 3181 } 3182 return 0; 3183 } 3184 handleRadioCommand()3185 private int handleRadioCommand() { 3186 String arg = getNextArg(); 3187 if (arg == null) { 3188 onHelpRadio(); 3189 return 0; 3190 } 3191 3192 switch (arg) { 3193 case RADIO_SET_MODEM_SERVICE: 3194 return handleRadioSetModemServiceCommand(); 3195 3196 case RADIO_GET_MODEM_SERVICE: 3197 return handleRadioGetModemServiceCommand(); 3198 } 3199 3200 return -1; 3201 } 3202 handleSetSatelliteServicePackageNameCommand()3203 private int handleSetSatelliteServicePackageNameCommand() { 3204 PrintWriter errPw = getErrPrintWriter(); 3205 String serviceName = null; 3206 3207 String opt; 3208 while ((opt = getNextOption()) != null) { 3209 switch (opt) { 3210 case "-s": { 3211 serviceName = getNextArgRequired(); 3212 break; 3213 } 3214 } 3215 } 3216 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName=" 3217 + serviceName); 3218 3219 try { 3220 boolean result = mInterface.setSatelliteServicePackageName(serviceName); 3221 if (VDBG) { 3222 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName 3223 + ", result = " + result); 3224 } 3225 getOutPrintWriter().println(result); 3226 } catch (RemoteException e) { 3227 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName 3228 + ", error = " + e.getMessage()); 3229 errPw.println("Exception: " + e.getMessage()); 3230 return -1; 3231 } 3232 return 0; 3233 } 3234 handleSetSatelliteGatewayServicePackageNameCommand()3235 private int handleSetSatelliteGatewayServicePackageNameCommand() { 3236 PrintWriter errPw = getErrPrintWriter(); 3237 String serviceName = null; 3238 3239 String opt; 3240 while ((opt = getNextOption()) != null) { 3241 switch (opt) { 3242 case "-s": { 3243 serviceName = getNextArgRequired(); 3244 break; 3245 } 3246 } 3247 } 3248 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName=" 3249 + serviceName); 3250 3251 try { 3252 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName); 3253 if (VDBG) { 3254 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName 3255 + ", result = " + result); 3256 } 3257 getOutPrintWriter().println(result); 3258 } catch (RemoteException e) { 3259 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName 3260 + ", error = " + e.getMessage()); 3261 errPw.println("Exception: " + e.getMessage()); 3262 return -1; 3263 } 3264 return 0; 3265 } 3266 handleSetSatellitePointingUiClassNameCommand()3267 private int handleSetSatellitePointingUiClassNameCommand() { 3268 PrintWriter errPw = getErrPrintWriter(); 3269 String packageName = null; 3270 String className = null; 3271 3272 String opt; 3273 while ((opt = getNextOption()) != null) { 3274 switch (opt) { 3275 case "-p": { 3276 packageName = getNextArgRequired(); 3277 break; 3278 } 3279 case "-c": { 3280 className = getNextArgRequired(); 3281 break; 3282 } 3283 } 3284 } 3285 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName=" 3286 + packageName + ", className=" + className); 3287 3288 try { 3289 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className); 3290 if (VDBG) { 3291 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result); 3292 } 3293 getOutPrintWriter().println(result); 3294 } catch (RemoteException e) { 3295 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName 3296 + ", error = " + e.getMessage()); 3297 errPw.println("Exception: " + e.getMessage()); 3298 return -1; 3299 } 3300 return 0; 3301 } 3302 handleSetEmergencyCallToSatelliteHandoverType()3303 private int handleSetEmergencyCallToSatelliteHandoverType() { 3304 PrintWriter errPw = getErrPrintWriter(); 3305 int handoverType = -1; 3306 int delaySeconds = 0; 3307 3308 String opt; 3309 while ((opt = getNextOption()) != null) { 3310 switch (opt) { 3311 case "-t": { 3312 try { 3313 handoverType = Integer.parseInt(getNextArgRequired()); 3314 } catch (NumberFormatException e) { 3315 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer" 3316 + " for handoverType"); 3317 return -1; 3318 } 3319 break; 3320 } 3321 case "-d": { 3322 try { 3323 delaySeconds = Integer.parseInt(getNextArgRequired()); 3324 } catch (NumberFormatException e) { 3325 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer" 3326 + " for delaySeconds"); 3327 return -1; 3328 } 3329 break; 3330 } 3331 } 3332 } 3333 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType=" 3334 + handoverType + ", delaySeconds=" + delaySeconds); 3335 3336 try { 3337 boolean result = 3338 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds); 3339 if (VDBG) { 3340 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result); 3341 } 3342 getOutPrintWriter().println(result); 3343 } catch (RemoteException e) { 3344 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType 3345 + ", error = " + e.getMessage()); 3346 errPw.println("Exception: " + e.getMessage()); 3347 return -1; 3348 } 3349 return 0; 3350 } 3351 handleSetSatelliteListeningTimeoutDuration()3352 private int handleSetSatelliteListeningTimeoutDuration() { 3353 PrintWriter errPw = getErrPrintWriter(); 3354 long timeoutMillis = 0; 3355 3356 String opt; 3357 while ((opt = getNextOption()) != null) { 3358 switch (opt) { 3359 case "-t": { 3360 timeoutMillis = Long.parseLong(getNextArgRequired()); 3361 break; 3362 } 3363 } 3364 } 3365 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis=" 3366 + timeoutMillis); 3367 3368 try { 3369 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis); 3370 if (VDBG) { 3371 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis 3372 + ", result = " + result); 3373 } 3374 getOutPrintWriter().println(result); 3375 } catch (RemoteException e) { 3376 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis 3377 + ", error = " + e.getMessage()); 3378 errPw.println("Exception: " + e.getMessage()); 3379 return -1; 3380 } 3381 return 0; 3382 } 3383 handleSetDatagramControllerTimeoutDuration()3384 private int handleSetDatagramControllerTimeoutDuration() { 3385 PrintWriter errPw = getErrPrintWriter(); 3386 boolean reset = false; 3387 int timeoutType = 0; 3388 long timeoutMillis = 0; 3389 3390 String opt; 3391 while ((opt = getNextOption()) != null) { 3392 switch (opt) { 3393 case "-d": { 3394 timeoutMillis = Long.parseLong(getNextArgRequired()); 3395 break; 3396 } 3397 case "-r": { 3398 reset = true; 3399 break; 3400 } 3401 case "-t": { 3402 timeoutType = Integer.parseInt(getNextArgRequired()); 3403 break; 3404 } 3405 } 3406 } 3407 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis=" 3408 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType); 3409 3410 try { 3411 boolean result = mInterface.setDatagramControllerTimeoutDuration( 3412 reset, timeoutType, timeoutMillis); 3413 if (VDBG) { 3414 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis 3415 + ", result = " + result); 3416 } 3417 getOutPrintWriter().println(result); 3418 } catch (RemoteException e) { 3419 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis 3420 + ", error = " + e.getMessage()); 3421 errPw.println("Exception: " + e.getMessage()); 3422 return -1; 3423 } 3424 return 0; 3425 } 3426 handleSetDatagramControllerBooleanConfig()3427 private int handleSetDatagramControllerBooleanConfig() { 3428 PrintWriter errPw = getErrPrintWriter(); 3429 boolean reset = false; 3430 int booleanType = 0; 3431 boolean enable = false; 3432 3433 String opt; 3434 while ((opt = getNextOption()) != null) { 3435 switch (opt) { 3436 case "-d": { 3437 enable = Boolean.parseBoolean(getNextArgRequired()); 3438 break; 3439 } 3440 case "-r": { 3441 reset = true; 3442 break; 3443 } 3444 case "-t": { 3445 booleanType = Integer.parseInt(getNextArgRequired()); 3446 break; 3447 } 3448 } 3449 } 3450 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable=" 3451 + enable + ", reset=" + reset + ", booleanType=" + booleanType); 3452 3453 try { 3454 boolean result = mInterface.setDatagramControllerBooleanConfig( 3455 reset, booleanType, enable); 3456 if (VDBG) { 3457 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result); 3458 } 3459 getOutPrintWriter().println(result); 3460 } catch (RemoteException e) { 3461 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage()); 3462 errPw.println("Exception: " + e.getMessage()); 3463 return -1; 3464 } 3465 return 0; 3466 } 3467 handleSetSatelliteControllerTimeoutDuration()3468 private int handleSetSatelliteControllerTimeoutDuration() { 3469 PrintWriter errPw = getErrPrintWriter(); 3470 boolean reset = false; 3471 int timeoutType = 0; 3472 long timeoutMillis = 0; 3473 3474 String opt; 3475 while ((opt = getNextOption()) != null) { 3476 switch (opt) { 3477 case "-d": { 3478 timeoutMillis = Long.parseLong(getNextArgRequired()); 3479 break; 3480 } 3481 case "-r": { 3482 reset = true; 3483 break; 3484 } 3485 case "-t": { 3486 timeoutType = Integer.parseInt(getNextArgRequired()); 3487 break; 3488 } 3489 } 3490 } 3491 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis=" 3492 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType); 3493 3494 try { 3495 boolean result = mInterface.setSatelliteControllerTimeoutDuration( 3496 reset, timeoutType, timeoutMillis); 3497 if (VDBG) { 3498 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis 3499 + ", result = " + result); 3500 } 3501 getOutPrintWriter().println(result); 3502 } catch (RemoteException e) { 3503 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis 3504 + ", error = " + e.getMessage()); 3505 errPw.println("Exception: " + e.getMessage()); 3506 return -1; 3507 } 3508 return 0; 3509 } 3510 handleSetShouldSendDatagramToModemInDemoMode()3511 private int handleSetShouldSendDatagramToModemInDemoMode() { 3512 PrintWriter errPw = getErrPrintWriter(); 3513 String opt; 3514 boolean shouldSendToDemoMode; 3515 3516 if ((opt = getNextArg()) == null) { 3517 errPw.println( 3518 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :" 3519 + " Invalid Argument"); 3520 return -1; 3521 } else { 3522 switch (opt) { 3523 case "true": { 3524 shouldSendToDemoMode = true; 3525 break; 3526 } 3527 case "false": { 3528 shouldSendToDemoMode = false; 3529 break; 3530 } 3531 default: 3532 errPw.println( 3533 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :" 3534 + " Invalid Argument"); 3535 return -1; 3536 } 3537 } 3538 3539 Log.d(LOG_TAG, 3540 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")"); 3541 3542 try { 3543 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode( 3544 shouldSendToDemoMode); 3545 if (VDBG) { 3546 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: " 3547 + result); 3548 } 3549 getOutPrintWriter().println(false); 3550 } catch (RemoteException e) { 3551 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode 3552 + "), error = " + e.getMessage()); 3553 errPw.println("Exception: " + e.getMessage()); 3554 return -1; 3555 } 3556 return 0; 3557 } 3558 handleSetSatelliteAccessControlOverlayConfigs()3559 private int handleSetSatelliteAccessControlOverlayConfigs() { 3560 PrintWriter errPw = getErrPrintWriter(); 3561 boolean reset = false; 3562 boolean isAllowed = false; 3563 String s2CellFile = null; 3564 long locationFreshDurationNanos = 0; 3565 List<String> satelliteCountryCodes = null; 3566 3567 String opt; 3568 while ((opt = getNextOption()) != null) { 3569 switch (opt) { 3570 case "-r": { 3571 reset = true; 3572 break; 3573 } 3574 case "-a": { 3575 isAllowed = true; 3576 break; 3577 } 3578 case "-f": { 3579 s2CellFile = getNextArgRequired(); 3580 break; 3581 } 3582 case "-d": { 3583 locationFreshDurationNanos = Long.parseLong(getNextArgRequired()); 3584 break; 3585 } 3586 case "-c": { 3587 String countryCodeStr = getNextArgRequired(); 3588 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(",")); 3589 break; 3590 } 3591 } 3592 } 3593 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset 3594 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile 3595 + ", locationFreshDurationNanos=" + locationFreshDurationNanos 3596 + ", satelliteCountryCodes=" + satelliteCountryCodes); 3597 3598 try { 3599 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed, 3600 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes); 3601 if (VDBG) { 3602 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result); 3603 } 3604 getOutPrintWriter().println(result); 3605 } catch (RemoteException e) { 3606 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage()); 3607 errPw.println("Exception: " + e.getMessage()); 3608 return -1; 3609 } 3610 return 0; 3611 } 3612 handleSetCountryCodes()3613 private int handleSetCountryCodes() { 3614 PrintWriter errPw = getErrPrintWriter(); 3615 List<String> currentNetworkCountryCodes = new ArrayList<>(); 3616 String locationCountryCode = null; 3617 long locationCountryCodeTimestampNanos = 0; 3618 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>(); 3619 boolean reset = false; 3620 3621 String opt; 3622 while ((opt = getNextOption()) != null) { 3623 switch (opt) { 3624 case "-r": { 3625 reset = true; 3626 break; 3627 } 3628 case "-n": { 3629 String countryCodeStr = getNextArgRequired(); 3630 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(",")); 3631 break; 3632 } 3633 case "-c": { 3634 String cachedNetworkCountryCodeStr = getNextArgRequired(); 3635 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr); 3636 break; 3637 } 3638 case "-l": { 3639 locationCountryCode = getNextArgRequired(); 3640 break; 3641 } 3642 case "-t": { 3643 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired()); 3644 break; 3645 } 3646 } 3647 } 3648 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode=" 3649 + locationCountryCode + ", locationCountryCodeTimestampNanos=" 3650 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes=" 3651 + currentNetworkCountryCodes); 3652 3653 try { 3654 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes, 3655 cachedNetworkCountryCodes, locationCountryCode, 3656 locationCountryCodeTimestampNanos); 3657 if (VDBG) { 3658 Log.v(LOG_TAG, "setCountryCodes result =" + result); 3659 } 3660 getOutPrintWriter().println(result); 3661 } catch (RemoteException e) { 3662 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage()); 3663 errPw.println("Exception: " + e.getMessage()); 3664 return -1; 3665 } 3666 return 0; 3667 } 3668 handleSetOemEnabledSatelliteProvisionStatus()3669 private int handleSetOemEnabledSatelliteProvisionStatus() { 3670 PrintWriter errPw = getErrPrintWriter(); 3671 boolean isProvisioned = false; 3672 boolean reset = true; 3673 3674 String opt; 3675 while ((opt = getNextOption()) != null) { 3676 switch (opt) { 3677 case "-p": { 3678 try { 3679 isProvisioned = Boolean.parseBoolean(getNextArgRequired()); 3680 reset = false; 3681 } catch (Exception e) { 3682 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean " 3683 + "after -p indicating provision status"); 3684 return -1; 3685 } 3686 } 3687 } 3688 } 3689 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset 3690 + ", isProvisioned=" + isProvisioned); 3691 3692 try { 3693 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned); 3694 if (VDBG) { 3695 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result); 3696 } 3697 getOutPrintWriter().println(result); 3698 } catch (RemoteException e) { 3699 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage()); 3700 errPw.println("Exception: " + e.getMessage()); 3701 return -1; 3702 } 3703 return 0; 3704 } 3705 handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache()3706 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() { 3707 PrintWriter errPw = getErrPrintWriter(); 3708 String opt; 3709 String state; 3710 3711 if ((opt = getNextArg()) == null) { 3712 errPw.println( 3713 "adb shell cmd phone set-is-satellite-communication-allowed-for-current" 3714 + "-location-cache :" 3715 + " Invalid Argument"); 3716 return -1; 3717 } else { 3718 switch (opt) { 3719 case "-a": { 3720 state = "cache_allowed"; 3721 break; 3722 } 3723 case "-n": { 3724 state = "cache_clear_and_not_allowed"; 3725 break; 3726 } 3727 case "-c": { 3728 state = "clear_cache_only"; 3729 break; 3730 } 3731 default: 3732 errPw.println( 3733 "adb shell cmd phone set-is-satellite-communication-allowed-for-current" 3734 + "-location-cache :" 3735 + " Invalid Argument"); 3736 return -1; 3737 } 3738 } 3739 3740 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache(" 3741 + state + ")"); 3742 3743 try { 3744 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache( 3745 state); 3746 if (VDBG) { 3747 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache " 3748 + "returns: " 3749 + result); 3750 } 3751 getOutPrintWriter().println(result); 3752 } catch (RemoteException e) { 3753 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache(" 3754 + state + "), error = " + e.getMessage()); 3755 errPw.println("Exception: " + e.getMessage()); 3756 return -1; 3757 } 3758 return 0; 3759 } 3760 3761 /** 3762 * Sample inputStr = "US,UK,CA;2,1,3" 3763 * Sample output: {[US,2], [UK,1], [CA,3]} 3764 */ parseStringLongMap(@ullable String inputStr)3765 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) { 3766 Map<String, Long> result = new HashMap<>(); 3767 if (!TextUtils.isEmpty(inputStr)) { 3768 String[] stringLongArr = inputStr.split(";"); 3769 if (stringLongArr.length != 2) { 3770 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr); 3771 return result; 3772 } 3773 3774 String[] stringArr = stringLongArr[0].split(","); 3775 String[] longArr = stringLongArr[1].split(","); 3776 if (stringArr.length != longArr.length) { 3777 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr); 3778 return result; 3779 } 3780 3781 for (int i = 0; i < stringArr.length; i++) { 3782 try { 3783 result.put(stringArr[i], Long.parseLong(longArr[i])); 3784 } catch (Exception ex) { 3785 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr 3786 + ", ex=" + ex); 3787 return result; 3788 } 3789 } 3790 } 3791 return result; 3792 } 3793 handleCarrierRestrictionStatusCommand()3794 private int handleCarrierRestrictionStatusCommand() { 3795 try { 3796 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService"; 3797 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase( 3798 mInterface.getModemService()))) { 3799 Log.v(LOG_TAG, 3800 "handleCarrierRestrictionStatusCommand, MockModem service check fails or " 3801 + " checkShellUid fails"); 3802 return -1; 3803 } 3804 } catch (RemoteException ex) { 3805 ex.printStackTrace(); 3806 } 3807 String callerInfo = getNextOption(); 3808 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext); 3809 if (TextUtils.isEmpty(callerInfo)) { 3810 // reset the Json content after testing 3811 allowListInfo.updateJsonForTest(null); 3812 return 0; 3813 } 3814 if (callerInfo.startsWith("--")) { 3815 callerInfo = callerInfo.replace("--", ""); 3816 } 3817 String params[] = callerInfo.split(","); 3818 StringBuffer jsonStrBuffer = new StringBuffer(); 3819 String tokens; 3820 for (int index = 0; index < params.length; index++) { 3821 tokens = convertToJsonString(index, params[index]); 3822 if (TextUtils.isEmpty(tokens)) { 3823 // received wrong format from CTS 3824 if (VDBG) { 3825 Log.v(LOG_TAG, 3826 "handleCarrierRestrictionStatusCommand, Shell command parsing error"); 3827 } 3828 return -1; 3829 } 3830 jsonStrBuffer.append(tokens); 3831 } 3832 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString()); 3833 return result; 3834 } 3835 3836 // set-carrier-service-package-override setCarrierServicePackageOverride()3837 private int setCarrierServicePackageOverride() { 3838 PrintWriter errPw = getErrPrintWriter(); 3839 int subId = SubscriptionManager.getDefaultSubscriptionId(); 3840 3841 String opt; 3842 while ((opt = getNextOption()) != null) { 3843 switch (opt) { 3844 case "-s": 3845 try { 3846 subId = Integer.parseInt(getNextArgRequired()); 3847 } catch (NumberFormatException e) { 3848 errPw.println( 3849 "set-carrier-service-package-override requires an integer as a" 3850 + " subscription ID."); 3851 return -1; 3852 } 3853 break; 3854 } 3855 } 3856 3857 String packageName = getNextArg(); 3858 if (packageName == null) { 3859 errPw.println("set-carrier-service-package-override requires a override package name."); 3860 return -1; 3861 } 3862 3863 try { 3864 mInterface.setCarrierServicePackageOverride( 3865 subId, packageName, mContext.getOpPackageName()); 3866 3867 if (VDBG) { 3868 Log.v( 3869 LOG_TAG, 3870 "set-carrier-service-package-override -s " + subId + " " + packageName); 3871 } 3872 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) { 3873 Log.w( 3874 LOG_TAG, 3875 "set-carrier-service-package-override -s " 3876 + subId 3877 + " " 3878 + packageName 3879 + ", error" 3880 + e.getMessage()); 3881 errPw.println("Exception: " + e.getMessage()); 3882 return -1; 3883 } 3884 return 0; 3885 } 3886 3887 // clear-carrier-service-package-override clearCarrierServicePackageOverride()3888 private int clearCarrierServicePackageOverride() { 3889 PrintWriter errPw = getErrPrintWriter(); 3890 int subId = SubscriptionManager.getDefaultSubscriptionId(); 3891 3892 String opt; 3893 while ((opt = getNextOption()) != null) { 3894 switch (opt) { 3895 case "-s": 3896 try { 3897 subId = Integer.parseInt(getNextArgRequired()); 3898 } catch (NumberFormatException e) { 3899 errPw.println( 3900 "clear-carrier-service-package-override requires an integer as a" 3901 + " subscription ID."); 3902 return -1; 3903 } 3904 break; 3905 } 3906 } 3907 3908 try { 3909 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName()); 3910 3911 if (VDBG) { 3912 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId); 3913 } 3914 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) { 3915 Log.w( 3916 LOG_TAG, 3917 "clear-carrier-service-package-override -s " 3918 + subId 3919 + ", error" 3920 + e.getMessage()); 3921 errPw.println("Exception: " + e.getMessage()); 3922 return -1; 3923 } 3924 return 0; 3925 } 3926 handleDomainSelectionCommand()3927 private int handleDomainSelectionCommand() { 3928 String arg = getNextArg(); 3929 if (arg == null) { 3930 onHelpDomainSelection(); 3931 return 0; 3932 } 3933 3934 switch (arg) { 3935 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: { 3936 return handleDomainSelectionSetServiceOverrideCommand(); 3937 } 3938 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: { 3939 return handleDomainSelectionClearServiceOverrideCommand(); 3940 } 3941 } 3942 3943 return -1; 3944 } 3945 3946 // domainselection set-dss-override handleDomainSelectionSetServiceOverrideCommand()3947 private int handleDomainSelectionSetServiceOverrideCommand() { 3948 PrintWriter errPw = getErrPrintWriter(); 3949 3950 String componentName = getNextArg(); 3951 3952 try { 3953 boolean result = mInterface.setDomainSelectionServiceOverride( 3954 ComponentName.unflattenFromString(componentName)); 3955 if (VDBG) { 3956 Log.v(LOG_TAG, "domainselection set-dss-override " 3957 + componentName + ", result=" + result); 3958 } 3959 getOutPrintWriter().println(result); 3960 } catch (Exception e) { 3961 Log.w(LOG_TAG, "domainselection set-dss-override " 3962 + componentName + ", error=" + e.getMessage()); 3963 errPw.println("Exception: " + e.getMessage()); 3964 return -1; 3965 } 3966 return 0; 3967 } 3968 3969 // domainselection clear-dss-override handleDomainSelectionClearServiceOverrideCommand()3970 private int handleDomainSelectionClearServiceOverrideCommand() { 3971 PrintWriter errPw = getErrPrintWriter(); 3972 3973 try { 3974 boolean result = mInterface.clearDomainSelectionServiceOverride(); 3975 if (VDBG) { 3976 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result); 3977 } 3978 getOutPrintWriter().println(result); 3979 } catch (RemoteException e) { 3980 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage()); 3981 errPw.println("Exception: " + e.getMessage()); 3982 return -1; 3983 } 3984 return 0; 3985 } 3986 3987 /** 3988 * Building the string that can be used to build the JsonObject which supports to stub the data 3989 * in CarrierAllowListInfo for CTS testing. sample format is like 3990 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}} 3991 */ convertToJsonString(int index, String param)3992 private String convertToJsonString(int index, String param) { 3993 3994 String token[] = param.split(":"); 3995 String jSonString; 3996 switch (index) { 3997 case 0: 3998 jSonString = "{" + QUOTES + token[1] + QUOTES + ":"; 3999 break; 4000 case 1: 4001 jSonString = 4002 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],"; 4003 break; 4004 case 2: 4005 jSonString = 4006 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}"; 4007 break; 4008 default: 4009 jSonString = null; 4010 } 4011 return jSonString; 4012 } 4013 } 4014