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 android.Manifest; 25 import android.content.Context; 26 import android.net.Uri; 27 import android.os.Binder; 28 import android.os.PersistableBundle; 29 import android.os.Process; 30 import android.os.RemoteException; 31 import android.os.ServiceSpecificException; 32 import android.provider.BlockedNumberContract; 33 import android.telephony.BarringInfo; 34 import android.telephony.CarrierConfigManager; 35 import android.telephony.SubscriptionInfo; 36 import android.telephony.SubscriptionManager; 37 import android.telephony.TelephonyManager; 38 import android.telephony.TelephonyRegistryManager; 39 import android.telephony.emergency.EmergencyNumber; 40 import android.telephony.ims.ImsException; 41 import android.telephony.ims.RcsContactUceCapability; 42 import android.telephony.ims.feature.ImsFeature; 43 import android.text.TextUtils; 44 import android.util.ArrayMap; 45 import android.util.ArraySet; 46 import android.util.Log; 47 import android.util.SparseArray; 48 49 import com.android.ims.rcs.uce.util.FeatureTags; 50 import com.android.internal.telephony.ITelephony; 51 import com.android.internal.telephony.Phone; 52 import com.android.internal.telephony.PhoneFactory; 53 import com.android.internal.telephony.d2d.Communicator; 54 import com.android.internal.telephony.emergency.EmergencyNumberTracker; 55 import com.android.internal.telephony.util.TelephonyUtils; 56 import com.android.modules.utils.BasicShellCommandHandler; 57 import com.android.phone.callcomposer.CallComposerPictureManager; 58 59 import java.io.IOException; 60 import java.io.PrintWriter; 61 import java.util.ArrayList; 62 import java.util.Arrays; 63 import java.util.Collections; 64 import java.util.HashMap; 65 import java.util.List; 66 import java.util.Map; 67 import java.util.Set; 68 import java.util.TreeSet; 69 import java.util.UUID; 70 import java.util.concurrent.CompletableFuture; 71 72 /** 73 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no 74 * permission checks have been done before onCommand was called. Make sure any commands processed 75 * here also contain the appropriate permissions checks. 76 */ 77 78 public class TelephonyShellCommand extends BasicShellCommandHandler { 79 80 private static final String LOG_TAG = "TelephonyShellCommand"; 81 // Don't commit with this true. 82 private static final boolean VDBG = true; 83 private static final int DEFAULT_PHONE_ID = 0; 84 85 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer"; 86 private static final String IMS_SUBCOMMAND = "ims"; 87 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify"; 88 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode"; 89 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode"; 90 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression"; 91 private static final String RESTART_MODEM = "restart-modem"; 92 private static final String UNATTENDED_REBOOT = "unattended-reboot"; 93 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc"; 94 private static final String DATA_TEST_MODE = "data"; 95 private static final String ENABLE = "enable"; 96 private static final String DISABLE = "disable"; 97 private static final String QUERY = "query"; 98 99 private static final String CALL_COMPOSER_TEST_MODE = "test-mode"; 100 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call"; 101 private static final String CALL_COMPOSER_USER_SETTING = "user-setting"; 102 103 private static final String IMS_SET_IMS_SERVICE = "set-ims-service"; 104 private static final String IMS_GET_IMS_SERVICE = "get-ims-service"; 105 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override"; 106 // Used to disable or enable processing of conference event package data from the network. 107 // This is handy for testing scenarios where CEP data does not exist on a network which does 108 // support CEP data. 109 private static final String IMS_CEP = "conference-event-package"; 110 111 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package"; 112 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call"; 113 114 private static final String CC_GET_VALUE = "get-value"; 115 private static final String CC_SET_VALUE = "set-value"; 116 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml"; 117 private static final String CC_CLEAR_VALUES = "clear-values"; 118 119 private static final String GBA_SUBCOMMAND = "gba"; 120 private static final String GBA_SET_SERVICE = "set-service"; 121 private static final String GBA_GET_SERVICE = "get-service"; 122 private static final String GBA_SET_RELEASE_TIME = "set-release"; 123 private static final String GBA_GET_RELEASE_TIME = "get-release"; 124 125 private static final String SINGLE_REGISTATION_CONFIG = "src"; 126 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled"; 127 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled"; 128 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled"; 129 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled"; 130 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled"; 131 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled"; 132 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation"; 133 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation"; 134 135 private static final String D2D_SUBCOMMAND = "d2d"; 136 private static final String D2D_SEND = "send"; 137 private static final String D2D_TRANSPORT = "transport"; 138 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support"; 139 140 private static final String BARRING_SUBCOMMAND = "barring"; 141 private static final String BARRING_SEND_INFO = "send"; 142 143 private static final String RCS_UCE_COMMAND = "uce"; 144 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact"; 145 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability"; 146 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact"; 147 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled"; 148 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled"; 149 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps"; 150 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf"; 151 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS = 152 "remove-request-disallowed-status"; 153 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT = 154 "set-capabilities-request-timeout"; 155 156 private static final String RADIO_SUBCOMMAND = "radio"; 157 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service"; 158 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service"; 159 160 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId. 161 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges"; 162 163 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription"; 164 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription"; 165 166 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation"; 167 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package"; 168 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package"; 169 170 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER = 171 "get-allowed-network-types-for-users"; 172 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER = 173 "set-allowed-network-types-for-users"; 174 // Check if telephony new data stack is enabled. 175 private static final String GET_DATA_MODE = "get-data-mode"; 176 private static final String GET_IMEI = "get-imei"; 177 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping"; 178 // Take advantage of existing methods that already contain permissions checks when possible. 179 private final ITelephony mInterface; 180 181 private SubscriptionManager mSubscriptionManager; 182 private CarrierConfigManager mCarrierConfigManager; 183 private TelephonyRegistryManager mTelephonyRegistryManager; 184 private Context mContext; 185 186 private enum CcType { 187 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING, 188 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN 189 } 190 191 private class CcOptionParseResult { 192 public int mSubId; 193 public boolean mPersistent; 194 } 195 196 // Maps carrier config keys to type. It is possible to infer the type for most carrier config 197 // keys by looking at the end of the string which usually tells the type. 198 // For instance: "xxxx_string", "xxxx_string_array", etc. 199 // The carrier config keys in this map does not follow this convention. It is therefore not 200 // possible to infer the type for these keys by looking at the string. 201 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{ 202 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING); 203 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING); 204 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING); 205 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING); 206 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING); 207 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING); 208 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING); 209 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING); 210 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING); 211 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING); 212 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING, 213 CcType.STRING); 214 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, 215 CcType.STRING_ARRAY); 216 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY, 217 CcType.STRING_ARRAY); 218 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING); 219 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING); 220 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING); 221 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING); 222 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING); 223 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING); 224 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING); 225 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY); 226 } 227 }; 228 229 /** 230 * Map from a shorthand string to the feature tags required in registration required in order 231 * for the RCS feature to be considered "capable". 232 */ 233 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP; 234 static { 235 ArrayMap<String, Set<String>> map = new ArrayMap<>(18); 236 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM)); 237 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION)); 238 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER)); 239 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS)); 240 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL)); 241 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL, 242 FeatureTags.FEATURE_TAG_VIDEO))); 243 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH)); 244 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS)); 245 map.put("call_comp", 246 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING)); 247 map.put("call_comp_mmtel", 248 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY)); 249 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL)); 250 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP)); 251 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH)); 252 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot 253 // version 254 map.put("chatbot", new ArraySet<>(Arrays.asList( 255 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION, 256 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED))); 257 map.put("chatbot_v2", new ArraySet<>(Arrays.asList( 258 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION, 259 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED))); 260 map.put("chatbot_sa", new ArraySet<>(Arrays.asList( 261 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG, 262 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED))); 263 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList( 264 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG, 265 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED))); 266 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE)); 267 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map); 268 } 269 270 TelephonyShellCommand(ITelephony binder, Context context)271 public TelephonyShellCommand(ITelephony binder, Context context) { 272 mInterface = binder; 273 mCarrierConfigManager = 274 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE); 275 mSubscriptionManager = (SubscriptionManager) 276 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 277 mTelephonyRegistryManager = (TelephonyRegistryManager) 278 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE); 279 mContext = context; 280 } 281 282 @Override onCommand(String cmd)283 public int onCommand(String cmd) { 284 if (cmd == null) { 285 return handleDefaultCommands(null); 286 } 287 288 switch (cmd) { 289 case IMS_SUBCOMMAND: { 290 return handleImsCommand(); 291 } 292 case RCS_UCE_COMMAND: 293 return handleRcsUceCommand(); 294 case NUMBER_VERIFICATION_SUBCOMMAND: 295 return handleNumberVerificationCommand(); 296 case EMERGENCY_CALLBACK_MODE: 297 return handleEmergencyCallbackModeCommand(); 298 case EMERGENCY_NUMBER_TEST_MODE: 299 return handleEmergencyNumberTestModeCommand(); 300 case CARRIER_CONFIG_SUBCOMMAND: { 301 return handleCcCommand(); 302 } 303 case DATA_TEST_MODE: 304 return handleDataTestModeCommand(); 305 case END_BLOCK_SUPPRESSION: 306 return handleEndBlockSuppressionCommand(); 307 case GBA_SUBCOMMAND: 308 return handleGbaCommand(); 309 case D2D_SUBCOMMAND: 310 return handleD2dCommand(); 311 case BARRING_SUBCOMMAND: 312 return handleBarringCommand(); 313 case SINGLE_REGISTATION_CONFIG: 314 return handleSingleRegistrationConfigCommand(); 315 case RESTART_MODEM: 316 return handleRestartModemCommand(); 317 case CALL_COMPOSER_SUBCOMMAND: 318 return handleCallComposerCommand(); 319 case UNATTENDED_REBOOT: 320 return handleUnattendedReboot(); 321 case HAS_CARRIER_PRIVILEGES_COMMAND: 322 return handleHasCarrierPrivilegesCommand(); 323 case THERMAL_MITIGATION_COMMAND: 324 return handleThermalMitigationCommand(); 325 case DISABLE_PHYSICAL_SUBSCRIPTION: 326 return handleEnablePhysicalSubscription(false); 327 case ENABLE_PHYSICAL_SUBSCRIPTION: 328 return handleEnablePhysicalSubscription(true); 329 case GET_ALLOWED_NETWORK_TYPES_FOR_USER: 330 case SET_ALLOWED_NETWORK_TYPES_FOR_USER: 331 return handleAllowedNetworkTypesCommand(cmd); 332 case GET_DATA_MODE: 333 return handleGetDataMode(); 334 case GET_IMEI: 335 return handleGetImei(); 336 case GET_SIM_SLOTS_MAPPING: 337 return handleGetSimSlotsMapping(); 338 case RADIO_SUBCOMMAND: 339 return handleRadioCommand(); 340 default: { 341 return handleDefaultCommands(cmd); 342 } 343 } 344 } 345 346 @Override onHelp()347 public void onHelp() { 348 PrintWriter pw = getOutPrintWriter(); 349 pw.println("Telephony Commands:"); 350 pw.println(" help"); 351 pw.println(" Print this help text."); 352 pw.println(" ims"); 353 pw.println(" IMS Commands."); 354 pw.println(" uce"); 355 pw.println(" RCS User Capability Exchange Commands."); 356 pw.println(" emergency-number-test-mode"); 357 pw.println(" Emergency Number Test Mode Commands."); 358 pw.println(" end-block-suppression"); 359 pw.println(" End Block Suppression command."); 360 pw.println(" data"); 361 pw.println(" Data Test Mode Commands."); 362 pw.println(" cc"); 363 pw.println(" Carrier Config Commands."); 364 pw.println(" gba"); 365 pw.println(" GBA Commands."); 366 pw.println(" src"); 367 pw.println(" RCS VoLTE Single Registration Config Commands."); 368 pw.println(" restart-modem"); 369 pw.println(" Restart modem command."); 370 pw.println(" unattended-reboot"); 371 pw.println(" Prepare for unattended reboot."); 372 pw.println(" has-carrier-privileges [package]"); 373 pw.println(" Query carrier privilege status for a package. Prints true or false."); 374 pw.println(" get-allowed-network-types-for-users"); 375 pw.println(" Get the Allowed Network Types."); 376 pw.println(" set-allowed-network-types-for-users"); 377 pw.println(" Set the Allowed Network Types."); 378 pw.println(" radio"); 379 pw.println(" Radio Commands."); 380 onHelpIms(); 381 onHelpUce(); 382 onHelpEmergencyNumber(); 383 onHelpEndBlockSupperssion(); 384 onHelpDataTestMode(); 385 onHelpCc(); 386 onHelpGba(); 387 onHelpSrc(); 388 onHelpD2D(); 389 onHelpDisableOrEnablePhysicalSubscription(); 390 onHelpAllowedNetworkTypes(); 391 onHelpRadio(); 392 onHelpImei(); 393 } 394 onHelpD2D()395 private void onHelpD2D() { 396 PrintWriter pw = getOutPrintWriter(); 397 pw.println("D2D Comms Commands:"); 398 pw.println(" d2d send TYPE VALUE"); 399 pw.println(" Sends a D2D message of specified type and value."); 400 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - " 401 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE)); 402 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString( 403 MESSAGE_CALL_AUDIO_CODEC)); 404 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - " 405 + Communicator.messageToString( 406 MESSAGE_DEVICE_BATTERY_STATE)); 407 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - " 408 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE)); 409 pw.println(" d2d transport TYPE"); 410 pw.println(" Forces the specified D2D transport TYPE to be active. Use the"); 411 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport."); 412 pw.println(" d2d set-device-support true/default"); 413 pw.println(" true - forces device support to be enabled for D2D."); 414 pw.println(" default - clear any previously set force-enable of D2D, reverting to "); 415 pw.println(" the current device's configuration."); 416 } 417 onHelpBarring()418 private void onHelpBarring() { 419 PrintWriter pw = getOutPrintWriter(); 420 pw.println("Barring Commands:"); 421 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED" 422 + " -t CONDITIONAL_BARRING_TIME_SECS"); 423 pw.println(" Notifies of a barring info change for the specified slot id."); 424 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE"); 425 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL"); 426 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL"); 427 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN"); 428 } 429 onHelpIms()430 private void onHelpIms() { 431 PrintWriter pw = getOutPrintWriter(); 432 pw.println("IMS Commands:"); 433 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME"); 434 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound"); 435 pw.println(" ImsService. Options are:"); 436 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option"); 437 pw.println(" is specified, it will choose the default voice SIM slot."); 438 pw.println(" -c: Override the ImsService defined in the carrier configuration."); 439 pw.println(" -d: Override the ImsService defined in the device overlay."); 440 pw.println(" -f: Set the feature that this override if for, if no option is"); 441 pw.println(" specified, the new package name will be used for all features."); 442 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]"); 443 pw.println(" Gets the package name of the currently defined ImsService."); 444 pw.println(" Options are:"); 445 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option"); 446 pw.println(" is specified, it will choose the default voice SIM slot."); 447 pw.println(" -c: The ImsService defined as the carrier configured ImsService."); 448 pw.println(" -d: The ImsService defined as the device default ImsService."); 449 pw.println(" -f: The feature type that the query will be requested for. If none is"); 450 pw.println(" specified, the returned package name will correspond to MMTEL."); 451 pw.println(" ims clear-ims-service-override [-s SLOT_ID]"); 452 pw.println(" Clear all carrier ImsService overrides. This does not work for device "); 453 pw.println(" configuration overrides. Options are:"); 454 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option"); 455 pw.println(" is specified, it will choose the default voice SIM slot."); 456 pw.println(" ims enable [-s SLOT_ID]"); 457 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot"); 458 pw.println(" if none is specified."); 459 pw.println(" ims disable [-s SLOT_ID]"); 460 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM"); 461 pw.println(" slot if none is specified."); 462 pw.println(" ims conference-event-package [enable/disable]"); 463 pw.println(" enables or disables handling or network conference event package data."); 464 } 465 onHelpUce()466 private void onHelpUce() { 467 PrintWriter pw = getOutPrintWriter(); 468 pw.println("User Capability Exchange Commands:"); 469 pw.println(" uce get-eab-contact [PHONE_NUMBER]"); 470 pw.println(" Get the EAB contacts from the EAB database."); 471 pw.println(" Options are:"); 472 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases"); 473 pw.println(" Expected output format :"); 474 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]"); 475 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]"); 476 pw.println(" Remove the EAB contacts from the EAB database."); 477 pw.println(" Options are:"); 478 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 479 pw.println(" is specified, it will choose the default voice SIM slot."); 480 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases"); 481 pw.println(" uce get-device-enabled"); 482 pw.println(" Get the config to check whether the device supports RCS UCE or not."); 483 pw.println(" uce set-device-enabled true|false"); 484 pw.println(" Set the device config for RCS User Capability Exchange to the value."); 485 pw.println(" The value could be true, false."); 486 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]"); 487 pw.println(" Override the existing SIP PUBLISH with different capabilities."); 488 pw.println(" Options are:"); 489 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 490 pw.println(" is specified, it will choose the default voice SIM slot."); 491 pw.println(" add [CAPABILITY]: add a new capability"); 492 pw.println(" remove [CAPABILITY]: remove a capability"); 493 pw.println(" clear: clear all capability overrides"); 494 pw.println(" CAPABILITY: \":\" separated list of capabilities."); 495 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,"); 496 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,"); 497 pw.println(" chatbot_sa, chatbot_role] as well as full length"); 498 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here."); 499 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]"); 500 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no "); 501 pw.println(" PUBLISH is active"); 502 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]"); 503 pw.println(" Remove the UCE is disallowed to execute UCE requests status"); 504 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]"); 505 pw.println(" Set the timeout for contact capabilities request."); 506 } 507 onHelpNumberVerification()508 private void onHelpNumberVerification() { 509 PrintWriter pw = getOutPrintWriter(); 510 pw.println("Number verification commands"); 511 pw.println(" numverify override-package PACKAGE_NAME;"); 512 pw.println(" Set the authorized package for number verification."); 513 pw.println(" Leave the package name blank to reset."); 514 pw.println(" numverify fake-call NUMBER;"); 515 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be"); 516 pw.println(" 1 if the call would have been intercepted, 0 otherwise."); 517 } 518 onHelpThermalMitigation()519 private void onHelpThermalMitigation() { 520 PrintWriter pw = getOutPrintWriter(); 521 pw.println("Thermal mitigation commands"); 522 pw.println(" thermal-mitigation allow-package PACKAGE_NAME"); 523 pw.println(" Set the package as one of authorized packages for thermal mitigation."); 524 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME"); 525 pw.println(" Remove the package from one of the authorized packages for thermal " 526 + "mitigation."); 527 } 528 onHelpDisableOrEnablePhysicalSubscription()529 private void onHelpDisableOrEnablePhysicalSubscription() { 530 PrintWriter pw = getOutPrintWriter(); 531 pw.println("Disable or enable a physical subscription"); 532 pw.println(" disable-physical-subscription SUB_ID"); 533 pw.println(" Disable the physical subscription with the provided subId, if allowed."); 534 pw.println(" enable-physical-subscription SUB_ID"); 535 pw.println(" Enable the physical subscription with the provided subId, if allowed."); 536 } 537 onHelpDataTestMode()538 private void onHelpDataTestMode() { 539 PrintWriter pw = getOutPrintWriter(); 540 pw.println("Mobile Data Test Mode Commands:"); 541 pw.println(" data enable: enable mobile data connectivity"); 542 pw.println(" data disable: disable mobile data connectivity"); 543 } 544 onHelpEmergencyNumber()545 private void onHelpEmergencyNumber() { 546 PrintWriter pw = getOutPrintWriter(); 547 pw.println("Emergency Number Test Mode Commands:"); 548 pw.println(" emergency-number-test-mode "); 549 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in" 550 + " the test mode"); 551 pw.println(" -a <emergency number address>: add an emergency number address for the" 552 + " test mode, only allows '0'-'9', '*', '#' or '+'."); 553 pw.println(" -c: clear the emergency number list in the test mode."); 554 pw.println(" -r <emergency number address>: remove an existing emergency number" 555 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'."); 556 pw.println(" -p: get the full emergency number list in the test mode."); 557 } 558 onHelpEndBlockSupperssion()559 private void onHelpEndBlockSupperssion() { 560 PrintWriter pw = getOutPrintWriter(); 561 pw.println("End Block Suppression command:"); 562 pw.println(" end-block-suppression: disable suppressing blocking by contact"); 563 pw.println(" with emergency services."); 564 } 565 onHelpCc()566 private void onHelpCc() { 567 PrintWriter pw = getOutPrintWriter(); 568 pw.println("Carrier Config Commands:"); 569 pw.println(" cc get-value [-s SLOT_ID] [KEY]"); 570 pw.println(" Print carrier config values."); 571 pw.println(" Options are:"); 572 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 573 pw.println(" is specified, it will choose the default voice SIM slot."); 574 pw.println(" KEY: The key to the carrier config value to print. All values are printed"); 575 pw.println(" if KEY is not specified."); 576 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]"); 577 pw.println(" Set carrier config KEY to NEW_VALUE."); 578 pw.println(" Options are:"); 579 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option"); 580 pw.println(" is specified, it will choose the default voice SIM slot."); 581 pw.println(" -p: Value will be stored persistent"); 582 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be"); 583 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with"); 584 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\""); 585 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\""); 586 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH"); 587 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be"); 588 pw.println(" provided through standard input and follow CarrierConfig XML format."); 589 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml"); 590 pw.println(" Options are:"); 591 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option"); 592 pw.println(" is specified, it will choose the default voice SIM slot."); 593 pw.println(" -p: Value will be stored persistent"); 594 pw.println(" cc clear-values [-s SLOT_ID]"); 595 pw.println(" Clear all carrier override values that has previously been set"); 596 pw.println(" with set-value or set-values-from-xml"); 597 pw.println(" Options are:"); 598 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option"); 599 pw.println(" is specified, it will choose the default voice SIM slot."); 600 } 601 onHelpGba()602 private void onHelpGba() { 603 PrintWriter pw = getOutPrintWriter(); 604 pw.println("Gba Commands:"); 605 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME"); 606 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound."); 607 pw.println(" Options are:"); 608 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 609 pw.println(" is specified, it will choose the default voice SIM slot."); 610 pw.println(" gba get-service [-s SLOT_ID]"); 611 pw.println(" Gets the package name of the currently defined GbaService."); 612 pw.println(" Options are:"); 613 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 614 pw.println(" is specified, it will choose the default voice SIM slot."); 615 pw.println(" gba set-release [-s SLOT_ID] n"); 616 pw.println(" Sets the time to release/unbind GbaService in n milli-second."); 617 pw.println(" Do not release/unbind if n is -1."); 618 pw.println(" Options are:"); 619 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 620 pw.println(" is specified, it will choose the default voice SIM slot."); 621 pw.println(" gba get-release [-s SLOT_ID]"); 622 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond."); 623 pw.println(" Options are:"); 624 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option"); 625 pw.println(" is specified, it will choose the default voice SIM slot."); 626 } 627 onHelpSrc()628 private void onHelpSrc() { 629 PrintWriter pw = getOutPrintWriter(); 630 pw.println("RCS VoLTE Single Registration Config Commands:"); 631 pw.println(" src set-test-enabled true|false"); 632 pw.println(" Sets the test mode enabled for RCS VoLTE single registration."); 633 pw.println(" The value could be true, false, or null(undefined)."); 634 pw.println(" src get-test-enabled"); 635 pw.println(" Gets the test mode for RCS VoLTE single registration."); 636 pw.println(" src set-device-enabled true|false|null"); 637 pw.println(" Sets the device config for RCS VoLTE single registration to the value."); 638 pw.println(" The value could be true, false, or null(undefined)."); 639 pw.println(" src get-device-enabled"); 640 pw.println(" Gets the device config for RCS VoLTE single registration."); 641 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null"); 642 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value."); 643 pw.println(" The value could be true, false, or null(undefined)."); 644 pw.println(" Options are:"); 645 pw.println(" -s: The SIM slot ID to set the config value for. If no option"); 646 pw.println(" is specified, it will choose the default voice SIM slot."); 647 pw.println(" src get-carrier-enabled [-s SLOT_ID]"); 648 pw.println(" Gets the carrier config for RCS VoLTE single registration."); 649 pw.println(" Options are:"); 650 pw.println(" -s: The SIM slot ID to read the config value for. If no option"); 651 pw.println(" is specified, it will choose the default voice SIM slot."); 652 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null"); 653 pw.println(" Sets ims feature validation result."); 654 pw.println(" The value could be true, false, or null(undefined)."); 655 pw.println(" Options are:"); 656 pw.println(" -s: The SIM slot ID to set the config value for. If no option"); 657 pw.println(" is specified, it will choose the default voice SIM slot."); 658 pw.println(" src get-feature-validation [-s SLOT_ID]"); 659 pw.println(" Gets ims feature validation override value."); 660 pw.println(" Options are:"); 661 pw.println(" -s: The SIM slot ID to read the config value for. If no option"); 662 pw.println(" is specified, it will choose the default voice SIM slot."); 663 } 664 onHelpAllowedNetworkTypes()665 private void onHelpAllowedNetworkTypes() { 666 PrintWriter pw = getOutPrintWriter(); 667 pw.println("Allowed Network Types Commands:"); 668 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]"); 669 pw.println(" Print allowed network types value."); 670 pw.println(" Options are:"); 671 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no"); 672 pw.println(" option is specified, it will choose the default voice SIM slot."); 673 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]"); 674 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK."); 675 pw.println(" Options are:"); 676 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no"); 677 pw.println(" option is specified, it will choose the default voice SIM slot."); 678 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type"); 679 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask"); 680 pw.println(" at TelephonyManager.java"); 681 pw.println(" For example:"); 682 pw.println(" NR only : 10000000000000000000"); 683 pw.println(" NR|LTE : 11000001000000000000"); 684 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111"); 685 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111"); 686 pw.println(" LTE only : 01000001000000000000"); 687 } 688 onHelpRadio()689 private void onHelpRadio() { 690 PrintWriter pw = getOutPrintWriter(); 691 pw.println("Radio Commands:"); 692 pw.println(" radio set-modem-service [-s SERVICE_NAME]"); 693 pw.println(" Sets the class name of modem service defined in SERVICE_NAME"); 694 pw.println(" to be the bound. Options are:"); 695 pw.println(" -s: the service name that the modem service should be bound for."); 696 pw.println(" If no option is specified, it will bind to the default."); 697 pw.println(" radio get-modem-service"); 698 pw.println(" Gets the service name of the currently defined modem service."); 699 pw.println(" If it is binding to default, 'default' returns."); 700 pw.println(" If it doesn't bind to any modem service for some reasons,"); 701 pw.println(" the result would be 'unknown'."); 702 } 703 onHelpImei()704 private void onHelpImei() { 705 PrintWriter pw = getOutPrintWriter(); 706 pw.println("IMEI Commands:"); 707 pw.println(" get-imei [-s SLOT_ID]"); 708 pw.println(" Gets the device IMEI. Options are:"); 709 pw.println(" -s: the slot ID to get the IMEI. If no option"); 710 pw.println(" is specified, it will choose the default voice SIM slot."); 711 } 712 handleImsCommand()713 private int handleImsCommand() { 714 String arg = getNextArg(); 715 if (arg == null) { 716 onHelpIms(); 717 return 0; 718 } 719 720 switch (arg) { 721 case IMS_SET_IMS_SERVICE: { 722 return handleImsSetServiceCommand(); 723 } 724 case IMS_GET_IMS_SERVICE: { 725 return handleImsGetServiceCommand(); 726 } 727 case IMS_CLEAR_SERVICE_OVERRIDE: { 728 return handleImsClearCarrierServiceCommand(); 729 } 730 case ENABLE: { 731 return handleEnableIms(); 732 } 733 case DISABLE: { 734 return handleDisableIms(); 735 } 736 case IMS_CEP: { 737 return handleCepChange(); 738 } 739 } 740 741 return -1; 742 } 743 handleDataTestModeCommand()744 private int handleDataTestModeCommand() { 745 PrintWriter errPw = getErrPrintWriter(); 746 String arg = getNextArgRequired(); 747 if (arg == null) { 748 onHelpDataTestMode(); 749 return 0; 750 } 751 switch (arg) { 752 case ENABLE: { 753 try { 754 mInterface.enableDataConnectivity(mContext.getOpPackageName()); 755 } catch (RemoteException ex) { 756 Log.w(LOG_TAG, "data enable, error " + ex.getMessage()); 757 errPw.println("Exception: " + ex.getMessage()); 758 return -1; 759 } 760 break; 761 } 762 case DISABLE: { 763 try { 764 mInterface.disableDataConnectivity(mContext.getOpPackageName()); 765 } catch (RemoteException ex) { 766 Log.w(LOG_TAG, "data disable, error " + ex.getMessage()); 767 errPw.println("Exception: " + ex.getMessage()); 768 return -1; 769 } 770 break; 771 } 772 default: 773 onHelpDataTestMode(); 774 break; 775 } 776 return 0; 777 } 778 handleEmergencyCallbackModeCommand()779 private int handleEmergencyCallbackModeCommand() { 780 PrintWriter errPw = getErrPrintWriter(); 781 try { 782 mInterface.startEmergencyCallbackMode(); 783 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered"); 784 } catch (RemoteException ex) { 785 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage()); 786 errPw.println("Exception: " + ex.getMessage()); 787 return -1; 788 } 789 return 0; 790 } 791 handleEmergencyNumberTestModeCommand()792 private int handleEmergencyNumberTestModeCommand() { 793 PrintWriter errPw = getErrPrintWriter(); 794 String opt = getNextOption(); 795 if (opt == null) { 796 onHelpEmergencyNumber(); 797 return 0; 798 } 799 800 switch (opt) { 801 case "-a": { 802 String emergencyNumberCmd = getNextArgRequired(); 803 if (emergencyNumberCmd == null 804 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) { 805 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs" 806 + " to be specified after -a in the command "); 807 return -1; 808 } 809 try { 810 mInterface.updateEmergencyNumberListTestMode( 811 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE, 812 new EmergencyNumber(emergencyNumberCmd, "", "", 813 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 814 new ArrayList<String>(), 815 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST, 816 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 817 } catch (RemoteException ex) { 818 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd 819 + ", error " + ex.getMessage()); 820 errPw.println("Exception: " + ex.getMessage()); 821 return -1; 822 } 823 break; 824 } 825 case "-c": { 826 try { 827 mInterface.updateEmergencyNumberListTestMode( 828 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null); 829 } catch (RemoteException ex) { 830 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage()); 831 errPw.println("Exception: " + ex.getMessage()); 832 return -1; 833 } 834 break; 835 } 836 case "-r": { 837 String emergencyNumberCmd = getNextArgRequired(); 838 if (emergencyNumberCmd == null 839 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) { 840 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs" 841 + " to be specified after -r in the command "); 842 return -1; 843 } 844 try { 845 mInterface.updateEmergencyNumberListTestMode( 846 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE, 847 new EmergencyNumber(emergencyNumberCmd, "", "", 848 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 849 new ArrayList<String>(), 850 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST, 851 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN)); 852 } catch (RemoteException ex) { 853 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd 854 + ", error " + ex.getMessage()); 855 errPw.println("Exception: " + ex.getMessage()); 856 return -1; 857 } 858 break; 859 } 860 case "-p": { 861 try { 862 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode()); 863 } catch (RemoteException ex) { 864 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage()); 865 errPw.println("Exception: " + ex.getMessage()); 866 return -1; 867 } 868 break; 869 } 870 default: 871 onHelpEmergencyNumber(); 872 break; 873 } 874 return 0; 875 } 876 handleNumberVerificationCommand()877 private int handleNumberVerificationCommand() { 878 String arg = getNextArg(); 879 if (arg == null) { 880 onHelpNumberVerification(); 881 return 0; 882 } 883 884 if (!checkShellUid()) { 885 return -1; 886 } 887 888 switch (arg) { 889 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: { 890 NumberVerificationManager.overrideAuthorizedPackage(getNextArg()); 891 return 0; 892 } 893 case NUMBER_VERIFICATION_FAKE_CALL: { 894 boolean val = NumberVerificationManager.getInstance() 895 .checkIncomingCall(getNextArg()); 896 getOutPrintWriter().println(val ? "1" : "0"); 897 return 0; 898 } 899 } 900 901 return -1; 902 } 903 subIsEsim(int subId)904 private boolean subIsEsim(int subId) { 905 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId); 906 if (info != null) { 907 return info.isEmbedded(); 908 } 909 return false; 910 } 911 handleEnablePhysicalSubscription(boolean enable)912 private int handleEnablePhysicalSubscription(boolean enable) { 913 PrintWriter errPw = getErrPrintWriter(); 914 int subId = 0; 915 try { 916 subId = Integer.parseInt(getNextArgRequired()); 917 } catch (NumberFormatException e) { 918 errPw.println((enable ? "enable" : "disable") 919 + "-physical-subscription requires an integer as a subId."); 920 return -1; 921 } 922 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 923 // non user build. 924 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 925 errPw.println("cc: Permission denied."); 926 return -1; 927 } 928 // Verify that the subId represents a physical sub 929 if (subIsEsim(subId)) { 930 errPw.println("SubId " + subId + " is not for a physical subscription"); 931 return -1; 932 } 933 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling") 934 + " physical subscription with subId=" + subId); 935 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable); 936 return 0; 937 } 938 handleThermalMitigationCommand()939 private int handleThermalMitigationCommand() { 940 String arg = getNextArg(); 941 String packageName = getNextArg(); 942 if (arg == null || packageName == null) { 943 onHelpThermalMitigation(); 944 return 0; 945 } 946 947 if (!checkShellUid()) { 948 return -1; 949 } 950 951 switch (arg) { 952 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: { 953 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext); 954 return 0; 955 } 956 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: { 957 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName, 958 mContext); 959 return 0; 960 } 961 default: 962 onHelpThermalMitigation(); 963 } 964 965 return -1; 966 967 } 968 handleD2dCommand()969 private int handleD2dCommand() { 970 String arg = getNextArg(); 971 if (arg == null) { 972 onHelpD2D(); 973 return 0; 974 } 975 976 switch (arg) { 977 case D2D_SEND: { 978 return handleD2dSendCommand(); 979 } 980 case D2D_TRANSPORT: { 981 return handleD2dTransportCommand(); 982 } 983 case D2D_SET_DEVICE_SUPPORT: { 984 return handleD2dDeviceSupportedCommand(); 985 } 986 } 987 988 return -1; 989 } 990 handleD2dSendCommand()991 private int handleD2dSendCommand() { 992 PrintWriter errPw = getErrPrintWriter(); 993 int messageType = -1; 994 int messageValue = -1; 995 996 String arg = getNextArg(); 997 if (arg == null) { 998 onHelpD2D(); 999 return 0; 1000 } 1001 try { 1002 messageType = Integer.parseInt(arg); 1003 } catch (NumberFormatException e) { 1004 errPw.println("message type must be a valid integer"); 1005 return -1; 1006 } 1007 1008 arg = getNextArg(); 1009 if (arg == null) { 1010 onHelpD2D(); 1011 return 0; 1012 } 1013 try { 1014 messageValue = Integer.parseInt(arg); 1015 } catch (NumberFormatException e) { 1016 errPw.println("message value must be a valid integer"); 1017 return -1; 1018 } 1019 1020 try { 1021 mInterface.sendDeviceToDeviceMessage(messageType, messageValue); 1022 } catch (RemoteException e) { 1023 Log.w(LOG_TAG, "d2d send error: " + e.getMessage()); 1024 errPw.println("Exception: " + e.getMessage()); 1025 return -1; 1026 } 1027 1028 return 0; 1029 } 1030 handleD2dTransportCommand()1031 private int handleD2dTransportCommand() { 1032 PrintWriter errPw = getErrPrintWriter(); 1033 1034 String arg = getNextArg(); 1035 if (arg == null) { 1036 onHelpD2D(); 1037 return 0; 1038 } 1039 1040 try { 1041 mInterface.setActiveDeviceToDeviceTransport(arg); 1042 } catch (RemoteException e) { 1043 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage()); 1044 errPw.println("Exception: " + e.getMessage()); 1045 return -1; 1046 } 1047 return 0; 1048 } handleBarringCommand()1049 private int handleBarringCommand() { 1050 String arg = getNextArg(); 1051 if (arg == null) { 1052 onHelpBarring(); 1053 return 0; 1054 } 1055 1056 switch (arg) { 1057 case BARRING_SEND_INFO: { 1058 return handleBarringSendCommand(); 1059 } 1060 } 1061 return -1; 1062 } 1063 handleBarringSendCommand()1064 private int handleBarringSendCommand() { 1065 PrintWriter errPw = getErrPrintWriter(); 1066 int slotId = getDefaultSlot(); 1067 int subId = SubscriptionManager.getSubId(slotId)[0]; 1068 @BarringInfo.BarringServiceInfo.BarringType int barringType = 1069 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL; 1070 boolean isConditionallyBarred = false; 1071 int conditionalBarringTimeSeconds = 0; 1072 1073 String opt; 1074 while ((opt = getNextOption()) != null) { 1075 switch (opt) { 1076 case "-s": { 1077 try { 1078 slotId = Integer.parseInt(getNextArgRequired()); 1079 subId = SubscriptionManager.getSubId(slotId)[0]; 1080 } catch (NumberFormatException e) { 1081 errPw.println("barring send requires an integer as a SLOT_ID."); 1082 return -1; 1083 } 1084 break; 1085 } 1086 case "-b": { 1087 try { 1088 barringType = Integer.parseInt(getNextArgRequired()); 1089 if (barringType < -1 || barringType > 2) { 1090 throw new NumberFormatException(); 1091 } 1092 1093 } catch (NumberFormatException e) { 1094 errPw.println("barring send requires an integer in range [-1,2] as " 1095 + "a BARRING_TYPE."); 1096 return -1; 1097 } 1098 break; 1099 } 1100 case "-c": { 1101 try { 1102 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired()); 1103 } catch (Exception e) { 1104 errPw.println("barring send requires a boolean after -c indicating" 1105 + " conditional barring"); 1106 return -1; 1107 } 1108 break; 1109 } 1110 case "-t": { 1111 try { 1112 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired()); 1113 } catch (NumberFormatException e) { 1114 errPw.println("barring send requires an integer for time of barring" 1115 + " in seconds after -t for conditional barring"); 1116 return -1; 1117 } 1118 break; 1119 } 1120 } 1121 } 1122 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>(); 1123 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo( 1124 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds); 1125 barringServiceInfos.append(0, bsi); 1126 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos); 1127 try { 1128 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo); 1129 } catch (Exception e) { 1130 Log.w(LOG_TAG, "barring send error: " + e.getMessage()); 1131 errPw.println("Exception: " + e.getMessage()); 1132 return -1; 1133 } 1134 return 0; 1135 } 1136 handleD2dDeviceSupportedCommand()1137 private int handleD2dDeviceSupportedCommand() { 1138 PrintWriter errPw = getErrPrintWriter(); 1139 1140 String arg = getNextArg(); 1141 if (arg == null) { 1142 onHelpD2D(); 1143 return 0; 1144 } 1145 1146 boolean isEnabled = "true".equals(arg.toLowerCase()); 1147 try { 1148 mInterface.setDeviceToDeviceForceEnabled(isEnabled); 1149 } catch (RemoteException e) { 1150 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage()); 1151 errPw.println("Exception: " + e.getMessage()); 1152 return -1; 1153 } 1154 return 0; 1155 } 1156 1157 // ims set-ims-service handleImsSetServiceCommand()1158 private int handleImsSetServiceCommand() { 1159 PrintWriter errPw = getErrPrintWriter(); 1160 int slotId = getDefaultSlot(); 1161 Boolean isCarrierService = null; 1162 List<Integer> featuresList = new ArrayList<>(); 1163 1164 String opt; 1165 while ((opt = getNextOption()) != null) { 1166 switch (opt) { 1167 case "-s": { 1168 try { 1169 slotId = Integer.parseInt(getNextArgRequired()); 1170 } catch (NumberFormatException e) { 1171 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1172 return -1; 1173 } 1174 break; 1175 } 1176 case "-c": { 1177 isCarrierService = true; 1178 break; 1179 } 1180 case "-d": { 1181 isCarrierService = false; 1182 break; 1183 } 1184 case "-f": { 1185 String featureString = getNextArgRequired(); 1186 String[] features = featureString.split(","); 1187 for (int i = 0; i < features.length; i++) { 1188 try { 1189 Integer result = Integer.parseInt(features[i]); 1190 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL 1191 || result >= ImsFeature.FEATURE_MAX) { 1192 errPw.println("ims set-ims-service -f " + result 1193 + " is an invalid feature."); 1194 return -1; 1195 } 1196 featuresList.add(result); 1197 } catch (NumberFormatException e) { 1198 errPw.println("ims set-ims-service -f tried to parse " + features[i] 1199 + " as an integer."); 1200 return -1; 1201 } 1202 } 1203 } 1204 } 1205 } 1206 // Mandatory param, either -c or -d 1207 if (isCarrierService == null) { 1208 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set."); 1209 return -1; 1210 } 1211 1212 String packageName = getNextArg(); 1213 1214 try { 1215 if (packageName == null) { 1216 packageName = ""; 1217 } 1218 int[] featureArray = new int[featuresList.size()]; 1219 for (int i = 0; i < featuresList.size(); i++) { 1220 featureArray[i] = featuresList.get(i); 1221 } 1222 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService, 1223 featureArray, packageName); 1224 if (VDBG) { 1225 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " " 1226 + (isCarrierService ? "-c " : "-d ") 1227 + "-f " + featuresList + " " 1228 + packageName + ", result=" + result); 1229 } 1230 getOutPrintWriter().println(result); 1231 } catch (RemoteException e) { 1232 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " " 1233 + (isCarrierService ? "-c " : "-d ") 1234 + "-f " + featuresList + " " 1235 + packageName + ", error" + e.getMessage()); 1236 errPw.println("Exception: " + e.getMessage()); 1237 return -1; 1238 } 1239 return 0; 1240 } 1241 1242 // ims clear-ims-service-override handleImsClearCarrierServiceCommand()1243 private int handleImsClearCarrierServiceCommand() { 1244 PrintWriter errPw = getErrPrintWriter(); 1245 int slotId = getDefaultSlot(); 1246 1247 String opt; 1248 while ((opt = getNextOption()) != null) { 1249 switch (opt) { 1250 case "-s": { 1251 try { 1252 slotId = Integer.parseInt(getNextArgRequired()); 1253 } catch (NumberFormatException e) { 1254 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1255 return -1; 1256 } 1257 break; 1258 } 1259 } 1260 } 1261 1262 try { 1263 boolean result = mInterface.clearCarrierImsServiceOverride(slotId); 1264 if (VDBG) { 1265 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId 1266 + ", result=" + result); 1267 } 1268 getOutPrintWriter().println(result); 1269 } catch (RemoteException e) { 1270 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId 1271 + ", error" + e.getMessage()); 1272 errPw.println("Exception: " + e.getMessage()); 1273 return -1; 1274 } 1275 return 0; 1276 } 1277 1278 // ims get-ims-service handleImsGetServiceCommand()1279 private int handleImsGetServiceCommand() { 1280 PrintWriter errPw = getErrPrintWriter(); 1281 int slotId = getDefaultSlot(); 1282 Boolean isCarrierService = null; 1283 Integer featureType = ImsFeature.FEATURE_MMTEL; 1284 1285 String opt; 1286 while ((opt = getNextOption()) != null) { 1287 switch (opt) { 1288 case "-s": { 1289 try { 1290 slotId = Integer.parseInt(getNextArgRequired()); 1291 } catch (NumberFormatException e) { 1292 errPw.println("ims set-ims-service requires an integer as a SLOT_ID."); 1293 return -1; 1294 } 1295 break; 1296 } 1297 case "-c": { 1298 isCarrierService = true; 1299 break; 1300 } 1301 case "-d": { 1302 isCarrierService = false; 1303 break; 1304 } 1305 case "-f": { 1306 try { 1307 featureType = Integer.parseInt(getNextArg()); 1308 } catch (NumberFormatException e) { 1309 errPw.println("ims get-ims-service -f requires valid integer as feature."); 1310 return -1; 1311 } 1312 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL 1313 || featureType >= ImsFeature.FEATURE_MAX) { 1314 errPw.println("ims get-ims-service -f invalid feature."); 1315 return -1; 1316 } 1317 } 1318 } 1319 } 1320 // Mandatory param, either -c or -d 1321 if (isCarrierService == null) { 1322 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set."); 1323 return -1; 1324 } 1325 1326 String result; 1327 try { 1328 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType); 1329 } catch (RemoteException e) { 1330 return -1; 1331 } 1332 if (VDBG) { 1333 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " " 1334 + (isCarrierService ? "-c " : "-d ") 1335 + (featureType != null ? ("-f " + featureType) : "") + " , returned: " 1336 + result); 1337 } 1338 getOutPrintWriter().println(result); 1339 return 0; 1340 } 1341 handleEnableIms()1342 private int handleEnableIms() { 1343 int slotId = getDefaultSlot(); 1344 String opt; 1345 while ((opt = getNextOption()) != null) { 1346 switch (opt) { 1347 case "-s": { 1348 try { 1349 slotId = Integer.parseInt(getNextArgRequired()); 1350 } catch (NumberFormatException e) { 1351 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID."); 1352 return -1; 1353 } 1354 break; 1355 } 1356 } 1357 } 1358 try { 1359 mInterface.enableIms(slotId); 1360 } catch (RemoteException e) { 1361 return -1; 1362 } 1363 if (VDBG) { 1364 Log.v(LOG_TAG, "ims enable -s " + slotId); 1365 } 1366 return 0; 1367 } 1368 handleDisableIms()1369 private int handleDisableIms() { 1370 int slotId = getDefaultSlot(); 1371 String opt; 1372 while ((opt = getNextOption()) != null) { 1373 switch (opt) { 1374 case "-s": { 1375 try { 1376 slotId = Integer.parseInt(getNextArgRequired()); 1377 } catch (NumberFormatException e) { 1378 getErrPrintWriter().println( 1379 "ims disable requires an integer as a SLOT_ID."); 1380 return -1; 1381 } 1382 break; 1383 } 1384 } 1385 } 1386 try { 1387 mInterface.disableIms(slotId); 1388 } catch (RemoteException e) { 1389 return -1; 1390 } 1391 if (VDBG) { 1392 Log.v(LOG_TAG, "ims disable -s " + slotId); 1393 } 1394 return 0; 1395 } 1396 handleCepChange()1397 private int handleCepChange() { 1398 Log.i(LOG_TAG, "handleCepChange"); 1399 String opt = getNextArg(); 1400 if (opt == null) { 1401 return -1; 1402 } 1403 boolean isCepEnabled = opt.equals("enable"); 1404 1405 try { 1406 mInterface.setCepEnabled(isCepEnabled); 1407 } catch (RemoteException e) { 1408 return -1; 1409 } 1410 return 0; 1411 } 1412 getDefaultSlot()1413 private int getDefaultSlot() { 1414 int slotId = SubscriptionManager.getDefaultVoicePhoneId(); 1415 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX 1416 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) { 1417 // If there is no default, default to slot 0. 1418 slotId = DEFAULT_PHONE_ID; 1419 } 1420 return slotId; 1421 } 1422 1423 // Parse options related to Carrier Config Commands. parseCcOptions(String tag, boolean allowOptionPersistent)1424 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) { 1425 PrintWriter errPw = getErrPrintWriter(); 1426 CcOptionParseResult result = new CcOptionParseResult(); 1427 result.mSubId = SubscriptionManager.getDefaultSubscriptionId(); 1428 result.mPersistent = false; 1429 1430 String opt; 1431 while ((opt = getNextOption()) != null) { 1432 switch (opt) { 1433 case "-s": { 1434 try { 1435 result.mSubId = slotStringToSubId(tag, getNextArgRequired()); 1436 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) { 1437 errPw.println(tag + "No valid subscription found."); 1438 return null; 1439 } 1440 1441 } catch (IllegalArgumentException e) { 1442 // Missing slot id 1443 errPw.println(tag + "SLOT_ID expected after -s."); 1444 return null; 1445 } 1446 break; 1447 } 1448 case "-p": { 1449 if (allowOptionPersistent) { 1450 result.mPersistent = true; 1451 } else { 1452 errPw.println(tag + "Unexpected option " + opt); 1453 return null; 1454 } 1455 break; 1456 } 1457 default: { 1458 errPw.println(tag + "Unknown option " + opt); 1459 return null; 1460 } 1461 } 1462 } 1463 return result; 1464 } 1465 slotStringToSubId(String tag, String slotString)1466 private int slotStringToSubId(String tag, String slotString) { 1467 int slotId = -1; 1468 try { 1469 slotId = Integer.parseInt(slotString); 1470 } catch (NumberFormatException e) { 1471 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID."); 1472 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1473 } 1474 1475 if (!SubscriptionManager.isValidPhoneId(slotId)) { 1476 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID."); 1477 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1478 } 1479 1480 Phone phone = PhoneFactory.getPhone(slotId); 1481 if (phone == null) { 1482 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + "."); 1483 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1484 } 1485 return phone.getSubId(); 1486 } 1487 checkShellUid()1488 private boolean checkShellUid() { 1489 // adb can run as root or as shell, depending on whether the device is rooted. 1490 return Binder.getCallingUid() == Process.SHELL_UID 1491 || Binder.getCallingUid() == Process.ROOT_UID; 1492 } 1493 handleCcCommand()1494 private int handleCcCommand() { 1495 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 1496 // non user build. 1497 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 1498 getErrPrintWriter().println("cc: Permission denied."); 1499 return -1; 1500 } 1501 1502 String arg = getNextArg(); 1503 if (arg == null) { 1504 onHelpCc(); 1505 return 0; 1506 } 1507 1508 switch (arg) { 1509 case CC_GET_VALUE: { 1510 return handleCcGetValue(); 1511 } 1512 case CC_SET_VALUE: { 1513 return handleCcSetValue(); 1514 } 1515 case CC_SET_VALUES_FROM_XML: { 1516 return handleCcSetValuesFromXml(); 1517 } 1518 case CC_CLEAR_VALUES: { 1519 return handleCcClearValues(); 1520 } 1521 default: { 1522 getErrPrintWriter().println("cc: Unknown argument: " + arg); 1523 } 1524 } 1525 return -1; 1526 } 1527 1528 // cc get-value handleCcGetValue()1529 private int handleCcGetValue() { 1530 PrintWriter errPw = getErrPrintWriter(); 1531 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": "; 1532 String key = null; 1533 1534 // Parse all options 1535 CcOptionParseResult options = parseCcOptions(tag, false); 1536 if (options == null) { 1537 return -1; 1538 } 1539 1540 // Get bundle containing all carrier configuration values. 1541 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1542 if (bundle == null) { 1543 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1544 return -1; 1545 } 1546 1547 // Get the key. 1548 key = getNextArg(); 1549 if (key != null) { 1550 // A key was provided. Verify if it is a valid key 1551 if (!bundle.containsKey(key)) { 1552 errPw.println(tag + key + " is not a valid key."); 1553 return -1; 1554 } 1555 1556 // Print the carrier config value for key. 1557 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle)); 1558 } else { 1559 // No key provided. Show all values. 1560 // Iterate over a sorted list of all carrier config keys and print them. 1561 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet()); 1562 for (String k : sortedSet) { 1563 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle)); 1564 } 1565 } 1566 return 0; 1567 } 1568 1569 // cc set-value handleCcSetValue()1570 private int handleCcSetValue() { 1571 PrintWriter errPw = getErrPrintWriter(); 1572 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": "; 1573 1574 // Parse all options 1575 CcOptionParseResult options = parseCcOptions(tag, true); 1576 if (options == null) { 1577 return -1; 1578 } 1579 1580 // Get bundle containing all current carrier configuration values. 1581 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1582 if (originalValues == null) { 1583 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1584 return -1; 1585 } 1586 1587 // Get the key. 1588 String key = getNextArg(); 1589 if (key == null || key.equals("")) { 1590 errPw.println(tag + "KEY is missing"); 1591 return -1; 1592 } 1593 1594 // Verify if the key is valid 1595 if (!originalValues.containsKey(key)) { 1596 errPw.println(tag + key + " is not a valid key."); 1597 return -1; 1598 } 1599 1600 // Remaining arguments is a list of new values. Add them all into an ArrayList. 1601 ArrayList<String> valueList = new ArrayList<String>(); 1602 while (peekNextArg() != null) { 1603 valueList.add(getNextArg()); 1604 } 1605 1606 // Find the type of the carrier config value 1607 CcType type = getType(tag, key, originalValues); 1608 if (type == CcType.UNKNOWN) { 1609 errPw.println(tag + "ERROR: Not possible to override key with unknown type."); 1610 return -1; 1611 } 1612 if (type == CcType.PERSISTABLE_BUNDLE) { 1613 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. " 1614 + "Use set-values-from-xml instead."); 1615 return -1; 1616 } 1617 1618 // Create an override bundle containing the key and value that should be overriden. 1619 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList); 1620 if (overrideBundle == null) { 1621 return -1; 1622 } 1623 1624 // Override the value 1625 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent); 1626 1627 // Find bundle containing all new carrier configuration values after the override. 1628 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1629 if (newValues == null) { 1630 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1631 return -1; 1632 } 1633 1634 // Print the original and new value. 1635 String originalValueString = ccValueToString(key, type, originalValues); 1636 String newValueString = ccValueToString(key, type, newValues); 1637 getOutPrintWriter().println("Previous value: \n" + originalValueString); 1638 getOutPrintWriter().println("New value: \n" + newValueString); 1639 1640 return 0; 1641 } 1642 1643 // cc set-values-from-xml handleCcSetValuesFromXml()1644 private int handleCcSetValuesFromXml() { 1645 PrintWriter errPw = getErrPrintWriter(); 1646 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": "; 1647 1648 // Parse all options 1649 CcOptionParseResult options = parseCcOptions(tag, true); 1650 if (options == null) { 1651 return -1; 1652 } 1653 1654 // Get bundle containing all current carrier configuration values. 1655 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1656 if (originalValues == null) { 1657 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1658 return -1; 1659 } 1660 1661 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag); 1662 if (overrideBundle == null) { 1663 return -1; 1664 } 1665 1666 // Verify all values are valid types 1667 for (String key : overrideBundle.keySet()) { 1668 CcType type = getType(tag, key, originalValues); 1669 if (type == CcType.UNKNOWN) { 1670 errPw.println(tag + "ERROR: Not possible to override key with unknown type."); 1671 return -1; 1672 } 1673 } 1674 1675 // Override the value 1676 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent); 1677 1678 // Find bundle containing all new carrier configuration values after the override. 1679 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId); 1680 if (newValues == null) { 1681 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + "."); 1682 return -1; 1683 } 1684 1685 // Print the original and new values 1686 overrideBundle.keySet().forEach(key -> { 1687 CcType type = getType(tag, key, originalValues); 1688 String originalValueString = ccValueToString(key, type, originalValues); 1689 String newValueString = ccValueToString(key, type, newValues); 1690 getOutPrintWriter().println("Previous value: \n" + originalValueString); 1691 getOutPrintWriter().println("New value: \n" + newValueString); 1692 }); 1693 1694 return 0; 1695 } 1696 readPersistableBundleFromXml(String tag)1697 private PersistableBundle readPersistableBundleFromXml(String tag) { 1698 PersistableBundle subIdBundles; 1699 try { 1700 subIdBundles = PersistableBundle.readFromStream(getRawInputStream()); 1701 } catch (IOException | RuntimeException e) { 1702 PrintWriter errPw = getErrPrintWriter(); 1703 errPw.println(tag + e); 1704 return null; 1705 } 1706 1707 return subIdBundles; 1708 } 1709 1710 // cc clear-values handleCcClearValues()1711 private int handleCcClearValues() { 1712 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": "; 1713 1714 // Parse all options 1715 CcOptionParseResult options = parseCcOptions(tag, false); 1716 if (options == null) { 1717 return -1; 1718 } 1719 1720 // Clear all values that has previously been set. 1721 mCarrierConfigManager.overrideConfig(options.mSubId, null, true); 1722 getOutPrintWriter() 1723 .println("All previously set carrier config override values has been cleared"); 1724 return 0; 1725 } 1726 getType(String tag, String key, PersistableBundle bundle)1727 private CcType getType(String tag, String key, PersistableBundle bundle) { 1728 // Find the type by checking the type of the current value stored in the bundle. 1729 Object value = bundle.get(key); 1730 1731 if (CC_TYPE_MAP.containsKey(key)) { 1732 return CC_TYPE_MAP.get(key); 1733 } else if (value != null) { 1734 if (value instanceof Boolean) { 1735 return CcType.BOOLEAN; 1736 } 1737 if (value instanceof Double) { 1738 return CcType.DOUBLE; 1739 } 1740 if (value instanceof double[]) { 1741 return CcType.DOUBLE_ARRAY; 1742 } 1743 if (value instanceof Integer) { 1744 return CcType.INT; 1745 } 1746 if (value instanceof int[]) { 1747 return CcType.INT_ARRAY; 1748 } 1749 if (value instanceof Long) { 1750 return CcType.LONG; 1751 } 1752 if (value instanceof long[]) { 1753 return CcType.LONG_ARRAY; 1754 } 1755 if (value instanceof String) { 1756 return CcType.STRING; 1757 } 1758 if (value instanceof String[]) { 1759 return CcType.STRING_ARRAY; 1760 } 1761 if (value instanceof PersistableBundle) { 1762 return CcType.PERSISTABLE_BUNDLE; 1763 } 1764 } else { 1765 // Current value was null and can therefore not be used in order to find the type. 1766 // Check the name of the key to infer the type. This check is not needed for primitive 1767 // data types (boolean, double, int and long), since they can not be null. 1768 if (key.endsWith("double_array")) { 1769 return CcType.DOUBLE_ARRAY; 1770 } 1771 if (key.endsWith("int_array")) { 1772 return CcType.INT_ARRAY; 1773 } 1774 if (key.endsWith("long_array")) { 1775 return CcType.LONG_ARRAY; 1776 } 1777 if (key.endsWith("string")) { 1778 return CcType.STRING; 1779 } 1780 if (key.endsWith("string_array") || key.endsWith("strings")) { 1781 return CcType.STRING_ARRAY; 1782 } 1783 if (key.endsWith("bundle")) { 1784 return CcType.PERSISTABLE_BUNDLE; 1785 } 1786 } 1787 1788 // Not possible to infer the type by looking at the current value or the key. 1789 PrintWriter errPw = getErrPrintWriter(); 1790 errPw.println(tag + "ERROR: " + key + " has unknown type."); 1791 return CcType.UNKNOWN; 1792 } 1793 ccValueToString(String key, CcType type, PersistableBundle bundle)1794 private String ccValueToString(String key, CcType type, PersistableBundle bundle) { 1795 String result; 1796 StringBuilder valueString = new StringBuilder(); 1797 String typeString = type.toString(); 1798 Object value = bundle.get(key); 1799 1800 if (value == null) { 1801 valueString.append("null"); 1802 } else { 1803 switch (type) { 1804 case DOUBLE_ARRAY: { 1805 // Format the string representation of the int array as value1 value2...... 1806 double[] valueArray = (double[]) value; 1807 for (int i = 0; i < valueArray.length; i++) { 1808 if (i != 0) { 1809 valueString.append(" "); 1810 } 1811 valueString.append(valueArray[i]); 1812 } 1813 break; 1814 } 1815 case INT_ARRAY: { 1816 // Format the string representation of the int array as value1 value2...... 1817 int[] valueArray = (int[]) value; 1818 for (int i = 0; i < valueArray.length; i++) { 1819 if (i != 0) { 1820 valueString.append(" "); 1821 } 1822 valueString.append(valueArray[i]); 1823 } 1824 break; 1825 } 1826 case LONG_ARRAY: { 1827 // Format the string representation of the int array as value1 value2...... 1828 long[] valueArray = (long[]) value; 1829 for (int i = 0; i < valueArray.length; i++) { 1830 if (i != 0) { 1831 valueString.append(" "); 1832 } 1833 valueString.append(valueArray[i]); 1834 } 1835 break; 1836 } 1837 case STRING: { 1838 valueString.append("\"" + value.toString() + "\""); 1839 break; 1840 } 1841 case STRING_ARRAY: { 1842 // Format the string representation of the string array as "value1" "value2".... 1843 String[] valueArray = (String[]) value; 1844 for (int i = 0; i < valueArray.length; i++) { 1845 if (i != 0) { 1846 valueString.append(" "); 1847 } 1848 if (valueArray[i] != null) { 1849 valueString.append("\"" + valueArray[i] + "\""); 1850 } else { 1851 valueString.append("null"); 1852 } 1853 } 1854 break; 1855 } 1856 default: { 1857 valueString.append(value.toString()); 1858 } 1859 } 1860 } 1861 return String.format("%-70s %-15s %s", key, typeString, valueString); 1862 } 1863 getOverrideBundle(String tag, CcType type, String key, ArrayList<String> valueList)1864 private PersistableBundle getOverrideBundle(String tag, CcType type, String key, 1865 ArrayList<String> valueList) { 1866 PrintWriter errPw = getErrPrintWriter(); 1867 PersistableBundle bundle = new PersistableBundle(); 1868 1869 // First verify that a valid number of values has been provided for the type. 1870 switch (type) { 1871 case BOOLEAN: 1872 case DOUBLE: 1873 case INT: 1874 case LONG: { 1875 if (valueList.size() != 1) { 1876 errPw.println(tag + "Expected 1 value for type " + type 1877 + ". Found: " + valueList.size()); 1878 return null; 1879 } 1880 break; 1881 } 1882 case STRING: { 1883 if (valueList.size() > 1) { 1884 errPw.println(tag + "Expected 0 or 1 values for type " + type 1885 + ". Found: " + valueList.size()); 1886 return null; 1887 } 1888 break; 1889 } 1890 } 1891 1892 // Parse the value according to type and add it to the Bundle. 1893 switch (type) { 1894 case BOOLEAN: { 1895 if ("true".equalsIgnoreCase(valueList.get(0))) { 1896 bundle.putBoolean(key, true); 1897 } else if ("false".equalsIgnoreCase(valueList.get(0))) { 1898 bundle.putBoolean(key, false); 1899 } else { 1900 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 1901 return null; 1902 } 1903 break; 1904 } 1905 case DOUBLE: { 1906 try { 1907 bundle.putDouble(key, Double.parseDouble(valueList.get(0))); 1908 } catch (NumberFormatException nfe) { 1909 // Not a valid double 1910 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 1911 return null; 1912 } 1913 break; 1914 } 1915 case DOUBLE_ARRAY: { 1916 double[] valueDoubleArray = null; 1917 if (valueList.size() > 0) { 1918 valueDoubleArray = new double[valueList.size()]; 1919 for (int i = 0; i < valueList.size(); i++) { 1920 try { 1921 valueDoubleArray[i] = Double.parseDouble(valueList.get(i)); 1922 } catch (NumberFormatException nfe) { 1923 // Not a valid double 1924 errPw.println( 1925 tag + "Unable to parse " + valueList.get(i) + " as a double."); 1926 return null; 1927 } 1928 } 1929 } 1930 bundle.putDoubleArray(key, valueDoubleArray); 1931 break; 1932 } 1933 case INT: { 1934 try { 1935 bundle.putInt(key, Integer.parseInt(valueList.get(0))); 1936 } catch (NumberFormatException nfe) { 1937 // Not a valid integer 1938 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type); 1939 return null; 1940 } 1941 break; 1942 } 1943 case INT_ARRAY: { 1944 int[] valueIntArray = null; 1945 if (valueList.size() > 0) { 1946 valueIntArray = new int[valueList.size()]; 1947 for (int i = 0; i < valueList.size(); i++) { 1948 try { 1949 valueIntArray[i] = Integer.parseInt(valueList.get(i)); 1950 } catch (NumberFormatException nfe) { 1951 // Not a valid integer 1952 errPw.println(tag 1953 + "Unable to parse " + valueList.get(i) + " as an integer."); 1954 return null; 1955 } 1956 } 1957 } 1958 bundle.putIntArray(key, valueIntArray); 1959 break; 1960 } 1961 case LONG: { 1962 try { 1963 bundle.putLong(key, Long.parseLong(valueList.get(0))); 1964 } catch (NumberFormatException nfe) { 1965 // Not a valid long 1966 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type); 1967 return null; 1968 } 1969 break; 1970 } 1971 case LONG_ARRAY: { 1972 long[] valueLongArray = null; 1973 if (valueList.size() > 0) { 1974 valueLongArray = new long[valueList.size()]; 1975 for (int i = 0; i < valueList.size(); i++) { 1976 try { 1977 valueLongArray[i] = Long.parseLong(valueList.get(i)); 1978 } catch (NumberFormatException nfe) { 1979 // Not a valid long 1980 errPw.println( 1981 tag + "Unable to parse " + valueList.get(i) + " as a long"); 1982 return null; 1983 } 1984 } 1985 } 1986 bundle.putLongArray(key, valueLongArray); 1987 break; 1988 } 1989 case STRING: { 1990 String value = null; 1991 if (valueList.size() > 0) { 1992 value = valueList.get(0); 1993 } 1994 bundle.putString(key, value); 1995 break; 1996 } 1997 case STRING_ARRAY: { 1998 String[] valueStringArray = null; 1999 if (valueList.size() > 0) { 2000 valueStringArray = new String[valueList.size()]; 2001 valueList.toArray(valueStringArray); 2002 } 2003 bundle.putStringArray(key, valueStringArray); 2004 break; 2005 } 2006 } 2007 return bundle; 2008 } 2009 handleEndBlockSuppressionCommand()2010 private int handleEndBlockSuppressionCommand() { 2011 if (!checkShellUid()) { 2012 return -1; 2013 } 2014 2015 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) { 2016 BlockedNumberContract.SystemContract.endBlockSuppression(mContext); 2017 } 2018 return 0; 2019 } 2020 handleRestartModemCommand()2021 private int handleRestartModemCommand() { 2022 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2023 // non user build. 2024 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2025 getErrPrintWriter().println("RestartModem: Permission denied."); 2026 return -1; 2027 } 2028 2029 boolean result = TelephonyManager.getDefault().rebootRadio(); 2030 getOutPrintWriter().println(result); 2031 2032 return result ? 0 : -1; 2033 } 2034 handleGetImei()2035 private int handleGetImei() { 2036 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2037 // non user build. 2038 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2039 getErrPrintWriter().println("Device IMEI: Permission denied."); 2040 return -1; 2041 } 2042 2043 final long identity = Binder.clearCallingIdentity(); 2044 2045 String imei = null; 2046 String arg = getNextArg(); 2047 if (arg != null) { 2048 try { 2049 int specifiedSlotIndex = Integer.parseInt(arg); 2050 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex); 2051 } catch (NumberFormatException exception) { 2052 PrintWriter errPw = getErrPrintWriter(); 2053 errPw.println("-s requires an integer as slot index."); 2054 return -1; 2055 } 2056 2057 } else { 2058 imei = TelephonyManager.from(mContext).getImei(); 2059 } 2060 getOutPrintWriter().println("Device IMEI: " + imei); 2061 2062 Binder.restoreCallingIdentity(identity); 2063 return 0; 2064 } 2065 handleUnattendedReboot()2066 private int handleUnattendedReboot() { 2067 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2068 // non user build. 2069 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2070 getErrPrintWriter().println("UnattendedReboot: Permission denied."); 2071 return -1; 2072 } 2073 2074 int result = TelephonyManager.getDefault().prepareForUnattendedReboot(); 2075 getOutPrintWriter().println("result: " + result); 2076 2077 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1; 2078 } 2079 handleGetSimSlotsMapping()2080 private int handleGetSimSlotsMapping() { 2081 // Verify that the user is allowed to run the command. Only allowed in rooted device in a 2082 // non user build. 2083 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) { 2084 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied."); 2085 return -1; 2086 } 2087 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class); 2088 String result = telephonyManager.getSimSlotMapping().toString(); 2089 getOutPrintWriter().println("simSlotsMapping: " + result); 2090 2091 return 0; 2092 } 2093 handleGbaCommand()2094 private int handleGbaCommand() { 2095 String arg = getNextArg(); 2096 if (arg == null) { 2097 onHelpGba(); 2098 return 0; 2099 } 2100 2101 switch (arg) { 2102 case GBA_SET_SERVICE: { 2103 return handleGbaSetServiceCommand(); 2104 } 2105 case GBA_GET_SERVICE: { 2106 return handleGbaGetServiceCommand(); 2107 } 2108 case GBA_SET_RELEASE_TIME: { 2109 return handleGbaSetReleaseCommand(); 2110 } 2111 case GBA_GET_RELEASE_TIME: { 2112 return handleGbaGetReleaseCommand(); 2113 } 2114 } 2115 2116 return -1; 2117 } 2118 getSubId(String cmd)2119 private int getSubId(String cmd) { 2120 int slotId = getDefaultSlot(); 2121 String opt = getNextOption(); 2122 if (opt != null && opt.equals("-s")) { 2123 try { 2124 slotId = Integer.parseInt(getNextArgRequired()); 2125 } catch (NumberFormatException e) { 2126 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID."); 2127 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 2128 } 2129 } 2130 int[] subIds = SubscriptionManager.getSubId(slotId); 2131 return subIds[0]; 2132 } 2133 handleGbaSetServiceCommand()2134 private int handleGbaSetServiceCommand() { 2135 int subId = getSubId("gba set-service"); 2136 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2137 return -1; 2138 } 2139 2140 String packageName = getNextArg(); 2141 try { 2142 if (packageName == null) { 2143 packageName = ""; 2144 } 2145 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName); 2146 if (VDBG) { 2147 Log.v(LOG_TAG, "gba set-service -s " + subId + " " 2148 + packageName + ", result=" + result); 2149 } 2150 getOutPrintWriter().println(result); 2151 } catch (RemoteException e) { 2152 Log.w(LOG_TAG, "gba set-service " + subId + " " 2153 + packageName + ", error" + e.getMessage()); 2154 getErrPrintWriter().println("Exception: " + e.getMessage()); 2155 return -1; 2156 } 2157 return 0; 2158 } 2159 handleGbaGetServiceCommand()2160 private int handleGbaGetServiceCommand() { 2161 String result; 2162 2163 int subId = getSubId("gba get-service"); 2164 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2165 return -1; 2166 } 2167 2168 try { 2169 result = mInterface.getBoundGbaService(subId); 2170 } catch (RemoteException e) { 2171 return -1; 2172 } 2173 if (VDBG) { 2174 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result); 2175 } 2176 getOutPrintWriter().println(result); 2177 return 0; 2178 } 2179 handleGbaSetReleaseCommand()2180 private int handleGbaSetReleaseCommand() { 2181 //the release time value could be -1 2182 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release") 2183 : SubscriptionManager.getDefaultSubscriptionId(); 2184 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2185 return -1; 2186 } 2187 2188 String intervalStr = getNextArg(); 2189 if (intervalStr == null) { 2190 return -1; 2191 } 2192 2193 try { 2194 int interval = Integer.parseInt(intervalStr); 2195 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval); 2196 if (VDBG) { 2197 Log.v(LOG_TAG, "gba set-release -s " + subId + " " 2198 + intervalStr + ", result=" + result); 2199 } 2200 getOutPrintWriter().println(result); 2201 } catch (NumberFormatException | RemoteException e) { 2202 Log.w(LOG_TAG, "gba set-release -s " + subId + " " 2203 + intervalStr + ", error" + e.getMessage()); 2204 getErrPrintWriter().println("Exception: " + e.getMessage()); 2205 return -1; 2206 } 2207 return 0; 2208 } 2209 handleGbaGetReleaseCommand()2210 private int handleGbaGetReleaseCommand() { 2211 int subId = getSubId("gba get-release"); 2212 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2213 return -1; 2214 } 2215 2216 int result = 0; 2217 try { 2218 result = mInterface.getGbaReleaseTime(subId); 2219 } catch (RemoteException e) { 2220 return -1; 2221 } 2222 if (VDBG) { 2223 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result); 2224 } 2225 getOutPrintWriter().println(result); 2226 return 0; 2227 } 2228 handleSingleRegistrationConfigCommand()2229 private int handleSingleRegistrationConfigCommand() { 2230 String arg = getNextArg(); 2231 if (arg == null) { 2232 onHelpSrc(); 2233 return 0; 2234 } 2235 2236 switch (arg) { 2237 case SRC_SET_TEST_ENABLED: { 2238 return handleSrcSetTestEnabledCommand(); 2239 } 2240 case SRC_GET_TEST_ENABLED: { 2241 return handleSrcGetTestEnabledCommand(); 2242 } 2243 case SRC_SET_DEVICE_ENABLED: { 2244 return handleSrcSetDeviceEnabledCommand(); 2245 } 2246 case SRC_GET_DEVICE_ENABLED: { 2247 return handleSrcGetDeviceEnabledCommand(); 2248 } 2249 case SRC_SET_CARRIER_ENABLED: { 2250 return handleSrcSetCarrierEnabledCommand(); 2251 } 2252 case SRC_GET_CARRIER_ENABLED: { 2253 return handleSrcGetCarrierEnabledCommand(); 2254 } 2255 case SRC_SET_FEATURE_ENABLED: { 2256 return handleSrcSetFeatureValidationCommand(); 2257 } 2258 case SRC_GET_FEATURE_ENABLED: { 2259 return handleSrcGetFeatureValidationCommand(); 2260 } 2261 } 2262 2263 return -1; 2264 } 2265 handleRcsUceCommand()2266 private int handleRcsUceCommand() { 2267 String arg = getNextArg(); 2268 if (arg == null) { 2269 onHelpUce(); 2270 return 0; 2271 } 2272 2273 switch (arg) { 2274 case UCE_REMOVE_EAB_CONTACT: 2275 return handleRemovingEabContactCommand(); 2276 case UCE_GET_EAB_CONTACT: 2277 return handleGettingEabContactCommand(); 2278 case UCE_GET_EAB_CAPABILITY: 2279 return handleGettingEabCapabilityCommand(); 2280 case UCE_GET_DEVICE_ENABLED: 2281 return handleUceGetDeviceEnabledCommand(); 2282 case UCE_SET_DEVICE_ENABLED: 2283 return handleUceSetDeviceEnabledCommand(); 2284 case UCE_OVERRIDE_PUBLISH_CAPS: 2285 return handleUceOverridePublishCaps(); 2286 case UCE_GET_LAST_PIDF_XML: 2287 return handleUceGetPidfXml(); 2288 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS: 2289 return handleUceRemoveRequestDisallowedStatus(); 2290 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT: 2291 return handleUceSetCapRequestTimeout(); 2292 } 2293 return -1; 2294 } 2295 handleRemovingEabContactCommand()2296 private int handleRemovingEabContactCommand() { 2297 int subId = getSubId("uce remove-eab-contact"); 2298 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2299 return -1; 2300 } 2301 2302 String phoneNumber = getNextArgRequired(); 2303 if (TextUtils.isEmpty(phoneNumber)) { 2304 return -1; 2305 } 2306 int result = 0; 2307 try { 2308 result = mInterface.removeContactFromEab(subId, phoneNumber); 2309 } catch (RemoteException e) { 2310 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage()); 2311 getErrPrintWriter().println("Exception: " + e.getMessage()); 2312 return -1; 2313 } 2314 2315 if (VDBG) { 2316 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result); 2317 } 2318 return 0; 2319 } 2320 handleGettingEabContactCommand()2321 private int handleGettingEabContactCommand() { 2322 String phoneNumber = getNextArgRequired(); 2323 if (TextUtils.isEmpty(phoneNumber)) { 2324 return -1; 2325 } 2326 String result = ""; 2327 try { 2328 result = mInterface.getContactFromEab(phoneNumber); 2329 } catch (RemoteException e) { 2330 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage()); 2331 getErrPrintWriter().println("Exception: " + e.getMessage()); 2332 return -1; 2333 } 2334 2335 if (VDBG) { 2336 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result); 2337 } 2338 getOutPrintWriter().println(result); 2339 return 0; 2340 } 2341 handleGettingEabCapabilityCommand()2342 private int handleGettingEabCapabilityCommand() { 2343 String phoneNumber = getNextArgRequired(); 2344 if (TextUtils.isEmpty(phoneNumber)) { 2345 return -1; 2346 } 2347 String result = ""; 2348 try { 2349 result = mInterface.getCapabilityFromEab(phoneNumber); 2350 } catch (RemoteException e) { 2351 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage()); 2352 getErrPrintWriter().println("Exception: " + e.getMessage()); 2353 return -1; 2354 } 2355 2356 if (VDBG) { 2357 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result); 2358 } 2359 getOutPrintWriter().println(result); 2360 return 0; 2361 } 2362 handleUceGetDeviceEnabledCommand()2363 private int handleUceGetDeviceEnabledCommand() { 2364 boolean result = false; 2365 try { 2366 result = mInterface.getDeviceUceEnabled(); 2367 } catch (RemoteException e) { 2368 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage()); 2369 return -1; 2370 } 2371 if (VDBG) { 2372 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result); 2373 } 2374 getOutPrintWriter().println(result); 2375 return 0; 2376 } 2377 handleUceSetDeviceEnabledCommand()2378 private int handleUceSetDeviceEnabledCommand() { 2379 String enabledStr = getNextArg(); 2380 if (TextUtils.isEmpty(enabledStr)) { 2381 return -1; 2382 } 2383 2384 try { 2385 boolean isEnabled = Boolean.parseBoolean(enabledStr); 2386 mInterface.setDeviceUceEnabled(isEnabled); 2387 if (VDBG) { 2388 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done"); 2389 } 2390 } catch (NumberFormatException | RemoteException e) { 2391 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage()); 2392 getErrPrintWriter().println("Exception: " + e.getMessage()); 2393 return -1; 2394 } 2395 return 0; 2396 } 2397 handleUceRemoveRequestDisallowedStatus()2398 private int handleUceRemoveRequestDisallowedStatus() { 2399 int subId = getSubId("uce remove-request-disallowed-status"); 2400 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2401 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID"); 2402 return -1; 2403 } 2404 boolean result; 2405 try { 2406 result = mInterface.removeUceRequestDisallowedStatus(subId); 2407 } catch (RemoteException e) { 2408 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage()); 2409 return -1; 2410 } 2411 if (VDBG) { 2412 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result); 2413 } 2414 getOutPrintWriter().println(result); 2415 return 0; 2416 } 2417 handleUceSetCapRequestTimeout()2418 private int handleUceSetCapRequestTimeout() { 2419 int subId = getSubId("uce set-capabilities-request-timeout"); 2420 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2421 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID"); 2422 return -1; 2423 } 2424 long timeoutAfterMs = Long.valueOf(getNextArg()); 2425 boolean result; 2426 try { 2427 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs); 2428 } catch (RemoteException e) { 2429 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage()); 2430 return -1; 2431 } 2432 if (VDBG) { 2433 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result); 2434 } 2435 getOutPrintWriter().println(result); 2436 return 0; 2437 } 2438 handleSrcSetTestEnabledCommand()2439 private int handleSrcSetTestEnabledCommand() { 2440 String enabledStr = getNextArg(); 2441 if (enabledStr == null) { 2442 return -1; 2443 } 2444 2445 try { 2446 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr)); 2447 if (VDBG) { 2448 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done"); 2449 } 2450 getOutPrintWriter().println("Done"); 2451 } catch (NumberFormatException | RemoteException e) { 2452 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage()); 2453 getErrPrintWriter().println("Exception: " + e.getMessage()); 2454 return -1; 2455 } 2456 return 0; 2457 } 2458 handleSrcGetTestEnabledCommand()2459 private int handleSrcGetTestEnabledCommand() { 2460 boolean result = false; 2461 try { 2462 result = mInterface.getRcsSingleRegistrationTestModeEnabled(); 2463 } catch (RemoteException e) { 2464 return -1; 2465 } 2466 if (VDBG) { 2467 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result); 2468 } 2469 getOutPrintWriter().println(result); 2470 return 0; 2471 } 2472 handleUceOverridePublishCaps()2473 private int handleUceOverridePublishCaps() { 2474 int subId = getSubId("uce override-published-caps"); 2475 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2476 return -1; 2477 } 2478 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES] 2479 String operation = getNextArgRequired(); 2480 String caps = getNextArg(); 2481 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation) 2482 && !"list".equals(operation)) { 2483 getErrPrintWriter().println("Invalid operation: " + operation); 2484 return -1; 2485 } 2486 2487 // add/remove requires capabilities to be specified. 2488 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) { 2489 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be " 2490 + "specified"); 2491 return -1; 2492 } 2493 2494 ArraySet<String> capSet = new ArraySet<>(); 2495 if (!TextUtils.isEmpty(caps)) { 2496 String[] capArray = caps.split(":"); 2497 for (String cap : capArray) { 2498 // Allow unknown tags to be passed in as well. 2499 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap))); 2500 } 2501 } 2502 2503 RcsContactUceCapability result = null; 2504 try { 2505 switch (operation) { 2506 case "add": 2507 result = mInterface.addUceRegistrationOverrideShell(subId, 2508 new ArrayList<>(capSet)); 2509 break; 2510 case "remove": 2511 result = mInterface.removeUceRegistrationOverrideShell(subId, 2512 new ArrayList<>(capSet)); 2513 break; 2514 case "clear": 2515 result = mInterface.clearUceRegistrationOverrideShell(subId); 2516 break; 2517 case "list": 2518 result = mInterface.getLatestRcsContactUceCapabilityShell(subId); 2519 break; 2520 } 2521 } catch (RemoteException e) { 2522 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage()); 2523 getErrPrintWriter().println("Exception: " + e.getMessage()); 2524 return -1; 2525 } catch (ServiceSpecificException sse) { 2526 // Reconstruct ImsException 2527 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode); 2528 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException); 2529 getErrPrintWriter().println("Exception: " + imsException); 2530 return -1; 2531 } 2532 if (result == null) { 2533 getErrPrintWriter().println("Service not available"); 2534 return -1; 2535 } 2536 getOutPrintWriter().println(result); 2537 return 0; 2538 } 2539 handleUceGetPidfXml()2540 private int handleUceGetPidfXml() { 2541 int subId = getSubId("uce get-last-publish-pidf"); 2542 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2543 return -1; 2544 } 2545 2546 String result; 2547 try { 2548 result = mInterface.getLastUcePidfXmlShell(subId); 2549 } catch (RemoteException e) { 2550 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage()); 2551 getErrPrintWriter().println("Exception: " + e.getMessage()); 2552 return -1; 2553 } catch (ServiceSpecificException sse) { 2554 // Reconstruct ImsException 2555 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode); 2556 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException); 2557 getErrPrintWriter().println("Exception: " + imsException); 2558 return -1; 2559 } 2560 if (result == null) { 2561 getErrPrintWriter().println("Service not available"); 2562 return -1; 2563 } 2564 getOutPrintWriter().println(result); 2565 return 0; 2566 } 2567 handleSrcSetDeviceEnabledCommand()2568 private int handleSrcSetDeviceEnabledCommand() { 2569 String enabledStr = getNextArg(); 2570 if (enabledStr == null) { 2571 return -1; 2572 } 2573 2574 try { 2575 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr); 2576 if (VDBG) { 2577 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done"); 2578 } 2579 getOutPrintWriter().println("Done"); 2580 } catch (NumberFormatException | RemoteException e) { 2581 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage()); 2582 getErrPrintWriter().println("Exception: " + e.getMessage()); 2583 return -1; 2584 } 2585 return 0; 2586 } 2587 handleSrcGetDeviceEnabledCommand()2588 private int handleSrcGetDeviceEnabledCommand() { 2589 boolean result = false; 2590 try { 2591 result = mInterface.getDeviceSingleRegistrationEnabled(); 2592 } catch (RemoteException e) { 2593 return -1; 2594 } 2595 if (VDBG) { 2596 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result); 2597 } 2598 getOutPrintWriter().println(result); 2599 return 0; 2600 } 2601 handleSrcSetCarrierEnabledCommand()2602 private int handleSrcSetCarrierEnabledCommand() { 2603 //the release time value could be -1 2604 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled") 2605 : SubscriptionManager.getDefaultSubscriptionId(); 2606 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2607 return -1; 2608 } 2609 2610 String enabledStr = getNextArg(); 2611 if (enabledStr == null) { 2612 return -1; 2613 } 2614 2615 try { 2616 boolean result = 2617 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr); 2618 if (VDBG) { 2619 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " " 2620 + enabledStr + ", result=" + result); 2621 } 2622 getOutPrintWriter().println(result); 2623 } catch (NumberFormatException | RemoteException e) { 2624 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " " 2625 + enabledStr + ", error" + e.getMessage()); 2626 getErrPrintWriter().println("Exception: " + e.getMessage()); 2627 return -1; 2628 } 2629 return 0; 2630 } 2631 handleSrcGetCarrierEnabledCommand()2632 private int handleSrcGetCarrierEnabledCommand() { 2633 int subId = getSubId("src get-carrier-enabled"); 2634 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2635 return -1; 2636 } 2637 2638 boolean result = false; 2639 try { 2640 result = mInterface.getCarrierSingleRegistrationEnabled(subId); 2641 } catch (RemoteException e) { 2642 return -1; 2643 } 2644 if (VDBG) { 2645 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result); 2646 } 2647 getOutPrintWriter().println(result); 2648 return 0; 2649 } 2650 handleSrcSetFeatureValidationCommand()2651 private int handleSrcSetFeatureValidationCommand() { 2652 //the release time value could be -1 2653 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation") 2654 : SubscriptionManager.getDefaultSubscriptionId(); 2655 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2656 return -1; 2657 } 2658 2659 String enabledStr = getNextArg(); 2660 if (enabledStr == null) { 2661 return -1; 2662 } 2663 2664 try { 2665 boolean result = 2666 mInterface.setImsFeatureValidationOverride(subId, enabledStr); 2667 if (VDBG) { 2668 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " " 2669 + enabledStr + ", result=" + result); 2670 } 2671 getOutPrintWriter().println(result); 2672 } catch (NumberFormatException | RemoteException e) { 2673 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " " 2674 + enabledStr + ", error" + e.getMessage()); 2675 getErrPrintWriter().println("Exception: " + e.getMessage()); 2676 return -1; 2677 } 2678 return 0; 2679 } 2680 handleSrcGetFeatureValidationCommand()2681 private int handleSrcGetFeatureValidationCommand() { 2682 int subId = getSubId("src get-feature-validation"); 2683 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2684 return -1; 2685 } 2686 2687 Boolean result = false; 2688 try { 2689 result = mInterface.getImsFeatureValidationOverride(subId); 2690 } catch (RemoteException e) { 2691 return -1; 2692 } 2693 if (VDBG) { 2694 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result); 2695 } 2696 getOutPrintWriter().println(result); 2697 return 0; 2698 } 2699 2700 onHelpCallComposer()2701 private void onHelpCallComposer() { 2702 PrintWriter pw = getOutPrintWriter(); 2703 pw.println("Call composer commands"); 2704 pw.println(" callcomposer test-mode enable|disable|query"); 2705 pw.println(" Enables or disables test mode for call composer. In test mode, picture"); 2706 pw.println(" upload/download from carrier servers is disabled, and operations are"); 2707 pw.println(" performed using emulated local files instead."); 2708 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]"); 2709 pw.println(" Simulates an outgoing call being placed with the picture ID as"); 2710 pw.println(" the provided UUID. This triggers storage to the call log."); 2711 pw.println(" callcomposer user-setting [subId] enable|disable|query"); 2712 pw.println(" Enables or disables the user setting for call composer, as set by"); 2713 pw.println(" TelephonyManager#setCallComposerStatus."); 2714 } 2715 handleCallComposerCommand()2716 private int handleCallComposerCommand() { 2717 String arg = getNextArg(); 2718 if (arg == null) { 2719 onHelpCallComposer(); 2720 return 0; 2721 } 2722 2723 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE, 2724 "MODIFY_PHONE_STATE required for call composer shell cmds"); 2725 switch (arg) { 2726 case CALL_COMPOSER_TEST_MODE: { 2727 String enabledStr = getNextArg(); 2728 if (ENABLE.equals(enabledStr)) { 2729 CallComposerPictureManager.sTestMode = true; 2730 } else if (DISABLE.equals(enabledStr)) { 2731 CallComposerPictureManager.sTestMode = false; 2732 } else if (QUERY.equals(enabledStr)) { 2733 getOutPrintWriter().println(CallComposerPictureManager.sTestMode); 2734 } else { 2735 onHelpCallComposer(); 2736 return 1; 2737 } 2738 break; 2739 } 2740 case CALL_COMPOSER_SIMULATE_CALL: { 2741 int subscriptionId = Integer.valueOf(getNextArg()); 2742 String uuidString = getNextArg(); 2743 UUID uuid = UUID.fromString(uuidString); 2744 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>(); 2745 Binder.withCleanCallingIdentity(() -> { 2746 CallComposerPictureManager.getInstance(mContext, subscriptionId) 2747 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete); 2748 }); 2749 try { 2750 Uri uri = storageUriFuture.get(); 2751 getOutPrintWriter().println(String.valueOf(uri)); 2752 } catch (Exception e) { 2753 throw new RuntimeException(e); 2754 } 2755 break; 2756 } 2757 case CALL_COMPOSER_USER_SETTING: { 2758 try { 2759 int subscriptionId = Integer.valueOf(getNextArg()); 2760 String enabledStr = getNextArg(); 2761 if (ENABLE.equals(enabledStr)) { 2762 mInterface.setCallComposerStatus(subscriptionId, 2763 TelephonyManager.CALL_COMPOSER_STATUS_ON); 2764 } else if (DISABLE.equals(enabledStr)) { 2765 mInterface.setCallComposerStatus(subscriptionId, 2766 TelephonyManager.CALL_COMPOSER_STATUS_OFF); 2767 } else if (QUERY.equals(enabledStr)) { 2768 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId) 2769 == TelephonyManager.CALL_COMPOSER_STATUS_ON); 2770 } else { 2771 onHelpCallComposer(); 2772 return 1; 2773 } 2774 } catch (RemoteException e) { 2775 e.printStackTrace(getOutPrintWriter()); 2776 return 1; 2777 } 2778 break; 2779 } 2780 } 2781 return 0; 2782 } 2783 handleHasCarrierPrivilegesCommand()2784 private int handleHasCarrierPrivilegesCommand() { 2785 String packageName = getNextArgRequired(); 2786 2787 boolean hasCarrierPrivileges; 2788 final long token = Binder.clearCallingIdentity(); 2789 try { 2790 hasCarrierPrivileges = 2791 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName) 2792 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; 2793 } catch (RemoteException e) { 2794 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e); 2795 getErrPrintWriter().println("Exception: " + e.getMessage()); 2796 return -1; 2797 } finally { 2798 Binder.restoreCallingIdentity(token); 2799 } 2800 2801 getOutPrintWriter().println(hasCarrierPrivileges); 2802 return 0; 2803 } 2804 handleAllowedNetworkTypesCommand(String command)2805 private int handleAllowedNetworkTypesCommand(String command) { 2806 if (!checkShellUid()) { 2807 return -1; 2808 } 2809 2810 PrintWriter errPw = getErrPrintWriter(); 2811 String tag = command + ": "; 2812 String opt; 2813 int subId = -1; 2814 Log.v(LOG_TAG, command + " start"); 2815 2816 while ((opt = getNextOption()) != null) { 2817 if (opt.equals("-s")) { 2818 try { 2819 subId = slotStringToSubId(tag, getNextArgRequired()); 2820 if (!SubscriptionManager.isValidSubscriptionId(subId)) { 2821 errPw.println(tag + "No valid subscription found."); 2822 return -1; 2823 } 2824 } catch (IllegalArgumentException e) { 2825 // Missing slot id 2826 errPw.println(tag + "SLOT_ID expected after -s."); 2827 return -1; 2828 } 2829 } else { 2830 errPw.println(tag + "Unknown option " + opt); 2831 return -1; 2832 } 2833 } 2834 2835 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) { 2836 return handleGetAllowedNetworkTypesCommand(subId); 2837 } 2838 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) { 2839 return handleSetAllowedNetworkTypesCommand(subId); 2840 } 2841 return -1; 2842 } 2843 handleGetAllowedNetworkTypesCommand(int subId)2844 private int handleGetAllowedNetworkTypesCommand(int subId) { 2845 PrintWriter errPw = getErrPrintWriter(); 2846 2847 long result = -1; 2848 try { 2849 if (mInterface != null) { 2850 result = mInterface.getAllowedNetworkTypesForReason(subId, 2851 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER); 2852 } else { 2853 throw new IllegalStateException("telephony service is null."); 2854 } 2855 } catch (RemoteException e) { 2856 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e); 2857 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e); 2858 return -1; 2859 } 2860 2861 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result)); 2862 return 0; 2863 } 2864 handleSetAllowedNetworkTypesCommand(int subId)2865 private int handleSetAllowedNetworkTypesCommand(int subId) { 2866 PrintWriter errPw = getErrPrintWriter(); 2867 2868 String bitmaskString = getNextArg(); 2869 if (TextUtils.isEmpty(bitmaskString)) { 2870 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK"); 2871 return -1; 2872 } 2873 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString); 2874 if (allowedNetworkTypes < 0) { 2875 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK"); 2876 return -1; 2877 } 2878 boolean result = false; 2879 try { 2880 if (mInterface != null) { 2881 result = mInterface.setAllowedNetworkTypesForReason(subId, 2882 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes); 2883 } else { 2884 throw new IllegalStateException("telephony service is null."); 2885 } 2886 } catch (RemoteException e) { 2887 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e); 2888 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e); 2889 return -1; 2890 } 2891 2892 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed"; 2893 if (result) { 2894 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed"; 2895 } 2896 getOutPrintWriter().println(resultMessage); 2897 return 0; 2898 } 2899 convertNetworkTypeBitmaskFromStringToLong(String bitmaskString)2900 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) { 2901 if (TextUtils.isEmpty(bitmaskString)) { 2902 return -1; 2903 } 2904 if (VDBG) { 2905 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString 2906 + ", length: " + bitmaskString.length()); 2907 } 2908 try { 2909 return Long.parseLong(bitmaskString, 2); 2910 } catch (NumberFormatException e) { 2911 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e); 2912 return -1; 2913 } 2914 } 2915 handleGetDataMode()2916 private int handleGetDataMode() { 2917 if (!checkShellUid()) { 2918 return -1; 2919 } 2920 2921 boolean newDataStackEnabled = false; 2922 try { 2923 newDataStackEnabled = mInterface.isUsingNewDataStack(); 2924 } catch (RemoteException e) { 2925 getOutPrintWriter().println("Something went wrong. " + e); 2926 return -1; 2927 } 2928 2929 getOutPrintWriter().println("Telephony is running with the " 2930 + (newDataStackEnabled ? "new" : "old") + " data stack."); 2931 return 0; 2932 } 2933 handleRadioSetModemServiceCommand()2934 private int handleRadioSetModemServiceCommand() { 2935 PrintWriter errPw = getErrPrintWriter(); 2936 String serviceName = null; 2937 2938 String opt; 2939 while ((opt = getNextOption()) != null) { 2940 switch (opt) { 2941 case "-s": { 2942 serviceName = getNextArgRequired(); 2943 break; 2944 } 2945 } 2946 } 2947 2948 try { 2949 boolean result = mInterface.setModemService(serviceName); 2950 if (VDBG) { 2951 Log.v(LOG_TAG, 2952 "RadioSetModemService " + serviceName + ", result = " + result); 2953 } 2954 getOutPrintWriter().println(result); 2955 } catch (RemoteException e) { 2956 Log.w(LOG_TAG, 2957 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage()); 2958 errPw.println("Exception: " + e.getMessage()); 2959 return -1; 2960 } 2961 return 0; 2962 } 2963 handleRadioGetModemServiceCommand()2964 private int handleRadioGetModemServiceCommand() { 2965 PrintWriter errPw = getErrPrintWriter(); 2966 String result; 2967 2968 try { 2969 result = mInterface.getModemService(); 2970 getOutPrintWriter().println(result); 2971 } catch (RemoteException e) { 2972 errPw.println("Exception: " + e.getMessage()); 2973 return -1; 2974 } 2975 if (VDBG) { 2976 Log.v(LOG_TAG, "RadioGetModemService, result = " + result); 2977 } 2978 return 0; 2979 } 2980 handleRadioCommand()2981 private int handleRadioCommand() { 2982 String arg = getNextArg(); 2983 if (arg == null) { 2984 onHelpRadio(); 2985 return 0; 2986 } 2987 2988 switch (arg) { 2989 case RADIO_SET_MODEM_SERVICE: 2990 return handleRadioSetModemServiceCommand(); 2991 2992 case RADIO_GET_MODEM_SERVICE: 2993 return handleRadioGetModemServiceCommand(); 2994 } 2995 2996 return -1; 2997 } 2998 } 2999