blob: 7a424cb4e889b7f0c6f66146ae501bc4ad133c3b [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 Mallampati3f0ef9b2024-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 Mallampati3f0ef9b2024-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;
Hakjun Choic3393242024-06-26 18:02:08 +00003206 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003207
3208 String opt;
3209 while ((opt = getNextOption()) != null) {
3210 switch (opt) {
3211 case "-s": {
3212 serviceName = getNextArgRequired();
3213 break;
3214 }
Hakjun Choic3393242024-06-26 18:02:08 +00003215
3216 case "-p": {
3217 provisioned = getNextArgRequired();
3218 break;
3219 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003220 }
3221 }
3222 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003223 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003224
3225 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003226 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003227 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003228 Log.v(LOG_TAG,
3229 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3230 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003231 }
3232 getOutPrintWriter().println(result);
3233 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003234 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3235 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003236 errPw.println("Exception: " + e.getMessage());
3237 return -1;
3238 }
Hakjun Choic3393242024-06-26 18:02:08 +00003239
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003240 return 0;
3241 }
3242
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003243 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3244 PrintWriter errPw = getErrPrintWriter();
3245 String serviceName = null;
3246
3247 String opt;
3248 while ((opt = getNextOption()) != null) {
3249 switch (opt) {
3250 case "-s": {
3251 serviceName = getNextArgRequired();
3252 break;
3253 }
3254 }
3255 }
3256 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3257 + serviceName);
3258
3259 try {
3260 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3261 if (VDBG) {
3262 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3263 + ", result = " + result);
3264 }
3265 getOutPrintWriter().println(result);
3266 } catch (RemoteException e) {
3267 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3268 + ", error = " + e.getMessage());
3269 errPw.println("Exception: " + e.getMessage());
3270 return -1;
3271 }
3272 return 0;
3273 }
3274
Thomas Nguyen87dce732023-04-20 18:27:16 -07003275 private int handleSetSatellitePointingUiClassNameCommand() {
3276 PrintWriter errPw = getErrPrintWriter();
3277 String packageName = null;
3278 String className = null;
3279
3280 String opt;
3281 while ((opt = getNextOption()) != null) {
3282 switch (opt) {
3283 case "-p": {
3284 packageName = getNextArgRequired();
3285 break;
3286 }
3287 case "-c": {
3288 className = getNextArgRequired();
3289 break;
3290 }
3291 }
3292 }
3293 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3294 + packageName + ", className=" + className);
3295
3296 try {
3297 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3298 if (VDBG) {
3299 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3300 }
3301 getOutPrintWriter().println(result);
3302 } catch (RemoteException e) {
3303 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3304 + ", error = " + e.getMessage());
3305 errPw.println("Exception: " + e.getMessage());
3306 return -1;
3307 }
3308 return 0;
3309 }
3310
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003311 private int handleSetEmergencyCallToSatelliteHandoverType() {
3312 PrintWriter errPw = getErrPrintWriter();
3313 int handoverType = -1;
3314 int delaySeconds = 0;
3315
3316 String opt;
3317 while ((opt = getNextOption()) != null) {
3318 switch (opt) {
3319 case "-t": {
3320 try {
3321 handoverType = Integer.parseInt(getNextArgRequired());
3322 } catch (NumberFormatException e) {
3323 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3324 + " for handoverType");
3325 return -1;
3326 }
3327 break;
3328 }
3329 case "-d": {
3330 try {
3331 delaySeconds = Integer.parseInt(getNextArgRequired());
3332 } catch (NumberFormatException e) {
3333 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3334 + " for delaySeconds");
3335 return -1;
3336 }
3337 break;
3338 }
3339 }
3340 }
3341 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3342 + handoverType + ", delaySeconds=" + delaySeconds);
3343
3344 try {
3345 boolean result =
3346 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3347 if (VDBG) {
3348 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3349 }
3350 getOutPrintWriter().println(result);
3351 } catch (RemoteException e) {
3352 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3353 + ", error = " + e.getMessage());
3354 errPw.println("Exception: " + e.getMessage());
3355 return -1;
3356 }
3357 return 0;
3358 }
3359
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003360 private int handleSetSatelliteListeningTimeoutDuration() {
3361 PrintWriter errPw = getErrPrintWriter();
3362 long timeoutMillis = 0;
3363
3364 String opt;
3365 while ((opt = getNextOption()) != null) {
3366 switch (opt) {
3367 case "-t": {
3368 timeoutMillis = Long.parseLong(getNextArgRequired());
3369 break;
3370 }
3371 }
3372 }
3373 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3374 + timeoutMillis);
3375
3376 try {
3377 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3378 if (VDBG) {
3379 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3380 + ", result = " + result);
3381 }
3382 getOutPrintWriter().println(result);
3383 } catch (RemoteException e) {
3384 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3385 + ", error = " + e.getMessage());
3386 errPw.println("Exception: " + e.getMessage());
3387 return -1;
3388 }
3389 return 0;
3390 }
3391
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003392 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003393 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003394 boolean reset = false;
3395 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003396 long timeoutMillis = 0;
3397
3398 String opt;
3399 while ((opt = getNextOption()) != null) {
3400 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003401 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003402 timeoutMillis = Long.parseLong(getNextArgRequired());
3403 break;
3404 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003405 case "-r": {
3406 reset = true;
3407 break;
3408 }
3409 case "-t": {
3410 timeoutType = Integer.parseInt(getNextArgRequired());
3411 break;
3412 }
Hakjun Choiae365972023-04-25 11:00:31 +00003413 }
3414 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003415 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3416 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003417
3418 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003419 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3420 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003421 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003422 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003423 + ", result = " + result);
3424 }
3425 getOutPrintWriter().println(result);
3426 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003427 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3428 + ", error = " + e.getMessage());
3429 errPw.println("Exception: " + e.getMessage());
3430 return -1;
3431 }
3432 return 0;
3433 }
3434
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003435 private int handleSetDatagramControllerBooleanConfig() {
3436 PrintWriter errPw = getErrPrintWriter();
3437 boolean reset = false;
3438 int booleanType = 0;
3439 boolean enable = false;
3440
3441 String opt;
3442 while ((opt = getNextOption()) != null) {
3443 switch (opt) {
3444 case "-d": {
3445 enable = Boolean.parseBoolean(getNextArgRequired());
3446 break;
3447 }
3448 case "-r": {
3449 reset = true;
3450 break;
3451 }
3452 case "-t": {
3453 booleanType = Integer.parseInt(getNextArgRequired());
3454 break;
3455 }
3456 }
3457 }
3458 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3459 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3460
3461 try {
3462 boolean result = mInterface.setDatagramControllerBooleanConfig(
3463 reset, booleanType, enable);
3464 if (VDBG) {
3465 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3466 }
3467 getOutPrintWriter().println(result);
3468 } catch (RemoteException e) {
3469 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3470 errPw.println("Exception: " + e.getMessage());
3471 return -1;
3472 }
3473 return 0;
3474 }
3475
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003476 private int handleSetSatelliteControllerTimeoutDuration() {
3477 PrintWriter errPw = getErrPrintWriter();
3478 boolean reset = false;
3479 int timeoutType = 0;
3480 long timeoutMillis = 0;
3481
3482 String opt;
3483 while ((opt = getNextOption()) != null) {
3484 switch (opt) {
3485 case "-d": {
3486 timeoutMillis = Long.parseLong(getNextArgRequired());
3487 break;
3488 }
3489 case "-r": {
3490 reset = true;
3491 break;
3492 }
3493 case "-t": {
3494 timeoutType = Integer.parseInt(getNextArgRequired());
3495 break;
3496 }
3497 }
3498 }
3499 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3500 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3501
3502 try {
3503 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3504 reset, timeoutType, timeoutMillis);
3505 if (VDBG) {
3506 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3507 + ", result = " + result);
3508 }
3509 getOutPrintWriter().println(result);
3510 } catch (RemoteException e) {
3511 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003512 + ", error = " + e.getMessage());
3513 errPw.println("Exception: " + e.getMessage());
3514 return -1;
3515 }
3516 return 0;
3517 }
3518
Hakjun Choibc6ce992023-11-07 16:04:33 +00003519 private int handleSetShouldSendDatagramToModemInDemoMode() {
3520 PrintWriter errPw = getErrPrintWriter();
3521 String opt;
3522 boolean shouldSendToDemoMode;
3523
3524 if ((opt = getNextArg()) == null) {
3525 errPw.println(
3526 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3527 + " Invalid Argument");
3528 return -1;
3529 } else {
3530 switch (opt) {
3531 case "true": {
3532 shouldSendToDemoMode = true;
3533 break;
3534 }
3535 case "false": {
3536 shouldSendToDemoMode = false;
3537 break;
3538 }
3539 default:
3540 errPw.println(
3541 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3542 + " Invalid Argument");
3543 return -1;
3544 }
3545 }
3546
3547 Log.d(LOG_TAG,
3548 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3549
3550 try {
3551 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3552 shouldSendToDemoMode);
3553 if (VDBG) {
3554 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3555 + result);
3556 }
3557 getOutPrintWriter().println(false);
3558 } catch (RemoteException e) {
3559 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3560 + "), error = " + e.getMessage());
3561 errPw.println("Exception: " + e.getMessage());
3562 return -1;
3563 }
3564 return 0;
3565 }
3566
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003567 private int handleSetSatelliteAccessControlOverlayConfigs() {
3568 PrintWriter errPw = getErrPrintWriter();
3569 boolean reset = false;
3570 boolean isAllowed = false;
3571 String s2CellFile = null;
3572 long locationFreshDurationNanos = 0;
3573 List<String> satelliteCountryCodes = null;
3574
3575 String opt;
3576 while ((opt = getNextOption()) != null) {
3577 switch (opt) {
3578 case "-r": {
3579 reset = true;
3580 break;
3581 }
3582 case "-a": {
3583 isAllowed = true;
3584 break;
3585 }
3586 case "-f": {
3587 s2CellFile = getNextArgRequired();
3588 break;
3589 }
3590 case "-d": {
3591 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3592 break;
3593 }
3594 case "-c": {
3595 String countryCodeStr = getNextArgRequired();
3596 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3597 break;
3598 }
3599 }
3600 }
3601 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3602 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3603 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3604 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3605
3606 try {
3607 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3608 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3609 if (VDBG) {
3610 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3611 }
3612 getOutPrintWriter().println(result);
3613 } catch (RemoteException e) {
3614 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3615 errPw.println("Exception: " + e.getMessage());
3616 return -1;
3617 }
3618 return 0;
3619 }
3620
3621 private int handleSetCountryCodes() {
3622 PrintWriter errPw = getErrPrintWriter();
3623 List<String> currentNetworkCountryCodes = new ArrayList<>();
3624 String locationCountryCode = null;
3625 long locationCountryCodeTimestampNanos = 0;
3626 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3627 boolean reset = false;
3628
3629 String opt;
3630 while ((opt = getNextOption()) != null) {
3631 switch (opt) {
3632 case "-r": {
3633 reset = true;
3634 break;
3635 }
3636 case "-n": {
3637 String countryCodeStr = getNextArgRequired();
3638 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3639 break;
3640 }
3641 case "-c": {
3642 String cachedNetworkCountryCodeStr = getNextArgRequired();
3643 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3644 break;
3645 }
3646 case "-l": {
3647 locationCountryCode = getNextArgRequired();
3648 break;
3649 }
3650 case "-t": {
3651 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3652 break;
3653 }
3654 }
3655 }
3656 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3657 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3658 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3659 + currentNetworkCountryCodes);
3660
3661 try {
3662 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3663 cachedNetworkCountryCodes, locationCountryCode,
3664 locationCountryCodeTimestampNanos);
3665 if (VDBG) {
3666 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3667 }
3668 getOutPrintWriter().println(result);
3669 } catch (RemoteException e) {
3670 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3671 errPw.println("Exception: " + e.getMessage());
3672 return -1;
3673 }
3674 return 0;
3675 }
3676
Thomas Nguyen3d602742024-01-19 11:29:35 -08003677 private int handleSetOemEnabledSatelliteProvisionStatus() {
3678 PrintWriter errPw = getErrPrintWriter();
3679 boolean isProvisioned = false;
3680 boolean reset = true;
3681
3682 String opt;
3683 while ((opt = getNextOption()) != null) {
3684 switch (opt) {
3685 case "-p": {
3686 try {
3687 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3688 reset = false;
3689 } catch (Exception e) {
3690 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3691 + "after -p indicating provision status");
3692 return -1;
3693 }
3694 }
3695 }
3696 }
3697 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3698 + ", isProvisioned=" + isProvisioned);
3699
3700 try {
3701 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3702 if (VDBG) {
3703 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3704 }
3705 getOutPrintWriter().println(result);
3706 } catch (RemoteException e) {
3707 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3708 errPw.println("Exception: " + e.getMessage());
3709 return -1;
3710 }
3711 return 0;
3712 }
3713
Hakjun Choi4a832d12024-05-28 22:23:55 +00003714 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3715 PrintWriter errPw = getErrPrintWriter();
3716 String opt;
3717 String state;
3718
3719 if ((opt = getNextArg()) == null) {
3720 errPw.println(
3721 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3722 + "-location-cache :"
3723 + " Invalid Argument");
3724 return -1;
3725 } else {
3726 switch (opt) {
3727 case "-a": {
3728 state = "cache_allowed";
3729 break;
3730 }
3731 case "-n": {
3732 state = "cache_clear_and_not_allowed";
3733 break;
3734 }
3735 case "-c": {
3736 state = "clear_cache_only";
3737 break;
3738 }
3739 default:
3740 errPw.println(
3741 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3742 + "-location-cache :"
3743 + " Invalid Argument");
3744 return -1;
3745 }
3746 }
3747
3748 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3749 + state + ")");
3750
3751 try {
3752 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3753 state);
3754 if (VDBG) {
3755 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3756 + "returns: "
3757 + result);
3758 }
3759 getOutPrintWriter().println(result);
3760 } catch (RemoteException e) {
3761 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3762 + state + "), error = " + e.getMessage());
3763 errPw.println("Exception: " + e.getMessage());
3764 return -1;
3765 }
3766 return 0;
3767 }
3768
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003769 /**
3770 * Sample inputStr = "US,UK,CA;2,1,3"
3771 * Sample output: {[US,2], [UK,1], [CA,3]}
3772 */
3773 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3774 Map<String, Long> result = new HashMap<>();
3775 if (!TextUtils.isEmpty(inputStr)) {
3776 String[] stringLongArr = inputStr.split(";");
3777 if (stringLongArr.length != 2) {
3778 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3779 return result;
3780 }
3781
3782 String[] stringArr = stringLongArr[0].split(",");
3783 String[] longArr = stringLongArr[1].split(",");
3784 if (stringArr.length != longArr.length) {
3785 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3786 return result;
3787 }
3788
3789 for (int i = 0; i < stringArr.length; i++) {
3790 try {
3791 result.put(stringArr[i], Long.parseLong(longArr[i]));
3792 } catch (Exception ex) {
3793 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3794 + ", ex=" + ex);
3795 return result;
3796 }
3797 }
3798 }
3799 return result;
3800 }
3801
arunvoddud7401012022-12-15 16:08:12 +00003802 private int handleCarrierRestrictionStatusCommand() {
3803 try {
3804 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3805 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3806 mInterface.getModemService()))) {
3807 Log.v(LOG_TAG,
3808 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3809 + " checkShellUid fails");
3810 return -1;
3811 }
3812 } catch (RemoteException ex) {
3813 ex.printStackTrace();
3814 }
3815 String callerInfo = getNextOption();
3816 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3817 if (TextUtils.isEmpty(callerInfo)) {
3818 // reset the Json content after testing
3819 allowListInfo.updateJsonForTest(null);
3820 return 0;
3821 }
3822 if (callerInfo.startsWith("--")) {
3823 callerInfo = callerInfo.replace("--", "");
3824 }
3825 String params[] = callerInfo.split(",");
3826 StringBuffer jsonStrBuffer = new StringBuffer();
3827 String tokens;
3828 for (int index = 0; index < params.length; index++) {
3829 tokens = convertToJsonString(index, params[index]);
3830 if (TextUtils.isEmpty(tokens)) {
3831 // received wrong format from CTS
3832 if (VDBG) {
3833 Log.v(LOG_TAG,
3834 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3835 }
3836 return -1;
3837 }
3838 jsonStrBuffer.append(tokens);
3839 }
3840 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3841 return result;
3842 }
3843
Benedict Wong66477622023-02-03 23:30:57 +00003844 // set-carrier-service-package-override
3845 private int setCarrierServicePackageOverride() {
3846 PrintWriter errPw = getErrPrintWriter();
3847 int subId = SubscriptionManager.getDefaultSubscriptionId();
3848
3849 String opt;
3850 while ((opt = getNextOption()) != null) {
3851 switch (opt) {
3852 case "-s":
3853 try {
3854 subId = Integer.parseInt(getNextArgRequired());
3855 } catch (NumberFormatException e) {
3856 errPw.println(
3857 "set-carrier-service-package-override requires an integer as a"
3858 + " subscription ID.");
3859 return -1;
3860 }
3861 break;
3862 }
3863 }
3864
3865 String packageName = getNextArg();
3866 if (packageName == null) {
3867 errPw.println("set-carrier-service-package-override requires a override package name.");
3868 return -1;
3869 }
3870
3871 try {
3872 mInterface.setCarrierServicePackageOverride(
3873 subId, packageName, mContext.getOpPackageName());
3874
3875 if (VDBG) {
3876 Log.v(
3877 LOG_TAG,
3878 "set-carrier-service-package-override -s " + subId + " " + packageName);
3879 }
3880 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3881 Log.w(
3882 LOG_TAG,
3883 "set-carrier-service-package-override -s "
3884 + subId
3885 + " "
3886 + packageName
3887 + ", error"
3888 + e.getMessage());
3889 errPw.println("Exception: " + e.getMessage());
3890 return -1;
3891 }
3892 return 0;
3893 }
3894
3895 // clear-carrier-service-package-override
3896 private int clearCarrierServicePackageOverride() {
3897 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003898 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003899
3900 String opt;
3901 while ((opt = getNextOption()) != null) {
3902 switch (opt) {
3903 case "-s":
3904 try {
3905 subId = Integer.parseInt(getNextArgRequired());
3906 } catch (NumberFormatException e) {
3907 errPw.println(
3908 "clear-carrier-service-package-override requires an integer as a"
3909 + " subscription ID.");
3910 return -1;
3911 }
3912 break;
3913 }
3914 }
3915
3916 try {
3917 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3918
3919 if (VDBG) {
3920 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3921 }
3922 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3923 Log.w(
3924 LOG_TAG,
3925 "clear-carrier-service-package-override -s "
3926 + subId
3927 + ", error"
3928 + e.getMessage());
3929 errPw.println("Exception: " + e.getMessage());
3930 return -1;
3931 }
3932 return 0;
3933 }
arunvoddud7401012022-12-15 16:08:12 +00003934
Hunsuk Choi13078be2023-09-13 10:55:21 +00003935 private int handleDomainSelectionCommand() {
3936 String arg = getNextArg();
3937 if (arg == null) {
3938 onHelpDomainSelection();
3939 return 0;
3940 }
3941
3942 switch (arg) {
3943 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3944 return handleDomainSelectionSetServiceOverrideCommand();
3945 }
3946 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3947 return handleDomainSelectionClearServiceOverrideCommand();
3948 }
3949 }
3950
3951 return -1;
3952 }
3953
3954 // domainselection set-dss-override
3955 private int handleDomainSelectionSetServiceOverrideCommand() {
3956 PrintWriter errPw = getErrPrintWriter();
3957
3958 String componentName = getNextArg();
3959
3960 try {
3961 boolean result = mInterface.setDomainSelectionServiceOverride(
3962 ComponentName.unflattenFromString(componentName));
3963 if (VDBG) {
3964 Log.v(LOG_TAG, "domainselection set-dss-override "
3965 + componentName + ", result=" + result);
3966 }
3967 getOutPrintWriter().println(result);
3968 } catch (Exception e) {
3969 Log.w(LOG_TAG, "domainselection set-dss-override "
3970 + componentName + ", error=" + e.getMessage());
3971 errPw.println("Exception: " + e.getMessage());
3972 return -1;
3973 }
3974 return 0;
3975 }
3976
3977 // domainselection clear-dss-override
3978 private int handleDomainSelectionClearServiceOverrideCommand() {
3979 PrintWriter errPw = getErrPrintWriter();
3980
3981 try {
3982 boolean result = mInterface.clearDomainSelectionServiceOverride();
3983 if (VDBG) {
3984 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
3985 }
3986 getOutPrintWriter().println(result);
3987 } catch (RemoteException e) {
3988 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
3989 errPw.println("Exception: " + e.getMessage());
3990 return -1;
3991 }
3992 return 0;
3993 }
3994
arunvoddud7401012022-12-15 16:08:12 +00003995 /**
3996 * Building the string that can be used to build the JsonObject which supports to stub the data
3997 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00003998 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00003999 */
4000 private String convertToJsonString(int index, String param) {
4001
4002 String token[] = param.split(":");
4003 String jSonString;
4004 switch (index) {
4005 case 0:
4006 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4007 break;
4008 case 1:
4009 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004010 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004011 break;
4012 case 2:
4013 jSonString =
4014 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4015 break;
4016 default:
4017 jSonString = null;
4018 }
4019 return jSonString;
4020 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004021}