blob: 2ae8d280370a9956710eafac1f11a0e5bd104169 [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080027import android.annotation.NonNull;
28import android.annotation.Nullable;
Hunsuk Choi13078be2023-09-13 10:55:21 +000029import android.content.ComponentName;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080031import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080032import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010033import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080034import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000036import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070037import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070038import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010039import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070040import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070041import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000042import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070043import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080044import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000045import android.telephony.ims.ImsException;
46import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080047import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080048import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000049import android.util.ArrayMap;
50import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070052import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070053
Brad Ebinger14d467f2021-02-12 06:18:28 +000054import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070055import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080056import com.android.internal.telephony.Phone;
57import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080058import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080059import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080060import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080061import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080062import com.android.phone.callcomposer.CallComposerPictureManager;
Shivakumar Neginal9cd61892022-12-19 04:38:52 +000063import com.android.phone.euicc.EuiccUiDispatcherActivity;
arunvoddud7401012022-12-15 16:08:12 +000064import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070065
Allen Xuee00f0e2022-03-14 21:04:49 +000066import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070067import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080068import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000069import java.util.Arrays;
70import java.util.Collections;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080071import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080072import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000073import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010074import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000075import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010076import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080077import java.util.UUID;
78import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070079
80/**
81 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
82 * permission checks have been done before onCommand was called. Make sure any commands processed
83 * here also contain the appropriate permissions checks.
84 */
85
Hall Liua1548bd2019-12-24 14:14:12 -080086public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087
88 private static final String LOG_TAG = "TelephonyShellCommand";
89 // Don't commit with this true.
90 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070091 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070092
Hall Liuaa4211e2021-01-20 15:43:39 -080093 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070094 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080095 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080096 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080097 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070098 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000099 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +0000100 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100101 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -0800102 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -0800103 private static final String ENABLE = "enable";
104 private static final String DISABLE = "disable";
105 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000106 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000107 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
108 "set-carrier-service-package-override";
109 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
110 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000111 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800112
Hall Liu7135e502021-02-04 16:58:17 -0800113 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800114 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800115 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800116
Brad Ebinger999d3302020-11-25 14:31:39 -0800117 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
118 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
119 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700120 // Used to disable or enable processing of conference event package data from the network.
121 // This is handy for testing scenarios where CEP data does not exist on a network which does
122 // support CEP data.
123 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700124
Hall Liud892bec2018-11-30 14:51:45 -0800125 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800126 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800127
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100128 private static final String CC_GET_VALUE = "get-value";
129 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000130 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100131 private static final String CC_CLEAR_VALUES = "clear-values";
132
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000133 private static final String EUICC_SUBCOMMAND = "euicc";
134 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
135
Hui Wang641e81c2020-10-12 12:14:23 -0700136 private static final String GBA_SUBCOMMAND = "gba";
137 private static final String GBA_SET_SERVICE = "set-service";
138 private static final String GBA_GET_SERVICE = "get-service";
139 private static final String GBA_SET_RELEASE_TIME = "set-release";
140 private static final String GBA_GET_RELEASE_TIME = "get-release";
141
Hui Wang761a6682020-10-31 05:12:53 +0000142 private static final String SINGLE_REGISTATION_CONFIG = "src";
143 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
144 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
145 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
146 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800147 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
148 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800149 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
150 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000151
Tyler Gunn92479152021-01-20 16:30:10 -0800152 private static final String D2D_SUBCOMMAND = "d2d";
153 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800154 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700155 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800156
Nazanin014f41e2021-05-06 17:26:31 -0700157 private static final String BARRING_SUBCOMMAND = "barring";
158 private static final String BARRING_SEND_INFO = "send";
159
James.cf Linbcdf8b32021-01-14 16:44:13 +0800160 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800161 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800162 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800163 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800164 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
165 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000166 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
167 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800168 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
169 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800170 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
171 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800172
jimsun3b9ccac2021-10-26 15:01:23 +0800173 private static final String RADIO_SUBCOMMAND = "radio";
174 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
175 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
176
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800177 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
178 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
179
Jordan Liu0ccee222021-04-27 11:55:13 -0700180 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
181 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
182
Jack Nudelman644b91a2021-03-12 14:09:48 -0800183 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
184 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
185 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700186 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
187 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700188 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
189 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700190 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
191 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700192 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
193 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800194 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
195 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +0000196 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
197 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800198
199 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
200 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700201 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
202 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800203 private static final String SET_COUNTRY_CODES = "set-country-codes";
204 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
205 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800206 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
207 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000208 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
209 "set-should-send-datagram-to-modem-in-demo-mode";
Hakjun Choi4a832d12024-05-28 22:23:55 +0000210 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
211 "set-is-satellite-communication-allowed-for-current-location-cache";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800212
Hunsuk Choi13078be2023-09-13 10:55:21 +0000213 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
214 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
215 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
216
Grant Menke567d48f2022-08-18 20:19:10 +0000217 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
218 + "'*', '#' or '+') needs to be specified after -a in the command ";
219
220 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
221 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
222 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
223
SongFerngWang98dd5992021-05-13 17:50:00 +0800224 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
225 "get-allowed-network-types-for-users";
226 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
227 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000228 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000229 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700230 // Take advantage of existing methods that already contain permissions checks when possible.
231 private final ITelephony mInterface;
232
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100233 private SubscriptionManager mSubscriptionManager;
234 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700235 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700236 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100237
238 private enum CcType {
239 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000240 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100241 }
242
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100243 private class CcOptionParseResult {
244 public int mSubId;
245 public boolean mPersistent;
246 }
247
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100248 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
249 // keys by looking at the end of the string which usually tells the type.
250 // For instance: "xxxx_string", "xxxx_string_array", etc.
251 // The carrier config keys in this map does not follow this convention. It is therefore not
252 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700253 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
254 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
255 CcType.STRING),
256 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
257 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
258 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
266 CcType.STRING),
267 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
268 CcType.STRING_ARRAY),
269 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
270 CcType.STRING_ARRAY),
271 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
272 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
273 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
274 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
275 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
276 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100279
Brad Ebinger14d467f2021-02-12 06:18:28 +0000280 /**
281 * Map from a shorthand string to the feature tags required in registration required in order
282 * for the RCS feature to be considered "capable".
283 */
284 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
285 static {
286 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
287 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
288 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
289 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
290 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
291 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
292 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
293 FeatureTags.FEATURE_TAG_VIDEO)));
294 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
295 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
296 map.put("call_comp",
297 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
298 map.put("call_comp_mmtel",
299 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
300 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
301 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
302 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
303 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
304 // version
305 map.put("chatbot", new ArraySet<>(Arrays.asList(
306 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
307 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
308 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
309 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000310 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000311 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
312 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
313 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
314 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
315 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000316 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000317 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
318 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
319 }
320
321
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100322 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700323 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100324 mCarrierConfigManager =
325 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
326 mSubscriptionManager = (SubscriptionManager)
327 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700328 mTelephonyRegistryManager = (TelephonyRegistryManager)
329 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700330 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700331 }
332
333 @Override
334 public int onCommand(String cmd) {
335 if (cmd == null) {
336 return handleDefaultCommands(null);
337 }
338
339 switch (cmd) {
340 case IMS_SUBCOMMAND: {
341 return handleImsCommand();
342 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800343 case RCS_UCE_COMMAND:
344 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800345 case NUMBER_VERIFICATION_SUBCOMMAND:
346 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800347 case EMERGENCY_CALLBACK_MODE:
348 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800349 case EMERGENCY_NUMBER_TEST_MODE:
350 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100351 case CARRIER_CONFIG_SUBCOMMAND: {
352 return handleCcCommand();
353 }
Shuo Qianf5125122019-12-16 17:03:07 -0800354 case DATA_TEST_MODE:
355 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700356 case END_BLOCK_SUPPRESSION:
357 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000358 case EUICC_SUBCOMMAND:
359 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700360 case GBA_SUBCOMMAND:
361 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800362 case D2D_SUBCOMMAND:
363 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700364 case BARRING_SUBCOMMAND:
365 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000366 case SINGLE_REGISTATION_CONFIG:
367 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000368 case RESTART_MODEM:
369 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800370 case CALL_COMPOSER_SUBCOMMAND:
371 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000372 case UNATTENDED_REBOOT:
373 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800374 case HAS_CARRIER_PRIVILEGES_COMMAND:
375 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800376 case THERMAL_MITIGATION_COMMAND:
377 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700378 case DISABLE_PHYSICAL_SUBSCRIPTION:
379 return handleEnablePhysicalSubscription(false);
380 case ENABLE_PHYSICAL_SUBSCRIPTION:
381 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800382 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
383 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
384 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000385 case GET_IMEI:
386 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000387 case GET_SIM_SLOTS_MAPPING:
388 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800389 case RADIO_SUBCOMMAND:
390 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000391 case CARRIER_RESTRICTION_STATUS_TEST:
392 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000393 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
394 return setCarrierServicePackageOverride();
395 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
396 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000397 case DOMAIN_SELECTION_SUBCOMMAND:
398 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700399 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
400 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700401 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
402 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700403 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
404 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700405 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
406 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800407 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
408 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +0000409 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
410 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800411 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
412 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700413 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
414 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000415 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
416 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800417 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
418 return handleSetSatelliteAccessControlOverlayConfigs();
419 case SET_COUNTRY_CODES:
420 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800421 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
422 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000423 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
424 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700425 default: {
426 return handleDefaultCommands(cmd);
427 }
428 }
429 }
430
431 @Override
432 public void onHelp() {
433 PrintWriter pw = getOutPrintWriter();
434 pw.println("Telephony Commands:");
435 pw.println(" help");
436 pw.println(" Print this help text.");
437 pw.println(" ims");
438 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800439 pw.println(" uce");
440 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800441 pw.println(" emergency-number-test-mode");
442 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700443 pw.println(" end-block-suppression");
444 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800445 pw.println(" data");
446 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100447 pw.println(" cc");
448 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700449 pw.println(" gba");
450 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000451 pw.println(" src");
452 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000453 pw.println(" restart-modem");
454 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000455 pw.println(" unattended-reboot");
456 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800457 pw.println(" has-carrier-privileges [package]");
458 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800459 pw.println(" get-allowed-network-types-for-users");
460 pw.println(" Get the Allowed Network Types.");
461 pw.println(" set-allowed-network-types-for-users");
462 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800463 pw.println(" radio");
464 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700465 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800466 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800467 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700468 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800469 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100470 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700471 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000472 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800473 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700474 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800475 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800476 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000477 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700478 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000479 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800480 }
481
482 private void onHelpD2D() {
483 PrintWriter pw = getOutPrintWriter();
484 pw.println("D2D Comms Commands:");
485 pw.println(" d2d send TYPE VALUE");
486 pw.println(" Sends a D2D message of specified type and value.");
487 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
488 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
489 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
490 MESSAGE_CALL_AUDIO_CODEC));
491 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
492 + Communicator.messageToString(
493 MESSAGE_DEVICE_BATTERY_STATE));
494 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
495 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800496 pw.println(" d2d transport TYPE");
497 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
498 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700499 pw.println(" d2d set-device-support true/default");
500 pw.println(" true - forces device support to be enabled for D2D.");
501 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
502 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700503 }
504
Nazanin014f41e2021-05-06 17:26:31 -0700505 private void onHelpBarring() {
506 PrintWriter pw = getOutPrintWriter();
507 pw.println("Barring Commands:");
508 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
509 + " -t CONDITIONAL_BARRING_TIME_SECS");
510 pw.println(" Notifies of a barring info change for the specified slot id.");
511 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
512 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
513 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
514 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
515 }
516
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700517 private void onHelpIms() {
518 PrintWriter pw = getOutPrintWriter();
519 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800520 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700521 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
522 pw.println(" ImsService. Options are:");
523 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
524 pw.println(" is specified, it will choose the default voice SIM slot.");
525 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
526 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800527 pw.println(" -f: Set the feature that this override if for, if no option is");
528 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700529 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
530 pw.println(" Gets the package name of the currently defined ImsService.");
531 pw.println(" Options are:");
532 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
533 pw.println(" is specified, it will choose the default voice SIM slot.");
534 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000535 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800536 pw.println(" -f: The feature type that the query will be requested for. If none is");
537 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800538 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
539 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
540 pw.println(" configuration overrides. Options are:");
541 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700543 pw.println(" ims enable [-s SLOT_ID]");
544 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
545 pw.println(" if none is specified.");
546 pw.println(" ims disable [-s SLOT_ID]");
547 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
548 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700549 pw.println(" ims conference-event-package [enable/disable]");
550 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700551 }
552
James.cf Linbcdf8b32021-01-14 16:44:13 +0800553 private void onHelpUce() {
554 PrintWriter pw = getOutPrintWriter();
555 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800556 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
557 pw.println(" Get the EAB contacts from the EAB database.");
558 pw.println(" Options are:");
559 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
560 pw.println(" Expected output format :");
561 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800562 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
563 pw.println(" Remove the EAB contacts from the EAB database.");
564 pw.println(" Options are:");
565 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
566 pw.println(" is specified, it will choose the default voice SIM slot.");
567 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800568 pw.println(" uce get-device-enabled");
569 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
570 pw.println(" uce set-device-enabled true|false");
571 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
572 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000573 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
574 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
575 pw.println(" Options are:");
576 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
577 pw.println(" is specified, it will choose the default voice SIM slot.");
578 pw.println(" add [CAPABILITY]: add a new capability");
579 pw.println(" remove [CAPABILITY]: remove a capability");
580 pw.println(" clear: clear all capability overrides");
581 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
582 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
583 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
584 pw.println(" chatbot_sa, chatbot_role] as well as full length");
585 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
586 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
587 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
588 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800589 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
590 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800591 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
592 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800593 }
594
Hall Liud892bec2018-11-30 14:51:45 -0800595 private void onHelpNumberVerification() {
596 PrintWriter pw = getOutPrintWriter();
597 pw.println("Number verification commands");
598 pw.println(" numverify override-package PACKAGE_NAME;");
599 pw.println(" Set the authorized package for number verification.");
600 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800601 pw.println(" numverify fake-call NUMBER;");
602 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
603 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800604 }
605
Jack Nudelman644b91a2021-03-12 14:09:48 -0800606 private void onHelpThermalMitigation() {
607 PrintWriter pw = getOutPrintWriter();
608 pw.println("Thermal mitigation commands");
609 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
610 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
611 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
612 pw.println(" Remove the package from one of the authorized packages for thermal "
613 + "mitigation.");
614 }
615
Jordan Liu0ccee222021-04-27 11:55:13 -0700616 private void onHelpDisableOrEnablePhysicalSubscription() {
617 PrintWriter pw = getOutPrintWriter();
618 pw.println("Disable or enable a physical subscription");
619 pw.println(" disable-physical-subscription SUB_ID");
620 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
621 pw.println(" enable-physical-subscription SUB_ID");
622 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
623 }
624
Shuo Qianf5125122019-12-16 17:03:07 -0800625 private void onHelpDataTestMode() {
626 PrintWriter pw = getOutPrintWriter();
627 pw.println("Mobile Data Test Mode Commands:");
628 pw.println(" data enable: enable mobile data connectivity");
629 pw.println(" data disable: disable mobile data connectivity");
630 }
631
sqian9d4df8b2019-01-15 18:32:07 -0800632 private void onHelpEmergencyNumber() {
633 PrintWriter pw = getOutPrintWriter();
634 pw.println("Emergency Number Test Mode Commands:");
635 pw.println(" emergency-number-test-mode ");
636 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
637 + " the test mode");
638 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700639 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800640 pw.println(" -c: clear the emergency number list in the test mode.");
641 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700642 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800643 pw.println(" -p: get the full emergency number list in the test mode.");
644 }
645
Shuo Qian489d9282020-07-09 11:30:03 -0700646 private void onHelpEndBlockSupperssion() {
647 PrintWriter pw = getOutPrintWriter();
648 pw.println("End Block Suppression command:");
649 pw.println(" end-block-suppression: disable suppressing blocking by contact");
650 pw.println(" with emergency services.");
651 }
652
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100653 private void onHelpCc() {
654 PrintWriter pw = getOutPrintWriter();
655 pw.println("Carrier Config Commands:");
656 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
657 pw.println(" Print carrier config values.");
658 pw.println(" Options are:");
659 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
660 pw.println(" is specified, it will choose the default voice SIM slot.");
661 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
662 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100663 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100664 pw.println(" Set carrier config KEY to NEW_VALUE.");
665 pw.println(" Options are:");
666 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
667 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100668 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100669 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
670 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
671 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
672 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000673 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
674 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
675 pw.println(" provided through standard input and follow CarrierConfig XML format.");
676 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
677 pw.println(" Options are:");
678 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
679 pw.println(" is specified, it will choose the default voice SIM slot.");
680 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100681 pw.println(" cc clear-values [-s SLOT_ID]");
682 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000683 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100684 pw.println(" Options are:");
685 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
686 pw.println(" is specified, it will choose the default voice SIM slot.");
687 }
688
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000689 private void onHelpEuicc() {
690 PrintWriter pw = getOutPrintWriter();
691 pw.println("Euicc Commands:");
692 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
693 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
694 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
695 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
696 }
697
Hui Wang641e81c2020-10-12 12:14:23 -0700698 private void onHelpGba() {
699 PrintWriter pw = getOutPrintWriter();
700 pw.println("Gba Commands:");
701 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
702 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
703 pw.println(" Options are:");
704 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
705 pw.println(" is specified, it will choose the default voice SIM slot.");
706 pw.println(" gba get-service [-s SLOT_ID]");
707 pw.println(" Gets the package name of the currently defined GbaService.");
708 pw.println(" Options are:");
709 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
710 pw.println(" is specified, it will choose the default voice SIM slot.");
711 pw.println(" gba set-release [-s SLOT_ID] n");
712 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
713 pw.println(" Do not release/unbind if n is -1.");
714 pw.println(" Options are:");
715 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
716 pw.println(" is specified, it will choose the default voice SIM slot.");
717 pw.println(" gba get-release [-s SLOT_ID]");
718 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
719 pw.println(" Options are:");
720 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
721 pw.println(" is specified, it will choose the default voice SIM slot.");
722 }
723
Hui Wang761a6682020-10-31 05:12:53 +0000724 private void onHelpSrc() {
725 PrintWriter pw = getOutPrintWriter();
726 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800727 pw.println(" src set-test-enabled true|false");
728 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
729 pw.println(" The value could be true, false, or null(undefined).");
730 pw.println(" src get-test-enabled");
731 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000732 pw.println(" src set-device-enabled true|false|null");
733 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
734 pw.println(" The value could be true, false, or null(undefined).");
735 pw.println(" src get-device-enabled");
736 pw.println(" Gets the device config for RCS VoLTE single registration.");
737 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
738 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
739 pw.println(" The value could be true, false, or null(undefined).");
740 pw.println(" Options are:");
741 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
742 pw.println(" is specified, it will choose the default voice SIM slot.");
743 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
744 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
745 pw.println(" Options are:");
746 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
747 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800748 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
749 pw.println(" Sets ims feature validation result.");
750 pw.println(" The value could be true, false, or null(undefined).");
751 pw.println(" Options are:");
752 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
753 pw.println(" is specified, it will choose the default voice SIM slot.");
754 pw.println(" src get-feature-validation [-s SLOT_ID]");
755 pw.println(" Gets ims feature validation override value.");
756 pw.println(" Options are:");
757 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
758 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000759 }
760
SongFerngWang98dd5992021-05-13 17:50:00 +0800761 private void onHelpAllowedNetworkTypes() {
762 PrintWriter pw = getOutPrintWriter();
763 pw.println("Allowed Network Types Commands:");
764 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
765 pw.println(" Print allowed network types value.");
766 pw.println(" Options are:");
767 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
768 pw.println(" option is specified, it will choose the default voice SIM slot.");
769 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
770 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
771 pw.println(" Options are:");
772 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
773 pw.println(" option is specified, it will choose the default voice SIM slot.");
774 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
775 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
776 pw.println(" at TelephonyManager.java");
777 pw.println(" For example:");
778 pw.println(" NR only : 10000000000000000000");
779 pw.println(" NR|LTE : 11000001000000000000");
780 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
781 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
782 pw.println(" LTE only : 01000001000000000000");
783 }
784
jimsun3b9ccac2021-10-26 15:01:23 +0800785 private void onHelpRadio() {
786 PrintWriter pw = getOutPrintWriter();
787 pw.println("Radio Commands:");
788 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
789 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
790 pw.println(" to be the bound. Options are:");
791 pw.println(" -s: the service name that the modem service should be bound for.");
792 pw.println(" If no option is specified, it will bind to the default.");
793 pw.println(" radio get-modem-service");
794 pw.println(" Gets the service name of the currently defined modem service.");
795 pw.println(" If it is binding to default, 'default' returns.");
796 pw.println(" If it doesn't bind to any modem service for some reasons,");
797 pw.println(" the result would be 'unknown'.");
798 }
799
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700800 private void onHelpSatellite() {
801 PrintWriter pw = getOutPrintWriter();
802 pw.println("Satellite Commands:");
803 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
804 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700805 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700806 pw.println(" -s: the satellite service package name that Telephony will bind to.");
807 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700808 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
809 pw.println(" Sets the package name of satellite gateway service defined in");
810 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
811 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
812 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700813 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
814 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
815 pw.println(" mode. Options are:");
816 pw.println(" -t: the timeout duration in milliseconds.");
817 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700818 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
819 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
820 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
821 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
822 pw.println(" launch. If no option is specified, it will launch the default.");
823 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
824 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700825 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
826 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
827 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
828 pw.println(" Options are:");
829 pw.println(" -t: the emergency call to satellite handover type.");
830 pw.println(" If no option is specified, override is disabled.");
831 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
832 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800833 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
834 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
835 pw.println(" configs of satellite access controller.");
836 pw.println(" Options are:");
837 pw.println(" -r: clear the overriding. Absent means enable overriding.");
838 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
839 pw.println(" -f: the satellite s2 file.");
840 pw.println(" -d: the location fresh duration nanos.");
841 pw.println(" -c: the list of satellite country codes separated by comma.");
842 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
843 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
844 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
845 pw.println(" Override the cached location country code and its update timestamp. ");
846 pw.println(" Options are:");
847 pw.println(" -r: clear the overriding. Absent means enable overriding.");
848 pw.println(" -n: the current network country code ISOs.");
849 pw.println(" -c: the cached network country code ISOs.");
850 pw.println(" -l: the location country code ISO.");
851 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800852 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
853 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
854 pw.println(" -p: the overriding satellite provision status. If no option is ");
855 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700856 }
857
Ling Ma4fbab492022-01-25 22:36:16 +0000858 private void onHelpImei() {
859 PrintWriter pw = getOutPrintWriter();
860 pw.println("IMEI Commands:");
861 pw.println(" get-imei [-s SLOT_ID]");
862 pw.println(" Gets the device IMEI. Options are:");
863 pw.println(" -s: the slot ID to get the IMEI. If no option");
864 pw.println(" is specified, it will choose the default voice SIM slot.");
865 }
866
Hunsuk Choi13078be2023-09-13 10:55:21 +0000867 private void onHelpDomainSelection() {
868 PrintWriter pw = getOutPrintWriter();
869 pw.println("Domain Selection Commands:");
870 pw.println(" domainselection set-dss-override COMPONENT_NAME");
871 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
872 pw.println(" domainselection clear-dss-override");
873 pw.println(" Clears DomainSelectionService override.");
874 }
875
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700876 private int handleImsCommand() {
877 String arg = getNextArg();
878 if (arg == null) {
879 onHelpIms();
880 return 0;
881 }
882
883 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800884 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700885 return handleImsSetServiceCommand();
886 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800887 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700888 return handleImsGetServiceCommand();
889 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800890 case IMS_CLEAR_SERVICE_OVERRIDE: {
891 return handleImsClearCarrierServiceCommand();
892 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800893 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700894 return handleEnableIms();
895 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800896 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700897 return handleDisableIms();
898 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700899 case IMS_CEP: {
900 return handleCepChange();
901 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700902 }
903
904 return -1;
905 }
906
Shuo Qianf5125122019-12-16 17:03:07 -0800907 private int handleDataTestModeCommand() {
908 PrintWriter errPw = getErrPrintWriter();
909 String arg = getNextArgRequired();
910 if (arg == null) {
911 onHelpDataTestMode();
912 return 0;
913 }
914 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800915 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800916 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700917 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800918 } catch (RemoteException ex) {
919 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
920 errPw.println("Exception: " + ex.getMessage());
921 return -1;
922 }
923 break;
924 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800925 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800926 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700927 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800928 } catch (RemoteException ex) {
929 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
930 errPw.println("Exception: " + ex.getMessage());
931 return -1;
932 }
933 break;
934 }
935 default:
936 onHelpDataTestMode();
937 break;
938 }
939 return 0;
940 }
941
Shuo Qianccbaf742021-02-22 18:32:21 -0800942 private int handleEmergencyCallbackModeCommand() {
943 PrintWriter errPw = getErrPrintWriter();
944 try {
945 mInterface.startEmergencyCallbackMode();
946 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
947 } catch (RemoteException ex) {
948 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
949 errPw.println("Exception: " + ex.getMessage());
950 return -1;
951 }
952 return 0;
953 }
954
Grant Menke567d48f2022-08-18 20:19:10 +0000955 private void removeEmergencyNumberTestMode(String emergencyNumber) {
956 PrintWriter errPw = getErrPrintWriter();
957 for (int routingType : ROUTING_TYPES) {
958 try {
959 mInterface.updateEmergencyNumberListTestMode(
960 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
961 new EmergencyNumber(emergencyNumber, "", "",
962 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
963 new ArrayList<String>(),
964 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
965 routingType));
966 } catch (RemoteException ex) {
967 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
968 errPw.println("Exception: " + ex.getMessage());
969 }
970 }
971 }
972
sqian9d4df8b2019-01-15 18:32:07 -0800973 private int handleEmergencyNumberTestModeCommand() {
974 PrintWriter errPw = getErrPrintWriter();
975 String opt = getNextOption();
976 if (opt == null) {
977 onHelpEmergencyNumber();
978 return 0;
979 }
sqian9d4df8b2019-01-15 18:32:07 -0800980 switch (opt) {
981 case "-a": {
982 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000983 if (emergencyNumberCmd == null){
984 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800985 return -1;
986 }
Grant Menke567d48f2022-08-18 20:19:10 +0000987 String[] params = emergencyNumberCmd.split(":");
988 String emergencyNumber;
989 if (params[0] == null ||
990 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
991 errPw.println(INVALID_ENTRY_ERROR);
992 return -1;
993 } else {
994 emergencyNumber = params[0];
995 }
996 removeEmergencyNumberTestMode(emergencyNumber);
997 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
998 if (params.length > 1) {
999 switch (params[1].toLowerCase(Locale.ROOT)) {
1000 case "emergency":
1001 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1002 break;
1003 case "normal":
1004 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1005 break;
1006 case "unknown":
1007 break;
1008 default:
1009 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1010 + "emergency call routing. Please enter either \"normal\", "
1011 + "\"unknown\", or \"emergency\" for call routing. "
1012 + "(-a 1234:normal)");
1013 return -1;
1014 }
1015 }
sqian9d4df8b2019-01-15 18:32:07 -08001016 try {
1017 mInterface.updateEmergencyNumberListTestMode(
1018 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001019 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001020 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1021 new ArrayList<String>(),
1022 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001023 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001024 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001025 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001026 + ", error " + ex.getMessage());
1027 errPw.println("Exception: " + ex.getMessage());
1028 return -1;
1029 }
1030 break;
1031 }
1032 case "-c": {
1033 try {
1034 mInterface.updateEmergencyNumberListTestMode(
1035 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1036 } catch (RemoteException ex) {
1037 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1038 errPw.println("Exception: " + ex.getMessage());
1039 return -1;
1040 }
1041 break;
1042 }
1043 case "-r": {
1044 String emergencyNumberCmd = getNextArgRequired();
1045 if (emergencyNumberCmd == null
1046 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001047 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001048 + " to be specified after -r in the command ");
1049 return -1;
1050 }
Grant Menke567d48f2022-08-18 20:19:10 +00001051 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001052 break;
1053 }
1054 case "-p": {
1055 try {
1056 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1057 } catch (RemoteException ex) {
1058 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1059 errPw.println("Exception: " + ex.getMessage());
1060 return -1;
1061 }
1062 break;
1063 }
1064 default:
1065 onHelpEmergencyNumber();
1066 break;
1067 }
1068 return 0;
1069 }
1070
Hall Liud892bec2018-11-30 14:51:45 -08001071 private int handleNumberVerificationCommand() {
1072 String arg = getNextArg();
1073 if (arg == null) {
1074 onHelpNumberVerification();
1075 return 0;
1076 }
1077
Hall Liuca5af3a2018-12-04 16:58:23 -08001078 if (!checkShellUid()) {
1079 return -1;
1080 }
1081
Hall Liud892bec2018-11-30 14:51:45 -08001082 switch (arg) {
1083 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001084 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1085 return 0;
1086 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001087 case NUMBER_VERIFICATION_FAKE_CALL: {
1088 boolean val = NumberVerificationManager.getInstance()
1089 .checkIncomingCall(getNextArg());
1090 getOutPrintWriter().println(val ? "1" : "0");
1091 return 0;
1092 }
Hall Liud892bec2018-11-30 14:51:45 -08001093 }
1094
1095 return -1;
1096 }
1097
Jordan Liu0ccee222021-04-27 11:55:13 -07001098 private boolean subIsEsim(int subId) {
1099 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1100 if (info != null) {
1101 return info.isEmbedded();
1102 }
1103 return false;
1104 }
1105
1106 private int handleEnablePhysicalSubscription(boolean enable) {
1107 PrintWriter errPw = getErrPrintWriter();
1108 int subId = 0;
1109 try {
1110 subId = Integer.parseInt(getNextArgRequired());
1111 } catch (NumberFormatException e) {
1112 errPw.println((enable ? "enable" : "disable")
1113 + "-physical-subscription requires an integer as a subId.");
1114 return -1;
1115 }
1116 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1117 // non user build.
1118 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1119 errPw.println("cc: Permission denied.");
1120 return -1;
1121 }
1122 // Verify that the subId represents a physical sub
1123 if (subIsEsim(subId)) {
1124 errPw.println("SubId " + subId + " is not for a physical subscription");
1125 return -1;
1126 }
1127 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1128 + " physical subscription with subId=" + subId);
1129 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1130 return 0;
1131 }
1132
Jack Nudelman644b91a2021-03-12 14:09:48 -08001133 private int handleThermalMitigationCommand() {
1134 String arg = getNextArg();
1135 String packageName = getNextArg();
1136 if (arg == null || packageName == null) {
1137 onHelpThermalMitigation();
1138 return 0;
1139 }
1140
1141 if (!checkShellUid()) {
1142 return -1;
1143 }
1144
1145 switch (arg) {
1146 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1147 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1148 return 0;
1149 }
1150 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1151 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1152 mContext);
1153 return 0;
1154 }
1155 default:
1156 onHelpThermalMitigation();
1157 }
1158
1159 return -1;
1160
1161 }
1162
Tyler Gunn92479152021-01-20 16:30:10 -08001163 private int handleD2dCommand() {
1164 String arg = getNextArg();
1165 if (arg == null) {
1166 onHelpD2D();
1167 return 0;
1168 }
1169
1170 switch (arg) {
1171 case D2D_SEND: {
1172 return handleD2dSendCommand();
1173 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001174 case D2D_TRANSPORT: {
1175 return handleD2dTransportCommand();
1176 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001177 case D2D_SET_DEVICE_SUPPORT: {
1178 return handleD2dDeviceSupportedCommand();
1179 }
Tyler Gunn92479152021-01-20 16:30:10 -08001180 }
1181
1182 return -1;
1183 }
1184
1185 private int handleD2dSendCommand() {
1186 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001187 int messageType = -1;
1188 int messageValue = -1;
1189
Tyler Gunn92479152021-01-20 16:30:10 -08001190 String arg = getNextArg();
1191 if (arg == null) {
1192 onHelpD2D();
1193 return 0;
1194 }
1195 try {
1196 messageType = Integer.parseInt(arg);
1197 } catch (NumberFormatException e) {
1198 errPw.println("message type must be a valid integer");
1199 return -1;
1200 }
1201
1202 arg = getNextArg();
1203 if (arg == null) {
1204 onHelpD2D();
1205 return 0;
1206 }
1207 try {
1208 messageValue = Integer.parseInt(arg);
1209 } catch (NumberFormatException e) {
1210 errPw.println("message value must be a valid integer");
1211 return -1;
1212 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001213
Tyler Gunn92479152021-01-20 16:30:10 -08001214 try {
1215 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1216 } catch (RemoteException e) {
1217 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1218 errPw.println("Exception: " + e.getMessage());
1219 return -1;
1220 }
1221
1222 return 0;
1223 }
1224
Tyler Gunnbabbda02021-02-10 11:05:02 -08001225 private int handleD2dTransportCommand() {
1226 PrintWriter errPw = getErrPrintWriter();
1227
1228 String arg = getNextArg();
1229 if (arg == null) {
1230 onHelpD2D();
1231 return 0;
1232 }
1233
1234 try {
1235 mInterface.setActiveDeviceToDeviceTransport(arg);
1236 } catch (RemoteException e) {
1237 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1238 errPw.println("Exception: " + e.getMessage());
1239 return -1;
1240 }
1241 return 0;
1242 }
Nazanin014f41e2021-05-06 17:26:31 -07001243 private int handleBarringCommand() {
1244 String arg = getNextArg();
1245 if (arg == null) {
1246 onHelpBarring();
1247 return 0;
1248 }
1249
1250 switch (arg) {
1251 case BARRING_SEND_INFO: {
1252 return handleBarringSendCommand();
1253 }
1254 }
1255 return -1;
1256 }
1257
1258 private int handleBarringSendCommand() {
1259 PrintWriter errPw = getErrPrintWriter();
1260 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001261 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001262 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1263 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1264 boolean isConditionallyBarred = false;
1265 int conditionalBarringTimeSeconds = 0;
1266
1267 String opt;
1268 while ((opt = getNextOption()) != null) {
1269 switch (opt) {
1270 case "-s": {
1271 try {
1272 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001273 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001274 } catch (NumberFormatException e) {
1275 errPw.println("barring send requires an integer as a SLOT_ID.");
1276 return -1;
1277 }
1278 break;
1279 }
1280 case "-b": {
1281 try {
1282 barringType = Integer.parseInt(getNextArgRequired());
1283 if (barringType < -1 || barringType > 2) {
1284 throw new NumberFormatException();
1285 }
1286
1287 } catch (NumberFormatException e) {
1288 errPw.println("barring send requires an integer in range [-1,2] as "
1289 + "a BARRING_TYPE.");
1290 return -1;
1291 }
1292 break;
1293 }
1294 case "-c": {
1295 try {
1296 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1297 } catch (Exception e) {
1298 errPw.println("barring send requires a boolean after -c indicating"
1299 + " conditional barring");
1300 return -1;
1301 }
1302 break;
1303 }
1304 case "-t": {
1305 try {
1306 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1307 } catch (NumberFormatException e) {
1308 errPw.println("barring send requires an integer for time of barring"
1309 + " in seconds after -t for conditional barring");
1310 return -1;
1311 }
1312 break;
1313 }
1314 }
1315 }
1316 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1317 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1318 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1319 barringServiceInfos.append(0, bsi);
1320 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1321 try {
1322 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1323 } catch (Exception e) {
1324 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1325 errPw.println("Exception: " + e.getMessage());
1326 return -1;
1327 }
1328 return 0;
1329 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001330
Tyler Gunnd4575212021-05-03 14:46:49 -07001331 private int handleD2dDeviceSupportedCommand() {
1332 PrintWriter errPw = getErrPrintWriter();
1333
1334 String arg = getNextArg();
1335 if (arg == null) {
1336 onHelpD2D();
1337 return 0;
1338 }
1339
Jack Yua533d632022-09-30 13:53:46 -07001340 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001341 try {
1342 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1343 } catch (RemoteException e) {
1344 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1345 errPw.println("Exception: " + e.getMessage());
1346 return -1;
1347 }
1348 return 0;
1349 }
1350
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001351 // ims set-ims-service
1352 private int handleImsSetServiceCommand() {
1353 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001354 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001355 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001356 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001357
1358 String opt;
1359 while ((opt = getNextOption()) != null) {
1360 switch (opt) {
1361 case "-s": {
1362 try {
1363 slotId = Integer.parseInt(getNextArgRequired());
1364 } catch (NumberFormatException e) {
1365 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1366 return -1;
1367 }
1368 break;
1369 }
1370 case "-c": {
1371 isCarrierService = true;
1372 break;
1373 }
1374 case "-d": {
1375 isCarrierService = false;
1376 break;
1377 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001378 case "-f": {
1379 String featureString = getNextArgRequired();
1380 String[] features = featureString.split(",");
1381 for (int i = 0; i < features.length; i++) {
1382 try {
1383 Integer result = Integer.parseInt(features[i]);
1384 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1385 || result >= ImsFeature.FEATURE_MAX) {
1386 errPw.println("ims set-ims-service -f " + result
1387 + " is an invalid feature.");
1388 return -1;
1389 }
1390 featuresList.add(result);
1391 } catch (NumberFormatException e) {
1392 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1393 + " as an integer.");
1394 return -1;
1395 }
1396 }
1397 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001398 }
1399 }
1400 // Mandatory param, either -c or -d
1401 if (isCarrierService == null) {
1402 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1403 return -1;
1404 }
1405
1406 String packageName = getNextArg();
1407
1408 try {
1409 if (packageName == null) {
1410 packageName = "";
1411 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001412 int[] featureArray = new int[featuresList.size()];
1413 for (int i = 0; i < featuresList.size(); i++) {
1414 featureArray[i] = featuresList.get(i);
1415 }
1416 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1417 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001418 if (VDBG) {
1419 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001420 + (isCarrierService ? "-c " : "-d ")
1421 + "-f " + featuresList + " "
1422 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001423 }
1424 getOutPrintWriter().println(result);
1425 } catch (RemoteException e) {
1426 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001427 + (isCarrierService ? "-c " : "-d ")
1428 + "-f " + featuresList + " "
1429 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001430 errPw.println("Exception: " + e.getMessage());
1431 return -1;
1432 }
1433 return 0;
1434 }
1435
Brad Ebinger999d3302020-11-25 14:31:39 -08001436 // ims clear-ims-service-override
1437 private int handleImsClearCarrierServiceCommand() {
1438 PrintWriter errPw = getErrPrintWriter();
1439 int slotId = getDefaultSlot();
1440
1441 String opt;
1442 while ((opt = getNextOption()) != null) {
1443 switch (opt) {
1444 case "-s": {
1445 try {
1446 slotId = Integer.parseInt(getNextArgRequired());
1447 } catch (NumberFormatException e) {
1448 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1449 return -1;
1450 }
1451 break;
1452 }
1453 }
1454 }
1455
1456 try {
1457 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1458 if (VDBG) {
1459 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1460 + ", result=" + result);
1461 }
1462 getOutPrintWriter().println(result);
1463 } catch (RemoteException e) {
1464 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1465 + ", error" + e.getMessage());
1466 errPw.println("Exception: " + e.getMessage());
1467 return -1;
1468 }
1469 return 0;
1470 }
1471
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001472 // ims get-ims-service
1473 private int handleImsGetServiceCommand() {
1474 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001475 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001476 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001477 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001478
1479 String opt;
1480 while ((opt = getNextOption()) != null) {
1481 switch (opt) {
1482 case "-s": {
1483 try {
1484 slotId = Integer.parseInt(getNextArgRequired());
1485 } catch (NumberFormatException e) {
1486 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1487 return -1;
1488 }
1489 break;
1490 }
1491 case "-c": {
1492 isCarrierService = true;
1493 break;
1494 }
1495 case "-d": {
1496 isCarrierService = false;
1497 break;
1498 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001499 case "-f": {
1500 try {
1501 featureType = Integer.parseInt(getNextArg());
1502 } catch (NumberFormatException e) {
1503 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1504 return -1;
1505 }
1506 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1507 || featureType >= ImsFeature.FEATURE_MAX) {
1508 errPw.println("ims get-ims-service -f invalid feature.");
1509 return -1;
1510 }
1511 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001512 }
1513 }
1514 // Mandatory param, either -c or -d
1515 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001516 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001517 return -1;
1518 }
1519
1520 String result;
1521 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001522 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001523 } catch (RemoteException e) {
1524 return -1;
1525 }
1526 if (VDBG) {
1527 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001528 + (isCarrierService ? "-c " : "-d ")
1529 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1530 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001531 }
1532 getOutPrintWriter().println(result);
1533 return 0;
1534 }
1535
1536 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001537 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001538 String opt;
1539 while ((opt = getNextOption()) != null) {
1540 switch (opt) {
1541 case "-s": {
1542 try {
1543 slotId = Integer.parseInt(getNextArgRequired());
1544 } catch (NumberFormatException e) {
1545 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1546 return -1;
1547 }
1548 break;
1549 }
1550 }
1551 }
1552 try {
1553 mInterface.enableIms(slotId);
1554 } catch (RemoteException e) {
1555 return -1;
1556 }
1557 if (VDBG) {
1558 Log.v(LOG_TAG, "ims enable -s " + slotId);
1559 }
1560 return 0;
1561 }
1562
1563 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001564 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001565 String opt;
1566 while ((opt = getNextOption()) != null) {
1567 switch (opt) {
1568 case "-s": {
1569 try {
1570 slotId = Integer.parseInt(getNextArgRequired());
1571 } catch (NumberFormatException e) {
1572 getErrPrintWriter().println(
1573 "ims disable requires an integer as a SLOT_ID.");
1574 return -1;
1575 }
1576 break;
1577 }
1578 }
1579 }
1580 try {
1581 mInterface.disableIms(slotId);
1582 } catch (RemoteException e) {
1583 return -1;
1584 }
1585 if (VDBG) {
1586 Log.v(LOG_TAG, "ims disable -s " + slotId);
1587 }
1588 return 0;
1589 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001590
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001591 private int handleCepChange() {
1592 Log.i(LOG_TAG, "handleCepChange");
1593 String opt = getNextArg();
1594 if (opt == null) {
1595 return -1;
1596 }
1597 boolean isCepEnabled = opt.equals("enable");
1598
1599 try {
1600 mInterface.setCepEnabled(isCepEnabled);
1601 } catch (RemoteException e) {
1602 return -1;
1603 }
1604 return 0;
1605 }
1606
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001607 private int getDefaultSlot() {
1608 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1609 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1610 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1611 // If there is no default, default to slot 0.
1612 slotId = DEFAULT_PHONE_ID;
1613 }
1614 return slotId;
1615 }
sqian2fff4a32018-11-05 14:18:37 -08001616
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001617 // Parse options related to Carrier Config Commands.
1618 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001619 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001620 CcOptionParseResult result = new CcOptionParseResult();
1621 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1622 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001623
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001624 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001625 while ((opt = getNextOption()) != null) {
1626 switch (opt) {
1627 case "-s": {
1628 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001629 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1630 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1631 errPw.println(tag + "No valid subscription found.");
1632 return null;
1633 }
1634
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001635 } catch (IllegalArgumentException e) {
1636 // Missing slot id
1637 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001638 return null;
1639 }
1640 break;
1641 }
1642 case "-p": {
1643 if (allowOptionPersistent) {
1644 result.mPersistent = true;
1645 } else {
1646 errPw.println(tag + "Unexpected option " + opt);
1647 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001648 }
1649 break;
1650 }
1651 default: {
1652 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001653 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001654 }
1655 }
1656 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001657 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001658 }
1659
1660 private int slotStringToSubId(String tag, String slotString) {
1661 int slotId = -1;
1662 try {
1663 slotId = Integer.parseInt(slotString);
1664 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001665 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1666 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1667 }
1668
1669 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001670 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1671 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1672 }
1673
Qiong Liuf25799b2020-09-10 10:13:46 +08001674 Phone phone = PhoneFactory.getPhone(slotId);
1675 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001676 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1677 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1678 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001679 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001680 }
1681
Hall Liud892bec2018-11-30 14:51:45 -08001682 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001683 // adb can run as root or as shell, depending on whether the device is rooted.
1684 return Binder.getCallingUid() == Process.SHELL_UID
1685 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001686 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001687
1688 private int handleCcCommand() {
1689 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1690 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001691 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001692 getErrPrintWriter().println("cc: Permission denied.");
1693 return -1;
1694 }
1695
1696 String arg = getNextArg();
1697 if (arg == null) {
1698 onHelpCc();
1699 return 0;
1700 }
1701
1702 switch (arg) {
1703 case CC_GET_VALUE: {
1704 return handleCcGetValue();
1705 }
1706 case CC_SET_VALUE: {
1707 return handleCcSetValue();
1708 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001709 case CC_SET_VALUES_FROM_XML: {
1710 return handleCcSetValuesFromXml();
1711 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001712 case CC_CLEAR_VALUES: {
1713 return handleCcClearValues();
1714 }
1715 default: {
1716 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1717 }
1718 }
1719 return -1;
1720 }
1721
1722 // cc get-value
1723 private int handleCcGetValue() {
1724 PrintWriter errPw = getErrPrintWriter();
1725 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1726 String key = null;
1727
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001728 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001729 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001730 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001731 return -1;
1732 }
1733
1734 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001735 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001736 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001737 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001738 return -1;
1739 }
1740
1741 // Get the key.
1742 key = getNextArg();
1743 if (key != null) {
1744 // A key was provided. Verify if it is a valid key
1745 if (!bundle.containsKey(key)) {
1746 errPw.println(tag + key + " is not a valid key.");
1747 return -1;
1748 }
1749
1750 // Print the carrier config value for key.
1751 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1752 } else {
1753 // No key provided. Show all values.
1754 // Iterate over a sorted list of all carrier config keys and print them.
1755 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1756 for (String k : sortedSet) {
1757 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1758 }
1759 }
1760 return 0;
1761 }
1762
1763 // cc set-value
1764 private int handleCcSetValue() {
1765 PrintWriter errPw = getErrPrintWriter();
1766 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1767
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001768 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001769 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001770 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001771 return -1;
1772 }
1773
1774 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001775 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001776 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001777 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001778 return -1;
1779 }
1780
1781 // Get the key.
1782 String key = getNextArg();
1783 if (key == null || key.equals("")) {
1784 errPw.println(tag + "KEY is missing");
1785 return -1;
1786 }
1787
1788 // Verify if the key is valid
1789 if (!originalValues.containsKey(key)) {
1790 errPw.println(tag + key + " is not a valid key.");
1791 return -1;
1792 }
1793
1794 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1795 ArrayList<String> valueList = new ArrayList<String>();
1796 while (peekNextArg() != null) {
1797 valueList.add(getNextArg());
1798 }
1799
1800 // Find the type of the carrier config value
1801 CcType type = getType(tag, key, originalValues);
1802 if (type == CcType.UNKNOWN) {
1803 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1804 return -1;
1805 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001806 if (type == CcType.PERSISTABLE_BUNDLE) {
1807 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1808 + "Use set-values-from-xml instead.");
1809 return -1;
1810 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001811
1812 // Create an override bundle containing the key and value that should be overriden.
1813 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1814 if (overrideBundle == null) {
1815 return -1;
1816 }
1817
1818 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001819 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001820
1821 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001822 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001823 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001824 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001825 return -1;
1826 }
1827
1828 // Print the original and new value.
1829 String originalValueString = ccValueToString(key, type, originalValues);
1830 String newValueString = ccValueToString(key, type, newValues);
1831 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1832 getOutPrintWriter().println("New value: \n" + newValueString);
1833
1834 return 0;
1835 }
1836
Allen Xuee00f0e2022-03-14 21:04:49 +00001837 // cc set-values-from-xml
1838 private int handleCcSetValuesFromXml() {
1839 PrintWriter errPw = getErrPrintWriter();
1840 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1841
1842 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001843 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001844 if (options == null) {
1845 return -1;
1846 }
1847
1848 // Get bundle containing all current carrier configuration values.
1849 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1850 if (originalValues == null) {
1851 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1852 return -1;
1853 }
1854
1855 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1856 if (overrideBundle == null) {
1857 return -1;
1858 }
1859
1860 // Verify all values are valid types
1861 for (String key : overrideBundle.keySet()) {
1862 CcType type = getType(tag, key, originalValues);
1863 if (type == CcType.UNKNOWN) {
1864 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1865 return -1;
1866 }
1867 }
1868
1869 // Override the value
1870 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1871
1872 // Find bundle containing all new carrier configuration values after the override.
1873 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1874 if (newValues == null) {
1875 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1876 return -1;
1877 }
1878
1879 // Print the original and new values
1880 overrideBundle.keySet().forEach(key -> {
1881 CcType type = getType(tag, key, originalValues);
1882 String originalValueString = ccValueToString(key, type, originalValues);
1883 String newValueString = ccValueToString(key, type, newValues);
1884 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1885 getOutPrintWriter().println("New value: \n" + newValueString);
1886 });
1887
1888 return 0;
1889 }
1890
1891 private PersistableBundle readPersistableBundleFromXml(String tag) {
1892 PersistableBundle subIdBundles;
1893 try {
1894 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1895 } catch (IOException | RuntimeException e) {
1896 PrintWriter errPw = getErrPrintWriter();
1897 errPw.println(tag + e);
1898 return null;
1899 }
1900
1901 return subIdBundles;
1902 }
1903
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001904 // cc clear-values
1905 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001906 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1907
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001908 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001909 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001910 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001911 return -1;
1912 }
1913
1914 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001915 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001916 getOutPrintWriter()
1917 .println("All previously set carrier config override values has been cleared");
1918 return 0;
1919 }
1920
1921 private CcType getType(String tag, String key, PersistableBundle bundle) {
1922 // Find the type by checking the type of the current value stored in the bundle.
1923 Object value = bundle.get(key);
1924
1925 if (CC_TYPE_MAP.containsKey(key)) {
1926 return CC_TYPE_MAP.get(key);
1927 } else if (value != null) {
1928 if (value instanceof Boolean) {
1929 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001930 }
1931 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001932 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001933 }
1934 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001935 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001936 }
1937 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001938 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001939 }
1940 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001941 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001942 }
1943 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001944 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001945 }
1946 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001947 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001948 }
1949 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001950 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001951 }
1952 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001953 return CcType.STRING_ARRAY;
1954 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 if (value instanceof PersistableBundle) {
1956 return CcType.PERSISTABLE_BUNDLE;
1957 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001958 } else {
1959 // Current value was null and can therefore not be used in order to find the type.
1960 // Check the name of the key to infer the type. This check is not needed for primitive
1961 // data types (boolean, double, int and long), since they can not be null.
1962 if (key.endsWith("double_array")) {
1963 return CcType.DOUBLE_ARRAY;
1964 }
1965 if (key.endsWith("int_array")) {
1966 return CcType.INT_ARRAY;
1967 }
1968 if (key.endsWith("long_array")) {
1969 return CcType.LONG_ARRAY;
1970 }
1971 if (key.endsWith("string")) {
1972 return CcType.STRING;
1973 }
1974 if (key.endsWith("string_array") || key.endsWith("strings")) {
1975 return CcType.STRING_ARRAY;
1976 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001977 if (key.endsWith("bundle")) {
1978 return CcType.PERSISTABLE_BUNDLE;
1979 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001980 }
1981
1982 // Not possible to infer the type by looking at the current value or the key.
1983 PrintWriter errPw = getErrPrintWriter();
1984 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1985 return CcType.UNKNOWN;
1986 }
1987
1988 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1989 String result;
1990 StringBuilder valueString = new StringBuilder();
1991 String typeString = type.toString();
1992 Object value = bundle.get(key);
1993
1994 if (value == null) {
1995 valueString.append("null");
1996 } else {
1997 switch (type) {
1998 case DOUBLE_ARRAY: {
1999 // Format the string representation of the int array as value1 value2......
2000 double[] valueArray = (double[]) value;
2001 for (int i = 0; i < valueArray.length; i++) {
2002 if (i != 0) {
2003 valueString.append(" ");
2004 }
2005 valueString.append(valueArray[i]);
2006 }
2007 break;
2008 }
2009 case INT_ARRAY: {
2010 // Format the string representation of the int array as value1 value2......
2011 int[] valueArray = (int[]) value;
2012 for (int i = 0; i < valueArray.length; i++) {
2013 if (i != 0) {
2014 valueString.append(" ");
2015 }
2016 valueString.append(valueArray[i]);
2017 }
2018 break;
2019 }
2020 case LONG_ARRAY: {
2021 // Format the string representation of the int array as value1 value2......
2022 long[] valueArray = (long[]) value;
2023 for (int i = 0; i < valueArray.length; i++) {
2024 if (i != 0) {
2025 valueString.append(" ");
2026 }
2027 valueString.append(valueArray[i]);
2028 }
2029 break;
2030 }
2031 case STRING: {
2032 valueString.append("\"" + value.toString() + "\"");
2033 break;
2034 }
2035 case STRING_ARRAY: {
2036 // Format the string representation of the string array as "value1" "value2"....
2037 String[] valueArray = (String[]) value;
2038 for (int i = 0; i < valueArray.length; i++) {
2039 if (i != 0) {
2040 valueString.append(" ");
2041 }
2042 if (valueArray[i] != null) {
2043 valueString.append("\"" + valueArray[i] + "\"");
2044 } else {
2045 valueString.append("null");
2046 }
2047 }
2048 break;
2049 }
2050 default: {
2051 valueString.append(value.toString());
2052 }
2053 }
2054 }
2055 return String.format("%-70s %-15s %s", key, typeString, valueString);
2056 }
2057
2058 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2059 ArrayList<String> valueList) {
2060 PrintWriter errPw = getErrPrintWriter();
2061 PersistableBundle bundle = new PersistableBundle();
2062
2063 // First verify that a valid number of values has been provided for the type.
2064 switch (type) {
2065 case BOOLEAN:
2066 case DOUBLE:
2067 case INT:
2068 case LONG: {
2069 if (valueList.size() != 1) {
2070 errPw.println(tag + "Expected 1 value for type " + type
2071 + ". Found: " + valueList.size());
2072 return null;
2073 }
2074 break;
2075 }
2076 case STRING: {
2077 if (valueList.size() > 1) {
2078 errPw.println(tag + "Expected 0 or 1 values for type " + type
2079 + ". Found: " + valueList.size());
2080 return null;
2081 }
2082 break;
2083 }
2084 }
2085
2086 // Parse the value according to type and add it to the Bundle.
2087 switch (type) {
2088 case BOOLEAN: {
2089 if ("true".equalsIgnoreCase(valueList.get(0))) {
2090 bundle.putBoolean(key, true);
2091 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2092 bundle.putBoolean(key, false);
2093 } else {
2094 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2095 return null;
2096 }
2097 break;
2098 }
2099 case DOUBLE: {
2100 try {
2101 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2102 } catch (NumberFormatException nfe) {
2103 // Not a valid double
2104 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2105 return null;
2106 }
2107 break;
2108 }
2109 case DOUBLE_ARRAY: {
2110 double[] valueDoubleArray = null;
2111 if (valueList.size() > 0) {
2112 valueDoubleArray = new double[valueList.size()];
2113 for (int i = 0; i < valueList.size(); i++) {
2114 try {
2115 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2116 } catch (NumberFormatException nfe) {
2117 // Not a valid double
2118 errPw.println(
2119 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2120 return null;
2121 }
2122 }
2123 }
2124 bundle.putDoubleArray(key, valueDoubleArray);
2125 break;
2126 }
2127 case INT: {
2128 try {
2129 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2130 } catch (NumberFormatException nfe) {
2131 // Not a valid integer
2132 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2133 return null;
2134 }
2135 break;
2136 }
2137 case INT_ARRAY: {
2138 int[] valueIntArray = null;
2139 if (valueList.size() > 0) {
2140 valueIntArray = new int[valueList.size()];
2141 for (int i = 0; i < valueList.size(); i++) {
2142 try {
2143 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2144 } catch (NumberFormatException nfe) {
2145 // Not a valid integer
2146 errPw.println(tag
2147 + "Unable to parse " + valueList.get(i) + " as an integer.");
2148 return null;
2149 }
2150 }
2151 }
2152 bundle.putIntArray(key, valueIntArray);
2153 break;
2154 }
2155 case LONG: {
2156 try {
2157 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2158 } catch (NumberFormatException nfe) {
2159 // Not a valid long
2160 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2161 return null;
2162 }
2163 break;
2164 }
2165 case LONG_ARRAY: {
2166 long[] valueLongArray = null;
2167 if (valueList.size() > 0) {
2168 valueLongArray = new long[valueList.size()];
2169 for (int i = 0; i < valueList.size(); i++) {
2170 try {
2171 valueLongArray[i] = Long.parseLong(valueList.get(i));
2172 } catch (NumberFormatException nfe) {
2173 // Not a valid long
2174 errPw.println(
2175 tag + "Unable to parse " + valueList.get(i) + " as a long");
2176 return null;
2177 }
2178 }
2179 }
2180 bundle.putLongArray(key, valueLongArray);
2181 break;
2182 }
2183 case STRING: {
2184 String value = null;
2185 if (valueList.size() > 0) {
2186 value = valueList.get(0);
2187 }
2188 bundle.putString(key, value);
2189 break;
2190 }
2191 case STRING_ARRAY: {
2192 String[] valueStringArray = null;
2193 if (valueList.size() > 0) {
2194 valueStringArray = new String[valueList.size()];
2195 valueList.toArray(valueStringArray);
2196 }
2197 bundle.putStringArray(key, valueStringArray);
2198 break;
2199 }
2200 }
2201 return bundle;
2202 }
Shuo Qian489d9282020-07-09 11:30:03 -07002203
2204 private int handleEndBlockSuppressionCommand() {
2205 if (!checkShellUid()) {
2206 return -1;
2207 }
2208
2209 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2210 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2211 }
2212 return 0;
2213 }
Hui Wang641e81c2020-10-12 12:14:23 -07002214
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002215 private int handleEuiccCommand() {
2216 String arg = getNextArg();
2217 if (arg == null) {
2218 onHelpEuicc();
2219 return 0;
2220 }
2221
2222 switch (arg) {
2223 case EUICC_SET_UI_COMPONENT: {
2224 return handleEuiccServiceCommand();
2225 }
2226 }
2227 return -1;
2228 }
2229
2230 private int handleEuiccServiceCommand() {
2231 String uiComponent = getNextArg();
2232 String packageName = getNextArg();
2233 if (packageName == null || uiComponent == null) {
2234 return -1;
2235 }
2236 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2237 if (VDBG) {
2238 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2239 + packageName);
2240 }
2241 return 0;
2242 }
2243
Michele Berionne54af4632020-12-28 20:23:16 +00002244 private int handleRestartModemCommand() {
2245 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2246 // non user build.
2247 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2248 getErrPrintWriter().println("RestartModem: Permission denied.");
2249 return -1;
2250 }
2251
2252 boolean result = TelephonyManager.getDefault().rebootRadio();
2253 getOutPrintWriter().println(result);
2254
2255 return result ? 0 : -1;
2256 }
2257
Ling Ma4fbab492022-01-25 22:36:16 +00002258 private int handleGetImei() {
2259 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2260 // non user build.
2261 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2262 getErrPrintWriter().println("Device IMEI: Permission denied.");
2263 return -1;
2264 }
2265
2266 final long identity = Binder.clearCallingIdentity();
2267
2268 String imei = null;
2269 String arg = getNextArg();
2270 if (arg != null) {
2271 try {
2272 int specifiedSlotIndex = Integer.parseInt(arg);
2273 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2274 } catch (NumberFormatException exception) {
2275 PrintWriter errPw = getErrPrintWriter();
2276 errPw.println("-s requires an integer as slot index.");
2277 return -1;
2278 }
2279
2280 } else {
2281 imei = TelephonyManager.from(mContext).getImei();
2282 }
2283 getOutPrintWriter().println("Device IMEI: " + imei);
2284
2285 Binder.restoreCallingIdentity(identity);
2286 return 0;
2287 }
2288
Michele Berionne5e411512020-11-13 02:36:59 +00002289 private int handleUnattendedReboot() {
2290 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2291 // non user build.
2292 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2293 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2294 return -1;
2295 }
2296
2297 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2298 getOutPrintWriter().println("result: " + result);
2299
2300 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2301 }
2302
Aman Gupta07124872022-02-09 08:02:14 +00002303 private int handleGetSimSlotsMapping() {
2304 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2305 // non user build.
2306 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2307 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2308 return -1;
2309 }
2310 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2311 String result = telephonyManager.getSimSlotMapping().toString();
2312 getOutPrintWriter().println("simSlotsMapping: " + result);
2313
2314 return 0;
2315 }
2316
Hui Wang641e81c2020-10-12 12:14:23 -07002317 private int handleGbaCommand() {
2318 String arg = getNextArg();
2319 if (arg == null) {
2320 onHelpGba();
2321 return 0;
2322 }
2323
2324 switch (arg) {
2325 case GBA_SET_SERVICE: {
2326 return handleGbaSetServiceCommand();
2327 }
2328 case GBA_GET_SERVICE: {
2329 return handleGbaGetServiceCommand();
2330 }
2331 case GBA_SET_RELEASE_TIME: {
2332 return handleGbaSetReleaseCommand();
2333 }
2334 case GBA_GET_RELEASE_TIME: {
2335 return handleGbaGetReleaseCommand();
2336 }
2337 }
2338
2339 return -1;
2340 }
2341
2342 private int getSubId(String cmd) {
2343 int slotId = getDefaultSlot();
2344 String opt = getNextOption();
2345 if (opt != null && opt.equals("-s")) {
2346 try {
2347 slotId = Integer.parseInt(getNextArgRequired());
2348 } catch (NumberFormatException e) {
2349 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2350 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2351 }
2352 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002353 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002354 }
2355
2356 private int handleGbaSetServiceCommand() {
2357 int subId = getSubId("gba set-service");
2358 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2359 return -1;
2360 }
2361
2362 String packageName = getNextArg();
2363 try {
2364 if (packageName == null) {
2365 packageName = "";
2366 }
2367 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2368 if (VDBG) {
2369 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2370 + packageName + ", result=" + result);
2371 }
2372 getOutPrintWriter().println(result);
2373 } catch (RemoteException e) {
2374 Log.w(LOG_TAG, "gba set-service " + subId + " "
2375 + packageName + ", error" + e.getMessage());
2376 getErrPrintWriter().println("Exception: " + e.getMessage());
2377 return -1;
2378 }
2379 return 0;
2380 }
2381
2382 private int handleGbaGetServiceCommand() {
2383 String result;
2384
2385 int subId = getSubId("gba get-service");
2386 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2387 return -1;
2388 }
2389
2390 try {
2391 result = mInterface.getBoundGbaService(subId);
2392 } catch (RemoteException e) {
2393 return -1;
2394 }
2395 if (VDBG) {
2396 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2397 }
2398 getOutPrintWriter().println(result);
2399 return 0;
2400 }
2401
2402 private int handleGbaSetReleaseCommand() {
2403 //the release time value could be -1
2404 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2405 : SubscriptionManager.getDefaultSubscriptionId();
2406 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2407 return -1;
2408 }
2409
2410 String intervalStr = getNextArg();
2411 if (intervalStr == null) {
2412 return -1;
2413 }
2414
2415 try {
2416 int interval = Integer.parseInt(intervalStr);
2417 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2418 if (VDBG) {
2419 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2420 + intervalStr + ", result=" + result);
2421 }
2422 getOutPrintWriter().println(result);
2423 } catch (NumberFormatException | RemoteException e) {
2424 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2425 + intervalStr + ", error" + e.getMessage());
2426 getErrPrintWriter().println("Exception: " + e.getMessage());
2427 return -1;
2428 }
2429 return 0;
2430 }
2431
2432 private int handleGbaGetReleaseCommand() {
2433 int subId = getSubId("gba get-release");
2434 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2435 return -1;
2436 }
2437
2438 int result = 0;
2439 try {
2440 result = mInterface.getGbaReleaseTime(subId);
2441 } catch (RemoteException e) {
2442 return -1;
2443 }
2444 if (VDBG) {
2445 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2446 }
2447 getOutPrintWriter().println(result);
2448 return 0;
2449 }
Hui Wang761a6682020-10-31 05:12:53 +00002450
2451 private int handleSingleRegistrationConfigCommand() {
2452 String arg = getNextArg();
2453 if (arg == null) {
2454 onHelpSrc();
2455 return 0;
2456 }
2457
2458 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002459 case SRC_SET_TEST_ENABLED: {
2460 return handleSrcSetTestEnabledCommand();
2461 }
2462 case SRC_GET_TEST_ENABLED: {
2463 return handleSrcGetTestEnabledCommand();
2464 }
Hui Wang761a6682020-10-31 05:12:53 +00002465 case SRC_SET_DEVICE_ENABLED: {
2466 return handleSrcSetDeviceEnabledCommand();
2467 }
2468 case SRC_GET_DEVICE_ENABLED: {
2469 return handleSrcGetDeviceEnabledCommand();
2470 }
2471 case SRC_SET_CARRIER_ENABLED: {
2472 return handleSrcSetCarrierEnabledCommand();
2473 }
2474 case SRC_GET_CARRIER_ENABLED: {
2475 return handleSrcGetCarrierEnabledCommand();
2476 }
Hui Wangb647abe2021-02-26 09:33:38 -08002477 case SRC_SET_FEATURE_ENABLED: {
2478 return handleSrcSetFeatureValidationCommand();
2479 }
2480 case SRC_GET_FEATURE_ENABLED: {
2481 return handleSrcGetFeatureValidationCommand();
2482 }
Hui Wang761a6682020-10-31 05:12:53 +00002483 }
2484
2485 return -1;
2486 }
2487
James.cf Linbcdf8b32021-01-14 16:44:13 +08002488 private int handleRcsUceCommand() {
2489 String arg = getNextArg();
2490 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002491 onHelpUce();
2492 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002493 }
2494
2495 switch (arg) {
2496 case UCE_REMOVE_EAB_CONTACT:
2497 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002498 case UCE_GET_EAB_CONTACT:
2499 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002500 case UCE_GET_EAB_CAPABILITY:
2501 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002502 case UCE_GET_DEVICE_ENABLED:
2503 return handleUceGetDeviceEnabledCommand();
2504 case UCE_SET_DEVICE_ENABLED:
2505 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002506 case UCE_OVERRIDE_PUBLISH_CAPS:
2507 return handleUceOverridePublishCaps();
2508 case UCE_GET_LAST_PIDF_XML:
2509 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002510 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2511 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002512 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2513 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002514 }
2515 return -1;
2516 }
2517
2518 private int handleRemovingEabContactCommand() {
2519 int subId = getSubId("uce remove-eab-contact");
2520 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2521 return -1;
2522 }
2523
2524 String phoneNumber = getNextArgRequired();
2525 if (TextUtils.isEmpty(phoneNumber)) {
2526 return -1;
2527 }
2528 int result = 0;
2529 try {
2530 result = mInterface.removeContactFromEab(subId, phoneNumber);
2531 } catch (RemoteException e) {
2532 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2533 getErrPrintWriter().println("Exception: " + e.getMessage());
2534 return -1;
2535 }
2536
2537 if (VDBG) {
2538 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2539 }
calvinpan293ea1b2021-02-04 17:52:13 +08002540 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002541 }
2542
calvinpane4a8a1d2021-01-25 13:51:18 +08002543 private int handleGettingEabContactCommand() {
2544 String phoneNumber = getNextArgRequired();
2545 if (TextUtils.isEmpty(phoneNumber)) {
2546 return -1;
2547 }
2548 String result = "";
2549 try {
2550 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002551 } catch (RemoteException e) {
2552 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2553 getErrPrintWriter().println("Exception: " + e.getMessage());
2554 return -1;
2555 }
2556
2557 if (VDBG) {
2558 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2559 }
calvinpan293ea1b2021-02-04 17:52:13 +08002560 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002561 return 0;
2562 }
2563
Calvin Pana1434322021-07-01 19:27:01 +08002564 private int handleGettingEabCapabilityCommand() {
2565 String phoneNumber = getNextArgRequired();
2566 if (TextUtils.isEmpty(phoneNumber)) {
2567 return -1;
2568 }
2569 String result = "";
2570 try {
2571 result = mInterface.getCapabilityFromEab(phoneNumber);
2572 } catch (RemoteException e) {
2573 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2574 getErrPrintWriter().println("Exception: " + e.getMessage());
2575 return -1;
2576 }
2577
2578 if (VDBG) {
2579 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2580 }
2581 getOutPrintWriter().println(result);
2582 return 0;
2583 }
2584
James.cf Lin4b784aa2021-01-31 03:25:15 +08002585 private int handleUceGetDeviceEnabledCommand() {
2586 boolean result = false;
2587 try {
2588 result = mInterface.getDeviceUceEnabled();
2589 } catch (RemoteException e) {
2590 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2591 return -1;
2592 }
2593 if (VDBG) {
2594 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2595 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002596 getOutPrintWriter().println(result);
2597 return 0;
2598 }
2599
James.cf Lin4b784aa2021-01-31 03:25:15 +08002600 private int handleUceSetDeviceEnabledCommand() {
2601 String enabledStr = getNextArg();
2602 if (TextUtils.isEmpty(enabledStr)) {
2603 return -1;
2604 }
2605
2606 try {
2607 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2608 mInterface.setDeviceUceEnabled(isEnabled);
2609 if (VDBG) {
2610 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2611 }
2612 } catch (NumberFormatException | RemoteException e) {
2613 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2614 getErrPrintWriter().println("Exception: " + e.getMessage());
2615 return -1;
2616 }
2617 return 0;
2618 }
2619
James.cf Line8713a42021-04-29 16:04:26 +08002620 private int handleUceRemoveRequestDisallowedStatus() {
2621 int subId = getSubId("uce remove-request-disallowed-status");
2622 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2623 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2624 return -1;
2625 }
2626 boolean result;
2627 try {
2628 result = mInterface.removeUceRequestDisallowedStatus(subId);
2629 } catch (RemoteException e) {
2630 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2631 return -1;
2632 }
2633 if (VDBG) {
2634 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2635 }
2636 getOutPrintWriter().println(result);
2637 return 0;
2638 }
2639
James.cf Lin0fc71b02021-05-25 01:37:38 +08002640 private int handleUceSetCapRequestTimeout() {
2641 int subId = getSubId("uce set-capabilities-request-timeout");
2642 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2643 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2644 return -1;
2645 }
2646 long timeoutAfterMs = Long.valueOf(getNextArg());
2647 boolean result;
2648 try {
2649 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2650 } catch (RemoteException e) {
2651 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2652 return -1;
2653 }
2654 if (VDBG) {
2655 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2656 }
2657 getOutPrintWriter().println(result);
2658 return 0;
2659 }
2660
Hui Wangbaaee6a2021-02-19 20:45:36 -08002661 private int handleSrcSetTestEnabledCommand() {
2662 String enabledStr = getNextArg();
2663 if (enabledStr == null) {
2664 return -1;
2665 }
2666
2667 try {
2668 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2669 if (VDBG) {
2670 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2671 }
2672 getOutPrintWriter().println("Done");
2673 } catch (NumberFormatException | RemoteException e) {
2674 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2675 getErrPrintWriter().println("Exception: " + e.getMessage());
2676 return -1;
2677 }
2678 return 0;
2679 }
2680
2681 private int handleSrcGetTestEnabledCommand() {
2682 boolean result = false;
2683 try {
2684 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2685 } catch (RemoteException e) {
2686 return -1;
2687 }
2688 if (VDBG) {
2689 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2690 }
2691 getOutPrintWriter().println(result);
2692 return 0;
2693 }
2694
Brad Ebinger14d467f2021-02-12 06:18:28 +00002695 private int handleUceOverridePublishCaps() {
2696 int subId = getSubId("uce override-published-caps");
2697 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2698 return -1;
2699 }
2700 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2701 String operation = getNextArgRequired();
2702 String caps = getNextArg();
2703 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2704 && !"list".equals(operation)) {
2705 getErrPrintWriter().println("Invalid operation: " + operation);
2706 return -1;
2707 }
2708
2709 // add/remove requires capabilities to be specified.
2710 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2711 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2712 + "specified");
2713 return -1;
2714 }
2715
2716 ArraySet<String> capSet = new ArraySet<>();
2717 if (!TextUtils.isEmpty(caps)) {
2718 String[] capArray = caps.split(":");
2719 for (String cap : capArray) {
2720 // Allow unknown tags to be passed in as well.
2721 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2722 }
2723 }
2724
2725 RcsContactUceCapability result = null;
2726 try {
2727 switch (operation) {
2728 case "add":
2729 result = mInterface.addUceRegistrationOverrideShell(subId,
2730 new ArrayList<>(capSet));
2731 break;
2732 case "remove":
2733 result = mInterface.removeUceRegistrationOverrideShell(subId,
2734 new ArrayList<>(capSet));
2735 break;
2736 case "clear":
2737 result = mInterface.clearUceRegistrationOverrideShell(subId);
2738 break;
2739 case "list":
2740 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2741 break;
2742 }
2743 } catch (RemoteException e) {
2744 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2745 getErrPrintWriter().println("Exception: " + e.getMessage());
2746 return -1;
2747 } catch (ServiceSpecificException sse) {
2748 // Reconstruct ImsException
2749 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2750 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2751 getErrPrintWriter().println("Exception: " + imsException);
2752 return -1;
2753 }
2754 if (result == null) {
2755 getErrPrintWriter().println("Service not available");
2756 return -1;
2757 }
2758 getOutPrintWriter().println(result);
2759 return 0;
2760 }
2761
2762 private int handleUceGetPidfXml() {
2763 int subId = getSubId("uce get-last-publish-pidf");
2764 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2765 return -1;
2766 }
2767
2768 String result;
2769 try {
2770 result = mInterface.getLastUcePidfXmlShell(subId);
2771 } catch (RemoteException e) {
2772 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2773 getErrPrintWriter().println("Exception: " + e.getMessage());
2774 return -1;
2775 } catch (ServiceSpecificException sse) {
2776 // Reconstruct ImsException
2777 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2778 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2779 getErrPrintWriter().println("Exception: " + imsException);
2780 return -1;
2781 }
2782 if (result == null) {
2783 getErrPrintWriter().println("Service not available");
2784 return -1;
2785 }
2786 getOutPrintWriter().println(result);
2787 return 0;
2788 }
2789
Hui Wang761a6682020-10-31 05:12:53 +00002790 private int handleSrcSetDeviceEnabledCommand() {
2791 String enabledStr = getNextArg();
2792 if (enabledStr == null) {
2793 return -1;
2794 }
2795
2796 try {
2797 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2798 if (VDBG) {
2799 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2800 }
2801 getOutPrintWriter().println("Done");
2802 } catch (NumberFormatException | RemoteException e) {
2803 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2804 getErrPrintWriter().println("Exception: " + e.getMessage());
2805 return -1;
2806 }
2807 return 0;
2808 }
2809
2810 private int handleSrcGetDeviceEnabledCommand() {
2811 boolean result = false;
2812 try {
2813 result = mInterface.getDeviceSingleRegistrationEnabled();
2814 } catch (RemoteException e) {
2815 return -1;
2816 }
2817 if (VDBG) {
2818 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2819 }
2820 getOutPrintWriter().println(result);
2821 return 0;
2822 }
2823
2824 private int handleSrcSetCarrierEnabledCommand() {
2825 //the release time value could be -1
2826 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2827 : SubscriptionManager.getDefaultSubscriptionId();
2828 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2829 return -1;
2830 }
2831
2832 String enabledStr = getNextArg();
2833 if (enabledStr == null) {
2834 return -1;
2835 }
2836
2837 try {
2838 boolean result =
2839 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2840 if (VDBG) {
2841 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2842 + enabledStr + ", result=" + result);
2843 }
2844 getOutPrintWriter().println(result);
2845 } catch (NumberFormatException | RemoteException e) {
2846 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2847 + enabledStr + ", error" + e.getMessage());
2848 getErrPrintWriter().println("Exception: " + e.getMessage());
2849 return -1;
2850 }
2851 return 0;
2852 }
2853
2854 private int handleSrcGetCarrierEnabledCommand() {
2855 int subId = getSubId("src get-carrier-enabled");
2856 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2857 return -1;
2858 }
2859
2860 boolean result = false;
2861 try {
2862 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2863 } catch (RemoteException e) {
2864 return -1;
2865 }
2866 if (VDBG) {
2867 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2868 }
2869 getOutPrintWriter().println(result);
2870 return 0;
2871 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002872
Hui Wangb647abe2021-02-26 09:33:38 -08002873 private int handleSrcSetFeatureValidationCommand() {
2874 //the release time value could be -1
2875 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2876 : SubscriptionManager.getDefaultSubscriptionId();
2877 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2878 return -1;
2879 }
2880
2881 String enabledStr = getNextArg();
2882 if (enabledStr == null) {
2883 return -1;
2884 }
2885
2886 try {
2887 boolean result =
2888 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2889 if (VDBG) {
2890 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2891 + enabledStr + ", result=" + result);
2892 }
2893 getOutPrintWriter().println(result);
2894 } catch (NumberFormatException | RemoteException e) {
2895 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2896 + enabledStr + ", error" + e.getMessage());
2897 getErrPrintWriter().println("Exception: " + e.getMessage());
2898 return -1;
2899 }
2900 return 0;
2901 }
2902
2903 private int handleSrcGetFeatureValidationCommand() {
2904 int subId = getSubId("src get-feature-validation");
2905 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2906 return -1;
2907 }
2908
2909 Boolean result = false;
2910 try {
2911 result = mInterface.getImsFeatureValidationOverride(subId);
2912 } catch (RemoteException e) {
2913 return -1;
2914 }
2915 if (VDBG) {
2916 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2917 }
2918 getOutPrintWriter().println(result);
2919 return 0;
2920 }
2921
2922
Hall Liuaa4211e2021-01-20 15:43:39 -08002923 private void onHelpCallComposer() {
2924 PrintWriter pw = getOutPrintWriter();
2925 pw.println("Call composer commands");
2926 pw.println(" callcomposer test-mode enable|disable|query");
2927 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2928 pw.println(" upload/download from carrier servers is disabled, and operations are");
2929 pw.println(" performed using emulated local files instead.");
2930 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2931 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2932 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002933 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2934 pw.println(" Enables or disables the user setting for call composer, as set by");
2935 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002936 }
2937
2938 private int handleCallComposerCommand() {
2939 String arg = getNextArg();
2940 if (arg == null) {
2941 onHelpCallComposer();
2942 return 0;
2943 }
2944
2945 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2946 "MODIFY_PHONE_STATE required for call composer shell cmds");
2947 switch (arg) {
2948 case CALL_COMPOSER_TEST_MODE: {
2949 String enabledStr = getNextArg();
2950 if (ENABLE.equals(enabledStr)) {
2951 CallComposerPictureManager.sTestMode = true;
2952 } else if (DISABLE.equals(enabledStr)) {
2953 CallComposerPictureManager.sTestMode = false;
2954 } else if (QUERY.equals(enabledStr)) {
2955 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2956 } else {
2957 onHelpCallComposer();
2958 return 1;
2959 }
2960 break;
2961 }
2962 case CALL_COMPOSER_SIMULATE_CALL: {
2963 int subscriptionId = Integer.valueOf(getNextArg());
2964 String uuidString = getNextArg();
2965 UUID uuid = UUID.fromString(uuidString);
2966 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2967 Binder.withCleanCallingIdentity(() -> {
2968 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2969 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2970 });
2971 try {
2972 Uri uri = storageUriFuture.get();
2973 getOutPrintWriter().println(String.valueOf(uri));
2974 } catch (Exception e) {
2975 throw new RuntimeException(e);
2976 }
2977 break;
2978 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002979 case CALL_COMPOSER_USER_SETTING: {
2980 try {
2981 int subscriptionId = Integer.valueOf(getNextArg());
2982 String enabledStr = getNextArg();
2983 if (ENABLE.equals(enabledStr)) {
2984 mInterface.setCallComposerStatus(subscriptionId,
2985 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2986 } else if (DISABLE.equals(enabledStr)) {
2987 mInterface.setCallComposerStatus(subscriptionId,
2988 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2989 } else if (QUERY.equals(enabledStr)) {
2990 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2991 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2992 } else {
2993 onHelpCallComposer();
2994 return 1;
2995 }
2996 } catch (RemoteException e) {
2997 e.printStackTrace(getOutPrintWriter());
2998 return 1;
2999 }
3000 break;
3001 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003002 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003003 return 0;
3004 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003005
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003006 private int handleHasCarrierPrivilegesCommand() {
3007 String packageName = getNextArgRequired();
3008
3009 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003010 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003011 try {
3012 hasCarrierPrivileges =
3013 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3014 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3015 } catch (RemoteException e) {
3016 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3017 getErrPrintWriter().println("Exception: " + e.getMessage());
3018 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003019 } finally {
3020 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003021 }
3022
3023 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003024 return 0;
3025 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003026
3027 private int handleAllowedNetworkTypesCommand(String command) {
3028 if (!checkShellUid()) {
3029 return -1;
3030 }
3031
3032 PrintWriter errPw = getErrPrintWriter();
3033 String tag = command + ": ";
3034 String opt;
3035 int subId = -1;
3036 Log.v(LOG_TAG, command + " start");
3037
3038 while ((opt = getNextOption()) != null) {
3039 if (opt.equals("-s")) {
3040 try {
3041 subId = slotStringToSubId(tag, getNextArgRequired());
3042 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3043 errPw.println(tag + "No valid subscription found.");
3044 return -1;
3045 }
3046 } catch (IllegalArgumentException e) {
3047 // Missing slot id
3048 errPw.println(tag + "SLOT_ID expected after -s.");
3049 return -1;
3050 }
3051 } else {
3052 errPw.println(tag + "Unknown option " + opt);
3053 return -1;
3054 }
3055 }
3056
3057 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3058 return handleGetAllowedNetworkTypesCommand(subId);
3059 }
3060 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3061 return handleSetAllowedNetworkTypesCommand(subId);
3062 }
3063 return -1;
3064 }
3065
3066 private int handleGetAllowedNetworkTypesCommand(int subId) {
3067 PrintWriter errPw = getErrPrintWriter();
3068
3069 long result = -1;
3070 try {
3071 if (mInterface != null) {
3072 result = mInterface.getAllowedNetworkTypesForReason(subId,
3073 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3074 } else {
3075 throw new IllegalStateException("telephony service is null.");
3076 }
3077 } catch (RemoteException e) {
3078 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3079 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3080 return -1;
3081 }
3082
3083 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3084 return 0;
3085 }
3086
3087 private int handleSetAllowedNetworkTypesCommand(int subId) {
3088 PrintWriter errPw = getErrPrintWriter();
3089
3090 String bitmaskString = getNextArg();
3091 if (TextUtils.isEmpty(bitmaskString)) {
3092 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3093 return -1;
3094 }
3095 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3096 if (allowedNetworkTypes < 0) {
3097 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3098 return -1;
3099 }
3100 boolean result = false;
3101 try {
3102 if (mInterface != null) {
3103 result = mInterface.setAllowedNetworkTypesForReason(subId,
3104 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3105 } else {
3106 throw new IllegalStateException("telephony service is null.");
3107 }
3108 } catch (RemoteException e) {
3109 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3110 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3111 return -1;
3112 }
3113
3114 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3115 if (result) {
3116 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3117 }
3118 getOutPrintWriter().println(resultMessage);
3119 return 0;
3120 }
3121
3122 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3123 if (TextUtils.isEmpty(bitmaskString)) {
3124 return -1;
3125 }
3126 if (VDBG) {
3127 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3128 + ", length: " + bitmaskString.length());
3129 }
3130 try {
3131 return Long.parseLong(bitmaskString, 2);
3132 } catch (NumberFormatException e) {
3133 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3134 return -1;
3135 }
3136 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003137
jimsun3b9ccac2021-10-26 15:01:23 +08003138 private int handleRadioSetModemServiceCommand() {
3139 PrintWriter errPw = getErrPrintWriter();
3140 String serviceName = null;
3141
3142 String opt;
3143 while ((opt = getNextOption()) != null) {
3144 switch (opt) {
3145 case "-s": {
3146 serviceName = getNextArgRequired();
3147 break;
3148 }
3149 }
3150 }
3151
3152 try {
3153 boolean result = mInterface.setModemService(serviceName);
3154 if (VDBG) {
3155 Log.v(LOG_TAG,
3156 "RadioSetModemService " + serviceName + ", result = " + result);
3157 }
3158 getOutPrintWriter().println(result);
3159 } catch (RemoteException e) {
3160 Log.w(LOG_TAG,
3161 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3162 errPw.println("Exception: " + e.getMessage());
3163 return -1;
3164 }
3165 return 0;
3166 }
3167
3168 private int handleRadioGetModemServiceCommand() {
3169 PrintWriter errPw = getErrPrintWriter();
3170 String result;
3171
3172 try {
3173 result = mInterface.getModemService();
3174 getOutPrintWriter().println(result);
3175 } catch (RemoteException e) {
3176 errPw.println("Exception: " + e.getMessage());
3177 return -1;
3178 }
3179 if (VDBG) {
3180 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3181 }
3182 return 0;
3183 }
3184
3185 private int handleRadioCommand() {
3186 String arg = getNextArg();
3187 if (arg == null) {
3188 onHelpRadio();
3189 return 0;
3190 }
3191
3192 switch (arg) {
3193 case RADIO_SET_MODEM_SERVICE:
3194 return handleRadioSetModemServiceCommand();
3195
3196 case RADIO_GET_MODEM_SERVICE:
3197 return handleRadioGetModemServiceCommand();
3198 }
3199
3200 return -1;
3201 }
arunvoddud7401012022-12-15 16:08:12 +00003202
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003203 private int handleSetSatelliteServicePackageNameCommand() {
3204 PrintWriter errPw = getErrPrintWriter();
3205 String serviceName = null;
3206
3207 String opt;
3208 while ((opt = getNextOption()) != null) {
3209 switch (opt) {
3210 case "-s": {
3211 serviceName = getNextArgRequired();
3212 break;
3213 }
3214 }
3215 }
3216 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3217 + serviceName);
3218
3219 try {
3220 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3221 if (VDBG) {
3222 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3223 + ", result = " + result);
3224 }
3225 getOutPrintWriter().println(result);
3226 } catch (RemoteException e) {
3227 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3228 + ", error = " + e.getMessage());
3229 errPw.println("Exception: " + e.getMessage());
3230 return -1;
3231 }
3232 return 0;
3233 }
3234
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003235 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3236 PrintWriter errPw = getErrPrintWriter();
3237 String serviceName = null;
3238
3239 String opt;
3240 while ((opt = getNextOption()) != null) {
3241 switch (opt) {
3242 case "-s": {
3243 serviceName = getNextArgRequired();
3244 break;
3245 }
3246 }
3247 }
3248 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3249 + serviceName);
3250
3251 try {
3252 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3253 if (VDBG) {
3254 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3255 + ", result = " + result);
3256 }
3257 getOutPrintWriter().println(result);
3258 } catch (RemoteException e) {
3259 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3260 + ", error = " + e.getMessage());
3261 errPw.println("Exception: " + e.getMessage());
3262 return -1;
3263 }
3264 return 0;
3265 }
3266
Thomas Nguyen87dce732023-04-20 18:27:16 -07003267 private int handleSetSatellitePointingUiClassNameCommand() {
3268 PrintWriter errPw = getErrPrintWriter();
3269 String packageName = null;
3270 String className = null;
3271
3272 String opt;
3273 while ((opt = getNextOption()) != null) {
3274 switch (opt) {
3275 case "-p": {
3276 packageName = getNextArgRequired();
3277 break;
3278 }
3279 case "-c": {
3280 className = getNextArgRequired();
3281 break;
3282 }
3283 }
3284 }
3285 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3286 + packageName + ", className=" + className);
3287
3288 try {
3289 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3290 if (VDBG) {
3291 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3292 }
3293 getOutPrintWriter().println(result);
3294 } catch (RemoteException e) {
3295 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3296 + ", error = " + e.getMessage());
3297 errPw.println("Exception: " + e.getMessage());
3298 return -1;
3299 }
3300 return 0;
3301 }
3302
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003303 private int handleSetEmergencyCallToSatelliteHandoverType() {
3304 PrintWriter errPw = getErrPrintWriter();
3305 int handoverType = -1;
3306 int delaySeconds = 0;
3307
3308 String opt;
3309 while ((opt = getNextOption()) != null) {
3310 switch (opt) {
3311 case "-t": {
3312 try {
3313 handoverType = Integer.parseInt(getNextArgRequired());
3314 } catch (NumberFormatException e) {
3315 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3316 + " for handoverType");
3317 return -1;
3318 }
3319 break;
3320 }
3321 case "-d": {
3322 try {
3323 delaySeconds = Integer.parseInt(getNextArgRequired());
3324 } catch (NumberFormatException e) {
3325 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3326 + " for delaySeconds");
3327 return -1;
3328 }
3329 break;
3330 }
3331 }
3332 }
3333 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3334 + handoverType + ", delaySeconds=" + delaySeconds);
3335
3336 try {
3337 boolean result =
3338 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3339 if (VDBG) {
3340 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3341 }
3342 getOutPrintWriter().println(result);
3343 } catch (RemoteException e) {
3344 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3345 + ", error = " + e.getMessage());
3346 errPw.println("Exception: " + e.getMessage());
3347 return -1;
3348 }
3349 return 0;
3350 }
3351
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003352 private int handleSetSatelliteListeningTimeoutDuration() {
3353 PrintWriter errPw = getErrPrintWriter();
3354 long timeoutMillis = 0;
3355
3356 String opt;
3357 while ((opt = getNextOption()) != null) {
3358 switch (opt) {
3359 case "-t": {
3360 timeoutMillis = Long.parseLong(getNextArgRequired());
3361 break;
3362 }
3363 }
3364 }
3365 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3366 + timeoutMillis);
3367
3368 try {
3369 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3370 if (VDBG) {
3371 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3372 + ", result = " + result);
3373 }
3374 getOutPrintWriter().println(result);
3375 } catch (RemoteException e) {
3376 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3377 + ", error = " + e.getMessage());
3378 errPw.println("Exception: " + e.getMessage());
3379 return -1;
3380 }
3381 return 0;
3382 }
3383
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003384 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003385 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003386 boolean reset = false;
3387 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003388 long timeoutMillis = 0;
3389
3390 String opt;
3391 while ((opt = getNextOption()) != null) {
3392 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003393 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003394 timeoutMillis = Long.parseLong(getNextArgRequired());
3395 break;
3396 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003397 case "-r": {
3398 reset = true;
3399 break;
3400 }
3401 case "-t": {
3402 timeoutType = Integer.parseInt(getNextArgRequired());
3403 break;
3404 }
Hakjun Choiae365972023-04-25 11:00:31 +00003405 }
3406 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003407 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3408 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003409
3410 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003411 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3412 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003413 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003414 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003415 + ", result = " + result);
3416 }
3417 getOutPrintWriter().println(result);
3418 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003419 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3420 + ", error = " + e.getMessage());
3421 errPw.println("Exception: " + e.getMessage());
3422 return -1;
3423 }
3424 return 0;
3425 }
3426
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +00003427 private int handleSetDatagramControllerBooleanConfig() {
3428 PrintWriter errPw = getErrPrintWriter();
3429 boolean reset = false;
3430 int booleanType = 0;
3431 boolean enable = false;
3432
3433 String opt;
3434 while ((opt = getNextOption()) != null) {
3435 switch (opt) {
3436 case "-d": {
3437 enable = Boolean.parseBoolean(getNextArgRequired());
3438 break;
3439 }
3440 case "-r": {
3441 reset = true;
3442 break;
3443 }
3444 case "-t": {
3445 booleanType = Integer.parseInt(getNextArgRequired());
3446 break;
3447 }
3448 }
3449 }
3450 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3451 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3452
3453 try {
3454 boolean result = mInterface.setDatagramControllerBooleanConfig(
3455 reset, booleanType, enable);
3456 if (VDBG) {
3457 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3458 }
3459 getOutPrintWriter().println(result);
3460 } catch (RemoteException e) {
3461 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3462 errPw.println("Exception: " + e.getMessage());
3463 return -1;
3464 }
3465 return 0;
3466 }
3467
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003468 private int handleSetSatelliteControllerTimeoutDuration() {
3469 PrintWriter errPw = getErrPrintWriter();
3470 boolean reset = false;
3471 int timeoutType = 0;
3472 long timeoutMillis = 0;
3473
3474 String opt;
3475 while ((opt = getNextOption()) != null) {
3476 switch (opt) {
3477 case "-d": {
3478 timeoutMillis = Long.parseLong(getNextArgRequired());
3479 break;
3480 }
3481 case "-r": {
3482 reset = true;
3483 break;
3484 }
3485 case "-t": {
3486 timeoutType = Integer.parseInt(getNextArgRequired());
3487 break;
3488 }
3489 }
3490 }
3491 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3492 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3493
3494 try {
3495 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3496 reset, timeoutType, timeoutMillis);
3497 if (VDBG) {
3498 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3499 + ", result = " + result);
3500 }
3501 getOutPrintWriter().println(result);
3502 } catch (RemoteException e) {
3503 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003504 + ", error = " + e.getMessage());
3505 errPw.println("Exception: " + e.getMessage());
3506 return -1;
3507 }
3508 return 0;
3509 }
3510
Hakjun Choibc6ce992023-11-07 16:04:33 +00003511 private int handleSetShouldSendDatagramToModemInDemoMode() {
3512 PrintWriter errPw = getErrPrintWriter();
3513 String opt;
3514 boolean shouldSendToDemoMode;
3515
3516 if ((opt = getNextArg()) == null) {
3517 errPw.println(
3518 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3519 + " Invalid Argument");
3520 return -1;
3521 } else {
3522 switch (opt) {
3523 case "true": {
3524 shouldSendToDemoMode = true;
3525 break;
3526 }
3527 case "false": {
3528 shouldSendToDemoMode = false;
3529 break;
3530 }
3531 default:
3532 errPw.println(
3533 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3534 + " Invalid Argument");
3535 return -1;
3536 }
3537 }
3538
3539 Log.d(LOG_TAG,
3540 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3541
3542 try {
3543 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3544 shouldSendToDemoMode);
3545 if (VDBG) {
3546 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3547 + result);
3548 }
3549 getOutPrintWriter().println(false);
3550 } catch (RemoteException e) {
3551 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3552 + "), error = " + e.getMessage());
3553 errPw.println("Exception: " + e.getMessage());
3554 return -1;
3555 }
3556 return 0;
3557 }
3558
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003559 private int handleSetSatelliteAccessControlOverlayConfigs() {
3560 PrintWriter errPw = getErrPrintWriter();
3561 boolean reset = false;
3562 boolean isAllowed = false;
3563 String s2CellFile = null;
3564 long locationFreshDurationNanos = 0;
3565 List<String> satelliteCountryCodes = null;
3566
3567 String opt;
3568 while ((opt = getNextOption()) != null) {
3569 switch (opt) {
3570 case "-r": {
3571 reset = true;
3572 break;
3573 }
3574 case "-a": {
3575 isAllowed = true;
3576 break;
3577 }
3578 case "-f": {
3579 s2CellFile = getNextArgRequired();
3580 break;
3581 }
3582 case "-d": {
3583 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3584 break;
3585 }
3586 case "-c": {
3587 String countryCodeStr = getNextArgRequired();
3588 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3589 break;
3590 }
3591 }
3592 }
3593 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3594 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3595 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3596 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3597
3598 try {
3599 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3600 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3601 if (VDBG) {
3602 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3603 }
3604 getOutPrintWriter().println(result);
3605 } catch (RemoteException e) {
3606 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3607 errPw.println("Exception: " + e.getMessage());
3608 return -1;
3609 }
3610 return 0;
3611 }
3612
3613 private int handleSetCountryCodes() {
3614 PrintWriter errPw = getErrPrintWriter();
3615 List<String> currentNetworkCountryCodes = new ArrayList<>();
3616 String locationCountryCode = null;
3617 long locationCountryCodeTimestampNanos = 0;
3618 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3619 boolean reset = false;
3620
3621 String opt;
3622 while ((opt = getNextOption()) != null) {
3623 switch (opt) {
3624 case "-r": {
3625 reset = true;
3626 break;
3627 }
3628 case "-n": {
3629 String countryCodeStr = getNextArgRequired();
3630 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3631 break;
3632 }
3633 case "-c": {
3634 String cachedNetworkCountryCodeStr = getNextArgRequired();
3635 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3636 break;
3637 }
3638 case "-l": {
3639 locationCountryCode = getNextArgRequired();
3640 break;
3641 }
3642 case "-t": {
3643 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3644 break;
3645 }
3646 }
3647 }
3648 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3649 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3650 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3651 + currentNetworkCountryCodes);
3652
3653 try {
3654 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3655 cachedNetworkCountryCodes, locationCountryCode,
3656 locationCountryCodeTimestampNanos);
3657 if (VDBG) {
3658 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3659 }
3660 getOutPrintWriter().println(result);
3661 } catch (RemoteException e) {
3662 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3663 errPw.println("Exception: " + e.getMessage());
3664 return -1;
3665 }
3666 return 0;
3667 }
3668
Thomas Nguyen3d602742024-01-19 11:29:35 -08003669 private int handleSetOemEnabledSatelliteProvisionStatus() {
3670 PrintWriter errPw = getErrPrintWriter();
3671 boolean isProvisioned = false;
3672 boolean reset = true;
3673
3674 String opt;
3675 while ((opt = getNextOption()) != null) {
3676 switch (opt) {
3677 case "-p": {
3678 try {
3679 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3680 reset = false;
3681 } catch (Exception e) {
3682 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3683 + "after -p indicating provision status");
3684 return -1;
3685 }
3686 }
3687 }
3688 }
3689 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3690 + ", isProvisioned=" + isProvisioned);
3691
3692 try {
3693 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3694 if (VDBG) {
3695 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3696 }
3697 getOutPrintWriter().println(result);
3698 } catch (RemoteException e) {
3699 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3700 errPw.println("Exception: " + e.getMessage());
3701 return -1;
3702 }
3703 return 0;
3704 }
3705
Hakjun Choi4a832d12024-05-28 22:23:55 +00003706 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3707 PrintWriter errPw = getErrPrintWriter();
3708 String opt;
3709 String state;
3710
3711 if ((opt = getNextArg()) == null) {
3712 errPw.println(
3713 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3714 + "-location-cache :"
3715 + " Invalid Argument");
3716 return -1;
3717 } else {
3718 switch (opt) {
3719 case "-a": {
3720 state = "cache_allowed";
3721 break;
3722 }
3723 case "-n": {
3724 state = "cache_clear_and_not_allowed";
3725 break;
3726 }
3727 case "-c": {
3728 state = "clear_cache_only";
3729 break;
3730 }
3731 default:
3732 errPw.println(
3733 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3734 + "-location-cache :"
3735 + " Invalid Argument");
3736 return -1;
3737 }
3738 }
3739
3740 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3741 + state + ")");
3742
3743 try {
3744 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3745 state);
3746 if (VDBG) {
3747 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3748 + "returns: "
3749 + result);
3750 }
3751 getOutPrintWriter().println(result);
3752 } catch (RemoteException e) {
3753 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3754 + state + "), error = " + e.getMessage());
3755 errPw.println("Exception: " + e.getMessage());
3756 return -1;
3757 }
3758 return 0;
3759 }
3760
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003761 /**
3762 * Sample inputStr = "US,UK,CA;2,1,3"
3763 * Sample output: {[US,2], [UK,1], [CA,3]}
3764 */
3765 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3766 Map<String, Long> result = new HashMap<>();
3767 if (!TextUtils.isEmpty(inputStr)) {
3768 String[] stringLongArr = inputStr.split(";");
3769 if (stringLongArr.length != 2) {
3770 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3771 return result;
3772 }
3773
3774 String[] stringArr = stringLongArr[0].split(",");
3775 String[] longArr = stringLongArr[1].split(",");
3776 if (stringArr.length != longArr.length) {
3777 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3778 return result;
3779 }
3780
3781 for (int i = 0; i < stringArr.length; i++) {
3782 try {
3783 result.put(stringArr[i], Long.parseLong(longArr[i]));
3784 } catch (Exception ex) {
3785 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3786 + ", ex=" + ex);
3787 return result;
3788 }
3789 }
3790 }
3791 return result;
3792 }
3793
arunvoddud7401012022-12-15 16:08:12 +00003794 private int handleCarrierRestrictionStatusCommand() {
3795 try {
3796 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3797 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3798 mInterface.getModemService()))) {
3799 Log.v(LOG_TAG,
3800 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3801 + " checkShellUid fails");
3802 return -1;
3803 }
3804 } catch (RemoteException ex) {
3805 ex.printStackTrace();
3806 }
3807 String callerInfo = getNextOption();
3808 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3809 if (TextUtils.isEmpty(callerInfo)) {
3810 // reset the Json content after testing
3811 allowListInfo.updateJsonForTest(null);
3812 return 0;
3813 }
3814 if (callerInfo.startsWith("--")) {
3815 callerInfo = callerInfo.replace("--", "");
3816 }
3817 String params[] = callerInfo.split(",");
3818 StringBuffer jsonStrBuffer = new StringBuffer();
3819 String tokens;
3820 for (int index = 0; index < params.length; index++) {
3821 tokens = convertToJsonString(index, params[index]);
3822 if (TextUtils.isEmpty(tokens)) {
3823 // received wrong format from CTS
3824 if (VDBG) {
3825 Log.v(LOG_TAG,
3826 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3827 }
3828 return -1;
3829 }
3830 jsonStrBuffer.append(tokens);
3831 }
3832 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3833 return result;
3834 }
3835
Benedict Wong66477622023-02-03 23:30:57 +00003836 // set-carrier-service-package-override
3837 private int setCarrierServicePackageOverride() {
3838 PrintWriter errPw = getErrPrintWriter();
3839 int subId = SubscriptionManager.getDefaultSubscriptionId();
3840
3841 String opt;
3842 while ((opt = getNextOption()) != null) {
3843 switch (opt) {
3844 case "-s":
3845 try {
3846 subId = Integer.parseInt(getNextArgRequired());
3847 } catch (NumberFormatException e) {
3848 errPw.println(
3849 "set-carrier-service-package-override requires an integer as a"
3850 + " subscription ID.");
3851 return -1;
3852 }
3853 break;
3854 }
3855 }
3856
3857 String packageName = getNextArg();
3858 if (packageName == null) {
3859 errPw.println("set-carrier-service-package-override requires a override package name.");
3860 return -1;
3861 }
3862
3863 try {
3864 mInterface.setCarrierServicePackageOverride(
3865 subId, packageName, mContext.getOpPackageName());
3866
3867 if (VDBG) {
3868 Log.v(
3869 LOG_TAG,
3870 "set-carrier-service-package-override -s " + subId + " " + packageName);
3871 }
3872 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3873 Log.w(
3874 LOG_TAG,
3875 "set-carrier-service-package-override -s "
3876 + subId
3877 + " "
3878 + packageName
3879 + ", error"
3880 + e.getMessage());
3881 errPw.println("Exception: " + e.getMessage());
3882 return -1;
3883 }
3884 return 0;
3885 }
3886
3887 // clear-carrier-service-package-override
3888 private int clearCarrierServicePackageOverride() {
3889 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003890 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003891
3892 String opt;
3893 while ((opt = getNextOption()) != null) {
3894 switch (opt) {
3895 case "-s":
3896 try {
3897 subId = Integer.parseInt(getNextArgRequired());
3898 } catch (NumberFormatException e) {
3899 errPw.println(
3900 "clear-carrier-service-package-override requires an integer as a"
3901 + " subscription ID.");
3902 return -1;
3903 }
3904 break;
3905 }
3906 }
3907
3908 try {
3909 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3910
3911 if (VDBG) {
3912 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3913 }
3914 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3915 Log.w(
3916 LOG_TAG,
3917 "clear-carrier-service-package-override -s "
3918 + subId
3919 + ", error"
3920 + e.getMessage());
3921 errPw.println("Exception: " + e.getMessage());
3922 return -1;
3923 }
3924 return 0;
3925 }
arunvoddud7401012022-12-15 16:08:12 +00003926
Hunsuk Choi13078be2023-09-13 10:55:21 +00003927 private int handleDomainSelectionCommand() {
3928 String arg = getNextArg();
3929 if (arg == null) {
3930 onHelpDomainSelection();
3931 return 0;
3932 }
3933
3934 switch (arg) {
3935 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3936 return handleDomainSelectionSetServiceOverrideCommand();
3937 }
3938 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3939 return handleDomainSelectionClearServiceOverrideCommand();
3940 }
3941 }
3942
3943 return -1;
3944 }
3945
3946 // domainselection set-dss-override
3947 private int handleDomainSelectionSetServiceOverrideCommand() {
3948 PrintWriter errPw = getErrPrintWriter();
3949
3950 String componentName = getNextArg();
3951
3952 try {
3953 boolean result = mInterface.setDomainSelectionServiceOverride(
3954 ComponentName.unflattenFromString(componentName));
3955 if (VDBG) {
3956 Log.v(LOG_TAG, "domainselection set-dss-override "
3957 + componentName + ", result=" + result);
3958 }
3959 getOutPrintWriter().println(result);
3960 } catch (Exception e) {
3961 Log.w(LOG_TAG, "domainselection set-dss-override "
3962 + componentName + ", error=" + e.getMessage());
3963 errPw.println("Exception: " + e.getMessage());
3964 return -1;
3965 }
3966 return 0;
3967 }
3968
3969 // domainselection clear-dss-override
3970 private int handleDomainSelectionClearServiceOverrideCommand() {
3971 PrintWriter errPw = getErrPrintWriter();
3972
3973 try {
3974 boolean result = mInterface.clearDomainSelectionServiceOverride();
3975 if (VDBG) {
3976 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
3977 }
3978 getOutPrintWriter().println(result);
3979 } catch (RemoteException e) {
3980 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
3981 errPw.println("Exception: " + e.getMessage());
3982 return -1;
3983 }
3984 return 0;
3985 }
3986
arunvoddud7401012022-12-15 16:08:12 +00003987 /**
3988 * Building the string that can be used to build the JsonObject which supports to stub the data
3989 * in CarrierAllowListInfo for CTS testing. sample format is like
3990 * {"com.android.example":{"carrierId":"10000","callerSHA1Id":["XXXXXXXXXXXXXX"]}}
3991 */
3992 private String convertToJsonString(int index, String param) {
3993
3994 String token[] = param.split(":");
3995 String jSonString;
3996 switch (index) {
3997 case 0:
3998 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3999 break;
4000 case 1:
4001 jSonString =
4002 "{" + QUOTES + token[0] + QUOTES + ":" + QUOTES + token[1] + QUOTES + ",";
4003 break;
4004 case 2:
4005 jSonString =
4006 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4007 break;
4008 default:
4009 jSonString = null;
4010 }
4011 return jSonString;
4012 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004013}