blob: 23232ce36181dcc4a683757b88b3da7afbc6641b [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080027import android.annotation.NonNull;
28import android.annotation.Nullable;
Hunsuk Choi13078be2023-09-13 10:55:21 +000029import android.content.ComponentName;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080031import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080032import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010033import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080034import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000036import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070037import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070038import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010039import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070040import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070041import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000042import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070043import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080044import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000045import android.telephony.ims.ImsException;
46import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080047import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080048import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000049import android.util.ArrayMap;
50import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070052import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070053
Brad Ebinger14d467f2021-02-12 06:18:28 +000054import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070055import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080056import com.android.internal.telephony.Phone;
57import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080058import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080059import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080060import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080061import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080062import com.android.phone.callcomposer.CallComposerPictureManager;
Shivakumar Neginal9cd61892022-12-19 04:38:52 +000063import com.android.phone.euicc.EuiccUiDispatcherActivity;
arunvoddud7401012022-12-15 16:08:12 +000064import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070065
Allen Xuee00f0e2022-03-14 21:04:49 +000066import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070067import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080068import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000069import java.util.Arrays;
70import java.util.Collections;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080071import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080072import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000073import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010074import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000075import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010076import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080077import java.util.UUID;
78import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070079
80/**
81 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
82 * permission checks have been done before onCommand was called. Make sure any commands processed
83 * here also contain the appropriate permissions checks.
84 */
85
Hall Liua1548bd2019-12-24 14:14:12 -080086public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087
88 private static final String LOG_TAG = "TelephonyShellCommand";
89 // Don't commit with this true.
90 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070091 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070092
Hall Liuaa4211e2021-01-20 15:43:39 -080093 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070094 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080095 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080096 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080097 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070098 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000099 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +0000100 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100101 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -0800102 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -0800103 private static final String ENABLE = "enable";
104 private static final String DISABLE = "disable";
105 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000106 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000107 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
108 "set-carrier-service-package-override";
109 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
110 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000111 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800112
Hall Liu7135e502021-02-04 16:58:17 -0800113 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800114 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800115 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800116
Brad Ebinger999d3302020-11-25 14:31:39 -0800117 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
118 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
119 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700120 // Used to disable or enable processing of conference event package data from the network.
121 // This is handy for testing scenarios where CEP data does not exist on a network which does
122 // support CEP data.
123 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700124
Hall Liud892bec2018-11-30 14:51:45 -0800125 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800126 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800127
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100128 private static final String CC_GET_VALUE = "get-value";
129 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000130 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100131 private static final String CC_CLEAR_VALUES = "clear-values";
132
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000133 private static final String EUICC_SUBCOMMAND = "euicc";
134 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
135
Hui Wang641e81c2020-10-12 12:14:23 -0700136 private static final String GBA_SUBCOMMAND = "gba";
137 private static final String GBA_SET_SERVICE = "set-service";
138 private static final String GBA_GET_SERVICE = "get-service";
139 private static final String GBA_SET_RELEASE_TIME = "set-release";
140 private static final String GBA_GET_RELEASE_TIME = "get-release";
141
Hui Wang761a6682020-10-31 05:12:53 +0000142 private static final String SINGLE_REGISTATION_CONFIG = "src";
143 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
144 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
145 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
146 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800147 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
148 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800149 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
150 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000151
Tyler Gunn92479152021-01-20 16:30:10 -0800152 private static final String D2D_SUBCOMMAND = "d2d";
153 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800154 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700155 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800156
Nazanin014f41e2021-05-06 17:26:31 -0700157 private static final String BARRING_SUBCOMMAND = "barring";
158 private static final String BARRING_SEND_INFO = "send";
159
James.cf Linbcdf8b32021-01-14 16:44:13 +0800160 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800161 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800162 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800163 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800164 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
165 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000166 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
167 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800168 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
169 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800170 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
171 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800172
jimsun3b9ccac2021-10-26 15:01:23 +0800173 private static final String RADIO_SUBCOMMAND = "radio";
174 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
175 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
176
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800177 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
178 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
179
Jordan Liu0ccee222021-04-27 11:55:13 -0700180 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
181 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
182
Jack Nudelman644b91a2021-03-12 14:09:48 -0800183 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
184 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
185 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700186 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
187 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700188 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
189 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700190 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
191 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700192 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
193 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800194 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
195 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +0000196 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
197 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800198
199 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
200 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700201 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
202 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800203 private static final String SET_COUNTRY_CODES = "set-country-codes";
204 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
205 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800206 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
207 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000208 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
209 "set-should-send-datagram-to-modem-in-demo-mode";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800210
Hunsuk Choi13078be2023-09-13 10:55:21 +0000211 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
212 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
213 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
214
Grant Menke567d48f2022-08-18 20:19:10 +0000215 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
216 + "'*', '#' or '+') needs to be specified after -a in the command ";
217
218 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
219 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
220 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
221
SongFerngWang98dd5992021-05-13 17:50:00 +0800222 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
223 "get-allowed-network-types-for-users";
224 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
225 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000226 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000227 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700228 // Take advantage of existing methods that already contain permissions checks when possible.
229 private final ITelephony mInterface;
230
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100231 private SubscriptionManager mSubscriptionManager;
232 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700233 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700234 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100235
236 private enum CcType {
237 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000238 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100239 }
240
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100241 private class CcOptionParseResult {
242 public int mSubId;
243 public boolean mPersistent;
244 }
245
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100246 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
247 // keys by looking at the end of the string which usually tells the type.
248 // For instance: "xxxx_string", "xxxx_string_array", etc.
249 // The carrier config keys in this map does not follow this convention. It is therefore not
250 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700251 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
252 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
253 CcType.STRING),
254 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
255 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
256 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
257 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
258 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
264 CcType.STRING),
265 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
266 CcType.STRING_ARRAY),
267 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
268 CcType.STRING_ARRAY),
269 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
270 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
271 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
272 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
273 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
274 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
275 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
276 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100277
Brad Ebinger14d467f2021-02-12 06:18:28 +0000278 /**
279 * Map from a shorthand string to the feature tags required in registration required in order
280 * for the RCS feature to be considered "capable".
281 */
282 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
283 static {
284 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
285 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
286 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
287 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
288 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
289 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
290 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
291 FeatureTags.FEATURE_TAG_VIDEO)));
292 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
293 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
294 map.put("call_comp",
295 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
296 map.put("call_comp_mmtel",
297 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
298 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
299 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
300 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
301 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
302 // version
303 map.put("chatbot", new ArraySet<>(Arrays.asList(
304 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
305 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
306 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
307 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000308 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000309 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
310 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
311 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
312 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
313 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000314 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000315 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
316 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
317 }
318
319
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100320 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700321 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100322 mCarrierConfigManager =
323 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
324 mSubscriptionManager = (SubscriptionManager)
325 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700326 mTelephonyRegistryManager = (TelephonyRegistryManager)
327 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700328 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700329 }
330
331 @Override
332 public int onCommand(String cmd) {
333 if (cmd == null) {
334 return handleDefaultCommands(null);
335 }
336
337 switch (cmd) {
338 case IMS_SUBCOMMAND: {
339 return handleImsCommand();
340 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800341 case RCS_UCE_COMMAND:
342 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800343 case NUMBER_VERIFICATION_SUBCOMMAND:
344 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800345 case EMERGENCY_CALLBACK_MODE:
346 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800347 case EMERGENCY_NUMBER_TEST_MODE:
348 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100349 case CARRIER_CONFIG_SUBCOMMAND: {
350 return handleCcCommand();
351 }
Shuo Qianf5125122019-12-16 17:03:07 -0800352 case DATA_TEST_MODE:
353 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700354 case END_BLOCK_SUPPRESSION:
355 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000356 case EUICC_SUBCOMMAND:
357 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700358 case GBA_SUBCOMMAND:
359 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800360 case D2D_SUBCOMMAND:
361 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700362 case BARRING_SUBCOMMAND:
363 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000364 case SINGLE_REGISTATION_CONFIG:
365 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000366 case RESTART_MODEM:
367 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800368 case CALL_COMPOSER_SUBCOMMAND:
369 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000370 case UNATTENDED_REBOOT:
371 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800372 case HAS_CARRIER_PRIVILEGES_COMMAND:
373 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800374 case THERMAL_MITIGATION_COMMAND:
375 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700376 case DISABLE_PHYSICAL_SUBSCRIPTION:
377 return handleEnablePhysicalSubscription(false);
378 case ENABLE_PHYSICAL_SUBSCRIPTION:
379 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800380 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
381 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
382 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000383 case GET_IMEI:
384 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000385 case GET_SIM_SLOTS_MAPPING:
386 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800387 case RADIO_SUBCOMMAND:
388 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000389 case CARRIER_RESTRICTION_STATUS_TEST:
390 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000391 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
392 return setCarrierServicePackageOverride();
393 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
394 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000395 case DOMAIN_SELECTION_SUBCOMMAND:
396 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700397 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
398 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700399 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
400 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700401 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
402 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700403 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
404 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800405 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
406 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +0000407 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
408 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800409 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
410 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700411 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
412 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000413 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
414 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800415 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
416 return handleSetSatelliteAccessControlOverlayConfigs();
417 case SET_COUNTRY_CODES:
418 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800419 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
420 return handleSetOemEnabledSatelliteProvisionStatus();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700421 default: {
422 return handleDefaultCommands(cmd);
423 }
424 }
425 }
426
427 @Override
428 public void onHelp() {
429 PrintWriter pw = getOutPrintWriter();
430 pw.println("Telephony Commands:");
431 pw.println(" help");
432 pw.println(" Print this help text.");
433 pw.println(" ims");
434 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800435 pw.println(" uce");
436 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800437 pw.println(" emergency-number-test-mode");
438 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700439 pw.println(" end-block-suppression");
440 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800441 pw.println(" data");
442 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100443 pw.println(" cc");
444 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700445 pw.println(" gba");
446 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000447 pw.println(" src");
448 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000449 pw.println(" restart-modem");
450 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000451 pw.println(" unattended-reboot");
452 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800453 pw.println(" has-carrier-privileges [package]");
454 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800455 pw.println(" get-allowed-network-types-for-users");
456 pw.println(" Get the Allowed Network Types.");
457 pw.println(" set-allowed-network-types-for-users");
458 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800459 pw.println(" radio");
460 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700461 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800462 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800463 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700464 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800465 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100466 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700467 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000468 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800469 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700470 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800471 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800472 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000473 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700474 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000475 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800476 }
477
478 private void onHelpD2D() {
479 PrintWriter pw = getOutPrintWriter();
480 pw.println("D2D Comms Commands:");
481 pw.println(" d2d send TYPE VALUE");
482 pw.println(" Sends a D2D message of specified type and value.");
483 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
484 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
485 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
486 MESSAGE_CALL_AUDIO_CODEC));
487 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
488 + Communicator.messageToString(
489 MESSAGE_DEVICE_BATTERY_STATE));
490 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
491 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800492 pw.println(" d2d transport TYPE");
493 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
494 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700495 pw.println(" d2d set-device-support true/default");
496 pw.println(" true - forces device support to be enabled for D2D.");
497 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
498 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700499 }
500
Nazanin014f41e2021-05-06 17:26:31 -0700501 private void onHelpBarring() {
502 PrintWriter pw = getOutPrintWriter();
503 pw.println("Barring Commands:");
504 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
505 + " -t CONDITIONAL_BARRING_TIME_SECS");
506 pw.println(" Notifies of a barring info change for the specified slot id.");
507 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
508 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
509 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
510 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
511 }
512
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700513 private void onHelpIms() {
514 PrintWriter pw = getOutPrintWriter();
515 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800516 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700517 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
518 pw.println(" ImsService. Options are:");
519 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
520 pw.println(" is specified, it will choose the default voice SIM slot.");
521 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
522 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800523 pw.println(" -f: Set the feature that this override if for, if no option is");
524 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700525 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
526 pw.println(" Gets the package name of the currently defined ImsService.");
527 pw.println(" Options are:");
528 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
529 pw.println(" is specified, it will choose the default voice SIM slot.");
530 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000531 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800532 pw.println(" -f: The feature type that the query will be requested for. If none is");
533 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800534 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
535 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
536 pw.println(" configuration overrides. Options are:");
537 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
538 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700539 pw.println(" ims enable [-s SLOT_ID]");
540 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
541 pw.println(" if none is specified.");
542 pw.println(" ims disable [-s SLOT_ID]");
543 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
544 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700545 pw.println(" ims conference-event-package [enable/disable]");
546 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700547 }
548
James.cf Linbcdf8b32021-01-14 16:44:13 +0800549 private void onHelpUce() {
550 PrintWriter pw = getOutPrintWriter();
551 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800552 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
553 pw.println(" Get the EAB contacts from the EAB database.");
554 pw.println(" Options are:");
555 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
556 pw.println(" Expected output format :");
557 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800558 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
559 pw.println(" Remove the EAB contacts from the EAB database.");
560 pw.println(" Options are:");
561 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
562 pw.println(" is specified, it will choose the default voice SIM slot.");
563 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800564 pw.println(" uce get-device-enabled");
565 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
566 pw.println(" uce set-device-enabled true|false");
567 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
568 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000569 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
570 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
571 pw.println(" Options are:");
572 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
573 pw.println(" is specified, it will choose the default voice SIM slot.");
574 pw.println(" add [CAPABILITY]: add a new capability");
575 pw.println(" remove [CAPABILITY]: remove a capability");
576 pw.println(" clear: clear all capability overrides");
577 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
578 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
579 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
580 pw.println(" chatbot_sa, chatbot_role] as well as full length");
581 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
582 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
583 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
584 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800585 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
586 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800587 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
588 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800589 }
590
Hall Liud892bec2018-11-30 14:51:45 -0800591 private void onHelpNumberVerification() {
592 PrintWriter pw = getOutPrintWriter();
593 pw.println("Number verification commands");
594 pw.println(" numverify override-package PACKAGE_NAME;");
595 pw.println(" Set the authorized package for number verification.");
596 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800597 pw.println(" numverify fake-call NUMBER;");
598 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
599 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800600 }
601
Jack Nudelman644b91a2021-03-12 14:09:48 -0800602 private void onHelpThermalMitigation() {
603 PrintWriter pw = getOutPrintWriter();
604 pw.println("Thermal mitigation commands");
605 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
606 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
607 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
608 pw.println(" Remove the package from one of the authorized packages for thermal "
609 + "mitigation.");
610 }
611
Jordan Liu0ccee222021-04-27 11:55:13 -0700612 private void onHelpDisableOrEnablePhysicalSubscription() {
613 PrintWriter pw = getOutPrintWriter();
614 pw.println("Disable or enable a physical subscription");
615 pw.println(" disable-physical-subscription SUB_ID");
616 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
617 pw.println(" enable-physical-subscription SUB_ID");
618 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
619 }
620
Shuo Qianf5125122019-12-16 17:03:07 -0800621 private void onHelpDataTestMode() {
622 PrintWriter pw = getOutPrintWriter();
623 pw.println("Mobile Data Test Mode Commands:");
624 pw.println(" data enable: enable mobile data connectivity");
625 pw.println(" data disable: disable mobile data connectivity");
626 }
627
sqian9d4df8b2019-01-15 18:32:07 -0800628 private void onHelpEmergencyNumber() {
629 PrintWriter pw = getOutPrintWriter();
630 pw.println("Emergency Number Test Mode Commands:");
631 pw.println(" emergency-number-test-mode ");
632 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
633 + " the test mode");
634 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700635 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800636 pw.println(" -c: clear the emergency number list in the test mode.");
637 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700638 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800639 pw.println(" -p: get the full emergency number list in the test mode.");
640 }
641
Shuo Qian489d9282020-07-09 11:30:03 -0700642 private void onHelpEndBlockSupperssion() {
643 PrintWriter pw = getOutPrintWriter();
644 pw.println("End Block Suppression command:");
645 pw.println(" end-block-suppression: disable suppressing blocking by contact");
646 pw.println(" with emergency services.");
647 }
648
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100649 private void onHelpCc() {
650 PrintWriter pw = getOutPrintWriter();
651 pw.println("Carrier Config Commands:");
652 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
653 pw.println(" Print carrier config values.");
654 pw.println(" Options are:");
655 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
656 pw.println(" is specified, it will choose the default voice SIM slot.");
657 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
658 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100659 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100660 pw.println(" Set carrier config KEY to NEW_VALUE.");
661 pw.println(" Options are:");
662 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
663 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100664 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100665 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
666 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
667 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
668 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000669 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
670 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
671 pw.println(" provided through standard input and follow CarrierConfig XML format.");
672 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
673 pw.println(" Options are:");
674 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
675 pw.println(" is specified, it will choose the default voice SIM slot.");
676 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100677 pw.println(" cc clear-values [-s SLOT_ID]");
678 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000679 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100680 pw.println(" Options are:");
681 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
682 pw.println(" is specified, it will choose the default voice SIM slot.");
683 }
684
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000685 private void onHelpEuicc() {
686 PrintWriter pw = getOutPrintWriter();
687 pw.println("Euicc Commands:");
688 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
689 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
690 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
691 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
692 }
693
Hui Wang641e81c2020-10-12 12:14:23 -0700694 private void onHelpGba() {
695 PrintWriter pw = getOutPrintWriter();
696 pw.println("Gba Commands:");
697 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
698 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
699 pw.println(" Options are:");
700 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
701 pw.println(" is specified, it will choose the default voice SIM slot.");
702 pw.println(" gba get-service [-s SLOT_ID]");
703 pw.println(" Gets the package name of the currently defined GbaService.");
704 pw.println(" Options are:");
705 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
706 pw.println(" is specified, it will choose the default voice SIM slot.");
707 pw.println(" gba set-release [-s SLOT_ID] n");
708 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
709 pw.println(" Do not release/unbind if n is -1.");
710 pw.println(" Options are:");
711 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
712 pw.println(" is specified, it will choose the default voice SIM slot.");
713 pw.println(" gba get-release [-s SLOT_ID]");
714 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
715 pw.println(" Options are:");
716 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
717 pw.println(" is specified, it will choose the default voice SIM slot.");
718 }
719
Hui Wang761a6682020-10-31 05:12:53 +0000720 private void onHelpSrc() {
721 PrintWriter pw = getOutPrintWriter();
722 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800723 pw.println(" src set-test-enabled true|false");
724 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
725 pw.println(" The value could be true, false, or null(undefined).");
726 pw.println(" src get-test-enabled");
727 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000728 pw.println(" src set-device-enabled true|false|null");
729 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
730 pw.println(" The value could be true, false, or null(undefined).");
731 pw.println(" src get-device-enabled");
732 pw.println(" Gets the device config for RCS VoLTE single registration.");
733 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
734 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
735 pw.println(" The value could be true, false, or null(undefined).");
736 pw.println(" Options are:");
737 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
738 pw.println(" is specified, it will choose the default voice SIM slot.");
739 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
740 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
741 pw.println(" Options are:");
742 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
743 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800744 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
745 pw.println(" Sets ims feature validation result.");
746 pw.println(" The value could be true, false, or null(undefined).");
747 pw.println(" Options are:");
748 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
749 pw.println(" is specified, it will choose the default voice SIM slot.");
750 pw.println(" src get-feature-validation [-s SLOT_ID]");
751 pw.println(" Gets ims feature validation override value.");
752 pw.println(" Options are:");
753 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
754 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000755 }
756
SongFerngWang98dd5992021-05-13 17:50:00 +0800757 private void onHelpAllowedNetworkTypes() {
758 PrintWriter pw = getOutPrintWriter();
759 pw.println("Allowed Network Types Commands:");
760 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
761 pw.println(" Print allowed network types value.");
762 pw.println(" Options are:");
763 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
764 pw.println(" option is specified, it will choose the default voice SIM slot.");
765 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
766 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
767 pw.println(" Options are:");
768 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
769 pw.println(" option is specified, it will choose the default voice SIM slot.");
770 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
771 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
772 pw.println(" at TelephonyManager.java");
773 pw.println(" For example:");
774 pw.println(" NR only : 10000000000000000000");
775 pw.println(" NR|LTE : 11000001000000000000");
776 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
777 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
778 pw.println(" LTE only : 01000001000000000000");
779 }
780
jimsun3b9ccac2021-10-26 15:01:23 +0800781 private void onHelpRadio() {
782 PrintWriter pw = getOutPrintWriter();
783 pw.println("Radio Commands:");
784 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
785 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
786 pw.println(" to be the bound. Options are:");
787 pw.println(" -s: the service name that the modem service should be bound for.");
788 pw.println(" If no option is specified, it will bind to the default.");
789 pw.println(" radio get-modem-service");
790 pw.println(" Gets the service name of the currently defined modem service.");
791 pw.println(" If it is binding to default, 'default' returns.");
792 pw.println(" If it doesn't bind to any modem service for some reasons,");
793 pw.println(" the result would be 'unknown'.");
794 }
795
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700796 private void onHelpSatellite() {
797 PrintWriter pw = getOutPrintWriter();
798 pw.println("Satellite Commands:");
799 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
800 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700801 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700802 pw.println(" -s: the satellite service package name that Telephony will bind to.");
803 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700804 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
805 pw.println(" Sets the package name of satellite gateway service defined in");
806 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
807 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
808 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700809 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
810 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
811 pw.println(" mode. Options are:");
812 pw.println(" -t: the timeout duration in milliseconds.");
813 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700814 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
815 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
816 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
817 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
818 pw.println(" launch. If no option is specified, it will launch the default.");
819 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
820 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700821 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
822 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
823 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
824 pw.println(" Options are:");
825 pw.println(" -t: the emergency call to satellite handover type.");
826 pw.println(" If no option is specified, override is disabled.");
827 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
828 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800829 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
830 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
831 pw.println(" configs of satellite access controller.");
832 pw.println(" Options are:");
833 pw.println(" -r: clear the overriding. Absent means enable overriding.");
834 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
835 pw.println(" -f: the satellite s2 file.");
836 pw.println(" -d: the location fresh duration nanos.");
837 pw.println(" -c: the list of satellite country codes separated by comma.");
838 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
839 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
840 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
841 pw.println(" Override the cached location country code and its update timestamp. ");
842 pw.println(" Options are:");
843 pw.println(" -r: clear the overriding. Absent means enable overriding.");
844 pw.println(" -n: the current network country code ISOs.");
845 pw.println(" -c: the cached network country code ISOs.");
846 pw.println(" -l: the location country code ISO.");
847 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800848 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
849 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
850 pw.println(" -p: the overriding satellite provision status. If no option is ");
851 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700852 }
853
Ling Ma4fbab492022-01-25 22:36:16 +0000854 private void onHelpImei() {
855 PrintWriter pw = getOutPrintWriter();
856 pw.println("IMEI Commands:");
857 pw.println(" get-imei [-s SLOT_ID]");
858 pw.println(" Gets the device IMEI. Options are:");
859 pw.println(" -s: the slot ID to get the IMEI. If no option");
860 pw.println(" is specified, it will choose the default voice SIM slot.");
861 }
862
Hunsuk Choi13078be2023-09-13 10:55:21 +0000863 private void onHelpDomainSelection() {
864 PrintWriter pw = getOutPrintWriter();
865 pw.println("Domain Selection Commands:");
866 pw.println(" domainselection set-dss-override COMPONENT_NAME");
867 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
868 pw.println(" domainselection clear-dss-override");
869 pw.println(" Clears DomainSelectionService override.");
870 }
871
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700872 private int handleImsCommand() {
873 String arg = getNextArg();
874 if (arg == null) {
875 onHelpIms();
876 return 0;
877 }
878
879 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800880 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700881 return handleImsSetServiceCommand();
882 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800883 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700884 return handleImsGetServiceCommand();
885 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800886 case IMS_CLEAR_SERVICE_OVERRIDE: {
887 return handleImsClearCarrierServiceCommand();
888 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800889 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700890 return handleEnableIms();
891 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800892 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700893 return handleDisableIms();
894 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700895 case IMS_CEP: {
896 return handleCepChange();
897 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700898 }
899
900 return -1;
901 }
902
Shuo Qianf5125122019-12-16 17:03:07 -0800903 private int handleDataTestModeCommand() {
904 PrintWriter errPw = getErrPrintWriter();
905 String arg = getNextArgRequired();
906 if (arg == null) {
907 onHelpDataTestMode();
908 return 0;
909 }
910 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800911 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800912 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700913 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800914 } catch (RemoteException ex) {
915 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
916 errPw.println("Exception: " + ex.getMessage());
917 return -1;
918 }
919 break;
920 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800921 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800922 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700923 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800924 } catch (RemoteException ex) {
925 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
926 errPw.println("Exception: " + ex.getMessage());
927 return -1;
928 }
929 break;
930 }
931 default:
932 onHelpDataTestMode();
933 break;
934 }
935 return 0;
936 }
937
Shuo Qianccbaf742021-02-22 18:32:21 -0800938 private int handleEmergencyCallbackModeCommand() {
939 PrintWriter errPw = getErrPrintWriter();
940 try {
941 mInterface.startEmergencyCallbackMode();
942 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
943 } catch (RemoteException ex) {
944 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
945 errPw.println("Exception: " + ex.getMessage());
946 return -1;
947 }
948 return 0;
949 }
950
Grant Menke567d48f2022-08-18 20:19:10 +0000951 private void removeEmergencyNumberTestMode(String emergencyNumber) {
952 PrintWriter errPw = getErrPrintWriter();
953 for (int routingType : ROUTING_TYPES) {
954 try {
955 mInterface.updateEmergencyNumberListTestMode(
956 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
957 new EmergencyNumber(emergencyNumber, "", "",
958 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
959 new ArrayList<String>(),
960 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
961 routingType));
962 } catch (RemoteException ex) {
963 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
964 errPw.println("Exception: " + ex.getMessage());
965 }
966 }
967 }
968
sqian9d4df8b2019-01-15 18:32:07 -0800969 private int handleEmergencyNumberTestModeCommand() {
970 PrintWriter errPw = getErrPrintWriter();
971 String opt = getNextOption();
972 if (opt == null) {
973 onHelpEmergencyNumber();
974 return 0;
975 }
sqian9d4df8b2019-01-15 18:32:07 -0800976 switch (opt) {
977 case "-a": {
978 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000979 if (emergencyNumberCmd == null){
980 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800981 return -1;
982 }
Grant Menke567d48f2022-08-18 20:19:10 +0000983 String[] params = emergencyNumberCmd.split(":");
984 String emergencyNumber;
985 if (params[0] == null ||
986 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
987 errPw.println(INVALID_ENTRY_ERROR);
988 return -1;
989 } else {
990 emergencyNumber = params[0];
991 }
992 removeEmergencyNumberTestMode(emergencyNumber);
993 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
994 if (params.length > 1) {
995 switch (params[1].toLowerCase(Locale.ROOT)) {
996 case "emergency":
997 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
998 break;
999 case "normal":
1000 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1001 break;
1002 case "unknown":
1003 break;
1004 default:
1005 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1006 + "emergency call routing. Please enter either \"normal\", "
1007 + "\"unknown\", or \"emergency\" for call routing. "
1008 + "(-a 1234:normal)");
1009 return -1;
1010 }
1011 }
sqian9d4df8b2019-01-15 18:32:07 -08001012 try {
1013 mInterface.updateEmergencyNumberListTestMode(
1014 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001015 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001016 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1017 new ArrayList<String>(),
1018 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001019 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001020 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001021 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001022 + ", error " + ex.getMessage());
1023 errPw.println("Exception: " + ex.getMessage());
1024 return -1;
1025 }
1026 break;
1027 }
1028 case "-c": {
1029 try {
1030 mInterface.updateEmergencyNumberListTestMode(
1031 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1032 } catch (RemoteException ex) {
1033 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1034 errPw.println("Exception: " + ex.getMessage());
1035 return -1;
1036 }
1037 break;
1038 }
1039 case "-r": {
1040 String emergencyNumberCmd = getNextArgRequired();
1041 if (emergencyNumberCmd == null
1042 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001043 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001044 + " to be specified after -r in the command ");
1045 return -1;
1046 }
Grant Menke567d48f2022-08-18 20:19:10 +00001047 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001048 break;
1049 }
1050 case "-p": {
1051 try {
1052 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1053 } catch (RemoteException ex) {
1054 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1055 errPw.println("Exception: " + ex.getMessage());
1056 return -1;
1057 }
1058 break;
1059 }
1060 default:
1061 onHelpEmergencyNumber();
1062 break;
1063 }
1064 return 0;
1065 }
1066
Hall Liud892bec2018-11-30 14:51:45 -08001067 private int handleNumberVerificationCommand() {
1068 String arg = getNextArg();
1069 if (arg == null) {
1070 onHelpNumberVerification();
1071 return 0;
1072 }
1073
Hall Liuca5af3a2018-12-04 16:58:23 -08001074 if (!checkShellUid()) {
1075 return -1;
1076 }
1077
Hall Liud892bec2018-11-30 14:51:45 -08001078 switch (arg) {
1079 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001080 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1081 return 0;
1082 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001083 case NUMBER_VERIFICATION_FAKE_CALL: {
1084 boolean val = NumberVerificationManager.getInstance()
1085 .checkIncomingCall(getNextArg());
1086 getOutPrintWriter().println(val ? "1" : "0");
1087 return 0;
1088 }
Hall Liud892bec2018-11-30 14:51:45 -08001089 }
1090
1091 return -1;
1092 }
1093
Jordan Liu0ccee222021-04-27 11:55:13 -07001094 private boolean subIsEsim(int subId) {
1095 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1096 if (info != null) {
1097 return info.isEmbedded();
1098 }
1099 return false;
1100 }
1101
1102 private int handleEnablePhysicalSubscription(boolean enable) {
1103 PrintWriter errPw = getErrPrintWriter();
1104 int subId = 0;
1105 try {
1106 subId = Integer.parseInt(getNextArgRequired());
1107 } catch (NumberFormatException e) {
1108 errPw.println((enable ? "enable" : "disable")
1109 + "-physical-subscription requires an integer as a subId.");
1110 return -1;
1111 }
1112 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1113 // non user build.
1114 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1115 errPw.println("cc: Permission denied.");
1116 return -1;
1117 }
1118 // Verify that the subId represents a physical sub
1119 if (subIsEsim(subId)) {
1120 errPw.println("SubId " + subId + " is not for a physical subscription");
1121 return -1;
1122 }
1123 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1124 + " physical subscription with subId=" + subId);
1125 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1126 return 0;
1127 }
1128
Jack Nudelman644b91a2021-03-12 14:09:48 -08001129 private int handleThermalMitigationCommand() {
1130 String arg = getNextArg();
1131 String packageName = getNextArg();
1132 if (arg == null || packageName == null) {
1133 onHelpThermalMitigation();
1134 return 0;
1135 }
1136
1137 if (!checkShellUid()) {
1138 return -1;
1139 }
1140
1141 switch (arg) {
1142 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1143 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1144 return 0;
1145 }
1146 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1147 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1148 mContext);
1149 return 0;
1150 }
1151 default:
1152 onHelpThermalMitigation();
1153 }
1154
1155 return -1;
1156
1157 }
1158
Tyler Gunn92479152021-01-20 16:30:10 -08001159 private int handleD2dCommand() {
1160 String arg = getNextArg();
1161 if (arg == null) {
1162 onHelpD2D();
1163 return 0;
1164 }
1165
1166 switch (arg) {
1167 case D2D_SEND: {
1168 return handleD2dSendCommand();
1169 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001170 case D2D_TRANSPORT: {
1171 return handleD2dTransportCommand();
1172 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001173 case D2D_SET_DEVICE_SUPPORT: {
1174 return handleD2dDeviceSupportedCommand();
1175 }
Tyler Gunn92479152021-01-20 16:30:10 -08001176 }
1177
1178 return -1;
1179 }
1180
1181 private int handleD2dSendCommand() {
1182 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001183 int messageType = -1;
1184 int messageValue = -1;
1185
Tyler Gunn92479152021-01-20 16:30:10 -08001186 String arg = getNextArg();
1187 if (arg == null) {
1188 onHelpD2D();
1189 return 0;
1190 }
1191 try {
1192 messageType = Integer.parseInt(arg);
1193 } catch (NumberFormatException e) {
1194 errPw.println("message type must be a valid integer");
1195 return -1;
1196 }
1197
1198 arg = getNextArg();
1199 if (arg == null) {
1200 onHelpD2D();
1201 return 0;
1202 }
1203 try {
1204 messageValue = Integer.parseInt(arg);
1205 } catch (NumberFormatException e) {
1206 errPw.println("message value must be a valid integer");
1207 return -1;
1208 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001209
Tyler Gunn92479152021-01-20 16:30:10 -08001210 try {
1211 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1212 } catch (RemoteException e) {
1213 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1214 errPw.println("Exception: " + e.getMessage());
1215 return -1;
1216 }
1217
1218 return 0;
1219 }
1220
Tyler Gunnbabbda02021-02-10 11:05:02 -08001221 private int handleD2dTransportCommand() {
1222 PrintWriter errPw = getErrPrintWriter();
1223
1224 String arg = getNextArg();
1225 if (arg == null) {
1226 onHelpD2D();
1227 return 0;
1228 }
1229
1230 try {
1231 mInterface.setActiveDeviceToDeviceTransport(arg);
1232 } catch (RemoteException e) {
1233 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1234 errPw.println("Exception: " + e.getMessage());
1235 return -1;
1236 }
1237 return 0;
1238 }
Nazanin014f41e2021-05-06 17:26:31 -07001239 private int handleBarringCommand() {
1240 String arg = getNextArg();
1241 if (arg == null) {
1242 onHelpBarring();
1243 return 0;
1244 }
1245
1246 switch (arg) {
1247 case BARRING_SEND_INFO: {
1248 return handleBarringSendCommand();
1249 }
1250 }
1251 return -1;
1252 }
1253
1254 private int handleBarringSendCommand() {
1255 PrintWriter errPw = getErrPrintWriter();
1256 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001257 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001258 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1259 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1260 boolean isConditionallyBarred = false;
1261 int conditionalBarringTimeSeconds = 0;
1262
1263 String opt;
1264 while ((opt = getNextOption()) != null) {
1265 switch (opt) {
1266 case "-s": {
1267 try {
1268 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001269 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001270 } catch (NumberFormatException e) {
1271 errPw.println("barring send requires an integer as a SLOT_ID.");
1272 return -1;
1273 }
1274 break;
1275 }
1276 case "-b": {
1277 try {
1278 barringType = Integer.parseInt(getNextArgRequired());
1279 if (barringType < -1 || barringType > 2) {
1280 throw new NumberFormatException();
1281 }
1282
1283 } catch (NumberFormatException e) {
1284 errPw.println("barring send requires an integer in range [-1,2] as "
1285 + "a BARRING_TYPE.");
1286 return -1;
1287 }
1288 break;
1289 }
1290 case "-c": {
1291 try {
1292 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1293 } catch (Exception e) {
1294 errPw.println("barring send requires a boolean after -c indicating"
1295 + " conditional barring");
1296 return -1;
1297 }
1298 break;
1299 }
1300 case "-t": {
1301 try {
1302 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1303 } catch (NumberFormatException e) {
1304 errPw.println("barring send requires an integer for time of barring"
1305 + " in seconds after -t for conditional barring");
1306 return -1;
1307 }
1308 break;
1309 }
1310 }
1311 }
1312 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1313 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1314 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1315 barringServiceInfos.append(0, bsi);
1316 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1317 try {
1318 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1319 } catch (Exception e) {
1320 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1321 errPw.println("Exception: " + e.getMessage());
1322 return -1;
1323 }
1324 return 0;
1325 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001326
Tyler Gunnd4575212021-05-03 14:46:49 -07001327 private int handleD2dDeviceSupportedCommand() {
1328 PrintWriter errPw = getErrPrintWriter();
1329
1330 String arg = getNextArg();
1331 if (arg == null) {
1332 onHelpD2D();
1333 return 0;
1334 }
1335
Jack Yua533d632022-09-30 13:53:46 -07001336 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001337 try {
1338 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1339 } catch (RemoteException e) {
1340 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1341 errPw.println("Exception: " + e.getMessage());
1342 return -1;
1343 }
1344 return 0;
1345 }
1346
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 // ims set-ims-service
1348 private int handleImsSetServiceCommand() {
1349 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001350 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001351 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001352 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001353
1354 String opt;
1355 while ((opt = getNextOption()) != null) {
1356 switch (opt) {
1357 case "-s": {
1358 try {
1359 slotId = Integer.parseInt(getNextArgRequired());
1360 } catch (NumberFormatException e) {
1361 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1362 return -1;
1363 }
1364 break;
1365 }
1366 case "-c": {
1367 isCarrierService = true;
1368 break;
1369 }
1370 case "-d": {
1371 isCarrierService = false;
1372 break;
1373 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001374 case "-f": {
1375 String featureString = getNextArgRequired();
1376 String[] features = featureString.split(",");
1377 for (int i = 0; i < features.length; i++) {
1378 try {
1379 Integer result = Integer.parseInt(features[i]);
1380 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1381 || result >= ImsFeature.FEATURE_MAX) {
1382 errPw.println("ims set-ims-service -f " + result
1383 + " is an invalid feature.");
1384 return -1;
1385 }
1386 featuresList.add(result);
1387 } catch (NumberFormatException e) {
1388 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1389 + " as an integer.");
1390 return -1;
1391 }
1392 }
1393 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001394 }
1395 }
1396 // Mandatory param, either -c or -d
1397 if (isCarrierService == null) {
1398 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1399 return -1;
1400 }
1401
1402 String packageName = getNextArg();
1403
1404 try {
1405 if (packageName == null) {
1406 packageName = "";
1407 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001408 int[] featureArray = new int[featuresList.size()];
1409 for (int i = 0; i < featuresList.size(); i++) {
1410 featureArray[i] = featuresList.get(i);
1411 }
1412 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1413 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001414 if (VDBG) {
1415 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001416 + (isCarrierService ? "-c " : "-d ")
1417 + "-f " + featuresList + " "
1418 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001419 }
1420 getOutPrintWriter().println(result);
1421 } catch (RemoteException e) {
1422 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001423 + (isCarrierService ? "-c " : "-d ")
1424 + "-f " + featuresList + " "
1425 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001426 errPw.println("Exception: " + e.getMessage());
1427 return -1;
1428 }
1429 return 0;
1430 }
1431
Brad Ebinger999d3302020-11-25 14:31:39 -08001432 // ims clear-ims-service-override
1433 private int handleImsClearCarrierServiceCommand() {
1434 PrintWriter errPw = getErrPrintWriter();
1435 int slotId = getDefaultSlot();
1436
1437 String opt;
1438 while ((opt = getNextOption()) != null) {
1439 switch (opt) {
1440 case "-s": {
1441 try {
1442 slotId = Integer.parseInt(getNextArgRequired());
1443 } catch (NumberFormatException e) {
1444 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1445 return -1;
1446 }
1447 break;
1448 }
1449 }
1450 }
1451
1452 try {
1453 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1454 if (VDBG) {
1455 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1456 + ", result=" + result);
1457 }
1458 getOutPrintWriter().println(result);
1459 } catch (RemoteException e) {
1460 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1461 + ", error" + e.getMessage());
1462 errPw.println("Exception: " + e.getMessage());
1463 return -1;
1464 }
1465 return 0;
1466 }
1467
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001468 // ims get-ims-service
1469 private int handleImsGetServiceCommand() {
1470 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001471 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001472 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001473 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001474
1475 String opt;
1476 while ((opt = getNextOption()) != null) {
1477 switch (opt) {
1478 case "-s": {
1479 try {
1480 slotId = Integer.parseInt(getNextArgRequired());
1481 } catch (NumberFormatException e) {
1482 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1483 return -1;
1484 }
1485 break;
1486 }
1487 case "-c": {
1488 isCarrierService = true;
1489 break;
1490 }
1491 case "-d": {
1492 isCarrierService = false;
1493 break;
1494 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001495 case "-f": {
1496 try {
1497 featureType = Integer.parseInt(getNextArg());
1498 } catch (NumberFormatException e) {
1499 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1500 return -1;
1501 }
1502 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1503 || featureType >= ImsFeature.FEATURE_MAX) {
1504 errPw.println("ims get-ims-service -f invalid feature.");
1505 return -1;
1506 }
1507 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001508 }
1509 }
1510 // Mandatory param, either -c or -d
1511 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001512 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001513 return -1;
1514 }
1515
1516 String result;
1517 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001518 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001519 } catch (RemoteException e) {
1520 return -1;
1521 }
1522 if (VDBG) {
1523 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001524 + (isCarrierService ? "-c " : "-d ")
1525 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1526 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001527 }
1528 getOutPrintWriter().println(result);
1529 return 0;
1530 }
1531
1532 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001533 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001534 String opt;
1535 while ((opt = getNextOption()) != null) {
1536 switch (opt) {
1537 case "-s": {
1538 try {
1539 slotId = Integer.parseInt(getNextArgRequired());
1540 } catch (NumberFormatException e) {
1541 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1542 return -1;
1543 }
1544 break;
1545 }
1546 }
1547 }
1548 try {
1549 mInterface.enableIms(slotId);
1550 } catch (RemoteException e) {
1551 return -1;
1552 }
1553 if (VDBG) {
1554 Log.v(LOG_TAG, "ims enable -s " + slotId);
1555 }
1556 return 0;
1557 }
1558
1559 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001560 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001561 String opt;
1562 while ((opt = getNextOption()) != null) {
1563 switch (opt) {
1564 case "-s": {
1565 try {
1566 slotId = Integer.parseInt(getNextArgRequired());
1567 } catch (NumberFormatException e) {
1568 getErrPrintWriter().println(
1569 "ims disable requires an integer as a SLOT_ID.");
1570 return -1;
1571 }
1572 break;
1573 }
1574 }
1575 }
1576 try {
1577 mInterface.disableIms(slotId);
1578 } catch (RemoteException e) {
1579 return -1;
1580 }
1581 if (VDBG) {
1582 Log.v(LOG_TAG, "ims disable -s " + slotId);
1583 }
1584 return 0;
1585 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001586
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001587 private int handleCepChange() {
1588 Log.i(LOG_TAG, "handleCepChange");
1589 String opt = getNextArg();
1590 if (opt == null) {
1591 return -1;
1592 }
1593 boolean isCepEnabled = opt.equals("enable");
1594
1595 try {
1596 mInterface.setCepEnabled(isCepEnabled);
1597 } catch (RemoteException e) {
1598 return -1;
1599 }
1600 return 0;
1601 }
1602
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001603 private int getDefaultSlot() {
1604 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1605 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1606 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1607 // If there is no default, default to slot 0.
1608 slotId = DEFAULT_PHONE_ID;
1609 }
1610 return slotId;
1611 }
sqian2fff4a32018-11-05 14:18:37 -08001612
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001613 // Parse options related to Carrier Config Commands.
1614 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001615 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001616 CcOptionParseResult result = new CcOptionParseResult();
1617 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1618 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001619
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001620 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001621 while ((opt = getNextOption()) != null) {
1622 switch (opt) {
1623 case "-s": {
1624 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001625 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1626 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1627 errPw.println(tag + "No valid subscription found.");
1628 return null;
1629 }
1630
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001631 } catch (IllegalArgumentException e) {
1632 // Missing slot id
1633 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 return null;
1635 }
1636 break;
1637 }
1638 case "-p": {
1639 if (allowOptionPersistent) {
1640 result.mPersistent = true;
1641 } else {
1642 errPw.println(tag + "Unexpected option " + opt);
1643 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001644 }
1645 break;
1646 }
1647 default: {
1648 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001649 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001650 }
1651 }
1652 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001653 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001654 }
1655
1656 private int slotStringToSubId(String tag, String slotString) {
1657 int slotId = -1;
1658 try {
1659 slotId = Integer.parseInt(slotString);
1660 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001661 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1662 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1663 }
1664
1665 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001666 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1667 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1668 }
1669
Qiong Liuf25799b2020-09-10 10:13:46 +08001670 Phone phone = PhoneFactory.getPhone(slotId);
1671 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001672 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1673 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1674 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001675 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001676 }
1677
Hall Liud892bec2018-11-30 14:51:45 -08001678 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001679 // adb can run as root or as shell, depending on whether the device is rooted.
1680 return Binder.getCallingUid() == Process.SHELL_UID
1681 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001682 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001683
1684 private int handleCcCommand() {
1685 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1686 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001687 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001688 getErrPrintWriter().println("cc: Permission denied.");
1689 return -1;
1690 }
1691
1692 String arg = getNextArg();
1693 if (arg == null) {
1694 onHelpCc();
1695 return 0;
1696 }
1697
1698 switch (arg) {
1699 case CC_GET_VALUE: {
1700 return handleCcGetValue();
1701 }
1702 case CC_SET_VALUE: {
1703 return handleCcSetValue();
1704 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001705 case CC_SET_VALUES_FROM_XML: {
1706 return handleCcSetValuesFromXml();
1707 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001708 case CC_CLEAR_VALUES: {
1709 return handleCcClearValues();
1710 }
1711 default: {
1712 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1713 }
1714 }
1715 return -1;
1716 }
1717
1718 // cc get-value
1719 private int handleCcGetValue() {
1720 PrintWriter errPw = getErrPrintWriter();
1721 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1722 String key = null;
1723
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001724 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001725 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001726 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001727 return -1;
1728 }
1729
1730 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001731 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001732 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001733 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001734 return -1;
1735 }
1736
1737 // Get the key.
1738 key = getNextArg();
1739 if (key != null) {
1740 // A key was provided. Verify if it is a valid key
1741 if (!bundle.containsKey(key)) {
1742 errPw.println(tag + key + " is not a valid key.");
1743 return -1;
1744 }
1745
1746 // Print the carrier config value for key.
1747 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1748 } else {
1749 // No key provided. Show all values.
1750 // Iterate over a sorted list of all carrier config keys and print them.
1751 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1752 for (String k : sortedSet) {
1753 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1754 }
1755 }
1756 return 0;
1757 }
1758
1759 // cc set-value
1760 private int handleCcSetValue() {
1761 PrintWriter errPw = getErrPrintWriter();
1762 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1763
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001764 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001765 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001766 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001767 return -1;
1768 }
1769
1770 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001771 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001772 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001773 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001774 return -1;
1775 }
1776
1777 // Get the key.
1778 String key = getNextArg();
1779 if (key == null || key.equals("")) {
1780 errPw.println(tag + "KEY is missing");
1781 return -1;
1782 }
1783
1784 // Verify if the key is valid
1785 if (!originalValues.containsKey(key)) {
1786 errPw.println(tag + key + " is not a valid key.");
1787 return -1;
1788 }
1789
1790 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1791 ArrayList<String> valueList = new ArrayList<String>();
1792 while (peekNextArg() != null) {
1793 valueList.add(getNextArg());
1794 }
1795
1796 // Find the type of the carrier config value
1797 CcType type = getType(tag, key, originalValues);
1798 if (type == CcType.UNKNOWN) {
1799 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1800 return -1;
1801 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001802 if (type == CcType.PERSISTABLE_BUNDLE) {
1803 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1804 + "Use set-values-from-xml instead.");
1805 return -1;
1806 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001807
1808 // Create an override bundle containing the key and value that should be overriden.
1809 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1810 if (overrideBundle == null) {
1811 return -1;
1812 }
1813
1814 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001815 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001816
1817 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001818 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001819 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001820 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001821 return -1;
1822 }
1823
1824 // Print the original and new value.
1825 String originalValueString = ccValueToString(key, type, originalValues);
1826 String newValueString = ccValueToString(key, type, newValues);
1827 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1828 getOutPrintWriter().println("New value: \n" + newValueString);
1829
1830 return 0;
1831 }
1832
Allen Xuee00f0e2022-03-14 21:04:49 +00001833 // cc set-values-from-xml
1834 private int handleCcSetValuesFromXml() {
1835 PrintWriter errPw = getErrPrintWriter();
1836 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1837
1838 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001839 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001840 if (options == null) {
1841 return -1;
1842 }
1843
1844 // Get bundle containing all current carrier configuration values.
1845 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1846 if (originalValues == null) {
1847 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1848 return -1;
1849 }
1850
1851 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1852 if (overrideBundle == null) {
1853 return -1;
1854 }
1855
1856 // Verify all values are valid types
1857 for (String key : overrideBundle.keySet()) {
1858 CcType type = getType(tag, key, originalValues);
1859 if (type == CcType.UNKNOWN) {
1860 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1861 return -1;
1862 }
1863 }
1864
1865 // Override the value
1866 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1867
1868 // Find bundle containing all new carrier configuration values after the override.
1869 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1870 if (newValues == null) {
1871 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1872 return -1;
1873 }
1874
1875 // Print the original and new values
1876 overrideBundle.keySet().forEach(key -> {
1877 CcType type = getType(tag, key, originalValues);
1878 String originalValueString = ccValueToString(key, type, originalValues);
1879 String newValueString = ccValueToString(key, type, newValues);
1880 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1881 getOutPrintWriter().println("New value: \n" + newValueString);
1882 });
1883
1884 return 0;
1885 }
1886
1887 private PersistableBundle readPersistableBundleFromXml(String tag) {
1888 PersistableBundle subIdBundles;
1889 try {
1890 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1891 } catch (IOException | RuntimeException e) {
1892 PrintWriter errPw = getErrPrintWriter();
1893 errPw.println(tag + e);
1894 return null;
1895 }
1896
1897 return subIdBundles;
1898 }
1899
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001900 // cc clear-values
1901 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001902 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1903
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001904 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001905 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001906 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001907 return -1;
1908 }
1909
1910 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001911 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001912 getOutPrintWriter()
1913 .println("All previously set carrier config override values has been cleared");
1914 return 0;
1915 }
1916
1917 private CcType getType(String tag, String key, PersistableBundle bundle) {
1918 // Find the type by checking the type of the current value stored in the bundle.
1919 Object value = bundle.get(key);
1920
1921 if (CC_TYPE_MAP.containsKey(key)) {
1922 return CC_TYPE_MAP.get(key);
1923 } else if (value != null) {
1924 if (value instanceof Boolean) {
1925 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001926 }
1927 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001928 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001929 }
1930 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001931 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001932 }
1933 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001934 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001935 }
1936 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001937 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001938 }
1939 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001940 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001941 }
1942 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001943 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001944 }
1945 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001946 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001947 }
1948 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001949 return CcType.STRING_ARRAY;
1950 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001951 if (value instanceof PersistableBundle) {
1952 return CcType.PERSISTABLE_BUNDLE;
1953 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001954 } else {
1955 // Current value was null and can therefore not be used in order to find the type.
1956 // Check the name of the key to infer the type. This check is not needed for primitive
1957 // data types (boolean, double, int and long), since they can not be null.
1958 if (key.endsWith("double_array")) {
1959 return CcType.DOUBLE_ARRAY;
1960 }
1961 if (key.endsWith("int_array")) {
1962 return CcType.INT_ARRAY;
1963 }
1964 if (key.endsWith("long_array")) {
1965 return CcType.LONG_ARRAY;
1966 }
1967 if (key.endsWith("string")) {
1968 return CcType.STRING;
1969 }
1970 if (key.endsWith("string_array") || key.endsWith("strings")) {
1971 return CcType.STRING_ARRAY;
1972 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001973 if (key.endsWith("bundle")) {
1974 return CcType.PERSISTABLE_BUNDLE;
1975 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001976 }
1977
1978 // Not possible to infer the type by looking at the current value or the key.
1979 PrintWriter errPw = getErrPrintWriter();
1980 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1981 return CcType.UNKNOWN;
1982 }
1983
1984 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1985 String result;
1986 StringBuilder valueString = new StringBuilder();
1987 String typeString = type.toString();
1988 Object value = bundle.get(key);
1989
1990 if (value == null) {
1991 valueString.append("null");
1992 } else {
1993 switch (type) {
1994 case DOUBLE_ARRAY: {
1995 // Format the string representation of the int array as value1 value2......
1996 double[] valueArray = (double[]) value;
1997 for (int i = 0; i < valueArray.length; i++) {
1998 if (i != 0) {
1999 valueString.append(" ");
2000 }
2001 valueString.append(valueArray[i]);
2002 }
2003 break;
2004 }
2005 case INT_ARRAY: {
2006 // Format the string representation of the int array as value1 value2......
2007 int[] valueArray = (int[]) value;
2008 for (int i = 0; i < valueArray.length; i++) {
2009 if (i != 0) {
2010 valueString.append(" ");
2011 }
2012 valueString.append(valueArray[i]);
2013 }
2014 break;
2015 }
2016 case LONG_ARRAY: {
2017 // Format the string representation of the int array as value1 value2......
2018 long[] valueArray = (long[]) value;
2019 for (int i = 0; i < valueArray.length; i++) {
2020 if (i != 0) {
2021 valueString.append(" ");
2022 }
2023 valueString.append(valueArray[i]);
2024 }
2025 break;
2026 }
2027 case STRING: {
2028 valueString.append("\"" + value.toString() + "\"");
2029 break;
2030 }
2031 case STRING_ARRAY: {
2032 // Format the string representation of the string array as "value1" "value2"....
2033 String[] valueArray = (String[]) value;
2034 for (int i = 0; i < valueArray.length; i++) {
2035 if (i != 0) {
2036 valueString.append(" ");
2037 }
2038 if (valueArray[i] != null) {
2039 valueString.append("\"" + valueArray[i] + "\"");
2040 } else {
2041 valueString.append("null");
2042 }
2043 }
2044 break;
2045 }
2046 default: {
2047 valueString.append(value.toString());
2048 }
2049 }
2050 }
2051 return String.format("%-70s %-15s %s", key, typeString, valueString);
2052 }
2053
2054 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2055 ArrayList<String> valueList) {
2056 PrintWriter errPw = getErrPrintWriter();
2057 PersistableBundle bundle = new PersistableBundle();
2058
2059 // First verify that a valid number of values has been provided for the type.
2060 switch (type) {
2061 case BOOLEAN:
2062 case DOUBLE:
2063 case INT:
2064 case LONG: {
2065 if (valueList.size() != 1) {
2066 errPw.println(tag + "Expected 1 value for type " + type
2067 + ". Found: " + valueList.size());
2068 return null;
2069 }
2070 break;
2071 }
2072 case STRING: {
2073 if (valueList.size() > 1) {
2074 errPw.println(tag + "Expected 0 or 1 values for type " + type
2075 + ". Found: " + valueList.size());
2076 return null;
2077 }
2078 break;
2079 }
2080 }
2081
2082 // Parse the value according to type and add it to the Bundle.
2083 switch (type) {
2084 case BOOLEAN: {
2085 if ("true".equalsIgnoreCase(valueList.get(0))) {
2086 bundle.putBoolean(key, true);
2087 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2088 bundle.putBoolean(key, false);
2089 } else {
2090 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2091 return null;
2092 }
2093 break;
2094 }
2095 case DOUBLE: {
2096 try {
2097 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2098 } catch (NumberFormatException nfe) {
2099 // Not a valid double
2100 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2101 return null;
2102 }
2103 break;
2104 }
2105 case DOUBLE_ARRAY: {
2106 double[] valueDoubleArray = null;
2107 if (valueList.size() > 0) {
2108 valueDoubleArray = new double[valueList.size()];
2109 for (int i = 0; i < valueList.size(); i++) {
2110 try {
2111 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2112 } catch (NumberFormatException nfe) {
2113 // Not a valid double
2114 errPw.println(
2115 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2116 return null;
2117 }
2118 }
2119 }
2120 bundle.putDoubleArray(key, valueDoubleArray);
2121 break;
2122 }
2123 case INT: {
2124 try {
2125 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2126 } catch (NumberFormatException nfe) {
2127 // Not a valid integer
2128 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2129 return null;
2130 }
2131 break;
2132 }
2133 case INT_ARRAY: {
2134 int[] valueIntArray = null;
2135 if (valueList.size() > 0) {
2136 valueIntArray = new int[valueList.size()];
2137 for (int i = 0; i < valueList.size(); i++) {
2138 try {
2139 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2140 } catch (NumberFormatException nfe) {
2141 // Not a valid integer
2142 errPw.println(tag
2143 + "Unable to parse " + valueList.get(i) + " as an integer.");
2144 return null;
2145 }
2146 }
2147 }
2148 bundle.putIntArray(key, valueIntArray);
2149 break;
2150 }
2151 case LONG: {
2152 try {
2153 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2154 } catch (NumberFormatException nfe) {
2155 // Not a valid long
2156 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2157 return null;
2158 }
2159 break;
2160 }
2161 case LONG_ARRAY: {
2162 long[] valueLongArray = null;
2163 if (valueList.size() > 0) {
2164 valueLongArray = new long[valueList.size()];
2165 for (int i = 0; i < valueList.size(); i++) {
2166 try {
2167 valueLongArray[i] = Long.parseLong(valueList.get(i));
2168 } catch (NumberFormatException nfe) {
2169 // Not a valid long
2170 errPw.println(
2171 tag + "Unable to parse " + valueList.get(i) + " as a long");
2172 return null;
2173 }
2174 }
2175 }
2176 bundle.putLongArray(key, valueLongArray);
2177 break;
2178 }
2179 case STRING: {
2180 String value = null;
2181 if (valueList.size() > 0) {
2182 value = valueList.get(0);
2183 }
2184 bundle.putString(key, value);
2185 break;
2186 }
2187 case STRING_ARRAY: {
2188 String[] valueStringArray = null;
2189 if (valueList.size() > 0) {
2190 valueStringArray = new String[valueList.size()];
2191 valueList.toArray(valueStringArray);
2192 }
2193 bundle.putStringArray(key, valueStringArray);
2194 break;
2195 }
2196 }
2197 return bundle;
2198 }
Shuo Qian489d9282020-07-09 11:30:03 -07002199
2200 private int handleEndBlockSuppressionCommand() {
2201 if (!checkShellUid()) {
2202 return -1;
2203 }
2204
2205 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2206 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2207 }
2208 return 0;
2209 }
Hui Wang641e81c2020-10-12 12:14:23 -07002210
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002211 private int handleEuiccCommand() {
2212 String arg = getNextArg();
2213 if (arg == null) {
2214 onHelpEuicc();
2215 return 0;
2216 }
2217
2218 switch (arg) {
2219 case EUICC_SET_UI_COMPONENT: {
2220 return handleEuiccServiceCommand();
2221 }
2222 }
2223 return -1;
2224 }
2225
2226 private int handleEuiccServiceCommand() {
2227 String uiComponent = getNextArg();
2228 String packageName = getNextArg();
2229 if (packageName == null || uiComponent == null) {
2230 return -1;
2231 }
2232 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2233 if (VDBG) {
2234 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2235 + packageName);
2236 }
2237 return 0;
2238 }
2239
Michele Berionne54af4632020-12-28 20:23:16 +00002240 private int handleRestartModemCommand() {
2241 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2242 // non user build.
2243 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2244 getErrPrintWriter().println("RestartModem: Permission denied.");
2245 return -1;
2246 }
2247
2248 boolean result = TelephonyManager.getDefault().rebootRadio();
2249 getOutPrintWriter().println(result);
2250
2251 return result ? 0 : -1;
2252 }
2253
Ling Ma4fbab492022-01-25 22:36:16 +00002254 private int handleGetImei() {
2255 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2256 // non user build.
2257 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2258 getErrPrintWriter().println("Device IMEI: Permission denied.");
2259 return -1;
2260 }
2261
2262 final long identity = Binder.clearCallingIdentity();
2263
2264 String imei = null;
2265 String arg = getNextArg();
2266 if (arg != null) {
2267 try {
2268 int specifiedSlotIndex = Integer.parseInt(arg);
2269 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2270 } catch (NumberFormatException exception) {
2271 PrintWriter errPw = getErrPrintWriter();
2272 errPw.println("-s requires an integer as slot index.");
2273 return -1;
2274 }
2275
2276 } else {
2277 imei = TelephonyManager.from(mContext).getImei();
2278 }
2279 getOutPrintWriter().println("Device IMEI: " + imei);
2280
2281 Binder.restoreCallingIdentity(identity);
2282 return 0;
2283 }
2284
Michele Berionne5e411512020-11-13 02:36:59 +00002285 private int handleUnattendedReboot() {
2286 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2287 // non user build.
2288 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2289 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2290 return -1;
2291 }
2292
2293 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2294 getOutPrintWriter().println("result: " + result);
2295
2296 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2297 }
2298
Aman Gupta07124872022-02-09 08:02:14 +00002299 private int handleGetSimSlotsMapping() {
2300 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2301 // non user build.
2302 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2303 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2304 return -1;
2305 }
2306 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2307 String result = telephonyManager.getSimSlotMapping().toString();
2308 getOutPrintWriter().println("simSlotsMapping: " + result);
2309
2310 return 0;
2311 }
2312
Hui Wang641e81c2020-10-12 12:14:23 -07002313 private int handleGbaCommand() {
2314 String arg = getNextArg();
2315 if (arg == null) {
2316 onHelpGba();
2317 return 0;
2318 }
2319
2320 switch (arg) {
2321 case GBA_SET_SERVICE: {
2322 return handleGbaSetServiceCommand();
2323 }
2324 case GBA_GET_SERVICE: {
2325 return handleGbaGetServiceCommand();
2326 }
2327 case GBA_SET_RELEASE_TIME: {
2328 return handleGbaSetReleaseCommand();
2329 }
2330 case GBA_GET_RELEASE_TIME: {
2331 return handleGbaGetReleaseCommand();
2332 }
2333 }
2334
2335 return -1;
2336 }
2337
2338 private int getSubId(String cmd) {
2339 int slotId = getDefaultSlot();
2340 String opt = getNextOption();
2341 if (opt != null && opt.equals("-s")) {
2342 try {
2343 slotId = Integer.parseInt(getNextArgRequired());
2344 } catch (NumberFormatException e) {
2345 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2346 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2347 }
2348 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002349 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002350 }
2351
2352 private int handleGbaSetServiceCommand() {
2353 int subId = getSubId("gba set-service");
2354 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2355 return -1;
2356 }
2357
2358 String packageName = getNextArg();
2359 try {
2360 if (packageName == null) {
2361 packageName = "";
2362 }
2363 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2364 if (VDBG) {
2365 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2366 + packageName + ", result=" + result);
2367 }
2368 getOutPrintWriter().println(result);
2369 } catch (RemoteException e) {
2370 Log.w(LOG_TAG, "gba set-service " + subId + " "
2371 + packageName + ", error" + e.getMessage());
2372 getErrPrintWriter().println("Exception: " + e.getMessage());
2373 return -1;
2374 }
2375 return 0;
2376 }
2377
2378 private int handleGbaGetServiceCommand() {
2379 String result;
2380
2381 int subId = getSubId("gba get-service");
2382 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2383 return -1;
2384 }
2385
2386 try {
2387 result = mInterface.getBoundGbaService(subId);
2388 } catch (RemoteException e) {
2389 return -1;
2390 }
2391 if (VDBG) {
2392 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2393 }
2394 getOutPrintWriter().println(result);
2395 return 0;
2396 }
2397
2398 private int handleGbaSetReleaseCommand() {
2399 //the release time value could be -1
2400 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2401 : SubscriptionManager.getDefaultSubscriptionId();
2402 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2403 return -1;
2404 }
2405
2406 String intervalStr = getNextArg();
2407 if (intervalStr == null) {
2408 return -1;
2409 }
2410
2411 try {
2412 int interval = Integer.parseInt(intervalStr);
2413 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2414 if (VDBG) {
2415 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2416 + intervalStr + ", result=" + result);
2417 }
2418 getOutPrintWriter().println(result);
2419 } catch (NumberFormatException | RemoteException e) {
2420 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2421 + intervalStr + ", error" + e.getMessage());
2422 getErrPrintWriter().println("Exception: " + e.getMessage());
2423 return -1;
2424 }
2425 return 0;
2426 }
2427
2428 private int handleGbaGetReleaseCommand() {
2429 int subId = getSubId("gba get-release");
2430 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2431 return -1;
2432 }
2433
2434 int result = 0;
2435 try {
2436 result = mInterface.getGbaReleaseTime(subId);
2437 } catch (RemoteException e) {
2438 return -1;
2439 }
2440 if (VDBG) {
2441 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2442 }
2443 getOutPrintWriter().println(result);
2444 return 0;
2445 }
Hui Wang761a6682020-10-31 05:12:53 +00002446
2447 private int handleSingleRegistrationConfigCommand() {
2448 String arg = getNextArg();
2449 if (arg == null) {
2450 onHelpSrc();
2451 return 0;
2452 }
2453
2454 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002455 case SRC_SET_TEST_ENABLED: {
2456 return handleSrcSetTestEnabledCommand();
2457 }
2458 case SRC_GET_TEST_ENABLED: {
2459 return handleSrcGetTestEnabledCommand();
2460 }
Hui Wang761a6682020-10-31 05:12:53 +00002461 case SRC_SET_DEVICE_ENABLED: {
2462 return handleSrcSetDeviceEnabledCommand();
2463 }
2464 case SRC_GET_DEVICE_ENABLED: {
2465 return handleSrcGetDeviceEnabledCommand();
2466 }
2467 case SRC_SET_CARRIER_ENABLED: {
2468 return handleSrcSetCarrierEnabledCommand();
2469 }
2470 case SRC_GET_CARRIER_ENABLED: {
2471 return handleSrcGetCarrierEnabledCommand();
2472 }
Hui Wangb647abe2021-02-26 09:33:38 -08002473 case SRC_SET_FEATURE_ENABLED: {
2474 return handleSrcSetFeatureValidationCommand();
2475 }
2476 case SRC_GET_FEATURE_ENABLED: {
2477 return handleSrcGetFeatureValidationCommand();
2478 }
Hui Wang761a6682020-10-31 05:12:53 +00002479 }
2480
2481 return -1;
2482 }
2483
James.cf Linbcdf8b32021-01-14 16:44:13 +08002484 private int handleRcsUceCommand() {
2485 String arg = getNextArg();
2486 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002487 onHelpUce();
2488 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002489 }
2490
2491 switch (arg) {
2492 case UCE_REMOVE_EAB_CONTACT:
2493 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002494 case UCE_GET_EAB_CONTACT:
2495 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002496 case UCE_GET_EAB_CAPABILITY:
2497 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002498 case UCE_GET_DEVICE_ENABLED:
2499 return handleUceGetDeviceEnabledCommand();
2500 case UCE_SET_DEVICE_ENABLED:
2501 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002502 case UCE_OVERRIDE_PUBLISH_CAPS:
2503 return handleUceOverridePublishCaps();
2504 case UCE_GET_LAST_PIDF_XML:
2505 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002506 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2507 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002508 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2509 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002510 }
2511 return -1;
2512 }
2513
2514 private int handleRemovingEabContactCommand() {
2515 int subId = getSubId("uce remove-eab-contact");
2516 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2517 return -1;
2518 }
2519
2520 String phoneNumber = getNextArgRequired();
2521 if (TextUtils.isEmpty(phoneNumber)) {
2522 return -1;
2523 }
2524 int result = 0;
2525 try {
2526 result = mInterface.removeContactFromEab(subId, phoneNumber);
2527 } catch (RemoteException e) {
2528 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2529 getErrPrintWriter().println("Exception: " + e.getMessage());
2530 return -1;
2531 }
2532
2533 if (VDBG) {
2534 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2535 }
calvinpan293ea1b2021-02-04 17:52:13 +08002536 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002537 }
2538
calvinpane4a8a1d2021-01-25 13:51:18 +08002539 private int handleGettingEabContactCommand() {
2540 String phoneNumber = getNextArgRequired();
2541 if (TextUtils.isEmpty(phoneNumber)) {
2542 return -1;
2543 }
2544 String result = "";
2545 try {
2546 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002547 } catch (RemoteException e) {
2548 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2549 getErrPrintWriter().println("Exception: " + e.getMessage());
2550 return -1;
2551 }
2552
2553 if (VDBG) {
2554 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2555 }
calvinpan293ea1b2021-02-04 17:52:13 +08002556 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002557 return 0;
2558 }
2559
Calvin Pana1434322021-07-01 19:27:01 +08002560 private int handleGettingEabCapabilityCommand() {
2561 String phoneNumber = getNextArgRequired();
2562 if (TextUtils.isEmpty(phoneNumber)) {
2563 return -1;
2564 }
2565 String result = "";
2566 try {
2567 result = mInterface.getCapabilityFromEab(phoneNumber);
2568 } catch (RemoteException e) {
2569 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2570 getErrPrintWriter().println("Exception: " + e.getMessage());
2571 return -1;
2572 }
2573
2574 if (VDBG) {
2575 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2576 }
2577 getOutPrintWriter().println(result);
2578 return 0;
2579 }
2580
James.cf Lin4b784aa2021-01-31 03:25:15 +08002581 private int handleUceGetDeviceEnabledCommand() {
2582 boolean result = false;
2583 try {
2584 result = mInterface.getDeviceUceEnabled();
2585 } catch (RemoteException e) {
2586 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2587 return -1;
2588 }
2589 if (VDBG) {
2590 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2591 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002592 getOutPrintWriter().println(result);
2593 return 0;
2594 }
2595
James.cf Lin4b784aa2021-01-31 03:25:15 +08002596 private int handleUceSetDeviceEnabledCommand() {
2597 String enabledStr = getNextArg();
2598 if (TextUtils.isEmpty(enabledStr)) {
2599 return -1;
2600 }
2601
2602 try {
2603 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2604 mInterface.setDeviceUceEnabled(isEnabled);
2605 if (VDBG) {
2606 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2607 }
2608 } catch (NumberFormatException | RemoteException e) {
2609 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2610 getErrPrintWriter().println("Exception: " + e.getMessage());
2611 return -1;
2612 }
2613 return 0;
2614 }
2615
James.cf Line8713a42021-04-29 16:04:26 +08002616 private int handleUceRemoveRequestDisallowedStatus() {
2617 int subId = getSubId("uce remove-request-disallowed-status");
2618 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2619 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2620 return -1;
2621 }
2622 boolean result;
2623 try {
2624 result = mInterface.removeUceRequestDisallowedStatus(subId);
2625 } catch (RemoteException e) {
2626 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2627 return -1;
2628 }
2629 if (VDBG) {
2630 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2631 }
2632 getOutPrintWriter().println(result);
2633 return 0;
2634 }
2635
James.cf Lin0fc71b02021-05-25 01:37:38 +08002636 private int handleUceSetCapRequestTimeout() {
2637 int subId = getSubId("uce set-capabilities-request-timeout");
2638 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2639 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2640 return -1;
2641 }
2642 long timeoutAfterMs = Long.valueOf(getNextArg());
2643 boolean result;
2644 try {
2645 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2646 } catch (RemoteException e) {
2647 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2648 return -1;
2649 }
2650 if (VDBG) {
2651 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2652 }
2653 getOutPrintWriter().println(result);
2654 return 0;
2655 }
2656
Hui Wangbaaee6a2021-02-19 20:45:36 -08002657 private int handleSrcSetTestEnabledCommand() {
2658 String enabledStr = getNextArg();
2659 if (enabledStr == null) {
2660 return -1;
2661 }
2662
2663 try {
2664 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2665 if (VDBG) {
2666 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2667 }
2668 getOutPrintWriter().println("Done");
2669 } catch (NumberFormatException | RemoteException e) {
2670 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2671 getErrPrintWriter().println("Exception: " + e.getMessage());
2672 return -1;
2673 }
2674 return 0;
2675 }
2676
2677 private int handleSrcGetTestEnabledCommand() {
2678 boolean result = false;
2679 try {
2680 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2681 } catch (RemoteException e) {
2682 return -1;
2683 }
2684 if (VDBG) {
2685 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2686 }
2687 getOutPrintWriter().println(result);
2688 return 0;
2689 }
2690
Brad Ebinger14d467f2021-02-12 06:18:28 +00002691 private int handleUceOverridePublishCaps() {
2692 int subId = getSubId("uce override-published-caps");
2693 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2694 return -1;
2695 }
2696 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2697 String operation = getNextArgRequired();
2698 String caps = getNextArg();
2699 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2700 && !"list".equals(operation)) {
2701 getErrPrintWriter().println("Invalid operation: " + operation);
2702 return -1;
2703 }
2704
2705 // add/remove requires capabilities to be specified.
2706 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2707 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2708 + "specified");
2709 return -1;
2710 }
2711
2712 ArraySet<String> capSet = new ArraySet<>();
2713 if (!TextUtils.isEmpty(caps)) {
2714 String[] capArray = caps.split(":");
2715 for (String cap : capArray) {
2716 // Allow unknown tags to be passed in as well.
2717 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2718 }
2719 }
2720
2721 RcsContactUceCapability result = null;
2722 try {
2723 switch (operation) {
2724 case "add":
2725 result = mInterface.addUceRegistrationOverrideShell(subId,
2726 new ArrayList<>(capSet));
2727 break;
2728 case "remove":
2729 result = mInterface.removeUceRegistrationOverrideShell(subId,
2730 new ArrayList<>(capSet));
2731 break;
2732 case "clear":
2733 result = mInterface.clearUceRegistrationOverrideShell(subId);
2734 break;
2735 case "list":
2736 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2737 break;
2738 }
2739 } catch (RemoteException e) {
2740 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2741 getErrPrintWriter().println("Exception: " + e.getMessage());
2742 return -1;
2743 } catch (ServiceSpecificException sse) {
2744 // Reconstruct ImsException
2745 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2746 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2747 getErrPrintWriter().println("Exception: " + imsException);
2748 return -1;
2749 }
2750 if (result == null) {
2751 getErrPrintWriter().println("Service not available");
2752 return -1;
2753 }
2754 getOutPrintWriter().println(result);
2755 return 0;
2756 }
2757
2758 private int handleUceGetPidfXml() {
2759 int subId = getSubId("uce get-last-publish-pidf");
2760 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2761 return -1;
2762 }
2763
2764 String result;
2765 try {
2766 result = mInterface.getLastUcePidfXmlShell(subId);
2767 } catch (RemoteException e) {
2768 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2769 getErrPrintWriter().println("Exception: " + e.getMessage());
2770 return -1;
2771 } catch (ServiceSpecificException sse) {
2772 // Reconstruct ImsException
2773 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2774 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2775 getErrPrintWriter().println("Exception: " + imsException);
2776 return -1;
2777 }
2778 if (result == null) {
2779 getErrPrintWriter().println("Service not available");
2780 return -1;
2781 }
2782 getOutPrintWriter().println(result);
2783 return 0;
2784 }
2785
Hui Wang761a6682020-10-31 05:12:53 +00002786 private int handleSrcSetDeviceEnabledCommand() {
2787 String enabledStr = getNextArg();
2788 if (enabledStr == null) {
2789 return -1;
2790 }
2791
2792 try {
2793 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2794 if (VDBG) {
2795 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2796 }
2797 getOutPrintWriter().println("Done");
2798 } catch (NumberFormatException | RemoteException e) {
2799 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2800 getErrPrintWriter().println("Exception: " + e.getMessage());
2801 return -1;
2802 }
2803 return 0;
2804 }
2805
2806 private int handleSrcGetDeviceEnabledCommand() {
2807 boolean result = false;
2808 try {
2809 result = mInterface.getDeviceSingleRegistrationEnabled();
2810 } catch (RemoteException e) {
2811 return -1;
2812 }
2813 if (VDBG) {
2814 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2815 }
2816 getOutPrintWriter().println(result);
2817 return 0;
2818 }
2819
2820 private int handleSrcSetCarrierEnabledCommand() {
2821 //the release time value could be -1
2822 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2823 : SubscriptionManager.getDefaultSubscriptionId();
2824 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2825 return -1;
2826 }
2827
2828 String enabledStr = getNextArg();
2829 if (enabledStr == null) {
2830 return -1;
2831 }
2832
2833 try {
2834 boolean result =
2835 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2836 if (VDBG) {
2837 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2838 + enabledStr + ", result=" + result);
2839 }
2840 getOutPrintWriter().println(result);
2841 } catch (NumberFormatException | RemoteException e) {
2842 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2843 + enabledStr + ", error" + e.getMessage());
2844 getErrPrintWriter().println("Exception: " + e.getMessage());
2845 return -1;
2846 }
2847 return 0;
2848 }
2849
2850 private int handleSrcGetCarrierEnabledCommand() {
2851 int subId = getSubId("src get-carrier-enabled");
2852 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2853 return -1;
2854 }
2855
2856 boolean result = false;
2857 try {
2858 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2859 } catch (RemoteException e) {
2860 return -1;
2861 }
2862 if (VDBG) {
2863 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2864 }
2865 getOutPrintWriter().println(result);
2866 return 0;
2867 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002868
Hui Wangb647abe2021-02-26 09:33:38 -08002869 private int handleSrcSetFeatureValidationCommand() {
2870 //the release time value could be -1
2871 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2872 : SubscriptionManager.getDefaultSubscriptionId();
2873 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2874 return -1;
2875 }
2876
2877 String enabledStr = getNextArg();
2878 if (enabledStr == null) {
2879 return -1;
2880 }
2881
2882 try {
2883 boolean result =
2884 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2885 if (VDBG) {
2886 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2887 + enabledStr + ", result=" + result);
2888 }
2889 getOutPrintWriter().println(result);
2890 } catch (NumberFormatException | RemoteException e) {
2891 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2892 + enabledStr + ", error" + e.getMessage());
2893 getErrPrintWriter().println("Exception: " + e.getMessage());
2894 return -1;
2895 }
2896 return 0;
2897 }
2898
2899 private int handleSrcGetFeatureValidationCommand() {
2900 int subId = getSubId("src get-feature-validation");
2901 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2902 return -1;
2903 }
2904
2905 Boolean result = false;
2906 try {
2907 result = mInterface.getImsFeatureValidationOverride(subId);
2908 } catch (RemoteException e) {
2909 return -1;
2910 }
2911 if (VDBG) {
2912 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2913 }
2914 getOutPrintWriter().println(result);
2915 return 0;
2916 }
2917
2918
Hall Liuaa4211e2021-01-20 15:43:39 -08002919 private void onHelpCallComposer() {
2920 PrintWriter pw = getOutPrintWriter();
2921 pw.println("Call composer commands");
2922 pw.println(" callcomposer test-mode enable|disable|query");
2923 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2924 pw.println(" upload/download from carrier servers is disabled, and operations are");
2925 pw.println(" performed using emulated local files instead.");
2926 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2927 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2928 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002929 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2930 pw.println(" Enables or disables the user setting for call composer, as set by");
2931 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002932 }
2933
2934 private int handleCallComposerCommand() {
2935 String arg = getNextArg();
2936 if (arg == null) {
2937 onHelpCallComposer();
2938 return 0;
2939 }
2940
2941 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2942 "MODIFY_PHONE_STATE required for call composer shell cmds");
2943 switch (arg) {
2944 case CALL_COMPOSER_TEST_MODE: {
2945 String enabledStr = getNextArg();
2946 if (ENABLE.equals(enabledStr)) {
2947 CallComposerPictureManager.sTestMode = true;
2948 } else if (DISABLE.equals(enabledStr)) {
2949 CallComposerPictureManager.sTestMode = false;
2950 } else if (QUERY.equals(enabledStr)) {
2951 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2952 } else {
2953 onHelpCallComposer();
2954 return 1;
2955 }
2956 break;
2957 }
2958 case CALL_COMPOSER_SIMULATE_CALL: {
2959 int subscriptionId = Integer.valueOf(getNextArg());
2960 String uuidString = getNextArg();
2961 UUID uuid = UUID.fromString(uuidString);
2962 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2963 Binder.withCleanCallingIdentity(() -> {
2964 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2965 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2966 });
2967 try {
2968 Uri uri = storageUriFuture.get();
2969 getOutPrintWriter().println(String.valueOf(uri));
2970 } catch (Exception e) {
2971 throw new RuntimeException(e);
2972 }
2973 break;
2974 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002975 case CALL_COMPOSER_USER_SETTING: {
2976 try {
2977 int subscriptionId = Integer.valueOf(getNextArg());
2978 String enabledStr = getNextArg();
2979 if (ENABLE.equals(enabledStr)) {
2980 mInterface.setCallComposerStatus(subscriptionId,
2981 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2982 } else if (DISABLE.equals(enabledStr)) {
2983 mInterface.setCallComposerStatus(subscriptionId,
2984 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2985 } else if (QUERY.equals(enabledStr)) {
2986 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2987 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2988 } else {
2989 onHelpCallComposer();
2990 return 1;
2991 }
2992 } catch (RemoteException e) {
2993 e.printStackTrace(getOutPrintWriter());
2994 return 1;
2995 }
2996 break;
2997 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002998 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002999 return 0;
3000 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003001
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003002 private int handleHasCarrierPrivilegesCommand() {
3003 String packageName = getNextArgRequired();
3004
3005 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003006 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003007 try {
3008 hasCarrierPrivileges =
3009 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3010 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3011 } catch (RemoteException e) {
3012 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3013 getErrPrintWriter().println("Exception: " + e.getMessage());
3014 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003015 } finally {
3016 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003017 }
3018
3019 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003020 return 0;
3021 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003022
3023 private int handleAllowedNetworkTypesCommand(String command) {
3024 if (!checkShellUid()) {
3025 return -1;
3026 }
3027
3028 PrintWriter errPw = getErrPrintWriter();
3029 String tag = command + ": ";
3030 String opt;
3031 int subId = -1;
3032 Log.v(LOG_TAG, command + " start");
3033
3034 while ((opt = getNextOption()) != null) {
3035 if (opt.equals("-s")) {
3036 try {
3037 subId = slotStringToSubId(tag, getNextArgRequired());
3038 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3039 errPw.println(tag + "No valid subscription found.");
3040 return -1;
3041 }
3042 } catch (IllegalArgumentException e) {
3043 // Missing slot id
3044 errPw.println(tag + "SLOT_ID expected after -s.");
3045 return -1;
3046 }
3047 } else {
3048 errPw.println(tag + "Unknown option " + opt);
3049 return -1;
3050 }
3051 }
3052
3053 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3054 return handleGetAllowedNetworkTypesCommand(subId);
3055 }
3056 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3057 return handleSetAllowedNetworkTypesCommand(subId);
3058 }
3059 return -1;
3060 }
3061
3062 private int handleGetAllowedNetworkTypesCommand(int subId) {
3063 PrintWriter errPw = getErrPrintWriter();
3064
3065 long result = -1;
3066 try {
3067 if (mInterface != null) {
3068 result = mInterface.getAllowedNetworkTypesForReason(subId,
3069 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3070 } else {
3071 throw new IllegalStateException("telephony service is null.");
3072 }
3073 } catch (RemoteException e) {
3074 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3075 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3076 return -1;
3077 }
3078
3079 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3080 return 0;
3081 }
3082
3083 private int handleSetAllowedNetworkTypesCommand(int subId) {
3084 PrintWriter errPw = getErrPrintWriter();
3085
3086 String bitmaskString = getNextArg();
3087 if (TextUtils.isEmpty(bitmaskString)) {
3088 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3089 return -1;
3090 }
3091 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3092 if (allowedNetworkTypes < 0) {
3093 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3094 return -1;
3095 }
3096 boolean result = false;
3097 try {
3098 if (mInterface != null) {
3099 result = mInterface.setAllowedNetworkTypesForReason(subId,
3100 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3101 } else {
3102 throw new IllegalStateException("telephony service is null.");
3103 }
3104 } catch (RemoteException e) {
3105 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3106 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3107 return -1;
3108 }
3109
3110 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3111 if (result) {
3112 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3113 }
3114 getOutPrintWriter().println(resultMessage);
3115 return 0;
3116 }
3117
3118 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3119 if (TextUtils.isEmpty(bitmaskString)) {
3120 return -1;
3121 }
3122 if (VDBG) {
3123 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3124 + ", length: " + bitmaskString.length());
3125 }
3126 try {
3127 return Long.parseLong(bitmaskString, 2);
3128 } catch (NumberFormatException e) {
3129 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3130 return -1;
3131 }
3132 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003133
jimsun3b9ccac2021-10-26 15:01:23 +08003134 private int handleRadioSetModemServiceCommand() {
3135 PrintWriter errPw = getErrPrintWriter();
3136 String serviceName = null;
3137
3138 String opt;
3139 while ((opt = getNextOption()) != null) {
3140 switch (opt) {
3141 case "-s": {
3142 serviceName = getNextArgRequired();
3143 break;
3144 }
3145 }
3146 }
3147
3148 try {
3149 boolean result = mInterface.setModemService(serviceName);
3150 if (VDBG) {
3151 Log.v(LOG_TAG,
3152 "RadioSetModemService " + serviceName + ", result = " + result);
3153 }
3154 getOutPrintWriter().println(result);
3155 } catch (RemoteException e) {
3156 Log.w(LOG_TAG,
3157 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3158 errPw.println("Exception: " + e.getMessage());
3159 return -1;
3160 }
3161 return 0;
3162 }
3163
3164 private int handleRadioGetModemServiceCommand() {
3165 PrintWriter errPw = getErrPrintWriter();
3166 String result;
3167
3168 try {
3169 result = mInterface.getModemService();
3170 getOutPrintWriter().println(result);
3171 } catch (RemoteException e) {
3172 errPw.println("Exception: " + e.getMessage());
3173 return -1;
3174 }
3175 if (VDBG) {
3176 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3177 }
3178 return 0;
3179 }
3180
3181 private int handleRadioCommand() {
3182 String arg = getNextArg();
3183 if (arg == null) {
3184 onHelpRadio();
3185 return 0;
3186 }
3187
3188 switch (arg) {
3189 case RADIO_SET_MODEM_SERVICE:
3190 return handleRadioSetModemServiceCommand();
3191
3192 case RADIO_GET_MODEM_SERVICE:
3193 return handleRadioGetModemServiceCommand();
3194 }
3195
3196 return -1;
3197 }
arunvoddud7401012022-12-15 16:08:12 +00003198
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003199 private int handleSetSatelliteServicePackageNameCommand() {
3200 PrintWriter errPw = getErrPrintWriter();
3201 String serviceName = null;
3202
3203 String opt;
3204 while ((opt = getNextOption()) != null) {
3205 switch (opt) {
3206 case "-s": {
3207 serviceName = getNextArgRequired();
3208 break;
3209 }
3210 }
3211 }
3212 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3213 + serviceName);
3214
3215 try {
3216 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3217 if (VDBG) {
3218 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3219 + ", result = " + result);
3220 }
3221 getOutPrintWriter().println(result);
3222 } catch (RemoteException e) {
3223 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3224 + ", error = " + e.getMessage());
3225 errPw.println("Exception: " + e.getMessage());
3226 return -1;
3227 }
3228 return 0;
3229 }
3230
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003231 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3232 PrintWriter errPw = getErrPrintWriter();
3233 String serviceName = null;
3234
3235 String opt;
3236 while ((opt = getNextOption()) != null) {
3237 switch (opt) {
3238 case "-s": {
3239 serviceName = getNextArgRequired();
3240 break;
3241 }
3242 }
3243 }
3244 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3245 + serviceName);
3246
3247 try {
3248 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3249 if (VDBG) {
3250 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3251 + ", result = " + result);
3252 }
3253 getOutPrintWriter().println(result);
3254 } catch (RemoteException e) {
3255 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3256 + ", error = " + e.getMessage());
3257 errPw.println("Exception: " + e.getMessage());
3258 return -1;
3259 }
3260 return 0;
3261 }
3262
Thomas Nguyen87dce732023-04-20 18:27:16 -07003263 private int handleSetSatellitePointingUiClassNameCommand() {
3264 PrintWriter errPw = getErrPrintWriter();
3265 String packageName = null;
3266 String className = null;
3267
3268 String opt;
3269 while ((opt = getNextOption()) != null) {
3270 switch (opt) {
3271 case "-p": {
3272 packageName = getNextArgRequired();
3273 break;
3274 }
3275 case "-c": {
3276 className = getNextArgRequired();
3277 break;
3278 }
3279 }
3280 }
3281 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3282 + packageName + ", className=" + className);
3283
3284 try {
3285 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3286 if (VDBG) {
3287 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3288 }
3289 getOutPrintWriter().println(result);
3290 } catch (RemoteException e) {
3291 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3292 + ", error = " + e.getMessage());
3293 errPw.println("Exception: " + e.getMessage());
3294 return -1;
3295 }
3296 return 0;
3297 }
3298
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003299 private int handleSetEmergencyCallToSatelliteHandoverType() {
3300 PrintWriter errPw = getErrPrintWriter();
3301 int handoverType = -1;
3302 int delaySeconds = 0;
3303
3304 String opt;
3305 while ((opt = getNextOption()) != null) {
3306 switch (opt) {
3307 case "-t": {
3308 try {
3309 handoverType = Integer.parseInt(getNextArgRequired());
3310 } catch (NumberFormatException e) {
3311 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3312 + " for handoverType");
3313 return -1;
3314 }
3315 break;
3316 }
3317 case "-d": {
3318 try {
3319 delaySeconds = Integer.parseInt(getNextArgRequired());
3320 } catch (NumberFormatException e) {
3321 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3322 + " for delaySeconds");
3323 return -1;
3324 }
3325 break;
3326 }
3327 }
3328 }
3329 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3330 + handoverType + ", delaySeconds=" + delaySeconds);
3331
3332 try {
3333 boolean result =
3334 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3335 if (VDBG) {
3336 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3337 }
3338 getOutPrintWriter().println(result);
3339 } catch (RemoteException e) {
3340 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3341 + ", error = " + e.getMessage());
3342 errPw.println("Exception: " + e.getMessage());
3343 return -1;
3344 }
3345 return 0;
3346 }
3347
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003348 private int handleSetSatelliteListeningTimeoutDuration() {
3349 PrintWriter errPw = getErrPrintWriter();
3350 long timeoutMillis = 0;
3351
3352 String opt;
3353 while ((opt = getNextOption()) != null) {
3354 switch (opt) {
3355 case "-t": {
3356 timeoutMillis = Long.parseLong(getNextArgRequired());
3357 break;
3358 }
3359 }
3360 }
3361 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3362 + timeoutMillis);
3363
3364 try {
3365 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3366 if (VDBG) {
3367 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3368 + ", result = " + result);
3369 }
3370 getOutPrintWriter().println(result);
3371 } catch (RemoteException e) {
3372 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3373 + ", error = " + e.getMessage());
3374 errPw.println("Exception: " + e.getMessage());
3375 return -1;
3376 }
3377 return 0;
3378 }
3379
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003380 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003381 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003382 boolean reset = false;
3383 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003384 long timeoutMillis = 0;
3385
3386 String opt;
3387 while ((opt = getNextOption()) != null) {
3388 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003389 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003390 timeoutMillis = Long.parseLong(getNextArgRequired());
3391 break;
3392 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003393 case "-r": {
3394 reset = true;
3395 break;
3396 }
3397 case "-t": {
3398 timeoutType = Integer.parseInt(getNextArgRequired());
3399 break;
3400 }
Hakjun Choiae365972023-04-25 11:00:31 +00003401 }
3402 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003403 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3404 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003405
3406 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003407 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3408 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003409 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003410 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003411 + ", result = " + result);
3412 }
3413 getOutPrintWriter().println(result);
3414 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003415 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3416 + ", error = " + e.getMessage());
3417 errPw.println("Exception: " + e.getMessage());
3418 return -1;
3419 }
3420 return 0;
3421 }
3422
Aishwarya Mallampati65d60ab2024-05-17 22:47:04 +00003423 private int handleSetDatagramControllerBooleanConfig() {
3424 PrintWriter errPw = getErrPrintWriter();
3425 boolean reset = false;
3426 int booleanType = 0;
3427 boolean enable = false;
3428
3429 String opt;
3430 while ((opt = getNextOption()) != null) {
3431 switch (opt) {
3432 case "-d": {
3433 enable = Boolean.parseBoolean(getNextArgRequired());
3434 break;
3435 }
3436 case "-r": {
3437 reset = true;
3438 break;
3439 }
3440 case "-t": {
3441 booleanType = Integer.parseInt(getNextArgRequired());
3442 break;
3443 }
3444 }
3445 }
3446 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3447 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3448
3449 try {
3450 boolean result = mInterface.setDatagramControllerBooleanConfig(
3451 reset, booleanType, enable);
3452 if (VDBG) {
3453 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3454 }
3455 getOutPrintWriter().println(result);
3456 } catch (RemoteException e) {
3457 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3458 errPw.println("Exception: " + e.getMessage());
3459 return -1;
3460 }
3461 return 0;
3462 }
3463
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003464 private int handleSetSatelliteControllerTimeoutDuration() {
3465 PrintWriter errPw = getErrPrintWriter();
3466 boolean reset = false;
3467 int timeoutType = 0;
3468 long timeoutMillis = 0;
3469
3470 String opt;
3471 while ((opt = getNextOption()) != null) {
3472 switch (opt) {
3473 case "-d": {
3474 timeoutMillis = Long.parseLong(getNextArgRequired());
3475 break;
3476 }
3477 case "-r": {
3478 reset = true;
3479 break;
3480 }
3481 case "-t": {
3482 timeoutType = Integer.parseInt(getNextArgRequired());
3483 break;
3484 }
3485 }
3486 }
3487 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3488 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3489
3490 try {
3491 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3492 reset, timeoutType, timeoutMillis);
3493 if (VDBG) {
3494 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3495 + ", result = " + result);
3496 }
3497 getOutPrintWriter().println(result);
3498 } catch (RemoteException e) {
3499 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003500 + ", error = " + e.getMessage());
3501 errPw.println("Exception: " + e.getMessage());
3502 return -1;
3503 }
3504 return 0;
3505 }
3506
Hakjun Choibc6ce992023-11-07 16:04:33 +00003507 private int handleSetShouldSendDatagramToModemInDemoMode() {
3508 PrintWriter errPw = getErrPrintWriter();
3509 String opt;
3510 boolean shouldSendToDemoMode;
3511
3512 if ((opt = getNextArg()) == null) {
3513 errPw.println(
3514 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3515 + " Invalid Argument");
3516 return -1;
3517 } else {
3518 switch (opt) {
3519 case "true": {
3520 shouldSendToDemoMode = true;
3521 break;
3522 }
3523 case "false": {
3524 shouldSendToDemoMode = false;
3525 break;
3526 }
3527 default:
3528 errPw.println(
3529 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3530 + " Invalid Argument");
3531 return -1;
3532 }
3533 }
3534
3535 Log.d(LOG_TAG,
3536 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3537
3538 try {
3539 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3540 shouldSendToDemoMode);
3541 if (VDBG) {
3542 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3543 + result);
3544 }
3545 getOutPrintWriter().println(false);
3546 } catch (RemoteException e) {
3547 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3548 + "), error = " + e.getMessage());
3549 errPw.println("Exception: " + e.getMessage());
3550 return -1;
3551 }
3552 return 0;
3553 }
3554
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003555 private int handleSetSatelliteAccessControlOverlayConfigs() {
3556 PrintWriter errPw = getErrPrintWriter();
3557 boolean reset = false;
3558 boolean isAllowed = false;
3559 String s2CellFile = null;
3560 long locationFreshDurationNanos = 0;
3561 List<String> satelliteCountryCodes = null;
3562
3563 String opt;
3564 while ((opt = getNextOption()) != null) {
3565 switch (opt) {
3566 case "-r": {
3567 reset = true;
3568 break;
3569 }
3570 case "-a": {
3571 isAllowed = true;
3572 break;
3573 }
3574 case "-f": {
3575 s2CellFile = getNextArgRequired();
3576 break;
3577 }
3578 case "-d": {
3579 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3580 break;
3581 }
3582 case "-c": {
3583 String countryCodeStr = getNextArgRequired();
3584 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3585 break;
3586 }
3587 }
3588 }
3589 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3590 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3591 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3592 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3593
3594 try {
3595 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3596 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3597 if (VDBG) {
3598 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3599 }
3600 getOutPrintWriter().println(result);
3601 } catch (RemoteException e) {
3602 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3603 errPw.println("Exception: " + e.getMessage());
3604 return -1;
3605 }
3606 return 0;
3607 }
3608
3609 private int handleSetCountryCodes() {
3610 PrintWriter errPw = getErrPrintWriter();
3611 List<String> currentNetworkCountryCodes = new ArrayList<>();
3612 String locationCountryCode = null;
3613 long locationCountryCodeTimestampNanos = 0;
3614 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3615 boolean reset = false;
3616
3617 String opt;
3618 while ((opt = getNextOption()) != null) {
3619 switch (opt) {
3620 case "-r": {
3621 reset = true;
3622 break;
3623 }
3624 case "-n": {
3625 String countryCodeStr = getNextArgRequired();
3626 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3627 break;
3628 }
3629 case "-c": {
3630 String cachedNetworkCountryCodeStr = getNextArgRequired();
3631 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3632 break;
3633 }
3634 case "-l": {
3635 locationCountryCode = getNextArgRequired();
3636 break;
3637 }
3638 case "-t": {
3639 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3640 break;
3641 }
3642 }
3643 }
3644 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3645 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3646 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3647 + currentNetworkCountryCodes);
3648
3649 try {
3650 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3651 cachedNetworkCountryCodes, locationCountryCode,
3652 locationCountryCodeTimestampNanos);
3653 if (VDBG) {
3654 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3655 }
3656 getOutPrintWriter().println(result);
3657 } catch (RemoteException e) {
3658 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3659 errPw.println("Exception: " + e.getMessage());
3660 return -1;
3661 }
3662 return 0;
3663 }
3664
Thomas Nguyen3d602742024-01-19 11:29:35 -08003665 private int handleSetOemEnabledSatelliteProvisionStatus() {
3666 PrintWriter errPw = getErrPrintWriter();
3667 boolean isProvisioned = false;
3668 boolean reset = true;
3669
3670 String opt;
3671 while ((opt = getNextOption()) != null) {
3672 switch (opt) {
3673 case "-p": {
3674 try {
3675 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3676 reset = false;
3677 } catch (Exception e) {
3678 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3679 + "after -p indicating provision status");
3680 return -1;
3681 }
3682 }
3683 }
3684 }
3685 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3686 + ", isProvisioned=" + isProvisioned);
3687
3688 try {
3689 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3690 if (VDBG) {
3691 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3692 }
3693 getOutPrintWriter().println(result);
3694 } catch (RemoteException e) {
3695 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3696 errPw.println("Exception: " + e.getMessage());
3697 return -1;
3698 }
3699 return 0;
3700 }
3701
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003702 /**
3703 * Sample inputStr = "US,UK,CA;2,1,3"
3704 * Sample output: {[US,2], [UK,1], [CA,3]}
3705 */
3706 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3707 Map<String, Long> result = new HashMap<>();
3708 if (!TextUtils.isEmpty(inputStr)) {
3709 String[] stringLongArr = inputStr.split(";");
3710 if (stringLongArr.length != 2) {
3711 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3712 return result;
3713 }
3714
3715 String[] stringArr = stringLongArr[0].split(",");
3716 String[] longArr = stringLongArr[1].split(",");
3717 if (stringArr.length != longArr.length) {
3718 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3719 return result;
3720 }
3721
3722 for (int i = 0; i < stringArr.length; i++) {
3723 try {
3724 result.put(stringArr[i], Long.parseLong(longArr[i]));
3725 } catch (Exception ex) {
3726 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3727 + ", ex=" + ex);
3728 return result;
3729 }
3730 }
3731 }
3732 return result;
3733 }
3734
arunvoddud7401012022-12-15 16:08:12 +00003735 private int handleCarrierRestrictionStatusCommand() {
3736 try {
3737 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3738 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3739 mInterface.getModemService()))) {
3740 Log.v(LOG_TAG,
3741 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3742 + " checkShellUid fails");
3743 return -1;
3744 }
3745 } catch (RemoteException ex) {
3746 ex.printStackTrace();
3747 }
3748 String callerInfo = getNextOption();
3749 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3750 if (TextUtils.isEmpty(callerInfo)) {
3751 // reset the Json content after testing
3752 allowListInfo.updateJsonForTest(null);
3753 return 0;
3754 }
3755 if (callerInfo.startsWith("--")) {
3756 callerInfo = callerInfo.replace("--", "");
3757 }
3758 String params[] = callerInfo.split(",");
3759 StringBuffer jsonStrBuffer = new StringBuffer();
3760 String tokens;
3761 for (int index = 0; index < params.length; index++) {
3762 tokens = convertToJsonString(index, params[index]);
3763 if (TextUtils.isEmpty(tokens)) {
3764 // received wrong format from CTS
3765 if (VDBG) {
3766 Log.v(LOG_TAG,
3767 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3768 }
3769 return -1;
3770 }
3771 jsonStrBuffer.append(tokens);
3772 }
3773 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3774 return result;
3775 }
3776
Benedict Wong66477622023-02-03 23:30:57 +00003777 // set-carrier-service-package-override
3778 private int setCarrierServicePackageOverride() {
3779 PrintWriter errPw = getErrPrintWriter();
3780 int subId = SubscriptionManager.getDefaultSubscriptionId();
3781
3782 String opt;
3783 while ((opt = getNextOption()) != null) {
3784 switch (opt) {
3785 case "-s":
3786 try {
3787 subId = Integer.parseInt(getNextArgRequired());
3788 } catch (NumberFormatException e) {
3789 errPw.println(
3790 "set-carrier-service-package-override requires an integer as a"
3791 + " subscription ID.");
3792 return -1;
3793 }
3794 break;
3795 }
3796 }
3797
3798 String packageName = getNextArg();
3799 if (packageName == null) {
3800 errPw.println("set-carrier-service-package-override requires a override package name.");
3801 return -1;
3802 }
3803
3804 try {
3805 mInterface.setCarrierServicePackageOverride(
3806 subId, packageName, mContext.getOpPackageName());
3807
3808 if (VDBG) {
3809 Log.v(
3810 LOG_TAG,
3811 "set-carrier-service-package-override -s " + subId + " " + packageName);
3812 }
3813 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3814 Log.w(
3815 LOG_TAG,
3816 "set-carrier-service-package-override -s "
3817 + subId
3818 + " "
3819 + packageName
3820 + ", error"
3821 + e.getMessage());
3822 errPw.println("Exception: " + e.getMessage());
3823 return -1;
3824 }
3825 return 0;
3826 }
3827
3828 // clear-carrier-service-package-override
3829 private int clearCarrierServicePackageOverride() {
3830 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003831 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003832
3833 String opt;
3834 while ((opt = getNextOption()) != null) {
3835 switch (opt) {
3836 case "-s":
3837 try {
3838 subId = Integer.parseInt(getNextArgRequired());
3839 } catch (NumberFormatException e) {
3840 errPw.println(
3841 "clear-carrier-service-package-override requires an integer as a"
3842 + " subscription ID.");
3843 return -1;
3844 }
3845 break;
3846 }
3847 }
3848
3849 try {
3850 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3851
3852 if (VDBG) {
3853 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3854 }
3855 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3856 Log.w(
3857 LOG_TAG,
3858 "clear-carrier-service-package-override -s "
3859 + subId
3860 + ", error"
3861 + e.getMessage());
3862 errPw.println("Exception: " + e.getMessage());
3863 return -1;
3864 }
3865 return 0;
3866 }
arunvoddud7401012022-12-15 16:08:12 +00003867
Hunsuk Choi13078be2023-09-13 10:55:21 +00003868 private int handleDomainSelectionCommand() {
3869 String arg = getNextArg();
3870 if (arg == null) {
3871 onHelpDomainSelection();
3872 return 0;
3873 }
3874
3875 switch (arg) {
3876 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3877 return handleDomainSelectionSetServiceOverrideCommand();
3878 }
3879 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3880 return handleDomainSelectionClearServiceOverrideCommand();
3881 }
3882 }
3883
3884 return -1;
3885 }
3886
3887 // domainselection set-dss-override
3888 private int handleDomainSelectionSetServiceOverrideCommand() {
3889 PrintWriter errPw = getErrPrintWriter();
3890
3891 String componentName = getNextArg();
3892
3893 try {
3894 boolean result = mInterface.setDomainSelectionServiceOverride(
3895 ComponentName.unflattenFromString(componentName));
3896 if (VDBG) {
3897 Log.v(LOG_TAG, "domainselection set-dss-override "
3898 + componentName + ", result=" + result);
3899 }
3900 getOutPrintWriter().println(result);
3901 } catch (Exception e) {
3902 Log.w(LOG_TAG, "domainselection set-dss-override "
3903 + componentName + ", error=" + e.getMessage());
3904 errPw.println("Exception: " + e.getMessage());
3905 return -1;
3906 }
3907 return 0;
3908 }
3909
3910 // domainselection clear-dss-override
3911 private int handleDomainSelectionClearServiceOverrideCommand() {
3912 PrintWriter errPw = getErrPrintWriter();
3913
3914 try {
3915 boolean result = mInterface.clearDomainSelectionServiceOverride();
3916 if (VDBG) {
3917 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
3918 }
3919 getOutPrintWriter().println(result);
3920 } catch (RemoteException e) {
3921 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
3922 errPw.println("Exception: " + e.getMessage());
3923 return -1;
3924 }
3925 return 0;
3926 }
3927
arunvoddud7401012022-12-15 16:08:12 +00003928 /**
3929 * Building the string that can be used to build the JsonObject which supports to stub the data
3930 * in CarrierAllowListInfo for CTS testing. sample format is like
3931 * {"com.android.example":{"carrierId":"10000","callerSHA1Id":["XXXXXXXXXXXXXX"]}}
3932 */
3933 private String convertToJsonString(int index, String param) {
3934
3935 String token[] = param.split(":");
3936 String jSonString;
3937 switch (index) {
3938 case 0:
3939 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3940 break;
3941 case 1:
3942 jSonString =
3943 "{" + QUOTES + token[0] + QUOTES + ":" + QUOTES + token[1] + QUOTES + ",";
3944 break;
3945 case 2:
3946 jSonString =
3947 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
3948 break;
3949 default:
3950 jSonString = null;
3951 }
3952 return jSonString;
3953 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003954}