blob: 429b7cca0be2297070d31236378f3ed6007d3eac [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";
196
197 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
198 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700199 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
200 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800201 private static final String SET_COUNTRY_CODES = "set-country-codes";
202 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
203 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800204 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
205 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000206 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
207 "set-should-send-datagram-to-modem-in-demo-mode";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800208
Hunsuk Choi13078be2023-09-13 10:55:21 +0000209 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
210 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
211 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
212
Grant Menke567d48f2022-08-18 20:19:10 +0000213 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
214 + "'*', '#' or '+') needs to be specified after -a in the command ";
215
216 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
217 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
218 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
219
SongFerngWang98dd5992021-05-13 17:50:00 +0800220 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
221 "get-allowed-network-types-for-users";
222 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
223 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000224 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000225 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700226 // Take advantage of existing methods that already contain permissions checks when possible.
227 private final ITelephony mInterface;
228
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100229 private SubscriptionManager mSubscriptionManager;
230 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700231 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700232 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100233
234 private enum CcType {
235 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000236 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100237 }
238
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100239 private class CcOptionParseResult {
240 public int mSubId;
241 public boolean mPersistent;
242 }
243
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100244 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
245 // keys by looking at the end of the string which usually tells the type.
246 // For instance: "xxxx_string", "xxxx_string_array", etc.
247 // The carrier config keys in this map does not follow this convention. It is therefore not
248 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700249 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
250 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
251 CcType.STRING),
252 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
253 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
254 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
255 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
256 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
257 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
258 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
262 CcType.STRING),
263 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
264 CcType.STRING_ARRAY),
265 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
266 CcType.STRING_ARRAY),
267 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
268 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
269 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
270 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
271 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
272 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
273 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
274 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100275
Brad Ebinger14d467f2021-02-12 06:18:28 +0000276 /**
277 * Map from a shorthand string to the feature tags required in registration required in order
278 * for the RCS feature to be considered "capable".
279 */
280 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
281 static {
282 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
283 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
284 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
285 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
286 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
287 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
288 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
289 FeatureTags.FEATURE_TAG_VIDEO)));
290 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
291 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
292 map.put("call_comp",
293 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
294 map.put("call_comp_mmtel",
295 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
296 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
297 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
298 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
299 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
300 // version
301 map.put("chatbot", new ArraySet<>(Arrays.asList(
302 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
303 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
304 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
305 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000306 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000307 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
308 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
309 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
310 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
311 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000312 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000313 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
314 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
315 }
316
317
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100318 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700319 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100320 mCarrierConfigManager =
321 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
322 mSubscriptionManager = (SubscriptionManager)
323 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700324 mTelephonyRegistryManager = (TelephonyRegistryManager)
325 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700326 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700327 }
328
329 @Override
330 public int onCommand(String cmd) {
331 if (cmd == null) {
332 return handleDefaultCommands(null);
333 }
334
335 switch (cmd) {
336 case IMS_SUBCOMMAND: {
337 return handleImsCommand();
338 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800339 case RCS_UCE_COMMAND:
340 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800341 case NUMBER_VERIFICATION_SUBCOMMAND:
342 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800343 case EMERGENCY_CALLBACK_MODE:
344 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800345 case EMERGENCY_NUMBER_TEST_MODE:
346 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100347 case CARRIER_CONFIG_SUBCOMMAND: {
348 return handleCcCommand();
349 }
Shuo Qianf5125122019-12-16 17:03:07 -0800350 case DATA_TEST_MODE:
351 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700352 case END_BLOCK_SUPPRESSION:
353 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000354 case EUICC_SUBCOMMAND:
355 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700356 case GBA_SUBCOMMAND:
357 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800358 case D2D_SUBCOMMAND:
359 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700360 case BARRING_SUBCOMMAND:
361 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000362 case SINGLE_REGISTATION_CONFIG:
363 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000364 case RESTART_MODEM:
365 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800366 case CALL_COMPOSER_SUBCOMMAND:
367 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000368 case UNATTENDED_REBOOT:
369 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800370 case HAS_CARRIER_PRIVILEGES_COMMAND:
371 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800372 case THERMAL_MITIGATION_COMMAND:
373 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700374 case DISABLE_PHYSICAL_SUBSCRIPTION:
375 return handleEnablePhysicalSubscription(false);
376 case ENABLE_PHYSICAL_SUBSCRIPTION:
377 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800378 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
379 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
380 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000381 case GET_IMEI:
382 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000383 case GET_SIM_SLOTS_MAPPING:
384 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800385 case RADIO_SUBCOMMAND:
386 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000387 case CARRIER_RESTRICTION_STATUS_TEST:
388 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000389 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
390 return setCarrierServicePackageOverride();
391 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
392 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000393 case DOMAIN_SELECTION_SUBCOMMAND:
394 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700395 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
396 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700397 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
398 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700399 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
400 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700401 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
402 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800403 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
404 return handleSetDatagramControllerTimeoutDuration();
405 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
406 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700407 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
408 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000409 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
410 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800411 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
412 return handleSetSatelliteAccessControlOverlayConfigs();
413 case SET_COUNTRY_CODES:
414 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800415 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
416 return handleSetOemEnabledSatelliteProvisionStatus();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700417 default: {
418 return handleDefaultCommands(cmd);
419 }
420 }
421 }
422
423 @Override
424 public void onHelp() {
425 PrintWriter pw = getOutPrintWriter();
426 pw.println("Telephony Commands:");
427 pw.println(" help");
428 pw.println(" Print this help text.");
429 pw.println(" ims");
430 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800431 pw.println(" uce");
432 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800433 pw.println(" emergency-number-test-mode");
434 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700435 pw.println(" end-block-suppression");
436 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800437 pw.println(" data");
438 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100439 pw.println(" cc");
440 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700441 pw.println(" gba");
442 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000443 pw.println(" src");
444 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000445 pw.println(" restart-modem");
446 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000447 pw.println(" unattended-reboot");
448 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800449 pw.println(" has-carrier-privileges [package]");
450 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800451 pw.println(" get-allowed-network-types-for-users");
452 pw.println(" Get the Allowed Network Types.");
453 pw.println(" set-allowed-network-types-for-users");
454 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800455 pw.println(" radio");
456 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700457 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800458 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800459 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700460 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800461 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100462 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700463 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000464 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800465 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700466 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800467 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800468 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000469 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700470 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000471 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800472 }
473
474 private void onHelpD2D() {
475 PrintWriter pw = getOutPrintWriter();
476 pw.println("D2D Comms Commands:");
477 pw.println(" d2d send TYPE VALUE");
478 pw.println(" Sends a D2D message of specified type and value.");
479 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
480 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
481 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
482 MESSAGE_CALL_AUDIO_CODEC));
483 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
484 + Communicator.messageToString(
485 MESSAGE_DEVICE_BATTERY_STATE));
486 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
487 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800488 pw.println(" d2d transport TYPE");
489 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
490 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700491 pw.println(" d2d set-device-support true/default");
492 pw.println(" true - forces device support to be enabled for D2D.");
493 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
494 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700495 }
496
Nazanin014f41e2021-05-06 17:26:31 -0700497 private void onHelpBarring() {
498 PrintWriter pw = getOutPrintWriter();
499 pw.println("Barring Commands:");
500 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
501 + " -t CONDITIONAL_BARRING_TIME_SECS");
502 pw.println(" Notifies of a barring info change for the specified slot id.");
503 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
504 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
505 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
506 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
507 }
508
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700509 private void onHelpIms() {
510 PrintWriter pw = getOutPrintWriter();
511 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800512 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700513 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
514 pw.println(" ImsService. Options are:");
515 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
516 pw.println(" is specified, it will choose the default voice SIM slot.");
517 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
518 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800519 pw.println(" -f: Set the feature that this override if for, if no option is");
520 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700521 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
522 pw.println(" Gets the package name of the currently defined ImsService.");
523 pw.println(" Options are:");
524 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
525 pw.println(" is specified, it will choose the default voice SIM slot.");
526 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000527 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800528 pw.println(" -f: The feature type that the query will be requested for. If none is");
529 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800530 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
531 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
532 pw.println(" configuration overrides. Options are:");
533 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
534 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700535 pw.println(" ims enable [-s SLOT_ID]");
536 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
537 pw.println(" if none is specified.");
538 pw.println(" ims disable [-s SLOT_ID]");
539 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
540 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700541 pw.println(" ims conference-event-package [enable/disable]");
542 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700543 }
544
James.cf Linbcdf8b32021-01-14 16:44:13 +0800545 private void onHelpUce() {
546 PrintWriter pw = getOutPrintWriter();
547 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800548 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
549 pw.println(" Get the EAB contacts from the EAB database.");
550 pw.println(" Options are:");
551 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
552 pw.println(" Expected output format :");
553 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800554 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
555 pw.println(" Remove the EAB contacts from the EAB database.");
556 pw.println(" Options are:");
557 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
558 pw.println(" is specified, it will choose the default voice SIM slot.");
559 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800560 pw.println(" uce get-device-enabled");
561 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
562 pw.println(" uce set-device-enabled true|false");
563 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
564 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000565 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
566 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
567 pw.println(" Options are:");
568 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
569 pw.println(" is specified, it will choose the default voice SIM slot.");
570 pw.println(" add [CAPABILITY]: add a new capability");
571 pw.println(" remove [CAPABILITY]: remove a capability");
572 pw.println(" clear: clear all capability overrides");
573 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
574 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
575 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
576 pw.println(" chatbot_sa, chatbot_role] as well as full length");
577 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
578 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
579 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
580 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800581 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
582 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800583 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
584 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800585 }
586
Hall Liud892bec2018-11-30 14:51:45 -0800587 private void onHelpNumberVerification() {
588 PrintWriter pw = getOutPrintWriter();
589 pw.println("Number verification commands");
590 pw.println(" numverify override-package PACKAGE_NAME;");
591 pw.println(" Set the authorized package for number verification.");
592 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800593 pw.println(" numverify fake-call NUMBER;");
594 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
595 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800596 }
597
Jack Nudelman644b91a2021-03-12 14:09:48 -0800598 private void onHelpThermalMitigation() {
599 PrintWriter pw = getOutPrintWriter();
600 pw.println("Thermal mitigation commands");
601 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
602 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
603 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
604 pw.println(" Remove the package from one of the authorized packages for thermal "
605 + "mitigation.");
606 }
607
Jordan Liu0ccee222021-04-27 11:55:13 -0700608 private void onHelpDisableOrEnablePhysicalSubscription() {
609 PrintWriter pw = getOutPrintWriter();
610 pw.println("Disable or enable a physical subscription");
611 pw.println(" disable-physical-subscription SUB_ID");
612 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
613 pw.println(" enable-physical-subscription SUB_ID");
614 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
615 }
616
Shuo Qianf5125122019-12-16 17:03:07 -0800617 private void onHelpDataTestMode() {
618 PrintWriter pw = getOutPrintWriter();
619 pw.println("Mobile Data Test Mode Commands:");
620 pw.println(" data enable: enable mobile data connectivity");
621 pw.println(" data disable: disable mobile data connectivity");
622 }
623
sqian9d4df8b2019-01-15 18:32:07 -0800624 private void onHelpEmergencyNumber() {
625 PrintWriter pw = getOutPrintWriter();
626 pw.println("Emergency Number Test Mode Commands:");
627 pw.println(" emergency-number-test-mode ");
628 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
629 + " the test mode");
630 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700631 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800632 pw.println(" -c: clear the emergency number list in the test mode.");
633 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700634 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800635 pw.println(" -p: get the full emergency number list in the test mode.");
636 }
637
Shuo Qian489d9282020-07-09 11:30:03 -0700638 private void onHelpEndBlockSupperssion() {
639 PrintWriter pw = getOutPrintWriter();
640 pw.println("End Block Suppression command:");
641 pw.println(" end-block-suppression: disable suppressing blocking by contact");
642 pw.println(" with emergency services.");
643 }
644
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100645 private void onHelpCc() {
646 PrintWriter pw = getOutPrintWriter();
647 pw.println("Carrier Config Commands:");
648 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
649 pw.println(" Print carrier config values.");
650 pw.println(" Options are:");
651 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
652 pw.println(" is specified, it will choose the default voice SIM slot.");
653 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
654 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100655 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100656 pw.println(" Set carrier config KEY to NEW_VALUE.");
657 pw.println(" Options are:");
658 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
659 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100660 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100661 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
662 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
663 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
664 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000665 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
666 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
667 pw.println(" provided through standard input and follow CarrierConfig XML format.");
668 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
669 pw.println(" Options are:");
670 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
671 pw.println(" is specified, it will choose the default voice SIM slot.");
672 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100673 pw.println(" cc clear-values [-s SLOT_ID]");
674 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000675 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100676 pw.println(" Options are:");
677 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
678 pw.println(" is specified, it will choose the default voice SIM slot.");
679 }
680
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000681 private void onHelpEuicc() {
682 PrintWriter pw = getOutPrintWriter();
683 pw.println("Euicc Commands:");
684 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
685 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
686 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
687 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
688 }
689
Hui Wang641e81c2020-10-12 12:14:23 -0700690 private void onHelpGba() {
691 PrintWriter pw = getOutPrintWriter();
692 pw.println("Gba Commands:");
693 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
694 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
695 pw.println(" Options are:");
696 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
697 pw.println(" is specified, it will choose the default voice SIM slot.");
698 pw.println(" gba get-service [-s SLOT_ID]");
699 pw.println(" Gets the package name of the currently defined GbaService.");
700 pw.println(" Options are:");
701 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
702 pw.println(" is specified, it will choose the default voice SIM slot.");
703 pw.println(" gba set-release [-s SLOT_ID] n");
704 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
705 pw.println(" Do not release/unbind if n is -1.");
706 pw.println(" Options are:");
707 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
708 pw.println(" is specified, it will choose the default voice SIM slot.");
709 pw.println(" gba get-release [-s SLOT_ID]");
710 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
711 pw.println(" Options are:");
712 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
713 pw.println(" is specified, it will choose the default voice SIM slot.");
714 }
715
Hui Wang761a6682020-10-31 05:12:53 +0000716 private void onHelpSrc() {
717 PrintWriter pw = getOutPrintWriter();
718 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800719 pw.println(" src set-test-enabled true|false");
720 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
721 pw.println(" The value could be true, false, or null(undefined).");
722 pw.println(" src get-test-enabled");
723 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000724 pw.println(" src set-device-enabled true|false|null");
725 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
726 pw.println(" The value could be true, false, or null(undefined).");
727 pw.println(" src get-device-enabled");
728 pw.println(" Gets the device config for RCS VoLTE single registration.");
729 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
730 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
731 pw.println(" The value could be true, false, or null(undefined).");
732 pw.println(" Options are:");
733 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
734 pw.println(" is specified, it will choose the default voice SIM slot.");
735 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
736 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
737 pw.println(" Options are:");
738 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
739 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800740 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
741 pw.println(" Sets ims feature validation result.");
742 pw.println(" The value could be true, false, or null(undefined).");
743 pw.println(" Options are:");
744 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
745 pw.println(" is specified, it will choose the default voice SIM slot.");
746 pw.println(" src get-feature-validation [-s SLOT_ID]");
747 pw.println(" Gets ims feature validation override value.");
748 pw.println(" Options are:");
749 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
750 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000751 }
752
SongFerngWang98dd5992021-05-13 17:50:00 +0800753 private void onHelpAllowedNetworkTypes() {
754 PrintWriter pw = getOutPrintWriter();
755 pw.println("Allowed Network Types Commands:");
756 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
757 pw.println(" Print allowed network types value.");
758 pw.println(" Options are:");
759 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
760 pw.println(" option is specified, it will choose the default voice SIM slot.");
761 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
762 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
763 pw.println(" Options are:");
764 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
765 pw.println(" option is specified, it will choose the default voice SIM slot.");
766 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
767 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
768 pw.println(" at TelephonyManager.java");
769 pw.println(" For example:");
770 pw.println(" NR only : 10000000000000000000");
771 pw.println(" NR|LTE : 11000001000000000000");
772 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
773 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
774 pw.println(" LTE only : 01000001000000000000");
775 }
776
jimsun3b9ccac2021-10-26 15:01:23 +0800777 private void onHelpRadio() {
778 PrintWriter pw = getOutPrintWriter();
779 pw.println("Radio Commands:");
780 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
781 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
782 pw.println(" to be the bound. Options are:");
783 pw.println(" -s: the service name that the modem service should be bound for.");
784 pw.println(" If no option is specified, it will bind to the default.");
785 pw.println(" radio get-modem-service");
786 pw.println(" Gets the service name of the currently defined modem service.");
787 pw.println(" If it is binding to default, 'default' returns.");
788 pw.println(" If it doesn't bind to any modem service for some reasons,");
789 pw.println(" the result would be 'unknown'.");
790 }
791
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700792 private void onHelpSatellite() {
793 PrintWriter pw = getOutPrintWriter();
794 pw.println("Satellite Commands:");
795 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
796 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700797 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700798 pw.println(" -s: the satellite service package name that Telephony will bind to.");
799 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700800 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
801 pw.println(" Sets the package name of satellite gateway service defined in");
802 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
803 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
804 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700805 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
806 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
807 pw.println(" mode. Options are:");
808 pw.println(" -t: the timeout duration in milliseconds.");
809 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700810 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
811 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
812 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
813 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
814 pw.println(" launch. If no option is specified, it will launch the default.");
815 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
816 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700817 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
818 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
819 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
820 pw.println(" Options are:");
821 pw.println(" -t: the emergency call to satellite handover type.");
822 pw.println(" If no option is specified, override is disabled.");
823 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
824 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800825 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
826 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
827 pw.println(" configs of satellite access controller.");
828 pw.println(" Options are:");
829 pw.println(" -r: clear the overriding. Absent means enable overriding.");
830 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
831 pw.println(" -f: the satellite s2 file.");
832 pw.println(" -d: the location fresh duration nanos.");
833 pw.println(" -c: the list of satellite country codes separated by comma.");
834 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
835 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
836 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
837 pw.println(" Override the cached location country code and its update timestamp. ");
838 pw.println(" Options are:");
839 pw.println(" -r: clear the overriding. Absent means enable overriding.");
840 pw.println(" -n: the current network country code ISOs.");
841 pw.println(" -c: the cached network country code ISOs.");
842 pw.println(" -l: the location country code ISO.");
843 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800844 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
845 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
846 pw.println(" -p: the overriding satellite provision status. If no option is ");
847 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700848 }
849
Ling Ma4fbab492022-01-25 22:36:16 +0000850 private void onHelpImei() {
851 PrintWriter pw = getOutPrintWriter();
852 pw.println("IMEI Commands:");
853 pw.println(" get-imei [-s SLOT_ID]");
854 pw.println(" Gets the device IMEI. Options are:");
855 pw.println(" -s: the slot ID to get the IMEI. If no option");
856 pw.println(" is specified, it will choose the default voice SIM slot.");
857 }
858
Hunsuk Choi13078be2023-09-13 10:55:21 +0000859 private void onHelpDomainSelection() {
860 PrintWriter pw = getOutPrintWriter();
861 pw.println("Domain Selection Commands:");
862 pw.println(" domainselection set-dss-override COMPONENT_NAME");
863 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
864 pw.println(" domainselection clear-dss-override");
865 pw.println(" Clears DomainSelectionService override.");
866 }
867
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700868 private int handleImsCommand() {
869 String arg = getNextArg();
870 if (arg == null) {
871 onHelpIms();
872 return 0;
873 }
874
875 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800876 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700877 return handleImsSetServiceCommand();
878 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800879 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700880 return handleImsGetServiceCommand();
881 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800882 case IMS_CLEAR_SERVICE_OVERRIDE: {
883 return handleImsClearCarrierServiceCommand();
884 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800885 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700886 return handleEnableIms();
887 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800888 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700889 return handleDisableIms();
890 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700891 case IMS_CEP: {
892 return handleCepChange();
893 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700894 }
895
896 return -1;
897 }
898
Shuo Qianf5125122019-12-16 17:03:07 -0800899 private int handleDataTestModeCommand() {
900 PrintWriter errPw = getErrPrintWriter();
901 String arg = getNextArgRequired();
902 if (arg == null) {
903 onHelpDataTestMode();
904 return 0;
905 }
906 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800907 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800908 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700909 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800910 } catch (RemoteException ex) {
911 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
912 errPw.println("Exception: " + ex.getMessage());
913 return -1;
914 }
915 break;
916 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800917 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800918 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700919 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800920 } catch (RemoteException ex) {
921 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
922 errPw.println("Exception: " + ex.getMessage());
923 return -1;
924 }
925 break;
926 }
927 default:
928 onHelpDataTestMode();
929 break;
930 }
931 return 0;
932 }
933
Shuo Qianccbaf742021-02-22 18:32:21 -0800934 private int handleEmergencyCallbackModeCommand() {
935 PrintWriter errPw = getErrPrintWriter();
936 try {
937 mInterface.startEmergencyCallbackMode();
938 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
939 } catch (RemoteException ex) {
940 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
941 errPw.println("Exception: " + ex.getMessage());
942 return -1;
943 }
944 return 0;
945 }
946
Grant Menke567d48f2022-08-18 20:19:10 +0000947 private void removeEmergencyNumberTestMode(String emergencyNumber) {
948 PrintWriter errPw = getErrPrintWriter();
949 for (int routingType : ROUTING_TYPES) {
950 try {
951 mInterface.updateEmergencyNumberListTestMode(
952 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
953 new EmergencyNumber(emergencyNumber, "", "",
954 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
955 new ArrayList<String>(),
956 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
957 routingType));
958 } catch (RemoteException ex) {
959 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
960 errPw.println("Exception: " + ex.getMessage());
961 }
962 }
963 }
964
sqian9d4df8b2019-01-15 18:32:07 -0800965 private int handleEmergencyNumberTestModeCommand() {
966 PrintWriter errPw = getErrPrintWriter();
967 String opt = getNextOption();
968 if (opt == null) {
969 onHelpEmergencyNumber();
970 return 0;
971 }
sqian9d4df8b2019-01-15 18:32:07 -0800972 switch (opt) {
973 case "-a": {
974 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000975 if (emergencyNumberCmd == null){
976 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800977 return -1;
978 }
Grant Menke567d48f2022-08-18 20:19:10 +0000979 String[] params = emergencyNumberCmd.split(":");
980 String emergencyNumber;
981 if (params[0] == null ||
982 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
983 errPw.println(INVALID_ENTRY_ERROR);
984 return -1;
985 } else {
986 emergencyNumber = params[0];
987 }
988 removeEmergencyNumberTestMode(emergencyNumber);
989 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
990 if (params.length > 1) {
991 switch (params[1].toLowerCase(Locale.ROOT)) {
992 case "emergency":
993 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
994 break;
995 case "normal":
996 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
997 break;
998 case "unknown":
999 break;
1000 default:
1001 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1002 + "emergency call routing. Please enter either \"normal\", "
1003 + "\"unknown\", or \"emergency\" for call routing. "
1004 + "(-a 1234:normal)");
1005 return -1;
1006 }
1007 }
sqian9d4df8b2019-01-15 18:32:07 -08001008 try {
1009 mInterface.updateEmergencyNumberListTestMode(
1010 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001011 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001012 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1013 new ArrayList<String>(),
1014 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001015 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001016 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001017 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001018 + ", error " + ex.getMessage());
1019 errPw.println("Exception: " + ex.getMessage());
1020 return -1;
1021 }
1022 break;
1023 }
1024 case "-c": {
1025 try {
1026 mInterface.updateEmergencyNumberListTestMode(
1027 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1028 } catch (RemoteException ex) {
1029 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1030 errPw.println("Exception: " + ex.getMessage());
1031 return -1;
1032 }
1033 break;
1034 }
1035 case "-r": {
1036 String emergencyNumberCmd = getNextArgRequired();
1037 if (emergencyNumberCmd == null
1038 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001039 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001040 + " to be specified after -r in the command ");
1041 return -1;
1042 }
Grant Menke567d48f2022-08-18 20:19:10 +00001043 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001044 break;
1045 }
1046 case "-p": {
1047 try {
1048 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1049 } catch (RemoteException ex) {
1050 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1051 errPw.println("Exception: " + ex.getMessage());
1052 return -1;
1053 }
1054 break;
1055 }
1056 default:
1057 onHelpEmergencyNumber();
1058 break;
1059 }
1060 return 0;
1061 }
1062
Hall Liud892bec2018-11-30 14:51:45 -08001063 private int handleNumberVerificationCommand() {
1064 String arg = getNextArg();
1065 if (arg == null) {
1066 onHelpNumberVerification();
1067 return 0;
1068 }
1069
Hall Liuca5af3a2018-12-04 16:58:23 -08001070 if (!checkShellUid()) {
1071 return -1;
1072 }
1073
Hall Liud892bec2018-11-30 14:51:45 -08001074 switch (arg) {
1075 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001076 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1077 return 0;
1078 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001079 case NUMBER_VERIFICATION_FAKE_CALL: {
1080 boolean val = NumberVerificationManager.getInstance()
1081 .checkIncomingCall(getNextArg());
1082 getOutPrintWriter().println(val ? "1" : "0");
1083 return 0;
1084 }
Hall Liud892bec2018-11-30 14:51:45 -08001085 }
1086
1087 return -1;
1088 }
1089
Jordan Liu0ccee222021-04-27 11:55:13 -07001090 private boolean subIsEsim(int subId) {
1091 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1092 if (info != null) {
1093 return info.isEmbedded();
1094 }
1095 return false;
1096 }
1097
1098 private int handleEnablePhysicalSubscription(boolean enable) {
1099 PrintWriter errPw = getErrPrintWriter();
1100 int subId = 0;
1101 try {
1102 subId = Integer.parseInt(getNextArgRequired());
1103 } catch (NumberFormatException e) {
1104 errPw.println((enable ? "enable" : "disable")
1105 + "-physical-subscription requires an integer as a subId.");
1106 return -1;
1107 }
1108 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1109 // non user build.
1110 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1111 errPw.println("cc: Permission denied.");
1112 return -1;
1113 }
1114 // Verify that the subId represents a physical sub
1115 if (subIsEsim(subId)) {
1116 errPw.println("SubId " + subId + " is not for a physical subscription");
1117 return -1;
1118 }
1119 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1120 + " physical subscription with subId=" + subId);
1121 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1122 return 0;
1123 }
1124
Jack Nudelman644b91a2021-03-12 14:09:48 -08001125 private int handleThermalMitigationCommand() {
1126 String arg = getNextArg();
1127 String packageName = getNextArg();
1128 if (arg == null || packageName == null) {
1129 onHelpThermalMitigation();
1130 return 0;
1131 }
1132
1133 if (!checkShellUid()) {
1134 return -1;
1135 }
1136
1137 switch (arg) {
1138 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1139 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1140 return 0;
1141 }
1142 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1143 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1144 mContext);
1145 return 0;
1146 }
1147 default:
1148 onHelpThermalMitigation();
1149 }
1150
1151 return -1;
1152
1153 }
1154
Tyler Gunn92479152021-01-20 16:30:10 -08001155 private int handleD2dCommand() {
1156 String arg = getNextArg();
1157 if (arg == null) {
1158 onHelpD2D();
1159 return 0;
1160 }
1161
1162 switch (arg) {
1163 case D2D_SEND: {
1164 return handleD2dSendCommand();
1165 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001166 case D2D_TRANSPORT: {
1167 return handleD2dTransportCommand();
1168 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001169 case D2D_SET_DEVICE_SUPPORT: {
1170 return handleD2dDeviceSupportedCommand();
1171 }
Tyler Gunn92479152021-01-20 16:30:10 -08001172 }
1173
1174 return -1;
1175 }
1176
1177 private int handleD2dSendCommand() {
1178 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001179 int messageType = -1;
1180 int messageValue = -1;
1181
Tyler Gunn92479152021-01-20 16:30:10 -08001182 String arg = getNextArg();
1183 if (arg == null) {
1184 onHelpD2D();
1185 return 0;
1186 }
1187 try {
1188 messageType = Integer.parseInt(arg);
1189 } catch (NumberFormatException e) {
1190 errPw.println("message type must be a valid integer");
1191 return -1;
1192 }
1193
1194 arg = getNextArg();
1195 if (arg == null) {
1196 onHelpD2D();
1197 return 0;
1198 }
1199 try {
1200 messageValue = Integer.parseInt(arg);
1201 } catch (NumberFormatException e) {
1202 errPw.println("message value must be a valid integer");
1203 return -1;
1204 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001205
Tyler Gunn92479152021-01-20 16:30:10 -08001206 try {
1207 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1208 } catch (RemoteException e) {
1209 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1210 errPw.println("Exception: " + e.getMessage());
1211 return -1;
1212 }
1213
1214 return 0;
1215 }
1216
Tyler Gunnbabbda02021-02-10 11:05:02 -08001217 private int handleD2dTransportCommand() {
1218 PrintWriter errPw = getErrPrintWriter();
1219
1220 String arg = getNextArg();
1221 if (arg == null) {
1222 onHelpD2D();
1223 return 0;
1224 }
1225
1226 try {
1227 mInterface.setActiveDeviceToDeviceTransport(arg);
1228 } catch (RemoteException e) {
1229 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1230 errPw.println("Exception: " + e.getMessage());
1231 return -1;
1232 }
1233 return 0;
1234 }
Nazanin014f41e2021-05-06 17:26:31 -07001235 private int handleBarringCommand() {
1236 String arg = getNextArg();
1237 if (arg == null) {
1238 onHelpBarring();
1239 return 0;
1240 }
1241
1242 switch (arg) {
1243 case BARRING_SEND_INFO: {
1244 return handleBarringSendCommand();
1245 }
1246 }
1247 return -1;
1248 }
1249
1250 private int handleBarringSendCommand() {
1251 PrintWriter errPw = getErrPrintWriter();
1252 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001253 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001254 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1255 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1256 boolean isConditionallyBarred = false;
1257 int conditionalBarringTimeSeconds = 0;
1258
1259 String opt;
1260 while ((opt = getNextOption()) != null) {
1261 switch (opt) {
1262 case "-s": {
1263 try {
1264 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001265 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001266 } catch (NumberFormatException e) {
1267 errPw.println("barring send requires an integer as a SLOT_ID.");
1268 return -1;
1269 }
1270 break;
1271 }
1272 case "-b": {
1273 try {
1274 barringType = Integer.parseInt(getNextArgRequired());
1275 if (barringType < -1 || barringType > 2) {
1276 throw new NumberFormatException();
1277 }
1278
1279 } catch (NumberFormatException e) {
1280 errPw.println("barring send requires an integer in range [-1,2] as "
1281 + "a BARRING_TYPE.");
1282 return -1;
1283 }
1284 break;
1285 }
1286 case "-c": {
1287 try {
1288 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1289 } catch (Exception e) {
1290 errPw.println("barring send requires a boolean after -c indicating"
1291 + " conditional barring");
1292 return -1;
1293 }
1294 break;
1295 }
1296 case "-t": {
1297 try {
1298 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1299 } catch (NumberFormatException e) {
1300 errPw.println("barring send requires an integer for time of barring"
1301 + " in seconds after -t for conditional barring");
1302 return -1;
1303 }
1304 break;
1305 }
1306 }
1307 }
1308 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1309 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1310 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1311 barringServiceInfos.append(0, bsi);
1312 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1313 try {
1314 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1315 } catch (Exception e) {
1316 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1317 errPw.println("Exception: " + e.getMessage());
1318 return -1;
1319 }
1320 return 0;
1321 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001322
Tyler Gunnd4575212021-05-03 14:46:49 -07001323 private int handleD2dDeviceSupportedCommand() {
1324 PrintWriter errPw = getErrPrintWriter();
1325
1326 String arg = getNextArg();
1327 if (arg == null) {
1328 onHelpD2D();
1329 return 0;
1330 }
1331
Jack Yua533d632022-09-30 13:53:46 -07001332 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001333 try {
1334 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1335 } catch (RemoteException e) {
1336 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1337 errPw.println("Exception: " + e.getMessage());
1338 return -1;
1339 }
1340 return 0;
1341 }
1342
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001343 // ims set-ims-service
1344 private int handleImsSetServiceCommand() {
1345 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001346 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001348 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001349
1350 String opt;
1351 while ((opt = getNextOption()) != null) {
1352 switch (opt) {
1353 case "-s": {
1354 try {
1355 slotId = Integer.parseInt(getNextArgRequired());
1356 } catch (NumberFormatException e) {
1357 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1358 return -1;
1359 }
1360 break;
1361 }
1362 case "-c": {
1363 isCarrierService = true;
1364 break;
1365 }
1366 case "-d": {
1367 isCarrierService = false;
1368 break;
1369 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001370 case "-f": {
1371 String featureString = getNextArgRequired();
1372 String[] features = featureString.split(",");
1373 for (int i = 0; i < features.length; i++) {
1374 try {
1375 Integer result = Integer.parseInt(features[i]);
1376 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1377 || result >= ImsFeature.FEATURE_MAX) {
1378 errPw.println("ims set-ims-service -f " + result
1379 + " is an invalid feature.");
1380 return -1;
1381 }
1382 featuresList.add(result);
1383 } catch (NumberFormatException e) {
1384 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1385 + " as an integer.");
1386 return -1;
1387 }
1388 }
1389 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001390 }
1391 }
1392 // Mandatory param, either -c or -d
1393 if (isCarrierService == null) {
1394 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1395 return -1;
1396 }
1397
1398 String packageName = getNextArg();
1399
1400 try {
1401 if (packageName == null) {
1402 packageName = "";
1403 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001404 int[] featureArray = new int[featuresList.size()];
1405 for (int i = 0; i < featuresList.size(); i++) {
1406 featureArray[i] = featuresList.get(i);
1407 }
1408 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1409 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001410 if (VDBG) {
1411 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001412 + (isCarrierService ? "-c " : "-d ")
1413 + "-f " + featuresList + " "
1414 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001415 }
1416 getOutPrintWriter().println(result);
1417 } catch (RemoteException e) {
1418 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001419 + (isCarrierService ? "-c " : "-d ")
1420 + "-f " + featuresList + " "
1421 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001422 errPw.println("Exception: " + e.getMessage());
1423 return -1;
1424 }
1425 return 0;
1426 }
1427
Brad Ebinger999d3302020-11-25 14:31:39 -08001428 // ims clear-ims-service-override
1429 private int handleImsClearCarrierServiceCommand() {
1430 PrintWriter errPw = getErrPrintWriter();
1431 int slotId = getDefaultSlot();
1432
1433 String opt;
1434 while ((opt = getNextOption()) != null) {
1435 switch (opt) {
1436 case "-s": {
1437 try {
1438 slotId = Integer.parseInt(getNextArgRequired());
1439 } catch (NumberFormatException e) {
1440 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1441 return -1;
1442 }
1443 break;
1444 }
1445 }
1446 }
1447
1448 try {
1449 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1450 if (VDBG) {
1451 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1452 + ", result=" + result);
1453 }
1454 getOutPrintWriter().println(result);
1455 } catch (RemoteException e) {
1456 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1457 + ", error" + e.getMessage());
1458 errPw.println("Exception: " + e.getMessage());
1459 return -1;
1460 }
1461 return 0;
1462 }
1463
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001464 // ims get-ims-service
1465 private int handleImsGetServiceCommand() {
1466 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001467 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001468 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001469 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001470
1471 String opt;
1472 while ((opt = getNextOption()) != null) {
1473 switch (opt) {
1474 case "-s": {
1475 try {
1476 slotId = Integer.parseInt(getNextArgRequired());
1477 } catch (NumberFormatException e) {
1478 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1479 return -1;
1480 }
1481 break;
1482 }
1483 case "-c": {
1484 isCarrierService = true;
1485 break;
1486 }
1487 case "-d": {
1488 isCarrierService = false;
1489 break;
1490 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001491 case "-f": {
1492 try {
1493 featureType = Integer.parseInt(getNextArg());
1494 } catch (NumberFormatException e) {
1495 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1496 return -1;
1497 }
1498 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1499 || featureType >= ImsFeature.FEATURE_MAX) {
1500 errPw.println("ims get-ims-service -f invalid feature.");
1501 return -1;
1502 }
1503 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001504 }
1505 }
1506 // Mandatory param, either -c or -d
1507 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001508 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001509 return -1;
1510 }
1511
1512 String result;
1513 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001514 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001515 } catch (RemoteException e) {
1516 return -1;
1517 }
1518 if (VDBG) {
1519 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001520 + (isCarrierService ? "-c " : "-d ")
1521 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1522 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001523 }
1524 getOutPrintWriter().println(result);
1525 return 0;
1526 }
1527
1528 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001529 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001530 String opt;
1531 while ((opt = getNextOption()) != null) {
1532 switch (opt) {
1533 case "-s": {
1534 try {
1535 slotId = Integer.parseInt(getNextArgRequired());
1536 } catch (NumberFormatException e) {
1537 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1538 return -1;
1539 }
1540 break;
1541 }
1542 }
1543 }
1544 try {
1545 mInterface.enableIms(slotId);
1546 } catch (RemoteException e) {
1547 return -1;
1548 }
1549 if (VDBG) {
1550 Log.v(LOG_TAG, "ims enable -s " + slotId);
1551 }
1552 return 0;
1553 }
1554
1555 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001556 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001557 String opt;
1558 while ((opt = getNextOption()) != null) {
1559 switch (opt) {
1560 case "-s": {
1561 try {
1562 slotId = Integer.parseInt(getNextArgRequired());
1563 } catch (NumberFormatException e) {
1564 getErrPrintWriter().println(
1565 "ims disable requires an integer as a SLOT_ID.");
1566 return -1;
1567 }
1568 break;
1569 }
1570 }
1571 }
1572 try {
1573 mInterface.disableIms(slotId);
1574 } catch (RemoteException e) {
1575 return -1;
1576 }
1577 if (VDBG) {
1578 Log.v(LOG_TAG, "ims disable -s " + slotId);
1579 }
1580 return 0;
1581 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001582
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001583 private int handleCepChange() {
1584 Log.i(LOG_TAG, "handleCepChange");
1585 String opt = getNextArg();
1586 if (opt == null) {
1587 return -1;
1588 }
1589 boolean isCepEnabled = opt.equals("enable");
1590
1591 try {
1592 mInterface.setCepEnabled(isCepEnabled);
1593 } catch (RemoteException e) {
1594 return -1;
1595 }
1596 return 0;
1597 }
1598
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001599 private int getDefaultSlot() {
1600 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1601 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1602 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1603 // If there is no default, default to slot 0.
1604 slotId = DEFAULT_PHONE_ID;
1605 }
1606 return slotId;
1607 }
sqian2fff4a32018-11-05 14:18:37 -08001608
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001609 // Parse options related to Carrier Config Commands.
1610 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001611 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001612 CcOptionParseResult result = new CcOptionParseResult();
1613 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1614 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001615
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001616 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001617 while ((opt = getNextOption()) != null) {
1618 switch (opt) {
1619 case "-s": {
1620 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001621 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1622 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1623 errPw.println(tag + "No valid subscription found.");
1624 return null;
1625 }
1626
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001627 } catch (IllegalArgumentException e) {
1628 // Missing slot id
1629 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 return null;
1631 }
1632 break;
1633 }
1634 case "-p": {
1635 if (allowOptionPersistent) {
1636 result.mPersistent = true;
1637 } else {
1638 errPw.println(tag + "Unexpected option " + opt);
1639 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001640 }
1641 break;
1642 }
1643 default: {
1644 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001645 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001646 }
1647 }
1648 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001649 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001650 }
1651
1652 private int slotStringToSubId(String tag, String slotString) {
1653 int slotId = -1;
1654 try {
1655 slotId = Integer.parseInt(slotString);
1656 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001657 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1658 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1659 }
1660
1661 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001662 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1663 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1664 }
1665
Qiong Liuf25799b2020-09-10 10:13:46 +08001666 Phone phone = PhoneFactory.getPhone(slotId);
1667 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001668 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1669 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1670 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001671 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001672 }
1673
Hall Liud892bec2018-11-30 14:51:45 -08001674 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001675 // adb can run as root or as shell, depending on whether the device is rooted.
1676 return Binder.getCallingUid() == Process.SHELL_UID
1677 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001678 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001679
1680 private int handleCcCommand() {
1681 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1682 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001683 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001684 getErrPrintWriter().println("cc: Permission denied.");
1685 return -1;
1686 }
1687
1688 String arg = getNextArg();
1689 if (arg == null) {
1690 onHelpCc();
1691 return 0;
1692 }
1693
1694 switch (arg) {
1695 case CC_GET_VALUE: {
1696 return handleCcGetValue();
1697 }
1698 case CC_SET_VALUE: {
1699 return handleCcSetValue();
1700 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001701 case CC_SET_VALUES_FROM_XML: {
1702 return handleCcSetValuesFromXml();
1703 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001704 case CC_CLEAR_VALUES: {
1705 return handleCcClearValues();
1706 }
1707 default: {
1708 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1709 }
1710 }
1711 return -1;
1712 }
1713
1714 // cc get-value
1715 private int handleCcGetValue() {
1716 PrintWriter errPw = getErrPrintWriter();
1717 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1718 String key = null;
1719
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001720 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001721 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001722 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001723 return -1;
1724 }
1725
1726 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001727 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001728 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001729 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001730 return -1;
1731 }
1732
1733 // Get the key.
1734 key = getNextArg();
1735 if (key != null) {
1736 // A key was provided. Verify if it is a valid key
1737 if (!bundle.containsKey(key)) {
1738 errPw.println(tag + key + " is not a valid key.");
1739 return -1;
1740 }
1741
1742 // Print the carrier config value for key.
1743 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1744 } else {
1745 // No key provided. Show all values.
1746 // Iterate over a sorted list of all carrier config keys and print them.
1747 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1748 for (String k : sortedSet) {
1749 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1750 }
1751 }
1752 return 0;
1753 }
1754
1755 // cc set-value
1756 private int handleCcSetValue() {
1757 PrintWriter errPw = getErrPrintWriter();
1758 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1759
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001760 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001761 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001762 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001763 return -1;
1764 }
1765
1766 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001767 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001768 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001769 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001770 return -1;
1771 }
1772
1773 // Get the key.
1774 String key = getNextArg();
1775 if (key == null || key.equals("")) {
1776 errPw.println(tag + "KEY is missing");
1777 return -1;
1778 }
1779
1780 // Verify if the key is valid
1781 if (!originalValues.containsKey(key)) {
1782 errPw.println(tag + key + " is not a valid key.");
1783 return -1;
1784 }
1785
1786 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1787 ArrayList<String> valueList = new ArrayList<String>();
1788 while (peekNextArg() != null) {
1789 valueList.add(getNextArg());
1790 }
1791
1792 // Find the type of the carrier config value
1793 CcType type = getType(tag, key, originalValues);
1794 if (type == CcType.UNKNOWN) {
1795 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1796 return -1;
1797 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001798 if (type == CcType.PERSISTABLE_BUNDLE) {
1799 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1800 + "Use set-values-from-xml instead.");
1801 return -1;
1802 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001803
1804 // Create an override bundle containing the key and value that should be overriden.
1805 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1806 if (overrideBundle == null) {
1807 return -1;
1808 }
1809
1810 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001811 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001812
1813 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001814 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001815 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001816 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001817 return -1;
1818 }
1819
1820 // Print the original and new value.
1821 String originalValueString = ccValueToString(key, type, originalValues);
1822 String newValueString = ccValueToString(key, type, newValues);
1823 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1824 getOutPrintWriter().println("New value: \n" + newValueString);
1825
1826 return 0;
1827 }
1828
Allen Xuee00f0e2022-03-14 21:04:49 +00001829 // cc set-values-from-xml
1830 private int handleCcSetValuesFromXml() {
1831 PrintWriter errPw = getErrPrintWriter();
1832 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1833
1834 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001835 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001836 if (options == null) {
1837 return -1;
1838 }
1839
1840 // Get bundle containing all current carrier configuration values.
1841 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1842 if (originalValues == null) {
1843 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1844 return -1;
1845 }
1846
1847 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1848 if (overrideBundle == null) {
1849 return -1;
1850 }
1851
1852 // Verify all values are valid types
1853 for (String key : overrideBundle.keySet()) {
1854 CcType type = getType(tag, key, originalValues);
1855 if (type == CcType.UNKNOWN) {
1856 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1857 return -1;
1858 }
1859 }
1860
1861 // Override the value
1862 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1863
1864 // Find bundle containing all new carrier configuration values after the override.
1865 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1866 if (newValues == null) {
1867 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1868 return -1;
1869 }
1870
1871 // Print the original and new values
1872 overrideBundle.keySet().forEach(key -> {
1873 CcType type = getType(tag, key, originalValues);
1874 String originalValueString = ccValueToString(key, type, originalValues);
1875 String newValueString = ccValueToString(key, type, newValues);
1876 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1877 getOutPrintWriter().println("New value: \n" + newValueString);
1878 });
1879
1880 return 0;
1881 }
1882
1883 private PersistableBundle readPersistableBundleFromXml(String tag) {
1884 PersistableBundle subIdBundles;
1885 try {
1886 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1887 } catch (IOException | RuntimeException e) {
1888 PrintWriter errPw = getErrPrintWriter();
1889 errPw.println(tag + e);
1890 return null;
1891 }
1892
1893 return subIdBundles;
1894 }
1895
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001896 // cc clear-values
1897 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001898 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1899
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001900 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001901 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001902 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001903 return -1;
1904 }
1905
1906 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001907 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001908 getOutPrintWriter()
1909 .println("All previously set carrier config override values has been cleared");
1910 return 0;
1911 }
1912
1913 private CcType getType(String tag, String key, PersistableBundle bundle) {
1914 // Find the type by checking the type of the current value stored in the bundle.
1915 Object value = bundle.get(key);
1916
1917 if (CC_TYPE_MAP.containsKey(key)) {
1918 return CC_TYPE_MAP.get(key);
1919 } else if (value != null) {
1920 if (value instanceof Boolean) {
1921 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001922 }
1923 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001924 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001925 }
1926 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001927 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001928 }
1929 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001930 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001931 }
1932 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001933 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001934 }
1935 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001936 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001937 }
1938 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001939 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001940 }
1941 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001942 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001943 }
1944 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001945 return CcType.STRING_ARRAY;
1946 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001947 if (value instanceof PersistableBundle) {
1948 return CcType.PERSISTABLE_BUNDLE;
1949 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001950 } else {
1951 // Current value was null and can therefore not be used in order to find the type.
1952 // Check the name of the key to infer the type. This check is not needed for primitive
1953 // data types (boolean, double, int and long), since they can not be null.
1954 if (key.endsWith("double_array")) {
1955 return CcType.DOUBLE_ARRAY;
1956 }
1957 if (key.endsWith("int_array")) {
1958 return CcType.INT_ARRAY;
1959 }
1960 if (key.endsWith("long_array")) {
1961 return CcType.LONG_ARRAY;
1962 }
1963 if (key.endsWith("string")) {
1964 return CcType.STRING;
1965 }
1966 if (key.endsWith("string_array") || key.endsWith("strings")) {
1967 return CcType.STRING_ARRAY;
1968 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001969 if (key.endsWith("bundle")) {
1970 return CcType.PERSISTABLE_BUNDLE;
1971 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001972 }
1973
1974 // Not possible to infer the type by looking at the current value or the key.
1975 PrintWriter errPw = getErrPrintWriter();
1976 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1977 return CcType.UNKNOWN;
1978 }
1979
1980 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1981 String result;
1982 StringBuilder valueString = new StringBuilder();
1983 String typeString = type.toString();
1984 Object value = bundle.get(key);
1985
1986 if (value == null) {
1987 valueString.append("null");
1988 } else {
1989 switch (type) {
1990 case DOUBLE_ARRAY: {
1991 // Format the string representation of the int array as value1 value2......
1992 double[] valueArray = (double[]) value;
1993 for (int i = 0; i < valueArray.length; i++) {
1994 if (i != 0) {
1995 valueString.append(" ");
1996 }
1997 valueString.append(valueArray[i]);
1998 }
1999 break;
2000 }
2001 case INT_ARRAY: {
2002 // Format the string representation of the int array as value1 value2......
2003 int[] valueArray = (int[]) value;
2004 for (int i = 0; i < valueArray.length; i++) {
2005 if (i != 0) {
2006 valueString.append(" ");
2007 }
2008 valueString.append(valueArray[i]);
2009 }
2010 break;
2011 }
2012 case LONG_ARRAY: {
2013 // Format the string representation of the int array as value1 value2......
2014 long[] valueArray = (long[]) value;
2015 for (int i = 0; i < valueArray.length; i++) {
2016 if (i != 0) {
2017 valueString.append(" ");
2018 }
2019 valueString.append(valueArray[i]);
2020 }
2021 break;
2022 }
2023 case STRING: {
2024 valueString.append("\"" + value.toString() + "\"");
2025 break;
2026 }
2027 case STRING_ARRAY: {
2028 // Format the string representation of the string array as "value1" "value2"....
2029 String[] valueArray = (String[]) value;
2030 for (int i = 0; i < valueArray.length; i++) {
2031 if (i != 0) {
2032 valueString.append(" ");
2033 }
2034 if (valueArray[i] != null) {
2035 valueString.append("\"" + valueArray[i] + "\"");
2036 } else {
2037 valueString.append("null");
2038 }
2039 }
2040 break;
2041 }
2042 default: {
2043 valueString.append(value.toString());
2044 }
2045 }
2046 }
2047 return String.format("%-70s %-15s %s", key, typeString, valueString);
2048 }
2049
2050 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2051 ArrayList<String> valueList) {
2052 PrintWriter errPw = getErrPrintWriter();
2053 PersistableBundle bundle = new PersistableBundle();
2054
2055 // First verify that a valid number of values has been provided for the type.
2056 switch (type) {
2057 case BOOLEAN:
2058 case DOUBLE:
2059 case INT:
2060 case LONG: {
2061 if (valueList.size() != 1) {
2062 errPw.println(tag + "Expected 1 value for type " + type
2063 + ". Found: " + valueList.size());
2064 return null;
2065 }
2066 break;
2067 }
2068 case STRING: {
2069 if (valueList.size() > 1) {
2070 errPw.println(tag + "Expected 0 or 1 values for type " + type
2071 + ". Found: " + valueList.size());
2072 return null;
2073 }
2074 break;
2075 }
2076 }
2077
2078 // Parse the value according to type and add it to the Bundle.
2079 switch (type) {
2080 case BOOLEAN: {
2081 if ("true".equalsIgnoreCase(valueList.get(0))) {
2082 bundle.putBoolean(key, true);
2083 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2084 bundle.putBoolean(key, false);
2085 } else {
2086 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2087 return null;
2088 }
2089 break;
2090 }
2091 case DOUBLE: {
2092 try {
2093 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2094 } catch (NumberFormatException nfe) {
2095 // Not a valid double
2096 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2097 return null;
2098 }
2099 break;
2100 }
2101 case DOUBLE_ARRAY: {
2102 double[] valueDoubleArray = null;
2103 if (valueList.size() > 0) {
2104 valueDoubleArray = new double[valueList.size()];
2105 for (int i = 0; i < valueList.size(); i++) {
2106 try {
2107 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2108 } catch (NumberFormatException nfe) {
2109 // Not a valid double
2110 errPw.println(
2111 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2112 return null;
2113 }
2114 }
2115 }
2116 bundle.putDoubleArray(key, valueDoubleArray);
2117 break;
2118 }
2119 case INT: {
2120 try {
2121 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2122 } catch (NumberFormatException nfe) {
2123 // Not a valid integer
2124 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2125 return null;
2126 }
2127 break;
2128 }
2129 case INT_ARRAY: {
2130 int[] valueIntArray = null;
2131 if (valueList.size() > 0) {
2132 valueIntArray = new int[valueList.size()];
2133 for (int i = 0; i < valueList.size(); i++) {
2134 try {
2135 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2136 } catch (NumberFormatException nfe) {
2137 // Not a valid integer
2138 errPw.println(tag
2139 + "Unable to parse " + valueList.get(i) + " as an integer.");
2140 return null;
2141 }
2142 }
2143 }
2144 bundle.putIntArray(key, valueIntArray);
2145 break;
2146 }
2147 case LONG: {
2148 try {
2149 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2150 } catch (NumberFormatException nfe) {
2151 // Not a valid long
2152 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2153 return null;
2154 }
2155 break;
2156 }
2157 case LONG_ARRAY: {
2158 long[] valueLongArray = null;
2159 if (valueList.size() > 0) {
2160 valueLongArray = new long[valueList.size()];
2161 for (int i = 0; i < valueList.size(); i++) {
2162 try {
2163 valueLongArray[i] = Long.parseLong(valueList.get(i));
2164 } catch (NumberFormatException nfe) {
2165 // Not a valid long
2166 errPw.println(
2167 tag + "Unable to parse " + valueList.get(i) + " as a long");
2168 return null;
2169 }
2170 }
2171 }
2172 bundle.putLongArray(key, valueLongArray);
2173 break;
2174 }
2175 case STRING: {
2176 String value = null;
2177 if (valueList.size() > 0) {
2178 value = valueList.get(0);
2179 }
2180 bundle.putString(key, value);
2181 break;
2182 }
2183 case STRING_ARRAY: {
2184 String[] valueStringArray = null;
2185 if (valueList.size() > 0) {
2186 valueStringArray = new String[valueList.size()];
2187 valueList.toArray(valueStringArray);
2188 }
2189 bundle.putStringArray(key, valueStringArray);
2190 break;
2191 }
2192 }
2193 return bundle;
2194 }
Shuo Qian489d9282020-07-09 11:30:03 -07002195
2196 private int handleEndBlockSuppressionCommand() {
2197 if (!checkShellUid()) {
2198 return -1;
2199 }
2200
2201 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2202 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2203 }
2204 return 0;
2205 }
Hui Wang641e81c2020-10-12 12:14:23 -07002206
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002207 private int handleEuiccCommand() {
2208 String arg = getNextArg();
2209 if (arg == null) {
2210 onHelpEuicc();
2211 return 0;
2212 }
2213
2214 switch (arg) {
2215 case EUICC_SET_UI_COMPONENT: {
2216 return handleEuiccServiceCommand();
2217 }
2218 }
2219 return -1;
2220 }
2221
2222 private int handleEuiccServiceCommand() {
2223 String uiComponent = getNextArg();
2224 String packageName = getNextArg();
2225 if (packageName == null || uiComponent == null) {
2226 return -1;
2227 }
2228 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2229 if (VDBG) {
2230 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2231 + packageName);
2232 }
2233 return 0;
2234 }
2235
Michele Berionne54af4632020-12-28 20:23:16 +00002236 private int handleRestartModemCommand() {
2237 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2238 // non user build.
2239 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2240 getErrPrintWriter().println("RestartModem: Permission denied.");
2241 return -1;
2242 }
2243
2244 boolean result = TelephonyManager.getDefault().rebootRadio();
2245 getOutPrintWriter().println(result);
2246
2247 return result ? 0 : -1;
2248 }
2249
Ling Ma4fbab492022-01-25 22:36:16 +00002250 private int handleGetImei() {
2251 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2252 // non user build.
2253 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2254 getErrPrintWriter().println("Device IMEI: Permission denied.");
2255 return -1;
2256 }
2257
2258 final long identity = Binder.clearCallingIdentity();
2259
2260 String imei = null;
2261 String arg = getNextArg();
2262 if (arg != null) {
2263 try {
2264 int specifiedSlotIndex = Integer.parseInt(arg);
2265 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2266 } catch (NumberFormatException exception) {
2267 PrintWriter errPw = getErrPrintWriter();
2268 errPw.println("-s requires an integer as slot index.");
2269 return -1;
2270 }
2271
2272 } else {
2273 imei = TelephonyManager.from(mContext).getImei();
2274 }
2275 getOutPrintWriter().println("Device IMEI: " + imei);
2276
2277 Binder.restoreCallingIdentity(identity);
2278 return 0;
2279 }
2280
Michele Berionne5e411512020-11-13 02:36:59 +00002281 private int handleUnattendedReboot() {
2282 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2283 // non user build.
2284 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2285 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2286 return -1;
2287 }
2288
2289 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2290 getOutPrintWriter().println("result: " + result);
2291
2292 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2293 }
2294
Aman Gupta07124872022-02-09 08:02:14 +00002295 private int handleGetSimSlotsMapping() {
2296 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2297 // non user build.
2298 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2299 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2300 return -1;
2301 }
2302 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2303 String result = telephonyManager.getSimSlotMapping().toString();
2304 getOutPrintWriter().println("simSlotsMapping: " + result);
2305
2306 return 0;
2307 }
2308
Hui Wang641e81c2020-10-12 12:14:23 -07002309 private int handleGbaCommand() {
2310 String arg = getNextArg();
2311 if (arg == null) {
2312 onHelpGba();
2313 return 0;
2314 }
2315
2316 switch (arg) {
2317 case GBA_SET_SERVICE: {
2318 return handleGbaSetServiceCommand();
2319 }
2320 case GBA_GET_SERVICE: {
2321 return handleGbaGetServiceCommand();
2322 }
2323 case GBA_SET_RELEASE_TIME: {
2324 return handleGbaSetReleaseCommand();
2325 }
2326 case GBA_GET_RELEASE_TIME: {
2327 return handleGbaGetReleaseCommand();
2328 }
2329 }
2330
2331 return -1;
2332 }
2333
2334 private int getSubId(String cmd) {
2335 int slotId = getDefaultSlot();
2336 String opt = getNextOption();
2337 if (opt != null && opt.equals("-s")) {
2338 try {
2339 slotId = Integer.parseInt(getNextArgRequired());
2340 } catch (NumberFormatException e) {
2341 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2342 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2343 }
2344 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002345 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002346 }
2347
2348 private int handleGbaSetServiceCommand() {
2349 int subId = getSubId("gba set-service");
2350 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2351 return -1;
2352 }
2353
2354 String packageName = getNextArg();
2355 try {
2356 if (packageName == null) {
2357 packageName = "";
2358 }
2359 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2360 if (VDBG) {
2361 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2362 + packageName + ", result=" + result);
2363 }
2364 getOutPrintWriter().println(result);
2365 } catch (RemoteException e) {
2366 Log.w(LOG_TAG, "gba set-service " + subId + " "
2367 + packageName + ", error" + e.getMessage());
2368 getErrPrintWriter().println("Exception: " + e.getMessage());
2369 return -1;
2370 }
2371 return 0;
2372 }
2373
2374 private int handleGbaGetServiceCommand() {
2375 String result;
2376
2377 int subId = getSubId("gba get-service");
2378 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2379 return -1;
2380 }
2381
2382 try {
2383 result = mInterface.getBoundGbaService(subId);
2384 } catch (RemoteException e) {
2385 return -1;
2386 }
2387 if (VDBG) {
2388 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2389 }
2390 getOutPrintWriter().println(result);
2391 return 0;
2392 }
2393
2394 private int handleGbaSetReleaseCommand() {
2395 //the release time value could be -1
2396 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2397 : SubscriptionManager.getDefaultSubscriptionId();
2398 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2399 return -1;
2400 }
2401
2402 String intervalStr = getNextArg();
2403 if (intervalStr == null) {
2404 return -1;
2405 }
2406
2407 try {
2408 int interval = Integer.parseInt(intervalStr);
2409 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2410 if (VDBG) {
2411 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2412 + intervalStr + ", result=" + result);
2413 }
2414 getOutPrintWriter().println(result);
2415 } catch (NumberFormatException | RemoteException e) {
2416 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2417 + intervalStr + ", error" + e.getMessage());
2418 getErrPrintWriter().println("Exception: " + e.getMessage());
2419 return -1;
2420 }
2421 return 0;
2422 }
2423
2424 private int handleGbaGetReleaseCommand() {
2425 int subId = getSubId("gba get-release");
2426 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2427 return -1;
2428 }
2429
2430 int result = 0;
2431 try {
2432 result = mInterface.getGbaReleaseTime(subId);
2433 } catch (RemoteException e) {
2434 return -1;
2435 }
2436 if (VDBG) {
2437 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2438 }
2439 getOutPrintWriter().println(result);
2440 return 0;
2441 }
Hui Wang761a6682020-10-31 05:12:53 +00002442
2443 private int handleSingleRegistrationConfigCommand() {
2444 String arg = getNextArg();
2445 if (arg == null) {
2446 onHelpSrc();
2447 return 0;
2448 }
2449
2450 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002451 case SRC_SET_TEST_ENABLED: {
2452 return handleSrcSetTestEnabledCommand();
2453 }
2454 case SRC_GET_TEST_ENABLED: {
2455 return handleSrcGetTestEnabledCommand();
2456 }
Hui Wang761a6682020-10-31 05:12:53 +00002457 case SRC_SET_DEVICE_ENABLED: {
2458 return handleSrcSetDeviceEnabledCommand();
2459 }
2460 case SRC_GET_DEVICE_ENABLED: {
2461 return handleSrcGetDeviceEnabledCommand();
2462 }
2463 case SRC_SET_CARRIER_ENABLED: {
2464 return handleSrcSetCarrierEnabledCommand();
2465 }
2466 case SRC_GET_CARRIER_ENABLED: {
2467 return handleSrcGetCarrierEnabledCommand();
2468 }
Hui Wangb647abe2021-02-26 09:33:38 -08002469 case SRC_SET_FEATURE_ENABLED: {
2470 return handleSrcSetFeatureValidationCommand();
2471 }
2472 case SRC_GET_FEATURE_ENABLED: {
2473 return handleSrcGetFeatureValidationCommand();
2474 }
Hui Wang761a6682020-10-31 05:12:53 +00002475 }
2476
2477 return -1;
2478 }
2479
James.cf Linbcdf8b32021-01-14 16:44:13 +08002480 private int handleRcsUceCommand() {
2481 String arg = getNextArg();
2482 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002483 onHelpUce();
2484 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002485 }
2486
2487 switch (arg) {
2488 case UCE_REMOVE_EAB_CONTACT:
2489 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002490 case UCE_GET_EAB_CONTACT:
2491 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002492 case UCE_GET_EAB_CAPABILITY:
2493 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002494 case UCE_GET_DEVICE_ENABLED:
2495 return handleUceGetDeviceEnabledCommand();
2496 case UCE_SET_DEVICE_ENABLED:
2497 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002498 case UCE_OVERRIDE_PUBLISH_CAPS:
2499 return handleUceOverridePublishCaps();
2500 case UCE_GET_LAST_PIDF_XML:
2501 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002502 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2503 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002504 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2505 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002506 }
2507 return -1;
2508 }
2509
2510 private int handleRemovingEabContactCommand() {
2511 int subId = getSubId("uce remove-eab-contact");
2512 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2513 return -1;
2514 }
2515
2516 String phoneNumber = getNextArgRequired();
2517 if (TextUtils.isEmpty(phoneNumber)) {
2518 return -1;
2519 }
2520 int result = 0;
2521 try {
2522 result = mInterface.removeContactFromEab(subId, phoneNumber);
2523 } catch (RemoteException e) {
2524 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2525 getErrPrintWriter().println("Exception: " + e.getMessage());
2526 return -1;
2527 }
2528
2529 if (VDBG) {
2530 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2531 }
calvinpan293ea1b2021-02-04 17:52:13 +08002532 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002533 }
2534
calvinpane4a8a1d2021-01-25 13:51:18 +08002535 private int handleGettingEabContactCommand() {
2536 String phoneNumber = getNextArgRequired();
2537 if (TextUtils.isEmpty(phoneNumber)) {
2538 return -1;
2539 }
2540 String result = "";
2541 try {
2542 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002543 } catch (RemoteException e) {
2544 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2545 getErrPrintWriter().println("Exception: " + e.getMessage());
2546 return -1;
2547 }
2548
2549 if (VDBG) {
2550 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2551 }
calvinpan293ea1b2021-02-04 17:52:13 +08002552 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002553 return 0;
2554 }
2555
Calvin Pana1434322021-07-01 19:27:01 +08002556 private int handleGettingEabCapabilityCommand() {
2557 String phoneNumber = getNextArgRequired();
2558 if (TextUtils.isEmpty(phoneNumber)) {
2559 return -1;
2560 }
2561 String result = "";
2562 try {
2563 result = mInterface.getCapabilityFromEab(phoneNumber);
2564 } catch (RemoteException e) {
2565 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2566 getErrPrintWriter().println("Exception: " + e.getMessage());
2567 return -1;
2568 }
2569
2570 if (VDBG) {
2571 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2572 }
2573 getOutPrintWriter().println(result);
2574 return 0;
2575 }
2576
James.cf Lin4b784aa2021-01-31 03:25:15 +08002577 private int handleUceGetDeviceEnabledCommand() {
2578 boolean result = false;
2579 try {
2580 result = mInterface.getDeviceUceEnabled();
2581 } catch (RemoteException e) {
2582 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2583 return -1;
2584 }
2585 if (VDBG) {
2586 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2587 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002588 getOutPrintWriter().println(result);
2589 return 0;
2590 }
2591
James.cf Lin4b784aa2021-01-31 03:25:15 +08002592 private int handleUceSetDeviceEnabledCommand() {
2593 String enabledStr = getNextArg();
2594 if (TextUtils.isEmpty(enabledStr)) {
2595 return -1;
2596 }
2597
2598 try {
2599 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2600 mInterface.setDeviceUceEnabled(isEnabled);
2601 if (VDBG) {
2602 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2603 }
2604 } catch (NumberFormatException | RemoteException e) {
2605 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2606 getErrPrintWriter().println("Exception: " + e.getMessage());
2607 return -1;
2608 }
2609 return 0;
2610 }
2611
James.cf Line8713a42021-04-29 16:04:26 +08002612 private int handleUceRemoveRequestDisallowedStatus() {
2613 int subId = getSubId("uce remove-request-disallowed-status");
2614 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2615 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2616 return -1;
2617 }
2618 boolean result;
2619 try {
2620 result = mInterface.removeUceRequestDisallowedStatus(subId);
2621 } catch (RemoteException e) {
2622 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2623 return -1;
2624 }
2625 if (VDBG) {
2626 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2627 }
2628 getOutPrintWriter().println(result);
2629 return 0;
2630 }
2631
James.cf Lin0fc71b02021-05-25 01:37:38 +08002632 private int handleUceSetCapRequestTimeout() {
2633 int subId = getSubId("uce set-capabilities-request-timeout");
2634 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2635 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2636 return -1;
2637 }
2638 long timeoutAfterMs = Long.valueOf(getNextArg());
2639 boolean result;
2640 try {
2641 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2642 } catch (RemoteException e) {
2643 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2644 return -1;
2645 }
2646 if (VDBG) {
2647 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2648 }
2649 getOutPrintWriter().println(result);
2650 return 0;
2651 }
2652
Hui Wangbaaee6a2021-02-19 20:45:36 -08002653 private int handleSrcSetTestEnabledCommand() {
2654 String enabledStr = getNextArg();
2655 if (enabledStr == null) {
2656 return -1;
2657 }
2658
2659 try {
2660 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2661 if (VDBG) {
2662 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2663 }
2664 getOutPrintWriter().println("Done");
2665 } catch (NumberFormatException | RemoteException e) {
2666 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2667 getErrPrintWriter().println("Exception: " + e.getMessage());
2668 return -1;
2669 }
2670 return 0;
2671 }
2672
2673 private int handleSrcGetTestEnabledCommand() {
2674 boolean result = false;
2675 try {
2676 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2677 } catch (RemoteException e) {
2678 return -1;
2679 }
2680 if (VDBG) {
2681 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2682 }
2683 getOutPrintWriter().println(result);
2684 return 0;
2685 }
2686
Brad Ebinger14d467f2021-02-12 06:18:28 +00002687 private int handleUceOverridePublishCaps() {
2688 int subId = getSubId("uce override-published-caps");
2689 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2690 return -1;
2691 }
2692 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2693 String operation = getNextArgRequired();
2694 String caps = getNextArg();
2695 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2696 && !"list".equals(operation)) {
2697 getErrPrintWriter().println("Invalid operation: " + operation);
2698 return -1;
2699 }
2700
2701 // add/remove requires capabilities to be specified.
2702 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2703 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2704 + "specified");
2705 return -1;
2706 }
2707
2708 ArraySet<String> capSet = new ArraySet<>();
2709 if (!TextUtils.isEmpty(caps)) {
2710 String[] capArray = caps.split(":");
2711 for (String cap : capArray) {
2712 // Allow unknown tags to be passed in as well.
2713 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2714 }
2715 }
2716
2717 RcsContactUceCapability result = null;
2718 try {
2719 switch (operation) {
2720 case "add":
2721 result = mInterface.addUceRegistrationOverrideShell(subId,
2722 new ArrayList<>(capSet));
2723 break;
2724 case "remove":
2725 result = mInterface.removeUceRegistrationOverrideShell(subId,
2726 new ArrayList<>(capSet));
2727 break;
2728 case "clear":
2729 result = mInterface.clearUceRegistrationOverrideShell(subId);
2730 break;
2731 case "list":
2732 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2733 break;
2734 }
2735 } catch (RemoteException e) {
2736 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2737 getErrPrintWriter().println("Exception: " + e.getMessage());
2738 return -1;
2739 } catch (ServiceSpecificException sse) {
2740 // Reconstruct ImsException
2741 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2742 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2743 getErrPrintWriter().println("Exception: " + imsException);
2744 return -1;
2745 }
2746 if (result == null) {
2747 getErrPrintWriter().println("Service not available");
2748 return -1;
2749 }
2750 getOutPrintWriter().println(result);
2751 return 0;
2752 }
2753
2754 private int handleUceGetPidfXml() {
2755 int subId = getSubId("uce get-last-publish-pidf");
2756 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2757 return -1;
2758 }
2759
2760 String result;
2761 try {
2762 result = mInterface.getLastUcePidfXmlShell(subId);
2763 } catch (RemoteException e) {
2764 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2765 getErrPrintWriter().println("Exception: " + e.getMessage());
2766 return -1;
2767 } catch (ServiceSpecificException sse) {
2768 // Reconstruct ImsException
2769 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2770 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2771 getErrPrintWriter().println("Exception: " + imsException);
2772 return -1;
2773 }
2774 if (result == null) {
2775 getErrPrintWriter().println("Service not available");
2776 return -1;
2777 }
2778 getOutPrintWriter().println(result);
2779 return 0;
2780 }
2781
Hui Wang761a6682020-10-31 05:12:53 +00002782 private int handleSrcSetDeviceEnabledCommand() {
2783 String enabledStr = getNextArg();
2784 if (enabledStr == null) {
2785 return -1;
2786 }
2787
2788 try {
2789 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2790 if (VDBG) {
2791 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2792 }
2793 getOutPrintWriter().println("Done");
2794 } catch (NumberFormatException | RemoteException e) {
2795 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2796 getErrPrintWriter().println("Exception: " + e.getMessage());
2797 return -1;
2798 }
2799 return 0;
2800 }
2801
2802 private int handleSrcGetDeviceEnabledCommand() {
2803 boolean result = false;
2804 try {
2805 result = mInterface.getDeviceSingleRegistrationEnabled();
2806 } catch (RemoteException e) {
2807 return -1;
2808 }
2809 if (VDBG) {
2810 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2811 }
2812 getOutPrintWriter().println(result);
2813 return 0;
2814 }
2815
2816 private int handleSrcSetCarrierEnabledCommand() {
2817 //the release time value could be -1
2818 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2819 : SubscriptionManager.getDefaultSubscriptionId();
2820 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2821 return -1;
2822 }
2823
2824 String enabledStr = getNextArg();
2825 if (enabledStr == null) {
2826 return -1;
2827 }
2828
2829 try {
2830 boolean result =
2831 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2832 if (VDBG) {
2833 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2834 + enabledStr + ", result=" + result);
2835 }
2836 getOutPrintWriter().println(result);
2837 } catch (NumberFormatException | RemoteException e) {
2838 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2839 + enabledStr + ", error" + e.getMessage());
2840 getErrPrintWriter().println("Exception: " + e.getMessage());
2841 return -1;
2842 }
2843 return 0;
2844 }
2845
2846 private int handleSrcGetCarrierEnabledCommand() {
2847 int subId = getSubId("src get-carrier-enabled");
2848 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2849 return -1;
2850 }
2851
2852 boolean result = false;
2853 try {
2854 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2855 } catch (RemoteException e) {
2856 return -1;
2857 }
2858 if (VDBG) {
2859 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2860 }
2861 getOutPrintWriter().println(result);
2862 return 0;
2863 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002864
Hui Wangb647abe2021-02-26 09:33:38 -08002865 private int handleSrcSetFeatureValidationCommand() {
2866 //the release time value could be -1
2867 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2868 : SubscriptionManager.getDefaultSubscriptionId();
2869 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2870 return -1;
2871 }
2872
2873 String enabledStr = getNextArg();
2874 if (enabledStr == null) {
2875 return -1;
2876 }
2877
2878 try {
2879 boolean result =
2880 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2881 if (VDBG) {
2882 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2883 + enabledStr + ", result=" + result);
2884 }
2885 getOutPrintWriter().println(result);
2886 } catch (NumberFormatException | RemoteException e) {
2887 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2888 + enabledStr + ", error" + e.getMessage());
2889 getErrPrintWriter().println("Exception: " + e.getMessage());
2890 return -1;
2891 }
2892 return 0;
2893 }
2894
2895 private int handleSrcGetFeatureValidationCommand() {
2896 int subId = getSubId("src get-feature-validation");
2897 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2898 return -1;
2899 }
2900
2901 Boolean result = false;
2902 try {
2903 result = mInterface.getImsFeatureValidationOverride(subId);
2904 } catch (RemoteException e) {
2905 return -1;
2906 }
2907 if (VDBG) {
2908 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2909 }
2910 getOutPrintWriter().println(result);
2911 return 0;
2912 }
2913
2914
Hall Liuaa4211e2021-01-20 15:43:39 -08002915 private void onHelpCallComposer() {
2916 PrintWriter pw = getOutPrintWriter();
2917 pw.println("Call composer commands");
2918 pw.println(" callcomposer test-mode enable|disable|query");
2919 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2920 pw.println(" upload/download from carrier servers is disabled, and operations are");
2921 pw.println(" performed using emulated local files instead.");
2922 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2923 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2924 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002925 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2926 pw.println(" Enables or disables the user setting for call composer, as set by");
2927 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002928 }
2929
2930 private int handleCallComposerCommand() {
2931 String arg = getNextArg();
2932 if (arg == null) {
2933 onHelpCallComposer();
2934 return 0;
2935 }
2936
2937 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2938 "MODIFY_PHONE_STATE required for call composer shell cmds");
2939 switch (arg) {
2940 case CALL_COMPOSER_TEST_MODE: {
2941 String enabledStr = getNextArg();
2942 if (ENABLE.equals(enabledStr)) {
2943 CallComposerPictureManager.sTestMode = true;
2944 } else if (DISABLE.equals(enabledStr)) {
2945 CallComposerPictureManager.sTestMode = false;
2946 } else if (QUERY.equals(enabledStr)) {
2947 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2948 } else {
2949 onHelpCallComposer();
2950 return 1;
2951 }
2952 break;
2953 }
2954 case CALL_COMPOSER_SIMULATE_CALL: {
2955 int subscriptionId = Integer.valueOf(getNextArg());
2956 String uuidString = getNextArg();
2957 UUID uuid = UUID.fromString(uuidString);
2958 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2959 Binder.withCleanCallingIdentity(() -> {
2960 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2961 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2962 });
2963 try {
2964 Uri uri = storageUriFuture.get();
2965 getOutPrintWriter().println(String.valueOf(uri));
2966 } catch (Exception e) {
2967 throw new RuntimeException(e);
2968 }
2969 break;
2970 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002971 case CALL_COMPOSER_USER_SETTING: {
2972 try {
2973 int subscriptionId = Integer.valueOf(getNextArg());
2974 String enabledStr = getNextArg();
2975 if (ENABLE.equals(enabledStr)) {
2976 mInterface.setCallComposerStatus(subscriptionId,
2977 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2978 } else if (DISABLE.equals(enabledStr)) {
2979 mInterface.setCallComposerStatus(subscriptionId,
2980 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2981 } else if (QUERY.equals(enabledStr)) {
2982 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2983 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2984 } else {
2985 onHelpCallComposer();
2986 return 1;
2987 }
2988 } catch (RemoteException e) {
2989 e.printStackTrace(getOutPrintWriter());
2990 return 1;
2991 }
2992 break;
2993 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002994 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002995 return 0;
2996 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002997
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002998 private int handleHasCarrierPrivilegesCommand() {
2999 String packageName = getNextArgRequired();
3000
3001 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003002 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003003 try {
3004 hasCarrierPrivileges =
3005 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3006 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3007 } catch (RemoteException e) {
3008 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3009 getErrPrintWriter().println("Exception: " + e.getMessage());
3010 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003011 } finally {
3012 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003013 }
3014
3015 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003016 return 0;
3017 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003018
3019 private int handleAllowedNetworkTypesCommand(String command) {
3020 if (!checkShellUid()) {
3021 return -1;
3022 }
3023
3024 PrintWriter errPw = getErrPrintWriter();
3025 String tag = command + ": ";
3026 String opt;
3027 int subId = -1;
3028 Log.v(LOG_TAG, command + " start");
3029
3030 while ((opt = getNextOption()) != null) {
3031 if (opt.equals("-s")) {
3032 try {
3033 subId = slotStringToSubId(tag, getNextArgRequired());
3034 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3035 errPw.println(tag + "No valid subscription found.");
3036 return -1;
3037 }
3038 } catch (IllegalArgumentException e) {
3039 // Missing slot id
3040 errPw.println(tag + "SLOT_ID expected after -s.");
3041 return -1;
3042 }
3043 } else {
3044 errPw.println(tag + "Unknown option " + opt);
3045 return -1;
3046 }
3047 }
3048
3049 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3050 return handleGetAllowedNetworkTypesCommand(subId);
3051 }
3052 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3053 return handleSetAllowedNetworkTypesCommand(subId);
3054 }
3055 return -1;
3056 }
3057
3058 private int handleGetAllowedNetworkTypesCommand(int subId) {
3059 PrintWriter errPw = getErrPrintWriter();
3060
3061 long result = -1;
3062 try {
3063 if (mInterface != null) {
3064 result = mInterface.getAllowedNetworkTypesForReason(subId,
3065 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3066 } else {
3067 throw new IllegalStateException("telephony service is null.");
3068 }
3069 } catch (RemoteException e) {
3070 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3071 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3072 return -1;
3073 }
3074
3075 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3076 return 0;
3077 }
3078
3079 private int handleSetAllowedNetworkTypesCommand(int subId) {
3080 PrintWriter errPw = getErrPrintWriter();
3081
3082 String bitmaskString = getNextArg();
3083 if (TextUtils.isEmpty(bitmaskString)) {
3084 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3085 return -1;
3086 }
3087 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3088 if (allowedNetworkTypes < 0) {
3089 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3090 return -1;
3091 }
3092 boolean result = false;
3093 try {
3094 if (mInterface != null) {
3095 result = mInterface.setAllowedNetworkTypesForReason(subId,
3096 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3097 } else {
3098 throw new IllegalStateException("telephony service is null.");
3099 }
3100 } catch (RemoteException e) {
3101 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3102 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3103 return -1;
3104 }
3105
3106 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3107 if (result) {
3108 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3109 }
3110 getOutPrintWriter().println(resultMessage);
3111 return 0;
3112 }
3113
3114 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3115 if (TextUtils.isEmpty(bitmaskString)) {
3116 return -1;
3117 }
3118 if (VDBG) {
3119 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3120 + ", length: " + bitmaskString.length());
3121 }
3122 try {
3123 return Long.parseLong(bitmaskString, 2);
3124 } catch (NumberFormatException e) {
3125 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3126 return -1;
3127 }
3128 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003129
jimsun3b9ccac2021-10-26 15:01:23 +08003130 private int handleRadioSetModemServiceCommand() {
3131 PrintWriter errPw = getErrPrintWriter();
3132 String serviceName = null;
3133
3134 String opt;
3135 while ((opt = getNextOption()) != null) {
3136 switch (opt) {
3137 case "-s": {
3138 serviceName = getNextArgRequired();
3139 break;
3140 }
3141 }
3142 }
3143
3144 try {
3145 boolean result = mInterface.setModemService(serviceName);
3146 if (VDBG) {
3147 Log.v(LOG_TAG,
3148 "RadioSetModemService " + serviceName + ", result = " + result);
3149 }
3150 getOutPrintWriter().println(result);
3151 } catch (RemoteException e) {
3152 Log.w(LOG_TAG,
3153 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3154 errPw.println("Exception: " + e.getMessage());
3155 return -1;
3156 }
3157 return 0;
3158 }
3159
3160 private int handleRadioGetModemServiceCommand() {
3161 PrintWriter errPw = getErrPrintWriter();
3162 String result;
3163
3164 try {
3165 result = mInterface.getModemService();
3166 getOutPrintWriter().println(result);
3167 } catch (RemoteException e) {
3168 errPw.println("Exception: " + e.getMessage());
3169 return -1;
3170 }
3171 if (VDBG) {
3172 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3173 }
3174 return 0;
3175 }
3176
3177 private int handleRadioCommand() {
3178 String arg = getNextArg();
3179 if (arg == null) {
3180 onHelpRadio();
3181 return 0;
3182 }
3183
3184 switch (arg) {
3185 case RADIO_SET_MODEM_SERVICE:
3186 return handleRadioSetModemServiceCommand();
3187
3188 case RADIO_GET_MODEM_SERVICE:
3189 return handleRadioGetModemServiceCommand();
3190 }
3191
3192 return -1;
3193 }
arunvoddud7401012022-12-15 16:08:12 +00003194
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003195 private int handleSetSatelliteServicePackageNameCommand() {
3196 PrintWriter errPw = getErrPrintWriter();
3197 String serviceName = null;
3198
3199 String opt;
3200 while ((opt = getNextOption()) != null) {
3201 switch (opt) {
3202 case "-s": {
3203 serviceName = getNextArgRequired();
3204 break;
3205 }
3206 }
3207 }
3208 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3209 + serviceName);
3210
3211 try {
3212 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3213 if (VDBG) {
3214 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3215 + ", result = " + result);
3216 }
3217 getOutPrintWriter().println(result);
3218 } catch (RemoteException e) {
3219 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3220 + ", error = " + e.getMessage());
3221 errPw.println("Exception: " + e.getMessage());
3222 return -1;
3223 }
3224 return 0;
3225 }
3226
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003227 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3228 PrintWriter errPw = getErrPrintWriter();
3229 String serviceName = null;
3230
3231 String opt;
3232 while ((opt = getNextOption()) != null) {
3233 switch (opt) {
3234 case "-s": {
3235 serviceName = getNextArgRequired();
3236 break;
3237 }
3238 }
3239 }
3240 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3241 + serviceName);
3242
3243 try {
3244 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3245 if (VDBG) {
3246 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3247 + ", result = " + result);
3248 }
3249 getOutPrintWriter().println(result);
3250 } catch (RemoteException e) {
3251 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3252 + ", error = " + e.getMessage());
3253 errPw.println("Exception: " + e.getMessage());
3254 return -1;
3255 }
3256 return 0;
3257 }
3258
Thomas Nguyen87dce732023-04-20 18:27:16 -07003259 private int handleSetSatellitePointingUiClassNameCommand() {
3260 PrintWriter errPw = getErrPrintWriter();
3261 String packageName = null;
3262 String className = null;
3263
3264 String opt;
3265 while ((opt = getNextOption()) != null) {
3266 switch (opt) {
3267 case "-p": {
3268 packageName = getNextArgRequired();
3269 break;
3270 }
3271 case "-c": {
3272 className = getNextArgRequired();
3273 break;
3274 }
3275 }
3276 }
3277 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3278 + packageName + ", className=" + className);
3279
3280 try {
3281 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3282 if (VDBG) {
3283 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3284 }
3285 getOutPrintWriter().println(result);
3286 } catch (RemoteException e) {
3287 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3288 + ", error = " + e.getMessage());
3289 errPw.println("Exception: " + e.getMessage());
3290 return -1;
3291 }
3292 return 0;
3293 }
3294
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003295 private int handleSetEmergencyCallToSatelliteHandoverType() {
3296 PrintWriter errPw = getErrPrintWriter();
3297 int handoverType = -1;
3298 int delaySeconds = 0;
3299
3300 String opt;
3301 while ((opt = getNextOption()) != null) {
3302 switch (opt) {
3303 case "-t": {
3304 try {
3305 handoverType = Integer.parseInt(getNextArgRequired());
3306 } catch (NumberFormatException e) {
3307 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3308 + " for handoverType");
3309 return -1;
3310 }
3311 break;
3312 }
3313 case "-d": {
3314 try {
3315 delaySeconds = Integer.parseInt(getNextArgRequired());
3316 } catch (NumberFormatException e) {
3317 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3318 + " for delaySeconds");
3319 return -1;
3320 }
3321 break;
3322 }
3323 }
3324 }
3325 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3326 + handoverType + ", delaySeconds=" + delaySeconds);
3327
3328 try {
3329 boolean result =
3330 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3331 if (VDBG) {
3332 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3333 }
3334 getOutPrintWriter().println(result);
3335 } catch (RemoteException e) {
3336 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3337 + ", error = " + e.getMessage());
3338 errPw.println("Exception: " + e.getMessage());
3339 return -1;
3340 }
3341 return 0;
3342 }
3343
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003344 private int handleSetSatelliteListeningTimeoutDuration() {
3345 PrintWriter errPw = getErrPrintWriter();
3346 long timeoutMillis = 0;
3347
3348 String opt;
3349 while ((opt = getNextOption()) != null) {
3350 switch (opt) {
3351 case "-t": {
3352 timeoutMillis = Long.parseLong(getNextArgRequired());
3353 break;
3354 }
3355 }
3356 }
3357 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3358 + timeoutMillis);
3359
3360 try {
3361 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3362 if (VDBG) {
3363 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3364 + ", result = " + result);
3365 }
3366 getOutPrintWriter().println(result);
3367 } catch (RemoteException e) {
3368 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3369 + ", error = " + e.getMessage());
3370 errPw.println("Exception: " + e.getMessage());
3371 return -1;
3372 }
3373 return 0;
3374 }
3375
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003376 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003377 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003378 boolean reset = false;
3379 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003380 long timeoutMillis = 0;
3381
3382 String opt;
3383 while ((opt = getNextOption()) != null) {
3384 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003385 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003386 timeoutMillis = Long.parseLong(getNextArgRequired());
3387 break;
3388 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003389 case "-r": {
3390 reset = true;
3391 break;
3392 }
3393 case "-t": {
3394 timeoutType = Integer.parseInt(getNextArgRequired());
3395 break;
3396 }
Hakjun Choiae365972023-04-25 11:00:31 +00003397 }
3398 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003399 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3400 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003401
3402 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003403 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3404 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003405 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003406 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003407 + ", result = " + result);
3408 }
3409 getOutPrintWriter().println(result);
3410 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003411 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3412 + ", error = " + e.getMessage());
3413 errPw.println("Exception: " + e.getMessage());
3414 return -1;
3415 }
3416 return 0;
3417 }
3418
3419 private int handleSetSatelliteControllerTimeoutDuration() {
3420 PrintWriter errPw = getErrPrintWriter();
3421 boolean reset = false;
3422 int timeoutType = 0;
3423 long timeoutMillis = 0;
3424
3425 String opt;
3426 while ((opt = getNextOption()) != null) {
3427 switch (opt) {
3428 case "-d": {
3429 timeoutMillis = Long.parseLong(getNextArgRequired());
3430 break;
3431 }
3432 case "-r": {
3433 reset = true;
3434 break;
3435 }
3436 case "-t": {
3437 timeoutType = Integer.parseInt(getNextArgRequired());
3438 break;
3439 }
3440 }
3441 }
3442 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3443 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3444
3445 try {
3446 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3447 reset, timeoutType, timeoutMillis);
3448 if (VDBG) {
3449 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3450 + ", result = " + result);
3451 }
3452 getOutPrintWriter().println(result);
3453 } catch (RemoteException e) {
3454 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003455 + ", error = " + e.getMessage());
3456 errPw.println("Exception: " + e.getMessage());
3457 return -1;
3458 }
3459 return 0;
3460 }
3461
Hakjun Choibc6ce992023-11-07 16:04:33 +00003462 private int handleSetShouldSendDatagramToModemInDemoMode() {
3463 PrintWriter errPw = getErrPrintWriter();
3464 String opt;
3465 boolean shouldSendToDemoMode;
3466
3467 if ((opt = getNextArg()) == null) {
3468 errPw.println(
3469 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3470 + " Invalid Argument");
3471 return -1;
3472 } else {
3473 switch (opt) {
3474 case "true": {
3475 shouldSendToDemoMode = true;
3476 break;
3477 }
3478 case "false": {
3479 shouldSendToDemoMode = false;
3480 break;
3481 }
3482 default:
3483 errPw.println(
3484 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3485 + " Invalid Argument");
3486 return -1;
3487 }
3488 }
3489
3490 Log.d(LOG_TAG,
3491 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3492
3493 try {
3494 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3495 shouldSendToDemoMode);
3496 if (VDBG) {
3497 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3498 + result);
3499 }
3500 getOutPrintWriter().println(false);
3501 } catch (RemoteException e) {
3502 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3503 + "), error = " + e.getMessage());
3504 errPw.println("Exception: " + e.getMessage());
3505 return -1;
3506 }
3507 return 0;
3508 }
3509
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003510 private int handleSetSatelliteAccessControlOverlayConfigs() {
3511 PrintWriter errPw = getErrPrintWriter();
3512 boolean reset = false;
3513 boolean isAllowed = false;
3514 String s2CellFile = null;
3515 long locationFreshDurationNanos = 0;
3516 List<String> satelliteCountryCodes = null;
3517
3518 String opt;
3519 while ((opt = getNextOption()) != null) {
3520 switch (opt) {
3521 case "-r": {
3522 reset = true;
3523 break;
3524 }
3525 case "-a": {
3526 isAllowed = true;
3527 break;
3528 }
3529 case "-f": {
3530 s2CellFile = getNextArgRequired();
3531 break;
3532 }
3533 case "-d": {
3534 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3535 break;
3536 }
3537 case "-c": {
3538 String countryCodeStr = getNextArgRequired();
3539 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3540 break;
3541 }
3542 }
3543 }
3544 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3545 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3546 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3547 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3548
3549 try {
3550 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3551 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3552 if (VDBG) {
3553 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3554 }
3555 getOutPrintWriter().println(result);
3556 } catch (RemoteException e) {
3557 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3558 errPw.println("Exception: " + e.getMessage());
3559 return -1;
3560 }
3561 return 0;
3562 }
3563
3564 private int handleSetCountryCodes() {
3565 PrintWriter errPw = getErrPrintWriter();
3566 List<String> currentNetworkCountryCodes = new ArrayList<>();
3567 String locationCountryCode = null;
3568 long locationCountryCodeTimestampNanos = 0;
3569 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3570 boolean reset = false;
3571
3572 String opt;
3573 while ((opt = getNextOption()) != null) {
3574 switch (opt) {
3575 case "-r": {
3576 reset = true;
3577 break;
3578 }
3579 case "-n": {
3580 String countryCodeStr = getNextArgRequired();
3581 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3582 break;
3583 }
3584 case "-c": {
3585 String cachedNetworkCountryCodeStr = getNextArgRequired();
3586 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3587 break;
3588 }
3589 case "-l": {
3590 locationCountryCode = getNextArgRequired();
3591 break;
3592 }
3593 case "-t": {
3594 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3595 break;
3596 }
3597 }
3598 }
3599 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3600 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3601 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3602 + currentNetworkCountryCodes);
3603
3604 try {
3605 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3606 cachedNetworkCountryCodes, locationCountryCode,
3607 locationCountryCodeTimestampNanos);
3608 if (VDBG) {
3609 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3610 }
3611 getOutPrintWriter().println(result);
3612 } catch (RemoteException e) {
3613 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3614 errPw.println("Exception: " + e.getMessage());
3615 return -1;
3616 }
3617 return 0;
3618 }
3619
Thomas Nguyen3d602742024-01-19 11:29:35 -08003620 private int handleSetOemEnabledSatelliteProvisionStatus() {
3621 PrintWriter errPw = getErrPrintWriter();
3622 boolean isProvisioned = false;
3623 boolean reset = true;
3624
3625 String opt;
3626 while ((opt = getNextOption()) != null) {
3627 switch (opt) {
3628 case "-p": {
3629 try {
3630 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3631 reset = false;
3632 } catch (Exception e) {
3633 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3634 + "after -p indicating provision status");
3635 return -1;
3636 }
3637 }
3638 }
3639 }
3640 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3641 + ", isProvisioned=" + isProvisioned);
3642
3643 try {
3644 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3645 if (VDBG) {
3646 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3647 }
3648 getOutPrintWriter().println(result);
3649 } catch (RemoteException e) {
3650 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3651 errPw.println("Exception: " + e.getMessage());
3652 return -1;
3653 }
3654 return 0;
3655 }
3656
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003657 /**
3658 * Sample inputStr = "US,UK,CA;2,1,3"
3659 * Sample output: {[US,2], [UK,1], [CA,3]}
3660 */
3661 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3662 Map<String, Long> result = new HashMap<>();
3663 if (!TextUtils.isEmpty(inputStr)) {
3664 String[] stringLongArr = inputStr.split(";");
3665 if (stringLongArr.length != 2) {
3666 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3667 return result;
3668 }
3669
3670 String[] stringArr = stringLongArr[0].split(",");
3671 String[] longArr = stringLongArr[1].split(",");
3672 if (stringArr.length != longArr.length) {
3673 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3674 return result;
3675 }
3676
3677 for (int i = 0; i < stringArr.length; i++) {
3678 try {
3679 result.put(stringArr[i], Long.parseLong(longArr[i]));
3680 } catch (Exception ex) {
3681 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3682 + ", ex=" + ex);
3683 return result;
3684 }
3685 }
3686 }
3687 return result;
3688 }
3689
arunvoddud7401012022-12-15 16:08:12 +00003690 private int handleCarrierRestrictionStatusCommand() {
3691 try {
3692 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3693 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3694 mInterface.getModemService()))) {
3695 Log.v(LOG_TAG,
3696 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3697 + " checkShellUid fails");
3698 return -1;
3699 }
3700 } catch (RemoteException ex) {
3701 ex.printStackTrace();
3702 }
3703 String callerInfo = getNextOption();
3704 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3705 if (TextUtils.isEmpty(callerInfo)) {
3706 // reset the Json content after testing
3707 allowListInfo.updateJsonForTest(null);
3708 return 0;
3709 }
3710 if (callerInfo.startsWith("--")) {
3711 callerInfo = callerInfo.replace("--", "");
3712 }
3713 String params[] = callerInfo.split(",");
3714 StringBuffer jsonStrBuffer = new StringBuffer();
3715 String tokens;
3716 for (int index = 0; index < params.length; index++) {
3717 tokens = convertToJsonString(index, params[index]);
3718 if (TextUtils.isEmpty(tokens)) {
3719 // received wrong format from CTS
3720 if (VDBG) {
3721 Log.v(LOG_TAG,
3722 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3723 }
3724 return -1;
3725 }
3726 jsonStrBuffer.append(tokens);
3727 }
3728 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3729 return result;
3730 }
3731
Benedict Wong66477622023-02-03 23:30:57 +00003732 // set-carrier-service-package-override
3733 private int setCarrierServicePackageOverride() {
3734 PrintWriter errPw = getErrPrintWriter();
3735 int subId = SubscriptionManager.getDefaultSubscriptionId();
3736
3737 String opt;
3738 while ((opt = getNextOption()) != null) {
3739 switch (opt) {
3740 case "-s":
3741 try {
3742 subId = Integer.parseInt(getNextArgRequired());
3743 } catch (NumberFormatException e) {
3744 errPw.println(
3745 "set-carrier-service-package-override requires an integer as a"
3746 + " subscription ID.");
3747 return -1;
3748 }
3749 break;
3750 }
3751 }
3752
3753 String packageName = getNextArg();
3754 if (packageName == null) {
3755 errPw.println("set-carrier-service-package-override requires a override package name.");
3756 return -1;
3757 }
3758
3759 try {
3760 mInterface.setCarrierServicePackageOverride(
3761 subId, packageName, mContext.getOpPackageName());
3762
3763 if (VDBG) {
3764 Log.v(
3765 LOG_TAG,
3766 "set-carrier-service-package-override -s " + subId + " " + packageName);
3767 }
3768 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3769 Log.w(
3770 LOG_TAG,
3771 "set-carrier-service-package-override -s "
3772 + subId
3773 + " "
3774 + packageName
3775 + ", error"
3776 + e.getMessage());
3777 errPw.println("Exception: " + e.getMessage());
3778 return -1;
3779 }
3780 return 0;
3781 }
3782
3783 // clear-carrier-service-package-override
3784 private int clearCarrierServicePackageOverride() {
3785 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003786 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003787
3788 String opt;
3789 while ((opt = getNextOption()) != null) {
3790 switch (opt) {
3791 case "-s":
3792 try {
3793 subId = Integer.parseInt(getNextArgRequired());
3794 } catch (NumberFormatException e) {
3795 errPw.println(
3796 "clear-carrier-service-package-override requires an integer as a"
3797 + " subscription ID.");
3798 return -1;
3799 }
3800 break;
3801 }
3802 }
3803
3804 try {
3805 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3806
3807 if (VDBG) {
3808 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3809 }
3810 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3811 Log.w(
3812 LOG_TAG,
3813 "clear-carrier-service-package-override -s "
3814 + subId
3815 + ", error"
3816 + e.getMessage());
3817 errPw.println("Exception: " + e.getMessage());
3818 return -1;
3819 }
3820 return 0;
3821 }
arunvoddud7401012022-12-15 16:08:12 +00003822
Hunsuk Choi13078be2023-09-13 10:55:21 +00003823 private int handleDomainSelectionCommand() {
3824 String arg = getNextArg();
3825 if (arg == null) {
3826 onHelpDomainSelection();
3827 return 0;
3828 }
3829
3830 switch (arg) {
3831 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3832 return handleDomainSelectionSetServiceOverrideCommand();
3833 }
3834 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3835 return handleDomainSelectionClearServiceOverrideCommand();
3836 }
3837 }
3838
3839 return -1;
3840 }
3841
3842 // domainselection set-dss-override
3843 private int handleDomainSelectionSetServiceOverrideCommand() {
3844 PrintWriter errPw = getErrPrintWriter();
3845
3846 String componentName = getNextArg();
3847
3848 try {
3849 boolean result = mInterface.setDomainSelectionServiceOverride(
3850 ComponentName.unflattenFromString(componentName));
3851 if (VDBG) {
3852 Log.v(LOG_TAG, "domainselection set-dss-override "
3853 + componentName + ", result=" + result);
3854 }
3855 getOutPrintWriter().println(result);
3856 } catch (Exception e) {
3857 Log.w(LOG_TAG, "domainselection set-dss-override "
3858 + componentName + ", error=" + e.getMessage());
3859 errPw.println("Exception: " + e.getMessage());
3860 return -1;
3861 }
3862 return 0;
3863 }
3864
3865 // domainselection clear-dss-override
3866 private int handleDomainSelectionClearServiceOverrideCommand() {
3867 PrintWriter errPw = getErrPrintWriter();
3868
3869 try {
3870 boolean result = mInterface.clearDomainSelectionServiceOverride();
3871 if (VDBG) {
3872 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
3873 }
3874 getOutPrintWriter().println(result);
3875 } catch (RemoteException e) {
3876 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
3877 errPw.println("Exception: " + e.getMessage());
3878 return -1;
3879 }
3880 return 0;
3881 }
3882
arunvoddud7401012022-12-15 16:08:12 +00003883 /**
3884 * Building the string that can be used to build the JsonObject which supports to stub the data
3885 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia28b7cb32024-03-11 23:58:50 +00003886 * {"com.android.example":{"carrierIds":[10000],"callerSHA1Id":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00003887 */
3888 private String convertToJsonString(int index, String param) {
3889
3890 String token[] = param.split(":");
3891 String jSonString;
3892 switch (index) {
3893 case 0:
3894 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3895 break;
3896 case 1:
3897 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00003898 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00003899 break;
3900 case 2:
3901 jSonString =
3902 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
3903 break;
3904 default:
3905 jSonString = null;
3906 }
3907 return jSonString;
3908 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003909}