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