blob: 96da48899835f7dd025cd0ed29b1df97481815cd [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;
Jack Yu86374492024-09-16 13:05:44 -070037import android.os.UserHandle;
Shuo Qian489d9282020-07-09 11:30:03 -070038import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070039import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010040import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070041import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070042import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000043import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070044import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080045import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import android.telephony.ims.ImsException;
47import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080048import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080049import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000050import android.util.ArrayMap;
51import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070053import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070054
Brad Ebinger14d467f2021-02-12 06:18:28 +000055import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070056import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080057import com.android.internal.telephony.Phone;
58import com.android.internal.telephony.PhoneFactory;
Jack Yu26735292024-09-25 14:33:49 -070059import com.android.internal.telephony.TelephonyPermissions;
Tyler Gunn92479152021-01-20 16:30:10 -080060import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080061import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080062import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080063import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080064import com.android.phone.callcomposer.CallComposerPictureManager;
arunvoddud7401012022-12-15 16:08:12 +000065import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070066
Allen Xuee00f0e2022-03-14 21:04:49 +000067import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070068import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080069import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000070import java.util.Arrays;
71import java.util.Collections;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080072import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080073import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000074import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010075import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000076import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010077import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080078import java.util.UUID;
79import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81/**
82 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
83 * permission checks have been done before onCommand was called. Make sure any commands processed
84 * here also contain the appropriate permissions checks.
85 */
86
Hall Liua1548bd2019-12-24 14:14:12 -080087public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070088
89 private static final String LOG_TAG = "TelephonyShellCommand";
90 // Don't commit with this true.
91 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070092 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070093
Hall Liuaa4211e2021-01-20 15:43:39 -080094 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070095 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080096 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080097 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080098 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070099 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +0000100 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +0000101 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100102 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -0800103 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -0800104 private static final String ENABLE = "enable";
105 private static final String DISABLE = "disable";
106 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000107 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000108 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
109 "set-carrier-service-package-override";
110 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
111 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000112 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800113
Hall Liu7135e502021-02-04 16:58:17 -0800114 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800115 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800116 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800117
Brad Ebinger999d3302020-11-25 14:31:39 -0800118 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
119 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
120 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700121 // Used to disable or enable processing of conference event package data from the network.
122 // This is handy for testing scenarios where CEP data does not exist on a network which does
123 // support CEP data.
124 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700125
Hall Liud892bec2018-11-30 14:51:45 -0800126 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800127 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800128
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100129 private static final String CC_GET_VALUE = "get-value";
130 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000131 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100132 private static final String CC_CLEAR_VALUES = "clear-values";
133
Hui Wang641e81c2020-10-12 12:14:23 -0700134 private static final String GBA_SUBCOMMAND = "gba";
135 private static final String GBA_SET_SERVICE = "set-service";
136 private static final String GBA_GET_SERVICE = "get-service";
137 private static final String GBA_SET_RELEASE_TIME = "set-release";
138 private static final String GBA_GET_RELEASE_TIME = "get-release";
139
Hui Wang761a6682020-10-31 05:12:53 +0000140 private static final String SINGLE_REGISTATION_CONFIG = "src";
141 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
142 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
143 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
144 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800145 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
146 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800147 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
148 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000149
Tyler Gunn92479152021-01-20 16:30:10 -0800150 private static final String D2D_SUBCOMMAND = "d2d";
151 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800152 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700153 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800154
Nazanin014f41e2021-05-06 17:26:31 -0700155 private static final String BARRING_SUBCOMMAND = "barring";
156 private static final String BARRING_SEND_INFO = "send";
157
James.cf Linbcdf8b32021-01-14 16:44:13 +0800158 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800159 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800160 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800161 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800162 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
163 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000164 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
165 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800166 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
167 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800168 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
169 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800170
jimsun3b9ccac2021-10-26 15:01:23 +0800171 private static final String RADIO_SUBCOMMAND = "radio";
172 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
173 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
174
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800175 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
176 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
177
Jordan Liu0ccee222021-04-27 11:55:13 -0700178 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
179 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
180
Jack Nudelman644b91a2021-03-12 14:09:48 -0800181 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
182 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
183 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700184 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
185 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700186 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
187 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700188 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
189 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700190 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
191 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800192 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
193 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000194 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
195 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800196
197 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
198 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700199 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
200 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800201 private static final String SET_COUNTRY_CODES = "set-country-codes";
202 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
203 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800204 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
205 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000206 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
207 "set-should-send-datagram-to-modem-in-demo-mode";
Hakjun Choi4a832d12024-05-28 22:23:55 +0000208 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
209 "set-is-satellite-communication-allowed-for-current-location-cache";
Hyosund6aaf062024-08-23 23:02:10 +0000210 private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
211 "set-satellite-subscriberid-list-changed-intent-component";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800212
Hunsuk Choi13078be2023-09-13 10:55:21 +0000213 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
214 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
215 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
216
Grant Menke567d48f2022-08-18 20:19:10 +0000217 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
218 + "'*', '#' or '+') needs to be specified after -a in the command ";
219
220 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
221 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
222 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
223
SongFerngWang98dd5992021-05-13 17:50:00 +0800224 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
225 "get-allowed-network-types-for-users";
226 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
227 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000228 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000229 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700230 // Take advantage of existing methods that already contain permissions checks when possible.
231 private final ITelephony mInterface;
232
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100233 private SubscriptionManager mSubscriptionManager;
234 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700235 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700236 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100237
238 private enum CcType {
239 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000240 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100241 }
242
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100243 private class CcOptionParseResult {
244 public int mSubId;
245 public boolean mPersistent;
246 }
247
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100248 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
249 // keys by looking at the end of the string which usually tells the type.
250 // For instance: "xxxx_string", "xxxx_string_array", etc.
251 // The carrier config keys in this map does not follow this convention. It is therefore not
252 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700253 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
254 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
255 CcType.STRING),
256 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
257 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
258 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
266 CcType.STRING),
267 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
268 CcType.STRING_ARRAY),
269 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
270 CcType.STRING_ARRAY),
271 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
272 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
273 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
274 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
275 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
276 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100279
Brad Ebinger14d467f2021-02-12 06:18:28 +0000280 /**
281 * Map from a shorthand string to the feature tags required in registration required in order
282 * for the RCS feature to be considered "capable".
283 */
284 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
285 static {
286 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
287 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
288 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
289 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
290 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
291 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
292 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
293 FeatureTags.FEATURE_TAG_VIDEO)));
294 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
295 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
296 map.put("call_comp",
297 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
298 map.put("call_comp_mmtel",
299 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
300 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
301 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
302 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
303 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
304 // version
305 map.put("chatbot", new ArraySet<>(Arrays.asList(
306 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
307 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
308 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
309 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000310 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000311 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
312 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
313 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
314 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
315 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000316 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000317 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
318 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
319 }
320
321
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100322 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700323 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100324 mCarrierConfigManager =
325 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
326 mSubscriptionManager = (SubscriptionManager)
327 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700328 mTelephonyRegistryManager = (TelephonyRegistryManager)
329 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700330 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700331 }
332
333 @Override
334 public int onCommand(String cmd) {
335 if (cmd == null) {
336 return handleDefaultCommands(null);
337 }
338
339 switch (cmd) {
340 case IMS_SUBCOMMAND: {
341 return handleImsCommand();
342 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800343 case RCS_UCE_COMMAND:
344 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800345 case NUMBER_VERIFICATION_SUBCOMMAND:
346 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800347 case EMERGENCY_CALLBACK_MODE:
348 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800349 case EMERGENCY_NUMBER_TEST_MODE:
350 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100351 case CARRIER_CONFIG_SUBCOMMAND: {
352 return handleCcCommand();
353 }
Shuo Qianf5125122019-12-16 17:03:07 -0800354 case DATA_TEST_MODE:
355 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700356 case END_BLOCK_SUPPRESSION:
357 return handleEndBlockSuppressionCommand();
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 Mallampati3f0ef9b2024-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();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000421 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
422 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000423 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
424 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700425 default: {
426 return handleDefaultCommands(cmd);
427 }
428 }
429 }
430
431 @Override
432 public void onHelp() {
433 PrintWriter pw = getOutPrintWriter();
434 pw.println("Telephony Commands:");
435 pw.println(" help");
436 pw.println(" Print this help text.");
437 pw.println(" ims");
438 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800439 pw.println(" uce");
440 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800441 pw.println(" emergency-number-test-mode");
442 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700443 pw.println(" end-block-suppression");
444 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800445 pw.println(" data");
446 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100447 pw.println(" cc");
448 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700449 pw.println(" gba");
450 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000451 pw.println(" src");
452 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000453 pw.println(" restart-modem");
454 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000455 pw.println(" unattended-reboot");
456 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800457 pw.println(" has-carrier-privileges [package]");
458 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800459 pw.println(" get-allowed-network-types-for-users");
460 pw.println(" Get the Allowed Network Types.");
461 pw.println(" set-allowed-network-types-for-users");
462 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800463 pw.println(" radio");
464 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700465 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800466 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800467 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700468 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800469 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100470 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700471 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000472 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800473 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700474 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800475 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800476 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000477 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700478 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000479 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800480 }
481
482 private void onHelpD2D() {
483 PrintWriter pw = getOutPrintWriter();
484 pw.println("D2D Comms Commands:");
485 pw.println(" d2d send TYPE VALUE");
486 pw.println(" Sends a D2D message of specified type and value.");
487 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
488 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
489 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
490 MESSAGE_CALL_AUDIO_CODEC));
491 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
492 + Communicator.messageToString(
493 MESSAGE_DEVICE_BATTERY_STATE));
494 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
495 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800496 pw.println(" d2d transport TYPE");
497 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
498 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700499 pw.println(" d2d set-device-support true/default");
500 pw.println(" true - forces device support to be enabled for D2D.");
501 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
502 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700503 }
504
Nazanin014f41e2021-05-06 17:26:31 -0700505 private void onHelpBarring() {
506 PrintWriter pw = getOutPrintWriter();
507 pw.println("Barring Commands:");
508 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
509 + " -t CONDITIONAL_BARRING_TIME_SECS");
510 pw.println(" Notifies of a barring info change for the specified slot id.");
511 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
512 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
513 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
514 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
515 }
516
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700517 private void onHelpIms() {
518 PrintWriter pw = getOutPrintWriter();
519 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800520 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700521 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
522 pw.println(" ImsService. Options are:");
523 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
524 pw.println(" is specified, it will choose the default voice SIM slot.");
525 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
526 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800527 pw.println(" -f: Set the feature that this override if for, if no option is");
528 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700529 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
530 pw.println(" Gets the package name of the currently defined ImsService.");
531 pw.println(" Options are:");
532 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
533 pw.println(" is specified, it will choose the default voice SIM slot.");
534 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000535 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800536 pw.println(" -f: The feature type that the query will be requested for. If none is");
537 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800538 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
539 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
540 pw.println(" configuration overrides. Options are:");
541 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700543 pw.println(" ims enable [-s SLOT_ID]");
544 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
545 pw.println(" if none is specified.");
546 pw.println(" ims disable [-s SLOT_ID]");
547 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
548 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700549 pw.println(" ims conference-event-package [enable/disable]");
550 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700551 }
552
James.cf Linbcdf8b32021-01-14 16:44:13 +0800553 private void onHelpUce() {
554 PrintWriter pw = getOutPrintWriter();
555 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800556 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
557 pw.println(" Get the EAB contacts from the EAB database.");
558 pw.println(" Options are:");
559 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
560 pw.println(" Expected output format :");
561 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800562 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
563 pw.println(" Remove the EAB contacts from the EAB database.");
564 pw.println(" Options are:");
565 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
566 pw.println(" is specified, it will choose the default voice SIM slot.");
567 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800568 pw.println(" uce get-device-enabled");
569 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
570 pw.println(" uce set-device-enabled true|false");
571 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
572 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000573 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
574 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
575 pw.println(" Options are:");
576 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
577 pw.println(" is specified, it will choose the default voice SIM slot.");
578 pw.println(" add [CAPABILITY]: add a new capability");
579 pw.println(" remove [CAPABILITY]: remove a capability");
580 pw.println(" clear: clear all capability overrides");
581 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
582 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
583 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
584 pw.println(" chatbot_sa, chatbot_role] as well as full length");
585 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
586 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
587 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
588 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800589 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
590 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800591 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
592 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800593 }
594
Hall Liud892bec2018-11-30 14:51:45 -0800595 private void onHelpNumberVerification() {
596 PrintWriter pw = getOutPrintWriter();
597 pw.println("Number verification commands");
598 pw.println(" numverify override-package PACKAGE_NAME;");
599 pw.println(" Set the authorized package for number verification.");
600 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800601 pw.println(" numverify fake-call NUMBER;");
602 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
603 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800604 }
605
Jack Nudelman644b91a2021-03-12 14:09:48 -0800606 private void onHelpThermalMitigation() {
607 PrintWriter pw = getOutPrintWriter();
608 pw.println("Thermal mitigation commands");
609 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
610 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
611 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
612 pw.println(" Remove the package from one of the authorized packages for thermal "
613 + "mitigation.");
614 }
615
Jordan Liu0ccee222021-04-27 11:55:13 -0700616 private void onHelpDisableOrEnablePhysicalSubscription() {
617 PrintWriter pw = getOutPrintWriter();
618 pw.println("Disable or enable a physical subscription");
619 pw.println(" disable-physical-subscription SUB_ID");
620 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
621 pw.println(" enable-physical-subscription SUB_ID");
622 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
623 }
624
Shuo Qianf5125122019-12-16 17:03:07 -0800625 private void onHelpDataTestMode() {
626 PrintWriter pw = getOutPrintWriter();
627 pw.println("Mobile Data Test Mode Commands:");
628 pw.println(" data enable: enable mobile data connectivity");
629 pw.println(" data disable: disable mobile data connectivity");
630 }
631
sqian9d4df8b2019-01-15 18:32:07 -0800632 private void onHelpEmergencyNumber() {
633 PrintWriter pw = getOutPrintWriter();
634 pw.println("Emergency Number Test Mode Commands:");
635 pw.println(" emergency-number-test-mode ");
636 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
637 + " the test mode");
638 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700639 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800640 pw.println(" -c: clear the emergency number list in the test mode.");
641 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700642 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800643 pw.println(" -p: get the full emergency number list in the test mode.");
644 }
645
Shuo Qian489d9282020-07-09 11:30:03 -0700646 private void onHelpEndBlockSupperssion() {
647 PrintWriter pw = getOutPrintWriter();
648 pw.println("End Block Suppression command:");
649 pw.println(" end-block-suppression: disable suppressing blocking by contact");
650 pw.println(" with emergency services.");
651 }
652
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100653 private void onHelpCc() {
654 PrintWriter pw = getOutPrintWriter();
655 pw.println("Carrier Config Commands:");
656 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
657 pw.println(" Print carrier config values.");
658 pw.println(" Options are:");
659 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
660 pw.println(" is specified, it will choose the default voice SIM slot.");
661 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
662 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100663 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100664 pw.println(" Set carrier config KEY to NEW_VALUE.");
665 pw.println(" Options are:");
666 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
667 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100668 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100669 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
670 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
671 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
672 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000673 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
674 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
675 pw.println(" provided through standard input and follow CarrierConfig XML format.");
676 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
677 pw.println(" Options are:");
678 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
679 pw.println(" is specified, it will choose the default voice SIM slot.");
680 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100681 pw.println(" cc clear-values [-s SLOT_ID]");
682 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000683 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100684 pw.println(" Options are:");
685 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
686 pw.println(" is specified, it will choose the default voice SIM slot.");
687 }
688
Hui Wang641e81c2020-10-12 12:14:23 -0700689 private void onHelpGba() {
690 PrintWriter pw = getOutPrintWriter();
691 pw.println("Gba Commands:");
692 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
693 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
694 pw.println(" Options are:");
695 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
696 pw.println(" is specified, it will choose the default voice SIM slot.");
697 pw.println(" gba get-service [-s SLOT_ID]");
698 pw.println(" Gets the package name of the currently defined GbaService.");
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 set-release [-s SLOT_ID] n");
703 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
704 pw.println(" Do not release/unbind if n is -1.");
705 pw.println(" Options are:");
706 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
707 pw.println(" is specified, it will choose the default voice SIM slot.");
708 pw.println(" gba get-release [-s SLOT_ID]");
709 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
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 }
714
Hui Wang761a6682020-10-31 05:12:53 +0000715 private void onHelpSrc() {
716 PrintWriter pw = getOutPrintWriter();
717 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800718 pw.println(" src set-test-enabled true|false");
719 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
720 pw.println(" The value could be true, false, or null(undefined).");
721 pw.println(" src get-test-enabled");
722 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000723 pw.println(" src set-device-enabled true|false|null");
724 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
725 pw.println(" The value could be true, false, or null(undefined).");
726 pw.println(" src get-device-enabled");
727 pw.println(" Gets the device config for RCS VoLTE single registration.");
728 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
729 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
730 pw.println(" The value could be true, false, or null(undefined).");
731 pw.println(" Options are:");
732 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
733 pw.println(" is specified, it will choose the default voice SIM slot.");
734 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
735 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
736 pw.println(" Options are:");
737 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
738 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800739 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
740 pw.println(" Sets ims feature validation result.");
741 pw.println(" The value could be true, false, or null(undefined).");
742 pw.println(" Options are:");
743 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
744 pw.println(" is specified, it will choose the default voice SIM slot.");
745 pw.println(" src get-feature-validation [-s SLOT_ID]");
746 pw.println(" Gets ims feature validation override value.");
747 pw.println(" Options are:");
748 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
749 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000750 }
751
SongFerngWang98dd5992021-05-13 17:50:00 +0800752 private void onHelpAllowedNetworkTypes() {
753 PrintWriter pw = getOutPrintWriter();
754 pw.println("Allowed Network Types Commands:");
755 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
756 pw.println(" Print allowed network types value.");
757 pw.println(" Options are:");
758 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
759 pw.println(" option is specified, it will choose the default voice SIM slot.");
760 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
761 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
762 pw.println(" Options are:");
763 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
764 pw.println(" option is specified, it will choose the default voice SIM slot.");
765 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
766 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
767 pw.println(" at TelephonyManager.java");
768 pw.println(" For example:");
769 pw.println(" NR only : 10000000000000000000");
770 pw.println(" NR|LTE : 11000001000000000000");
771 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
772 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
773 pw.println(" LTE only : 01000001000000000000");
774 }
775
jimsun3b9ccac2021-10-26 15:01:23 +0800776 private void onHelpRadio() {
777 PrintWriter pw = getOutPrintWriter();
778 pw.println("Radio Commands:");
779 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
780 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
781 pw.println(" to be the bound. Options are:");
782 pw.println(" -s: the service name that the modem service should be bound for.");
783 pw.println(" If no option is specified, it will bind to the default.");
784 pw.println(" radio get-modem-service");
785 pw.println(" Gets the service name of the currently defined modem service.");
786 pw.println(" If it is binding to default, 'default' returns.");
787 pw.println(" If it doesn't bind to any modem service for some reasons,");
788 pw.println(" the result would be 'unknown'.");
789 }
790
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700791 private void onHelpSatellite() {
792 PrintWriter pw = getOutPrintWriter();
793 pw.println("Satellite Commands:");
794 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
795 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700796 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700797 pw.println(" -s: the satellite service package name that Telephony will bind to.");
798 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700799 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
800 pw.println(" Sets the package name of satellite gateway service defined in");
801 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
802 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
803 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700804 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
805 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
806 pw.println(" mode. Options are:");
807 pw.println(" -t: the timeout duration in milliseconds.");
808 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700809 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
810 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
811 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
812 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
813 pw.println(" launch. If no option is specified, it will launch the default.");
814 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
815 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700816 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
817 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
818 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
819 pw.println(" Options are:");
820 pw.println(" -t: the emergency call to satellite handover type.");
821 pw.println(" If no option is specified, override is disabled.");
822 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
823 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800824 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
825 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
826 pw.println(" configs of satellite access controller.");
827 pw.println(" Options are:");
828 pw.println(" -r: clear the overriding. Absent means enable overriding.");
829 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
830 pw.println(" -f: the satellite s2 file.");
831 pw.println(" -d: the location fresh duration nanos.");
832 pw.println(" -c: the list of satellite country codes separated by comma.");
833 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
834 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
835 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
836 pw.println(" Override the cached location country code and its update timestamp. ");
837 pw.println(" Options are:");
838 pw.println(" -r: clear the overriding. Absent means enable overriding.");
839 pw.println(" -n: the current network country code ISOs.");
840 pw.println(" -c: the cached network country code ISOs.");
841 pw.println(" -l: the location country code ISO.");
842 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800843 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
844 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
845 pw.println(" -p: the overriding satellite provision status. If no option is ");
846 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700847 }
848
Ling Ma4fbab492022-01-25 22:36:16 +0000849 private void onHelpImei() {
850 PrintWriter pw = getOutPrintWriter();
851 pw.println("IMEI Commands:");
852 pw.println(" get-imei [-s SLOT_ID]");
853 pw.println(" Gets the device IMEI. Options are:");
854 pw.println(" -s: the slot ID to get the IMEI. If no option");
855 pw.println(" is specified, it will choose the default voice SIM slot.");
856 }
857
Hunsuk Choi13078be2023-09-13 10:55:21 +0000858 private void onHelpDomainSelection() {
859 PrintWriter pw = getOutPrintWriter();
860 pw.println("Domain Selection Commands:");
861 pw.println(" domainselection set-dss-override COMPONENT_NAME");
862 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
863 pw.println(" domainselection clear-dss-override");
864 pw.println(" Clears DomainSelectionService override.");
865 }
866
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700867 private int handleImsCommand() {
868 String arg = getNextArg();
869 if (arg == null) {
870 onHelpIms();
871 return 0;
872 }
873
874 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800875 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700876 return handleImsSetServiceCommand();
877 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800878 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700879 return handleImsGetServiceCommand();
880 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800881 case IMS_CLEAR_SERVICE_OVERRIDE: {
882 return handleImsClearCarrierServiceCommand();
883 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800884 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700885 return handleEnableIms();
886 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800887 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700888 return handleDisableIms();
889 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700890 case IMS_CEP: {
891 return handleCepChange();
892 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700893 }
894
895 return -1;
896 }
897
Shuo Qianf5125122019-12-16 17:03:07 -0800898 private int handleDataTestModeCommand() {
899 PrintWriter errPw = getErrPrintWriter();
900 String arg = getNextArgRequired();
901 if (arg == null) {
902 onHelpDataTestMode();
903 return 0;
904 }
905 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800906 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800907 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700908 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800909 } catch (RemoteException ex) {
910 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
911 errPw.println("Exception: " + ex.getMessage());
912 return -1;
913 }
914 break;
915 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800916 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800917 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700918 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800919 } catch (RemoteException ex) {
920 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
921 errPw.println("Exception: " + ex.getMessage());
922 return -1;
923 }
924 break;
925 }
926 default:
927 onHelpDataTestMode();
928 break;
929 }
930 return 0;
931 }
932
Shuo Qianccbaf742021-02-22 18:32:21 -0800933 private int handleEmergencyCallbackModeCommand() {
934 PrintWriter errPw = getErrPrintWriter();
935 try {
936 mInterface.startEmergencyCallbackMode();
937 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
938 } catch (RemoteException ex) {
939 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
940 errPw.println("Exception: " + ex.getMessage());
941 return -1;
942 }
943 return 0;
944 }
945
Grant Menke567d48f2022-08-18 20:19:10 +0000946 private void removeEmergencyNumberTestMode(String emergencyNumber) {
947 PrintWriter errPw = getErrPrintWriter();
948 for (int routingType : ROUTING_TYPES) {
949 try {
950 mInterface.updateEmergencyNumberListTestMode(
951 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
952 new EmergencyNumber(emergencyNumber, "", "",
953 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
954 new ArrayList<String>(),
955 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
956 routingType));
957 } catch (RemoteException ex) {
958 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
959 errPw.println("Exception: " + ex.getMessage());
960 }
961 }
962 }
963
sqian9d4df8b2019-01-15 18:32:07 -0800964 private int handleEmergencyNumberTestModeCommand() {
965 PrintWriter errPw = getErrPrintWriter();
966 String opt = getNextOption();
967 if (opt == null) {
968 onHelpEmergencyNumber();
969 return 0;
970 }
sqian9d4df8b2019-01-15 18:32:07 -0800971 switch (opt) {
972 case "-a": {
973 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000974 if (emergencyNumberCmd == null){
975 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800976 return -1;
977 }
Grant Menke567d48f2022-08-18 20:19:10 +0000978 String[] params = emergencyNumberCmd.split(":");
979 String emergencyNumber;
980 if (params[0] == null ||
981 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
982 errPw.println(INVALID_ENTRY_ERROR);
983 return -1;
984 } else {
985 emergencyNumber = params[0];
986 }
987 removeEmergencyNumberTestMode(emergencyNumber);
988 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
989 if (params.length > 1) {
990 switch (params[1].toLowerCase(Locale.ROOT)) {
991 case "emergency":
992 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
993 break;
994 case "normal":
995 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
996 break;
997 case "unknown":
998 break;
999 default:
1000 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1001 + "emergency call routing. Please enter either \"normal\", "
1002 + "\"unknown\", or \"emergency\" for call routing. "
1003 + "(-a 1234:normal)");
1004 return -1;
1005 }
1006 }
sqian9d4df8b2019-01-15 18:32:07 -08001007 try {
1008 mInterface.updateEmergencyNumberListTestMode(
1009 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001010 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001011 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1012 new ArrayList<String>(),
1013 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001014 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001015 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001016 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001017 + ", error " + ex.getMessage());
1018 errPw.println("Exception: " + ex.getMessage());
1019 return -1;
1020 }
1021 break;
1022 }
1023 case "-c": {
1024 try {
1025 mInterface.updateEmergencyNumberListTestMode(
1026 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1027 } catch (RemoteException ex) {
1028 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1029 errPw.println("Exception: " + ex.getMessage());
1030 return -1;
1031 }
1032 break;
1033 }
1034 case "-r": {
1035 String emergencyNumberCmd = getNextArgRequired();
1036 if (emergencyNumberCmd == null
1037 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001038 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001039 + " to be specified after -r in the command ");
1040 return -1;
1041 }
Grant Menke567d48f2022-08-18 20:19:10 +00001042 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001043 break;
1044 }
1045 case "-p": {
1046 try {
1047 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1048 } catch (RemoteException ex) {
1049 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1050 errPw.println("Exception: " + ex.getMessage());
1051 return -1;
1052 }
1053 break;
1054 }
1055 default:
1056 onHelpEmergencyNumber();
1057 break;
1058 }
1059 return 0;
1060 }
1061
Hall Liud892bec2018-11-30 14:51:45 -08001062 private int handleNumberVerificationCommand() {
1063 String arg = getNextArg();
1064 if (arg == null) {
1065 onHelpNumberVerification();
1066 return 0;
1067 }
1068
Hall Liuca5af3a2018-12-04 16:58:23 -08001069 if (!checkShellUid()) {
1070 return -1;
1071 }
1072
Hall Liud892bec2018-11-30 14:51:45 -08001073 switch (arg) {
1074 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001075 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1076 return 0;
1077 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001078 case NUMBER_VERIFICATION_FAKE_CALL: {
1079 boolean val = NumberVerificationManager.getInstance()
1080 .checkIncomingCall(getNextArg());
1081 getOutPrintWriter().println(val ? "1" : "0");
1082 return 0;
1083 }
Hall Liud892bec2018-11-30 14:51:45 -08001084 }
1085
1086 return -1;
1087 }
1088
Jordan Liu0ccee222021-04-27 11:55:13 -07001089 private boolean subIsEsim(int subId) {
1090 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1091 if (info != null) {
1092 return info.isEmbedded();
1093 }
1094 return false;
1095 }
1096
1097 private int handleEnablePhysicalSubscription(boolean enable) {
1098 PrintWriter errPw = getErrPrintWriter();
1099 int subId = 0;
1100 try {
1101 subId = Integer.parseInt(getNextArgRequired());
1102 } catch (NumberFormatException e) {
1103 errPw.println((enable ? "enable" : "disable")
1104 + "-physical-subscription requires an integer as a subId.");
1105 return -1;
1106 }
1107 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1108 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001109 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1110 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001111 errPw.println("cc: Permission denied.");
1112 return -1;
1113 }
1114 // Verify that the subId represents a physical sub
1115 if (subIsEsim(subId)) {
1116 errPw.println("SubId " + subId + " is not for a physical subscription");
1117 return -1;
1118 }
1119 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1120 + " physical subscription with subId=" + subId);
1121 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1122 return 0;
1123 }
1124
Jack Nudelman644b91a2021-03-12 14:09:48 -08001125 private int handleThermalMitigationCommand() {
1126 String arg = getNextArg();
1127 String packageName = getNextArg();
1128 if (arg == null || packageName == null) {
1129 onHelpThermalMitigation();
1130 return 0;
1131 }
1132
1133 if (!checkShellUid()) {
1134 return -1;
1135 }
1136
1137 switch (arg) {
1138 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1139 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1140 return 0;
1141 }
1142 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1143 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1144 mContext);
1145 return 0;
1146 }
1147 default:
1148 onHelpThermalMitigation();
1149 }
1150
1151 return -1;
1152
1153 }
1154
Tyler Gunn92479152021-01-20 16:30:10 -08001155 private int handleD2dCommand() {
1156 String arg = getNextArg();
1157 if (arg == null) {
1158 onHelpD2D();
1159 return 0;
1160 }
1161
1162 switch (arg) {
1163 case D2D_SEND: {
1164 return handleD2dSendCommand();
1165 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001166 case D2D_TRANSPORT: {
1167 return handleD2dTransportCommand();
1168 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001169 case D2D_SET_DEVICE_SUPPORT: {
1170 return handleD2dDeviceSupportedCommand();
1171 }
Tyler Gunn92479152021-01-20 16:30:10 -08001172 }
1173
1174 return -1;
1175 }
1176
1177 private int handleD2dSendCommand() {
1178 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001179 int messageType = -1;
1180 int messageValue = -1;
1181
Tyler Gunn92479152021-01-20 16:30:10 -08001182 String arg = getNextArg();
1183 if (arg == null) {
1184 onHelpD2D();
1185 return 0;
1186 }
1187 try {
1188 messageType = Integer.parseInt(arg);
1189 } catch (NumberFormatException e) {
1190 errPw.println("message type must be a valid integer");
1191 return -1;
1192 }
1193
1194 arg = getNextArg();
1195 if (arg == null) {
1196 onHelpD2D();
1197 return 0;
1198 }
1199 try {
1200 messageValue = Integer.parseInt(arg);
1201 } catch (NumberFormatException e) {
1202 errPw.println("message value must be a valid integer");
1203 return -1;
1204 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001205
Tyler Gunn92479152021-01-20 16:30:10 -08001206 try {
1207 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1208 } catch (RemoteException e) {
1209 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1210 errPw.println("Exception: " + e.getMessage());
1211 return -1;
1212 }
1213
1214 return 0;
1215 }
1216
Tyler Gunnbabbda02021-02-10 11:05:02 -08001217 private int handleD2dTransportCommand() {
1218 PrintWriter errPw = getErrPrintWriter();
1219
1220 String arg = getNextArg();
1221 if (arg == null) {
1222 onHelpD2D();
1223 return 0;
1224 }
1225
1226 try {
1227 mInterface.setActiveDeviceToDeviceTransport(arg);
1228 } catch (RemoteException e) {
1229 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1230 errPw.println("Exception: " + e.getMessage());
1231 return -1;
1232 }
1233 return 0;
1234 }
Nazanin014f41e2021-05-06 17:26:31 -07001235 private int handleBarringCommand() {
1236 String arg = getNextArg();
1237 if (arg == null) {
1238 onHelpBarring();
1239 return 0;
1240 }
1241
1242 switch (arg) {
1243 case BARRING_SEND_INFO: {
1244 return handleBarringSendCommand();
1245 }
1246 }
1247 return -1;
1248 }
1249
1250 private int handleBarringSendCommand() {
1251 PrintWriter errPw = getErrPrintWriter();
1252 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001253 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001254 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1255 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1256 boolean isConditionallyBarred = false;
1257 int conditionalBarringTimeSeconds = 0;
1258
1259 String opt;
1260 while ((opt = getNextOption()) != null) {
1261 switch (opt) {
1262 case "-s": {
1263 try {
1264 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001265 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001266 } catch (NumberFormatException e) {
1267 errPw.println("barring send requires an integer as a SLOT_ID.");
1268 return -1;
1269 }
1270 break;
1271 }
1272 case "-b": {
1273 try {
1274 barringType = Integer.parseInt(getNextArgRequired());
1275 if (barringType < -1 || barringType > 2) {
1276 throw new NumberFormatException();
1277 }
1278
1279 } catch (NumberFormatException e) {
1280 errPw.println("barring send requires an integer in range [-1,2] as "
1281 + "a BARRING_TYPE.");
1282 return -1;
1283 }
1284 break;
1285 }
1286 case "-c": {
1287 try {
1288 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1289 } catch (Exception e) {
1290 errPw.println("barring send requires a boolean after -c indicating"
1291 + " conditional barring");
1292 return -1;
1293 }
1294 break;
1295 }
1296 case "-t": {
1297 try {
1298 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1299 } catch (NumberFormatException e) {
1300 errPw.println("barring send requires an integer for time of barring"
1301 + " in seconds after -t for conditional barring");
1302 return -1;
1303 }
1304 break;
1305 }
1306 }
1307 }
1308 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1309 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1310 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1311 barringServiceInfos.append(0, bsi);
1312 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1313 try {
1314 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1315 } catch (Exception e) {
1316 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1317 errPw.println("Exception: " + e.getMessage());
1318 return -1;
1319 }
1320 return 0;
1321 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001322
Tyler Gunnd4575212021-05-03 14:46:49 -07001323 private int handleD2dDeviceSupportedCommand() {
1324 PrintWriter errPw = getErrPrintWriter();
1325
1326 String arg = getNextArg();
1327 if (arg == null) {
1328 onHelpD2D();
1329 return 0;
1330 }
1331
Jack Yua533d632022-09-30 13:53:46 -07001332 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001333 try {
1334 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1335 } catch (RemoteException e) {
1336 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1337 errPw.println("Exception: " + e.getMessage());
1338 return -1;
1339 }
1340 return 0;
1341 }
1342
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001343 // ims set-ims-service
1344 private int handleImsSetServiceCommand() {
1345 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001346 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001348 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001349
1350 String opt;
1351 while ((opt = getNextOption()) != null) {
1352 switch (opt) {
1353 case "-s": {
1354 try {
1355 slotId = Integer.parseInt(getNextArgRequired());
1356 } catch (NumberFormatException e) {
1357 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1358 return -1;
1359 }
1360 break;
1361 }
1362 case "-c": {
1363 isCarrierService = true;
1364 break;
1365 }
1366 case "-d": {
1367 isCarrierService = false;
1368 break;
1369 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001370 case "-f": {
1371 String featureString = getNextArgRequired();
1372 String[] features = featureString.split(",");
1373 for (int i = 0; i < features.length; i++) {
1374 try {
1375 Integer result = Integer.parseInt(features[i]);
1376 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1377 || result >= ImsFeature.FEATURE_MAX) {
1378 errPw.println("ims set-ims-service -f " + result
1379 + " is an invalid feature.");
1380 return -1;
1381 }
1382 featuresList.add(result);
1383 } catch (NumberFormatException e) {
1384 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1385 + " as an integer.");
1386 return -1;
1387 }
1388 }
1389 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001390 }
1391 }
1392 // Mandatory param, either -c or -d
1393 if (isCarrierService == null) {
1394 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1395 return -1;
1396 }
1397
1398 String packageName = getNextArg();
1399
1400 try {
1401 if (packageName == null) {
1402 packageName = "";
1403 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001404 int[] featureArray = new int[featuresList.size()];
1405 for (int i = 0; i < featuresList.size(); i++) {
1406 featureArray[i] = featuresList.get(i);
1407 }
1408 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1409 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001410 if (VDBG) {
1411 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001412 + (isCarrierService ? "-c " : "-d ")
1413 + "-f " + featuresList + " "
1414 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001415 }
1416 getOutPrintWriter().println(result);
1417 } catch (RemoteException e) {
1418 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001419 + (isCarrierService ? "-c " : "-d ")
1420 + "-f " + featuresList + " "
1421 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001422 errPw.println("Exception: " + e.getMessage());
1423 return -1;
1424 }
1425 return 0;
1426 }
1427
Brad Ebinger999d3302020-11-25 14:31:39 -08001428 // ims clear-ims-service-override
1429 private int handleImsClearCarrierServiceCommand() {
1430 PrintWriter errPw = getErrPrintWriter();
1431 int slotId = getDefaultSlot();
1432
1433 String opt;
1434 while ((opt = getNextOption()) != null) {
1435 switch (opt) {
1436 case "-s": {
1437 try {
1438 slotId = Integer.parseInt(getNextArgRequired());
1439 } catch (NumberFormatException e) {
1440 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1441 return -1;
1442 }
1443 break;
1444 }
1445 }
1446 }
1447
1448 try {
1449 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1450 if (VDBG) {
1451 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1452 + ", result=" + result);
1453 }
1454 getOutPrintWriter().println(result);
1455 } catch (RemoteException e) {
1456 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1457 + ", error" + e.getMessage());
1458 errPw.println("Exception: " + e.getMessage());
1459 return -1;
1460 }
1461 return 0;
1462 }
1463
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001464 // ims get-ims-service
1465 private int handleImsGetServiceCommand() {
1466 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001467 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001468 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001469 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001470
1471 String opt;
1472 while ((opt = getNextOption()) != null) {
1473 switch (opt) {
1474 case "-s": {
1475 try {
1476 slotId = Integer.parseInt(getNextArgRequired());
1477 } catch (NumberFormatException e) {
1478 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1479 return -1;
1480 }
1481 break;
1482 }
1483 case "-c": {
1484 isCarrierService = true;
1485 break;
1486 }
1487 case "-d": {
1488 isCarrierService = false;
1489 break;
1490 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001491 case "-f": {
1492 try {
1493 featureType = Integer.parseInt(getNextArg());
1494 } catch (NumberFormatException e) {
1495 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1496 return -1;
1497 }
1498 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1499 || featureType >= ImsFeature.FEATURE_MAX) {
1500 errPw.println("ims get-ims-service -f invalid feature.");
1501 return -1;
1502 }
1503 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001504 }
1505 }
1506 // Mandatory param, either -c or -d
1507 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001508 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001509 return -1;
1510 }
1511
1512 String result;
1513 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001514 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001515 } catch (RemoteException e) {
1516 return -1;
1517 }
1518 if (VDBG) {
1519 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001520 + (isCarrierService ? "-c " : "-d ")
1521 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1522 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001523 }
1524 getOutPrintWriter().println(result);
1525 return 0;
1526 }
1527
1528 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001529 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001530 String opt;
1531 while ((opt = getNextOption()) != null) {
1532 switch (opt) {
1533 case "-s": {
1534 try {
1535 slotId = Integer.parseInt(getNextArgRequired());
1536 } catch (NumberFormatException e) {
1537 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1538 return -1;
1539 }
1540 break;
1541 }
1542 }
1543 }
1544 try {
1545 mInterface.enableIms(slotId);
1546 } catch (RemoteException e) {
1547 return -1;
1548 }
1549 if (VDBG) {
1550 Log.v(LOG_TAG, "ims enable -s " + slotId);
1551 }
1552 return 0;
1553 }
1554
1555 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001556 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001557 String opt;
1558 while ((opt = getNextOption()) != null) {
1559 switch (opt) {
1560 case "-s": {
1561 try {
1562 slotId = Integer.parseInt(getNextArgRequired());
1563 } catch (NumberFormatException e) {
1564 getErrPrintWriter().println(
1565 "ims disable requires an integer as a SLOT_ID.");
1566 return -1;
1567 }
1568 break;
1569 }
1570 }
1571 }
1572 try {
1573 mInterface.disableIms(slotId);
1574 } catch (RemoteException e) {
1575 return -1;
1576 }
1577 if (VDBG) {
1578 Log.v(LOG_TAG, "ims disable -s " + slotId);
1579 }
1580 return 0;
1581 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001582
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001583 private int handleCepChange() {
1584 Log.i(LOG_TAG, "handleCepChange");
1585 String opt = getNextArg();
1586 if (opt == null) {
1587 return -1;
1588 }
1589 boolean isCepEnabled = opt.equals("enable");
1590
1591 try {
1592 mInterface.setCepEnabled(isCepEnabled);
1593 } catch (RemoteException e) {
1594 return -1;
1595 }
1596 return 0;
1597 }
1598
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001599 private int getDefaultSlot() {
1600 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1601 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1602 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1603 // If there is no default, default to slot 0.
1604 slotId = DEFAULT_PHONE_ID;
1605 }
1606 return slotId;
1607 }
sqian2fff4a32018-11-05 14:18:37 -08001608
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001609 // Parse options related to Carrier Config Commands.
1610 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001611 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001612 CcOptionParseResult result = new CcOptionParseResult();
1613 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1614 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001615
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001616 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001617 while ((opt = getNextOption()) != null) {
1618 switch (opt) {
1619 case "-s": {
1620 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001621 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1622 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1623 errPw.println(tag + "No valid subscription found.");
1624 return null;
1625 }
1626
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001627 } catch (IllegalArgumentException e) {
1628 // Missing slot id
1629 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 return null;
1631 }
1632 break;
1633 }
1634 case "-p": {
1635 if (allowOptionPersistent) {
1636 result.mPersistent = true;
1637 } else {
1638 errPw.println(tag + "Unexpected option " + opt);
1639 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001640 }
1641 break;
1642 }
1643 default: {
1644 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001645 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001646 }
1647 }
1648 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001649 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001650 }
1651
1652 private int slotStringToSubId(String tag, String slotString) {
1653 int slotId = -1;
1654 try {
1655 slotId = Integer.parseInt(slotString);
1656 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001657 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1658 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1659 }
1660
1661 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001662 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1663 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1664 }
1665
Qiong Liuf25799b2020-09-10 10:13:46 +08001666 Phone phone = PhoneFactory.getPhone(slotId);
1667 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001668 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1669 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1670 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001671 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001672 }
1673
Hall Liud892bec2018-11-30 14:51:45 -08001674 private boolean checkShellUid() {
Jack Yu26735292024-09-25 14:33:49 -07001675 return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
Hall Liud892bec2018-11-30 14:51:45 -08001676 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001677
1678 private int handleCcCommand() {
1679 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1680 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001681 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1682 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001683 getErrPrintWriter().println("cc: Permission denied.");
1684 return -1;
1685 }
1686
1687 String arg = getNextArg();
1688 if (arg == null) {
1689 onHelpCc();
1690 return 0;
1691 }
1692
1693 switch (arg) {
1694 case CC_GET_VALUE: {
1695 return handleCcGetValue();
1696 }
1697 case CC_SET_VALUE: {
1698 return handleCcSetValue();
1699 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001700 case CC_SET_VALUES_FROM_XML: {
1701 return handleCcSetValuesFromXml();
1702 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001703 case CC_CLEAR_VALUES: {
1704 return handleCcClearValues();
1705 }
1706 default: {
1707 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1708 }
1709 }
1710 return -1;
1711 }
1712
1713 // cc get-value
1714 private int handleCcGetValue() {
1715 PrintWriter errPw = getErrPrintWriter();
1716 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1717 String key = null;
1718
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001719 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001720 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001721 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001722 return -1;
1723 }
1724
1725 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001726 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001727 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001728 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001729 return -1;
1730 }
1731
1732 // Get the key.
1733 key = getNextArg();
1734 if (key != null) {
1735 // A key was provided. Verify if it is a valid key
1736 if (!bundle.containsKey(key)) {
1737 errPw.println(tag + key + " is not a valid key.");
1738 return -1;
1739 }
1740
1741 // Print the carrier config value for key.
1742 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1743 } else {
1744 // No key provided. Show all values.
1745 // Iterate over a sorted list of all carrier config keys and print them.
1746 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1747 for (String k : sortedSet) {
1748 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1749 }
1750 }
1751 return 0;
1752 }
1753
1754 // cc set-value
1755 private int handleCcSetValue() {
1756 PrintWriter errPw = getErrPrintWriter();
1757 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1758
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001759 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001760 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001761 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001762 return -1;
1763 }
1764
1765 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001766 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001767 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001768 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001769 return -1;
1770 }
1771
1772 // Get the key.
1773 String key = getNextArg();
1774 if (key == null || key.equals("")) {
1775 errPw.println(tag + "KEY is missing");
1776 return -1;
1777 }
1778
1779 // Verify if the key is valid
1780 if (!originalValues.containsKey(key)) {
1781 errPw.println(tag + key + " is not a valid key.");
1782 return -1;
1783 }
1784
1785 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1786 ArrayList<String> valueList = new ArrayList<String>();
1787 while (peekNextArg() != null) {
1788 valueList.add(getNextArg());
1789 }
1790
1791 // Find the type of the carrier config value
1792 CcType type = getType(tag, key, originalValues);
1793 if (type == CcType.UNKNOWN) {
1794 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1795 return -1;
1796 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001797 if (type == CcType.PERSISTABLE_BUNDLE) {
1798 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1799 + "Use set-values-from-xml instead.");
1800 return -1;
1801 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001802
1803 // Create an override bundle containing the key and value that should be overriden.
1804 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1805 if (overrideBundle == null) {
1806 return -1;
1807 }
1808
1809 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001810 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001811
1812 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001813 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001814 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001815 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001816 return -1;
1817 }
1818
1819 // Print the original and new value.
1820 String originalValueString = ccValueToString(key, type, originalValues);
1821 String newValueString = ccValueToString(key, type, newValues);
1822 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1823 getOutPrintWriter().println("New value: \n" + newValueString);
1824
1825 return 0;
1826 }
1827
Allen Xuee00f0e2022-03-14 21:04:49 +00001828 // cc set-values-from-xml
1829 private int handleCcSetValuesFromXml() {
1830 PrintWriter errPw = getErrPrintWriter();
1831 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1832
1833 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001834 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001835 if (options == null) {
1836 return -1;
1837 }
1838
1839 // Get bundle containing all current carrier configuration values.
1840 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1841 if (originalValues == null) {
1842 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1843 return -1;
1844 }
1845
1846 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1847 if (overrideBundle == null) {
1848 return -1;
1849 }
1850
1851 // Verify all values are valid types
1852 for (String key : overrideBundle.keySet()) {
1853 CcType type = getType(tag, key, originalValues);
1854 if (type == CcType.UNKNOWN) {
1855 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1856 return -1;
1857 }
1858 }
1859
1860 // Override the value
1861 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1862
1863 // Find bundle containing all new carrier configuration values after the override.
1864 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1865 if (newValues == null) {
1866 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1867 return -1;
1868 }
1869
1870 // Print the original and new values
1871 overrideBundle.keySet().forEach(key -> {
1872 CcType type = getType(tag, key, originalValues);
1873 String originalValueString = ccValueToString(key, type, originalValues);
1874 String newValueString = ccValueToString(key, type, newValues);
1875 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1876 getOutPrintWriter().println("New value: \n" + newValueString);
1877 });
1878
1879 return 0;
1880 }
1881
1882 private PersistableBundle readPersistableBundleFromXml(String tag) {
1883 PersistableBundle subIdBundles;
1884 try {
1885 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1886 } catch (IOException | RuntimeException e) {
1887 PrintWriter errPw = getErrPrintWriter();
1888 errPw.println(tag + e);
1889 return null;
1890 }
1891
1892 return subIdBundles;
1893 }
1894
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001895 // cc clear-values
1896 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001897 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1898
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001899 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001900 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001901 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001902 return -1;
1903 }
1904
1905 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001906 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001907 getOutPrintWriter()
1908 .println("All previously set carrier config override values has been cleared");
1909 return 0;
1910 }
1911
1912 private CcType getType(String tag, String key, PersistableBundle bundle) {
1913 // Find the type by checking the type of the current value stored in the bundle.
1914 Object value = bundle.get(key);
1915
1916 if (CC_TYPE_MAP.containsKey(key)) {
1917 return CC_TYPE_MAP.get(key);
1918 } else if (value != null) {
1919 if (value instanceof Boolean) {
1920 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001921 }
1922 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001923 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001924 }
1925 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001926 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001927 }
1928 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001929 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001930 }
1931 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001932 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001933 }
1934 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001935 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001936 }
1937 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001938 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001939 }
1940 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001941 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001942 }
1943 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001944 return CcType.STRING_ARRAY;
1945 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 if (value instanceof PersistableBundle) {
1947 return CcType.PERSISTABLE_BUNDLE;
1948 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001949 } else {
1950 // Current value was null and can therefore not be used in order to find the type.
1951 // Check the name of the key to infer the type. This check is not needed for primitive
1952 // data types (boolean, double, int and long), since they can not be null.
1953 if (key.endsWith("double_array")) {
1954 return CcType.DOUBLE_ARRAY;
1955 }
1956 if (key.endsWith("int_array")) {
1957 return CcType.INT_ARRAY;
1958 }
1959 if (key.endsWith("long_array")) {
1960 return CcType.LONG_ARRAY;
1961 }
1962 if (key.endsWith("string")) {
1963 return CcType.STRING;
1964 }
1965 if (key.endsWith("string_array") || key.endsWith("strings")) {
1966 return CcType.STRING_ARRAY;
1967 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001968 if (key.endsWith("bundle")) {
1969 return CcType.PERSISTABLE_BUNDLE;
1970 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001971 }
1972
1973 // Not possible to infer the type by looking at the current value or the key.
1974 PrintWriter errPw = getErrPrintWriter();
1975 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1976 return CcType.UNKNOWN;
1977 }
1978
1979 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1980 String result;
1981 StringBuilder valueString = new StringBuilder();
1982 String typeString = type.toString();
1983 Object value = bundle.get(key);
1984
1985 if (value == null) {
1986 valueString.append("null");
1987 } else {
1988 switch (type) {
1989 case DOUBLE_ARRAY: {
1990 // Format the string representation of the int array as value1 value2......
1991 double[] valueArray = (double[]) value;
1992 for (int i = 0; i < valueArray.length; i++) {
1993 if (i != 0) {
1994 valueString.append(" ");
1995 }
1996 valueString.append(valueArray[i]);
1997 }
1998 break;
1999 }
2000 case INT_ARRAY: {
2001 // Format the string representation of the int array as value1 value2......
2002 int[] valueArray = (int[]) value;
2003 for (int i = 0; i < valueArray.length; i++) {
2004 if (i != 0) {
2005 valueString.append(" ");
2006 }
2007 valueString.append(valueArray[i]);
2008 }
2009 break;
2010 }
2011 case LONG_ARRAY: {
2012 // Format the string representation of the int array as value1 value2......
2013 long[] valueArray = (long[]) value;
2014 for (int i = 0; i < valueArray.length; i++) {
2015 if (i != 0) {
2016 valueString.append(" ");
2017 }
2018 valueString.append(valueArray[i]);
2019 }
2020 break;
2021 }
2022 case STRING: {
2023 valueString.append("\"" + value.toString() + "\"");
2024 break;
2025 }
2026 case STRING_ARRAY: {
2027 // Format the string representation of the string array as "value1" "value2"....
2028 String[] valueArray = (String[]) value;
2029 for (int i = 0; i < valueArray.length; i++) {
2030 if (i != 0) {
2031 valueString.append(" ");
2032 }
2033 if (valueArray[i] != null) {
2034 valueString.append("\"" + valueArray[i] + "\"");
2035 } else {
2036 valueString.append("null");
2037 }
2038 }
2039 break;
2040 }
2041 default: {
2042 valueString.append(value.toString());
2043 }
2044 }
2045 }
2046 return String.format("%-70s %-15s %s", key, typeString, valueString);
2047 }
2048
2049 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2050 ArrayList<String> valueList) {
2051 PrintWriter errPw = getErrPrintWriter();
2052 PersistableBundle bundle = new PersistableBundle();
2053
2054 // First verify that a valid number of values has been provided for the type.
2055 switch (type) {
2056 case BOOLEAN:
2057 case DOUBLE:
2058 case INT:
2059 case LONG: {
2060 if (valueList.size() != 1) {
2061 errPw.println(tag + "Expected 1 value for type " + type
2062 + ". Found: " + valueList.size());
2063 return null;
2064 }
2065 break;
2066 }
2067 case STRING: {
2068 if (valueList.size() > 1) {
2069 errPw.println(tag + "Expected 0 or 1 values for type " + type
2070 + ". Found: " + valueList.size());
2071 return null;
2072 }
2073 break;
2074 }
2075 }
2076
2077 // Parse the value according to type and add it to the Bundle.
2078 switch (type) {
2079 case BOOLEAN: {
2080 if ("true".equalsIgnoreCase(valueList.get(0))) {
2081 bundle.putBoolean(key, true);
2082 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2083 bundle.putBoolean(key, false);
2084 } else {
2085 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2086 return null;
2087 }
2088 break;
2089 }
2090 case DOUBLE: {
2091 try {
2092 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2093 } catch (NumberFormatException nfe) {
2094 // Not a valid double
2095 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2096 return null;
2097 }
2098 break;
2099 }
2100 case DOUBLE_ARRAY: {
2101 double[] valueDoubleArray = null;
2102 if (valueList.size() > 0) {
2103 valueDoubleArray = new double[valueList.size()];
2104 for (int i = 0; i < valueList.size(); i++) {
2105 try {
2106 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2107 } catch (NumberFormatException nfe) {
2108 // Not a valid double
2109 errPw.println(
2110 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2111 return null;
2112 }
2113 }
2114 }
2115 bundle.putDoubleArray(key, valueDoubleArray);
2116 break;
2117 }
2118 case INT: {
2119 try {
2120 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2121 } catch (NumberFormatException nfe) {
2122 // Not a valid integer
2123 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2124 return null;
2125 }
2126 break;
2127 }
2128 case INT_ARRAY: {
2129 int[] valueIntArray = null;
2130 if (valueList.size() > 0) {
2131 valueIntArray = new int[valueList.size()];
2132 for (int i = 0; i < valueList.size(); i++) {
2133 try {
2134 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2135 } catch (NumberFormatException nfe) {
2136 // Not a valid integer
2137 errPw.println(tag
2138 + "Unable to parse " + valueList.get(i) + " as an integer.");
2139 return null;
2140 }
2141 }
2142 }
2143 bundle.putIntArray(key, valueIntArray);
2144 break;
2145 }
2146 case LONG: {
2147 try {
2148 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2149 } catch (NumberFormatException nfe) {
2150 // Not a valid long
2151 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2152 return null;
2153 }
2154 break;
2155 }
2156 case LONG_ARRAY: {
2157 long[] valueLongArray = null;
2158 if (valueList.size() > 0) {
2159 valueLongArray = new long[valueList.size()];
2160 for (int i = 0; i < valueList.size(); i++) {
2161 try {
2162 valueLongArray[i] = Long.parseLong(valueList.get(i));
2163 } catch (NumberFormatException nfe) {
2164 // Not a valid long
2165 errPw.println(
2166 tag + "Unable to parse " + valueList.get(i) + " as a long");
2167 return null;
2168 }
2169 }
2170 }
2171 bundle.putLongArray(key, valueLongArray);
2172 break;
2173 }
2174 case STRING: {
2175 String value = null;
2176 if (valueList.size() > 0) {
2177 value = valueList.get(0);
2178 }
2179 bundle.putString(key, value);
2180 break;
2181 }
2182 case STRING_ARRAY: {
2183 String[] valueStringArray = null;
2184 if (valueList.size() > 0) {
2185 valueStringArray = new String[valueList.size()];
2186 valueList.toArray(valueStringArray);
2187 }
2188 bundle.putStringArray(key, valueStringArray);
2189 break;
2190 }
2191 }
2192 return bundle;
2193 }
Shuo Qian489d9282020-07-09 11:30:03 -07002194
2195 private int handleEndBlockSuppressionCommand() {
2196 if (!checkShellUid()) {
2197 return -1;
2198 }
2199
2200 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2201 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2202 }
2203 return 0;
2204 }
Hui Wang641e81c2020-10-12 12:14:23 -07002205
Michele Berionne54af4632020-12-28 20:23:16 +00002206 private int handleRestartModemCommand() {
2207 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2208 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002209 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2210 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002211 getErrPrintWriter().println("RestartModem: Permission denied.");
2212 return -1;
2213 }
2214
2215 boolean result = TelephonyManager.getDefault().rebootRadio();
2216 getOutPrintWriter().println(result);
2217
2218 return result ? 0 : -1;
2219 }
2220
Ling Ma4fbab492022-01-25 22:36:16 +00002221 private int handleGetImei() {
2222 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2223 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002224 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2225 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002226 getErrPrintWriter().println("Device IMEI: Permission denied.");
2227 return -1;
2228 }
2229
2230 final long identity = Binder.clearCallingIdentity();
2231
2232 String imei = null;
2233 String arg = getNextArg();
2234 if (arg != null) {
2235 try {
2236 int specifiedSlotIndex = Integer.parseInt(arg);
2237 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2238 } catch (NumberFormatException exception) {
2239 PrintWriter errPw = getErrPrintWriter();
2240 errPw.println("-s requires an integer as slot index.");
2241 return -1;
2242 }
2243
2244 } else {
2245 imei = TelephonyManager.from(mContext).getImei();
2246 }
2247 getOutPrintWriter().println("Device IMEI: " + imei);
2248
2249 Binder.restoreCallingIdentity(identity);
2250 return 0;
2251 }
2252
Michele Berionne5e411512020-11-13 02:36:59 +00002253 private int handleUnattendedReboot() {
2254 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2255 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002256 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2257 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002258 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2259 return -1;
2260 }
2261
2262 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2263 getOutPrintWriter().println("result: " + result);
2264
2265 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2266 }
2267
Aman Gupta07124872022-02-09 08:02:14 +00002268 private int handleGetSimSlotsMapping() {
2269 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2270 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002271 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2272 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002273 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2274 return -1;
2275 }
2276 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2277 String result = telephonyManager.getSimSlotMapping().toString();
2278 getOutPrintWriter().println("simSlotsMapping: " + result);
2279
2280 return 0;
2281 }
2282
Hui Wang641e81c2020-10-12 12:14:23 -07002283 private int handleGbaCommand() {
2284 String arg = getNextArg();
2285 if (arg == null) {
2286 onHelpGba();
2287 return 0;
2288 }
2289
2290 switch (arg) {
2291 case GBA_SET_SERVICE: {
2292 return handleGbaSetServiceCommand();
2293 }
2294 case GBA_GET_SERVICE: {
2295 return handleGbaGetServiceCommand();
2296 }
2297 case GBA_SET_RELEASE_TIME: {
2298 return handleGbaSetReleaseCommand();
2299 }
2300 case GBA_GET_RELEASE_TIME: {
2301 return handleGbaGetReleaseCommand();
2302 }
2303 }
2304
2305 return -1;
2306 }
2307
2308 private int getSubId(String cmd) {
2309 int slotId = getDefaultSlot();
2310 String opt = getNextOption();
2311 if (opt != null && opt.equals("-s")) {
2312 try {
2313 slotId = Integer.parseInt(getNextArgRequired());
2314 } catch (NumberFormatException e) {
2315 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2316 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2317 }
2318 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002319 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002320 }
2321
2322 private int handleGbaSetServiceCommand() {
2323 int subId = getSubId("gba set-service");
2324 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2325 return -1;
2326 }
2327
2328 String packageName = getNextArg();
2329 try {
2330 if (packageName == null) {
2331 packageName = "";
2332 }
2333 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2334 if (VDBG) {
2335 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2336 + packageName + ", result=" + result);
2337 }
2338 getOutPrintWriter().println(result);
2339 } catch (RemoteException e) {
2340 Log.w(LOG_TAG, "gba set-service " + subId + " "
2341 + packageName + ", error" + e.getMessage());
2342 getErrPrintWriter().println("Exception: " + e.getMessage());
2343 return -1;
2344 }
2345 return 0;
2346 }
2347
2348 private int handleGbaGetServiceCommand() {
2349 String result;
2350
2351 int subId = getSubId("gba get-service");
2352 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2353 return -1;
2354 }
2355
2356 try {
2357 result = mInterface.getBoundGbaService(subId);
2358 } catch (RemoteException e) {
2359 return -1;
2360 }
2361 if (VDBG) {
2362 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2363 }
2364 getOutPrintWriter().println(result);
2365 return 0;
2366 }
2367
2368 private int handleGbaSetReleaseCommand() {
2369 //the release time value could be -1
2370 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2371 : SubscriptionManager.getDefaultSubscriptionId();
2372 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2373 return -1;
2374 }
2375
2376 String intervalStr = getNextArg();
2377 if (intervalStr == null) {
2378 return -1;
2379 }
2380
2381 try {
2382 int interval = Integer.parseInt(intervalStr);
2383 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2384 if (VDBG) {
2385 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2386 + intervalStr + ", result=" + result);
2387 }
2388 getOutPrintWriter().println(result);
2389 } catch (NumberFormatException | RemoteException e) {
2390 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2391 + intervalStr + ", error" + e.getMessage());
2392 getErrPrintWriter().println("Exception: " + e.getMessage());
2393 return -1;
2394 }
2395 return 0;
2396 }
2397
2398 private int handleGbaGetReleaseCommand() {
2399 int subId = getSubId("gba get-release");
2400 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2401 return -1;
2402 }
2403
2404 int result = 0;
2405 try {
2406 result = mInterface.getGbaReleaseTime(subId);
2407 } catch (RemoteException e) {
2408 return -1;
2409 }
2410 if (VDBG) {
2411 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2412 }
2413 getOutPrintWriter().println(result);
2414 return 0;
2415 }
Hui Wang761a6682020-10-31 05:12:53 +00002416
2417 private int handleSingleRegistrationConfigCommand() {
2418 String arg = getNextArg();
2419 if (arg == null) {
2420 onHelpSrc();
2421 return 0;
2422 }
2423
2424 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002425 case SRC_SET_TEST_ENABLED: {
2426 return handleSrcSetTestEnabledCommand();
2427 }
2428 case SRC_GET_TEST_ENABLED: {
2429 return handleSrcGetTestEnabledCommand();
2430 }
Hui Wang761a6682020-10-31 05:12:53 +00002431 case SRC_SET_DEVICE_ENABLED: {
2432 return handleSrcSetDeviceEnabledCommand();
2433 }
2434 case SRC_GET_DEVICE_ENABLED: {
2435 return handleSrcGetDeviceEnabledCommand();
2436 }
2437 case SRC_SET_CARRIER_ENABLED: {
2438 return handleSrcSetCarrierEnabledCommand();
2439 }
2440 case SRC_GET_CARRIER_ENABLED: {
2441 return handleSrcGetCarrierEnabledCommand();
2442 }
Hui Wangb647abe2021-02-26 09:33:38 -08002443 case SRC_SET_FEATURE_ENABLED: {
2444 return handleSrcSetFeatureValidationCommand();
2445 }
2446 case SRC_GET_FEATURE_ENABLED: {
2447 return handleSrcGetFeatureValidationCommand();
2448 }
Hui Wang761a6682020-10-31 05:12:53 +00002449 }
2450
2451 return -1;
2452 }
2453
James.cf Linbcdf8b32021-01-14 16:44:13 +08002454 private int handleRcsUceCommand() {
2455 String arg = getNextArg();
2456 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002457 onHelpUce();
2458 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002459 }
2460
2461 switch (arg) {
2462 case UCE_REMOVE_EAB_CONTACT:
2463 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002464 case UCE_GET_EAB_CONTACT:
2465 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002466 case UCE_GET_EAB_CAPABILITY:
2467 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002468 case UCE_GET_DEVICE_ENABLED:
2469 return handleUceGetDeviceEnabledCommand();
2470 case UCE_SET_DEVICE_ENABLED:
2471 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002472 case UCE_OVERRIDE_PUBLISH_CAPS:
2473 return handleUceOverridePublishCaps();
2474 case UCE_GET_LAST_PIDF_XML:
2475 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002476 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2477 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002478 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2479 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002480 }
2481 return -1;
2482 }
2483
2484 private int handleRemovingEabContactCommand() {
2485 int subId = getSubId("uce remove-eab-contact");
2486 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2487 return -1;
2488 }
2489
2490 String phoneNumber = getNextArgRequired();
2491 if (TextUtils.isEmpty(phoneNumber)) {
2492 return -1;
2493 }
2494 int result = 0;
2495 try {
2496 result = mInterface.removeContactFromEab(subId, phoneNumber);
2497 } catch (RemoteException e) {
2498 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2499 getErrPrintWriter().println("Exception: " + e.getMessage());
2500 return -1;
2501 }
2502
2503 if (VDBG) {
2504 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2505 }
calvinpan293ea1b2021-02-04 17:52:13 +08002506 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002507 }
2508
calvinpane4a8a1d2021-01-25 13:51:18 +08002509 private int handleGettingEabContactCommand() {
2510 String phoneNumber = getNextArgRequired();
2511 if (TextUtils.isEmpty(phoneNumber)) {
2512 return -1;
2513 }
2514 String result = "";
2515 try {
2516 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002517 } catch (RemoteException e) {
2518 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2519 getErrPrintWriter().println("Exception: " + e.getMessage());
2520 return -1;
2521 }
2522
2523 if (VDBG) {
2524 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2525 }
calvinpan293ea1b2021-02-04 17:52:13 +08002526 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002527 return 0;
2528 }
2529
Calvin Pana1434322021-07-01 19:27:01 +08002530 private int handleGettingEabCapabilityCommand() {
2531 String phoneNumber = getNextArgRequired();
2532 if (TextUtils.isEmpty(phoneNumber)) {
2533 return -1;
2534 }
2535 String result = "";
2536 try {
2537 result = mInterface.getCapabilityFromEab(phoneNumber);
2538 } catch (RemoteException e) {
2539 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2540 getErrPrintWriter().println("Exception: " + e.getMessage());
2541 return -1;
2542 }
2543
2544 if (VDBG) {
2545 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2546 }
2547 getOutPrintWriter().println(result);
2548 return 0;
2549 }
2550
James.cf Lin4b784aa2021-01-31 03:25:15 +08002551 private int handleUceGetDeviceEnabledCommand() {
2552 boolean result = false;
2553 try {
2554 result = mInterface.getDeviceUceEnabled();
2555 } catch (RemoteException e) {
2556 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2557 return -1;
2558 }
2559 if (VDBG) {
2560 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2561 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002562 getOutPrintWriter().println(result);
2563 return 0;
2564 }
2565
James.cf Lin4b784aa2021-01-31 03:25:15 +08002566 private int handleUceSetDeviceEnabledCommand() {
2567 String enabledStr = getNextArg();
2568 if (TextUtils.isEmpty(enabledStr)) {
2569 return -1;
2570 }
2571
2572 try {
2573 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2574 mInterface.setDeviceUceEnabled(isEnabled);
2575 if (VDBG) {
2576 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2577 }
2578 } catch (NumberFormatException | RemoteException e) {
2579 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2580 getErrPrintWriter().println("Exception: " + e.getMessage());
2581 return -1;
2582 }
2583 return 0;
2584 }
2585
James.cf Line8713a42021-04-29 16:04:26 +08002586 private int handleUceRemoveRequestDisallowedStatus() {
2587 int subId = getSubId("uce remove-request-disallowed-status");
2588 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2589 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2590 return -1;
2591 }
2592 boolean result;
2593 try {
2594 result = mInterface.removeUceRequestDisallowedStatus(subId);
2595 } catch (RemoteException e) {
2596 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2597 return -1;
2598 }
2599 if (VDBG) {
2600 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2601 }
2602 getOutPrintWriter().println(result);
2603 return 0;
2604 }
2605
James.cf Lin0fc71b02021-05-25 01:37:38 +08002606 private int handleUceSetCapRequestTimeout() {
2607 int subId = getSubId("uce set-capabilities-request-timeout");
2608 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2609 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2610 return -1;
2611 }
2612 long timeoutAfterMs = Long.valueOf(getNextArg());
2613 boolean result;
2614 try {
2615 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2616 } catch (RemoteException e) {
2617 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2618 return -1;
2619 }
2620 if (VDBG) {
2621 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2622 }
2623 getOutPrintWriter().println(result);
2624 return 0;
2625 }
2626
Hui Wangbaaee6a2021-02-19 20:45:36 -08002627 private int handleSrcSetTestEnabledCommand() {
2628 String enabledStr = getNextArg();
2629 if (enabledStr == null) {
2630 return -1;
2631 }
2632
2633 try {
2634 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2635 if (VDBG) {
2636 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2637 }
2638 getOutPrintWriter().println("Done");
2639 } catch (NumberFormatException | RemoteException e) {
2640 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2641 getErrPrintWriter().println("Exception: " + e.getMessage());
2642 return -1;
2643 }
2644 return 0;
2645 }
2646
2647 private int handleSrcGetTestEnabledCommand() {
2648 boolean result = false;
2649 try {
2650 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2651 } catch (RemoteException e) {
2652 return -1;
2653 }
2654 if (VDBG) {
2655 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2656 }
2657 getOutPrintWriter().println(result);
2658 return 0;
2659 }
2660
Brad Ebinger14d467f2021-02-12 06:18:28 +00002661 private int handleUceOverridePublishCaps() {
2662 int subId = getSubId("uce override-published-caps");
2663 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2664 return -1;
2665 }
2666 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2667 String operation = getNextArgRequired();
2668 String caps = getNextArg();
2669 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2670 && !"list".equals(operation)) {
2671 getErrPrintWriter().println("Invalid operation: " + operation);
2672 return -1;
2673 }
2674
2675 // add/remove requires capabilities to be specified.
2676 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2677 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2678 + "specified");
2679 return -1;
2680 }
2681
2682 ArraySet<String> capSet = new ArraySet<>();
2683 if (!TextUtils.isEmpty(caps)) {
2684 String[] capArray = caps.split(":");
2685 for (String cap : capArray) {
2686 // Allow unknown tags to be passed in as well.
2687 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2688 }
2689 }
2690
2691 RcsContactUceCapability result = null;
2692 try {
2693 switch (operation) {
2694 case "add":
2695 result = mInterface.addUceRegistrationOverrideShell(subId,
2696 new ArrayList<>(capSet));
2697 break;
2698 case "remove":
2699 result = mInterface.removeUceRegistrationOverrideShell(subId,
2700 new ArrayList<>(capSet));
2701 break;
2702 case "clear":
2703 result = mInterface.clearUceRegistrationOverrideShell(subId);
2704 break;
2705 case "list":
2706 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2707 break;
2708 }
2709 } catch (RemoteException e) {
2710 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2711 getErrPrintWriter().println("Exception: " + e.getMessage());
2712 return -1;
2713 } catch (ServiceSpecificException sse) {
2714 // Reconstruct ImsException
2715 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2716 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2717 getErrPrintWriter().println("Exception: " + imsException);
2718 return -1;
2719 }
2720 if (result == null) {
2721 getErrPrintWriter().println("Service not available");
2722 return -1;
2723 }
2724 getOutPrintWriter().println(result);
2725 return 0;
2726 }
2727
2728 private int handleUceGetPidfXml() {
2729 int subId = getSubId("uce get-last-publish-pidf");
2730 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2731 return -1;
2732 }
2733
2734 String result;
2735 try {
2736 result = mInterface.getLastUcePidfXmlShell(subId);
2737 } catch (RemoteException e) {
2738 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2739 getErrPrintWriter().println("Exception: " + e.getMessage());
2740 return -1;
2741 } catch (ServiceSpecificException sse) {
2742 // Reconstruct ImsException
2743 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2744 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2745 getErrPrintWriter().println("Exception: " + imsException);
2746 return -1;
2747 }
2748 if (result == null) {
2749 getErrPrintWriter().println("Service not available");
2750 return -1;
2751 }
2752 getOutPrintWriter().println(result);
2753 return 0;
2754 }
2755
Hui Wang761a6682020-10-31 05:12:53 +00002756 private int handleSrcSetDeviceEnabledCommand() {
2757 String enabledStr = getNextArg();
2758 if (enabledStr == null) {
2759 return -1;
2760 }
2761
2762 try {
2763 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2764 if (VDBG) {
2765 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2766 }
2767 getOutPrintWriter().println("Done");
2768 } catch (NumberFormatException | RemoteException e) {
2769 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2770 getErrPrintWriter().println("Exception: " + e.getMessage());
2771 return -1;
2772 }
2773 return 0;
2774 }
2775
2776 private int handleSrcGetDeviceEnabledCommand() {
2777 boolean result = false;
2778 try {
2779 result = mInterface.getDeviceSingleRegistrationEnabled();
2780 } catch (RemoteException e) {
2781 return -1;
2782 }
2783 if (VDBG) {
2784 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2785 }
2786 getOutPrintWriter().println(result);
2787 return 0;
2788 }
2789
2790 private int handleSrcSetCarrierEnabledCommand() {
2791 //the release time value could be -1
2792 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2793 : SubscriptionManager.getDefaultSubscriptionId();
2794 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2795 return -1;
2796 }
2797
2798 String enabledStr = getNextArg();
2799 if (enabledStr == null) {
2800 return -1;
2801 }
2802
2803 try {
2804 boolean result =
2805 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2806 if (VDBG) {
2807 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2808 + enabledStr + ", result=" + result);
2809 }
2810 getOutPrintWriter().println(result);
2811 } catch (NumberFormatException | RemoteException e) {
2812 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2813 + enabledStr + ", error" + e.getMessage());
2814 getErrPrintWriter().println("Exception: " + e.getMessage());
2815 return -1;
2816 }
2817 return 0;
2818 }
2819
2820 private int handleSrcGetCarrierEnabledCommand() {
2821 int subId = getSubId("src get-carrier-enabled");
2822 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2823 return -1;
2824 }
2825
2826 boolean result = false;
2827 try {
2828 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2829 } catch (RemoteException e) {
2830 return -1;
2831 }
2832 if (VDBG) {
2833 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2834 }
2835 getOutPrintWriter().println(result);
2836 return 0;
2837 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002838
Hui Wangb647abe2021-02-26 09:33:38 -08002839 private int handleSrcSetFeatureValidationCommand() {
2840 //the release time value could be -1
2841 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2842 : SubscriptionManager.getDefaultSubscriptionId();
2843 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2844 return -1;
2845 }
2846
2847 String enabledStr = getNextArg();
2848 if (enabledStr == null) {
2849 return -1;
2850 }
2851
2852 try {
2853 boolean result =
2854 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2855 if (VDBG) {
2856 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2857 + enabledStr + ", result=" + result);
2858 }
2859 getOutPrintWriter().println(result);
2860 } catch (NumberFormatException | RemoteException e) {
2861 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2862 + enabledStr + ", error" + e.getMessage());
2863 getErrPrintWriter().println("Exception: " + e.getMessage());
2864 return -1;
2865 }
2866 return 0;
2867 }
2868
2869 private int handleSrcGetFeatureValidationCommand() {
2870 int subId = getSubId("src get-feature-validation");
2871 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2872 return -1;
2873 }
2874
2875 Boolean result = false;
2876 try {
2877 result = mInterface.getImsFeatureValidationOverride(subId);
2878 } catch (RemoteException e) {
2879 return -1;
2880 }
2881 if (VDBG) {
2882 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2883 }
2884 getOutPrintWriter().println(result);
2885 return 0;
2886 }
2887
2888
Hall Liuaa4211e2021-01-20 15:43:39 -08002889 private void onHelpCallComposer() {
2890 PrintWriter pw = getOutPrintWriter();
2891 pw.println("Call composer commands");
2892 pw.println(" callcomposer test-mode enable|disable|query");
2893 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2894 pw.println(" upload/download from carrier servers is disabled, and operations are");
2895 pw.println(" performed using emulated local files instead.");
2896 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2897 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2898 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002899 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2900 pw.println(" Enables or disables the user setting for call composer, as set by");
2901 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002902 }
2903
2904 private int handleCallComposerCommand() {
2905 String arg = getNextArg();
2906 if (arg == null) {
2907 onHelpCallComposer();
2908 return 0;
2909 }
2910
2911 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2912 "MODIFY_PHONE_STATE required for call composer shell cmds");
2913 switch (arg) {
2914 case CALL_COMPOSER_TEST_MODE: {
2915 String enabledStr = getNextArg();
2916 if (ENABLE.equals(enabledStr)) {
2917 CallComposerPictureManager.sTestMode = true;
2918 } else if (DISABLE.equals(enabledStr)) {
2919 CallComposerPictureManager.sTestMode = false;
2920 } else if (QUERY.equals(enabledStr)) {
2921 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2922 } else {
2923 onHelpCallComposer();
2924 return 1;
2925 }
2926 break;
2927 }
2928 case CALL_COMPOSER_SIMULATE_CALL: {
2929 int subscriptionId = Integer.valueOf(getNextArg());
2930 String uuidString = getNextArg();
2931 UUID uuid = UUID.fromString(uuidString);
2932 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2933 Binder.withCleanCallingIdentity(() -> {
2934 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2935 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2936 });
2937 try {
2938 Uri uri = storageUriFuture.get();
2939 getOutPrintWriter().println(String.valueOf(uri));
2940 } catch (Exception e) {
2941 throw new RuntimeException(e);
2942 }
2943 break;
2944 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002945 case CALL_COMPOSER_USER_SETTING: {
2946 try {
2947 int subscriptionId = Integer.valueOf(getNextArg());
2948 String enabledStr = getNextArg();
2949 if (ENABLE.equals(enabledStr)) {
2950 mInterface.setCallComposerStatus(subscriptionId,
2951 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2952 } else if (DISABLE.equals(enabledStr)) {
2953 mInterface.setCallComposerStatus(subscriptionId,
2954 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2955 } else if (QUERY.equals(enabledStr)) {
2956 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2957 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2958 } else {
2959 onHelpCallComposer();
2960 return 1;
2961 }
2962 } catch (RemoteException e) {
2963 e.printStackTrace(getOutPrintWriter());
2964 return 1;
2965 }
2966 break;
2967 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002968 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002969 return 0;
2970 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002971
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002972 private int handleHasCarrierPrivilegesCommand() {
2973 String packageName = getNextArgRequired();
2974
2975 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002976 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002977 try {
2978 hasCarrierPrivileges =
2979 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2980 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2981 } catch (RemoteException e) {
2982 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2983 getErrPrintWriter().println("Exception: " + e.getMessage());
2984 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002985 } finally {
2986 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002987 }
2988
2989 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002990 return 0;
2991 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002992
2993 private int handleAllowedNetworkTypesCommand(String command) {
2994 if (!checkShellUid()) {
2995 return -1;
2996 }
2997
2998 PrintWriter errPw = getErrPrintWriter();
2999 String tag = command + ": ";
3000 String opt;
3001 int subId = -1;
3002 Log.v(LOG_TAG, command + " start");
3003
3004 while ((opt = getNextOption()) != null) {
3005 if (opt.equals("-s")) {
3006 try {
3007 subId = slotStringToSubId(tag, getNextArgRequired());
3008 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3009 errPw.println(tag + "No valid subscription found.");
3010 return -1;
3011 }
3012 } catch (IllegalArgumentException e) {
3013 // Missing slot id
3014 errPw.println(tag + "SLOT_ID expected after -s.");
3015 return -1;
3016 }
3017 } else {
3018 errPw.println(tag + "Unknown option " + opt);
3019 return -1;
3020 }
3021 }
3022
3023 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3024 return handleGetAllowedNetworkTypesCommand(subId);
3025 }
3026 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3027 return handleSetAllowedNetworkTypesCommand(subId);
3028 }
3029 return -1;
3030 }
3031
3032 private int handleGetAllowedNetworkTypesCommand(int subId) {
3033 PrintWriter errPw = getErrPrintWriter();
3034
3035 long result = -1;
3036 try {
3037 if (mInterface != null) {
3038 result = mInterface.getAllowedNetworkTypesForReason(subId,
3039 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3040 } else {
3041 throw new IllegalStateException("telephony service is null.");
3042 }
3043 } catch (RemoteException e) {
3044 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3045 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3046 return -1;
3047 }
3048
3049 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3050 return 0;
3051 }
3052
3053 private int handleSetAllowedNetworkTypesCommand(int subId) {
3054 PrintWriter errPw = getErrPrintWriter();
3055
3056 String bitmaskString = getNextArg();
3057 if (TextUtils.isEmpty(bitmaskString)) {
3058 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3059 return -1;
3060 }
3061 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3062 if (allowedNetworkTypes < 0) {
3063 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3064 return -1;
3065 }
3066 boolean result = false;
3067 try {
3068 if (mInterface != null) {
3069 result = mInterface.setAllowedNetworkTypesForReason(subId,
3070 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3071 } else {
3072 throw new IllegalStateException("telephony service is null.");
3073 }
3074 } catch (RemoteException e) {
3075 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3076 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3077 return -1;
3078 }
3079
3080 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3081 if (result) {
3082 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3083 }
3084 getOutPrintWriter().println(resultMessage);
3085 return 0;
3086 }
3087
3088 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3089 if (TextUtils.isEmpty(bitmaskString)) {
3090 return -1;
3091 }
3092 if (VDBG) {
3093 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3094 + ", length: " + bitmaskString.length());
3095 }
3096 try {
3097 return Long.parseLong(bitmaskString, 2);
3098 } catch (NumberFormatException e) {
3099 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3100 return -1;
3101 }
3102 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003103
jimsun3b9ccac2021-10-26 15:01:23 +08003104 private int handleRadioSetModemServiceCommand() {
3105 PrintWriter errPw = getErrPrintWriter();
3106 String serviceName = null;
3107
3108 String opt;
3109 while ((opt = getNextOption()) != null) {
3110 switch (opt) {
3111 case "-s": {
3112 serviceName = getNextArgRequired();
3113 break;
3114 }
3115 }
3116 }
3117
3118 try {
3119 boolean result = mInterface.setModemService(serviceName);
3120 if (VDBG) {
3121 Log.v(LOG_TAG,
3122 "RadioSetModemService " + serviceName + ", result = " + result);
3123 }
3124 getOutPrintWriter().println(result);
3125 } catch (RemoteException e) {
3126 Log.w(LOG_TAG,
3127 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3128 errPw.println("Exception: " + e.getMessage());
3129 return -1;
3130 }
3131 return 0;
3132 }
3133
3134 private int handleRadioGetModemServiceCommand() {
3135 PrintWriter errPw = getErrPrintWriter();
3136 String result;
3137
3138 try {
3139 result = mInterface.getModemService();
3140 getOutPrintWriter().println(result);
3141 } catch (RemoteException e) {
3142 errPw.println("Exception: " + e.getMessage());
3143 return -1;
3144 }
3145 if (VDBG) {
3146 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3147 }
3148 return 0;
3149 }
3150
3151 private int handleRadioCommand() {
3152 String arg = getNextArg();
3153 if (arg == null) {
3154 onHelpRadio();
3155 return 0;
3156 }
3157
3158 switch (arg) {
3159 case RADIO_SET_MODEM_SERVICE:
3160 return handleRadioSetModemServiceCommand();
3161
3162 case RADIO_GET_MODEM_SERVICE:
3163 return handleRadioGetModemServiceCommand();
3164 }
3165
3166 return -1;
3167 }
arunvoddud7401012022-12-15 16:08:12 +00003168
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003169 private int handleSetSatelliteServicePackageNameCommand() {
3170 PrintWriter errPw = getErrPrintWriter();
3171 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003172 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003173
3174 String opt;
3175 while ((opt = getNextOption()) != null) {
3176 switch (opt) {
3177 case "-s": {
3178 serviceName = getNextArgRequired();
3179 break;
3180 }
Hakjun Choic3393242024-06-26 18:02:08 +00003181
3182 case "-p": {
3183 provisioned = getNextArgRequired();
3184 break;
3185 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003186 }
3187 }
3188 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003189 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003190
3191 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003192 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003193 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003194 Log.v(LOG_TAG,
3195 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3196 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003197 }
3198 getOutPrintWriter().println(result);
3199 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003200 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3201 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003202 errPw.println("Exception: " + e.getMessage());
3203 return -1;
3204 }
Hakjun Choic3393242024-06-26 18:02:08 +00003205
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003206 return 0;
3207 }
3208
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003209 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3210 PrintWriter errPw = getErrPrintWriter();
3211 String serviceName = null;
3212
3213 String opt;
3214 while ((opt = getNextOption()) != null) {
3215 switch (opt) {
3216 case "-s": {
3217 serviceName = getNextArgRequired();
3218 break;
3219 }
3220 }
3221 }
3222 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3223 + serviceName);
3224
3225 try {
3226 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3227 if (VDBG) {
3228 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3229 + ", result = " + result);
3230 }
3231 getOutPrintWriter().println(result);
3232 } catch (RemoteException e) {
3233 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3234 + ", error = " + e.getMessage());
3235 errPw.println("Exception: " + e.getMessage());
3236 return -1;
3237 }
3238 return 0;
3239 }
3240
Thomas Nguyen87dce732023-04-20 18:27:16 -07003241 private int handleSetSatellitePointingUiClassNameCommand() {
3242 PrintWriter errPw = getErrPrintWriter();
3243 String packageName = null;
3244 String className = null;
3245
3246 String opt;
3247 while ((opt = getNextOption()) != null) {
3248 switch (opt) {
3249 case "-p": {
3250 packageName = getNextArgRequired();
3251 break;
3252 }
3253 case "-c": {
3254 className = getNextArgRequired();
3255 break;
3256 }
3257 }
3258 }
3259 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3260 + packageName + ", className=" + className);
3261
3262 try {
3263 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3264 if (VDBG) {
3265 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3266 }
3267 getOutPrintWriter().println(result);
3268 } catch (RemoteException e) {
3269 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3270 + ", error = " + e.getMessage());
3271 errPw.println("Exception: " + e.getMessage());
3272 return -1;
3273 }
3274 return 0;
3275 }
3276
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003277 private int handleSetEmergencyCallToSatelliteHandoverType() {
3278 PrintWriter errPw = getErrPrintWriter();
3279 int handoverType = -1;
3280 int delaySeconds = 0;
3281
3282 String opt;
3283 while ((opt = getNextOption()) != null) {
3284 switch (opt) {
3285 case "-t": {
3286 try {
3287 handoverType = Integer.parseInt(getNextArgRequired());
3288 } catch (NumberFormatException e) {
3289 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3290 + " for handoverType");
3291 return -1;
3292 }
3293 break;
3294 }
3295 case "-d": {
3296 try {
3297 delaySeconds = Integer.parseInt(getNextArgRequired());
3298 } catch (NumberFormatException e) {
3299 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3300 + " for delaySeconds");
3301 return -1;
3302 }
3303 break;
3304 }
3305 }
3306 }
3307 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3308 + handoverType + ", delaySeconds=" + delaySeconds);
3309
3310 try {
3311 boolean result =
3312 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3313 if (VDBG) {
3314 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3315 }
3316 getOutPrintWriter().println(result);
3317 } catch (RemoteException e) {
3318 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3319 + ", error = " + e.getMessage());
3320 errPw.println("Exception: " + e.getMessage());
3321 return -1;
3322 }
3323 return 0;
3324 }
3325
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003326 private int handleSetSatelliteListeningTimeoutDuration() {
3327 PrintWriter errPw = getErrPrintWriter();
3328 long timeoutMillis = 0;
3329
3330 String opt;
3331 while ((opt = getNextOption()) != null) {
3332 switch (opt) {
3333 case "-t": {
3334 timeoutMillis = Long.parseLong(getNextArgRequired());
3335 break;
3336 }
3337 }
3338 }
3339 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3340 + timeoutMillis);
3341
3342 try {
3343 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3344 if (VDBG) {
3345 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3346 + ", result = " + result);
3347 }
3348 getOutPrintWriter().println(result);
3349 } catch (RemoteException e) {
3350 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3351 + ", error = " + e.getMessage());
3352 errPw.println("Exception: " + e.getMessage());
3353 return -1;
3354 }
3355 return 0;
3356 }
3357
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003358 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003359 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003360 boolean reset = false;
3361 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003362 long timeoutMillis = 0;
3363
3364 String opt;
3365 while ((opt = getNextOption()) != null) {
3366 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003367 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003368 timeoutMillis = Long.parseLong(getNextArgRequired());
3369 break;
3370 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003371 case "-r": {
3372 reset = true;
3373 break;
3374 }
3375 case "-t": {
3376 timeoutType = Integer.parseInt(getNextArgRequired());
3377 break;
3378 }
Hakjun Choiae365972023-04-25 11:00:31 +00003379 }
3380 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003381 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3382 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003383
3384 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003385 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3386 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003387 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003388 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003389 + ", result = " + result);
3390 }
3391 getOutPrintWriter().println(result);
3392 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003393 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3394 + ", error = " + e.getMessage());
3395 errPw.println("Exception: " + e.getMessage());
3396 return -1;
3397 }
3398 return 0;
3399 }
3400
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003401 private int handleSetDatagramControllerBooleanConfig() {
3402 PrintWriter errPw = getErrPrintWriter();
3403 boolean reset = false;
3404 int booleanType = 0;
3405 boolean enable = false;
3406
3407 String opt;
3408 while ((opt = getNextOption()) != null) {
3409 switch (opt) {
3410 case "-d": {
3411 enable = Boolean.parseBoolean(getNextArgRequired());
3412 break;
3413 }
3414 case "-r": {
3415 reset = true;
3416 break;
3417 }
3418 case "-t": {
3419 booleanType = Integer.parseInt(getNextArgRequired());
3420 break;
3421 }
3422 }
3423 }
3424 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3425 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3426
3427 try {
3428 boolean result = mInterface.setDatagramControllerBooleanConfig(
3429 reset, booleanType, enable);
3430 if (VDBG) {
3431 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3432 }
3433 getOutPrintWriter().println(result);
3434 } catch (RemoteException e) {
3435 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3436 errPw.println("Exception: " + e.getMessage());
3437 return -1;
3438 }
3439 return 0;
3440 }
3441
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003442 private int handleSetSatelliteControllerTimeoutDuration() {
3443 PrintWriter errPw = getErrPrintWriter();
3444 boolean reset = false;
3445 int timeoutType = 0;
3446 long timeoutMillis = 0;
3447
3448 String opt;
3449 while ((opt = getNextOption()) != null) {
3450 switch (opt) {
3451 case "-d": {
3452 timeoutMillis = Long.parseLong(getNextArgRequired());
3453 break;
3454 }
3455 case "-r": {
3456 reset = true;
3457 break;
3458 }
3459 case "-t": {
3460 timeoutType = Integer.parseInt(getNextArgRequired());
3461 break;
3462 }
3463 }
3464 }
3465 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3466 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3467
3468 try {
3469 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3470 reset, timeoutType, timeoutMillis);
3471 if (VDBG) {
3472 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3473 + ", result = " + result);
3474 }
3475 getOutPrintWriter().println(result);
3476 } catch (RemoteException e) {
3477 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003478 + ", error = " + e.getMessage());
3479 errPw.println("Exception: " + e.getMessage());
3480 return -1;
3481 }
3482 return 0;
3483 }
3484
Hakjun Choibc6ce992023-11-07 16:04:33 +00003485 private int handleSetShouldSendDatagramToModemInDemoMode() {
3486 PrintWriter errPw = getErrPrintWriter();
3487 String opt;
3488 boolean shouldSendToDemoMode;
3489
3490 if ((opt = getNextArg()) == null) {
3491 errPw.println(
3492 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3493 + " Invalid Argument");
3494 return -1;
3495 } else {
3496 switch (opt) {
3497 case "true": {
3498 shouldSendToDemoMode = true;
3499 break;
3500 }
3501 case "false": {
3502 shouldSendToDemoMode = false;
3503 break;
3504 }
3505 default:
3506 errPw.println(
3507 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3508 + " Invalid Argument");
3509 return -1;
3510 }
3511 }
3512
3513 Log.d(LOG_TAG,
3514 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3515
3516 try {
3517 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3518 shouldSendToDemoMode);
3519 if (VDBG) {
3520 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3521 + result);
3522 }
3523 getOutPrintWriter().println(false);
3524 } catch (RemoteException e) {
3525 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3526 + "), error = " + e.getMessage());
3527 errPw.println("Exception: " + e.getMessage());
3528 return -1;
3529 }
3530 return 0;
3531 }
3532
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003533 private int handleSetSatelliteAccessControlOverlayConfigs() {
3534 PrintWriter errPw = getErrPrintWriter();
3535 boolean reset = false;
3536 boolean isAllowed = false;
3537 String s2CellFile = null;
3538 long locationFreshDurationNanos = 0;
3539 List<String> satelliteCountryCodes = null;
3540
3541 String opt;
3542 while ((opt = getNextOption()) != null) {
3543 switch (opt) {
3544 case "-r": {
3545 reset = true;
3546 break;
3547 }
3548 case "-a": {
3549 isAllowed = true;
3550 break;
3551 }
3552 case "-f": {
3553 s2CellFile = getNextArgRequired();
3554 break;
3555 }
3556 case "-d": {
3557 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3558 break;
3559 }
3560 case "-c": {
3561 String countryCodeStr = getNextArgRequired();
3562 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3563 break;
3564 }
3565 }
3566 }
3567 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3568 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3569 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3570 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3571
3572 try {
3573 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3574 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3575 if (VDBG) {
3576 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3577 }
3578 getOutPrintWriter().println(result);
3579 } catch (RemoteException e) {
3580 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3581 errPw.println("Exception: " + e.getMessage());
3582 return -1;
3583 }
3584 return 0;
3585 }
3586
3587 private int handleSetCountryCodes() {
3588 PrintWriter errPw = getErrPrintWriter();
3589 List<String> currentNetworkCountryCodes = new ArrayList<>();
3590 String locationCountryCode = null;
3591 long locationCountryCodeTimestampNanos = 0;
3592 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3593 boolean reset = false;
3594
3595 String opt;
3596 while ((opt = getNextOption()) != null) {
3597 switch (opt) {
3598 case "-r": {
3599 reset = true;
3600 break;
3601 }
3602 case "-n": {
3603 String countryCodeStr = getNextArgRequired();
3604 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3605 break;
3606 }
3607 case "-c": {
3608 String cachedNetworkCountryCodeStr = getNextArgRequired();
3609 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3610 break;
3611 }
3612 case "-l": {
3613 locationCountryCode = getNextArgRequired();
3614 break;
3615 }
3616 case "-t": {
3617 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3618 break;
3619 }
3620 }
3621 }
3622 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3623 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3624 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3625 + currentNetworkCountryCodes);
3626
3627 try {
3628 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3629 cachedNetworkCountryCodes, locationCountryCode,
3630 locationCountryCodeTimestampNanos);
3631 if (VDBG) {
3632 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3633 }
3634 getOutPrintWriter().println(result);
3635 } catch (RemoteException e) {
3636 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3637 errPw.println("Exception: " + e.getMessage());
3638 return -1;
3639 }
3640 return 0;
3641 }
3642
Thomas Nguyen3d602742024-01-19 11:29:35 -08003643 private int handleSetOemEnabledSatelliteProvisionStatus() {
3644 PrintWriter errPw = getErrPrintWriter();
3645 boolean isProvisioned = false;
3646 boolean reset = true;
3647
3648 String opt;
3649 while ((opt = getNextOption()) != null) {
3650 switch (opt) {
3651 case "-p": {
3652 try {
3653 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3654 reset = false;
3655 } catch (Exception e) {
3656 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3657 + "after -p indicating provision status");
3658 return -1;
3659 }
3660 }
3661 }
3662 }
3663 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3664 + ", isProvisioned=" + isProvisioned);
3665
3666 try {
3667 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3668 if (VDBG) {
3669 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3670 }
3671 getOutPrintWriter().println(result);
3672 } catch (RemoteException e) {
3673 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3674 errPw.println("Exception: " + e.getMessage());
3675 return -1;
3676 }
3677 return 0;
3678 }
3679
Hakjun Choi4a832d12024-05-28 22:23:55 +00003680 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3681 PrintWriter errPw = getErrPrintWriter();
3682 String opt;
3683 String state;
3684
3685 if ((opt = getNextArg()) == null) {
3686 errPw.println(
3687 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3688 + "-location-cache :"
3689 + " Invalid Argument");
3690 return -1;
3691 } else {
3692 switch (opt) {
3693 case "-a": {
3694 state = "cache_allowed";
3695 break;
3696 }
3697 case "-n": {
3698 state = "cache_clear_and_not_allowed";
3699 break;
3700 }
3701 case "-c": {
3702 state = "clear_cache_only";
3703 break;
3704 }
3705 default:
3706 errPw.println(
3707 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3708 + "-location-cache :"
3709 + " Invalid Argument");
3710 return -1;
3711 }
3712 }
3713
3714 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3715 + state + ")");
3716
3717 try {
3718 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3719 state);
3720 if (VDBG) {
3721 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3722 + "returns: "
3723 + result);
3724 }
3725 getOutPrintWriter().println(result);
3726 } catch (RemoteException e) {
3727 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3728 + state + "), error = " + e.getMessage());
3729 errPw.println("Exception: " + e.getMessage());
3730 return -1;
3731 }
3732 return 0;
3733 }
3734
Hyosund6aaf062024-08-23 23:02:10 +00003735 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3736 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3737 PrintWriter errPw = getErrPrintWriter();
3738 String opt;
3739 String name;
3740
3741 if ((opt = getNextArg()) == null) {
3742 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3743 return -1;
3744 } else {
3745 switch (opt) {
3746 case "-p": {
3747 name = opt + "/" + "android.telephony.cts";
3748 break;
3749 }
3750 case "-c": {
3751 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3752 break;
3753 }
3754 case "-r": {
3755 name = "reset";
3756 break;
3757 }
3758 default:
3759 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3760 return -1;
3761 }
3762 }
3763
3764 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3765 + name + ")");
3766
3767 try {
3768 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3769 if (VDBG) {
3770 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3771 + "returns: " + result);
3772 }
3773 getOutPrintWriter().println(result);
3774 } catch (RemoteException e) {
3775 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3776 + name + "), error = " + e.getMessage());
3777 errPw.println("Exception: " + e.getMessage());
3778 return -1;
3779 }
3780 return 0;
3781 }
3782
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003783 /**
3784 * Sample inputStr = "US,UK,CA;2,1,3"
3785 * Sample output: {[US,2], [UK,1], [CA,3]}
3786 */
3787 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3788 Map<String, Long> result = new HashMap<>();
3789 if (!TextUtils.isEmpty(inputStr)) {
3790 String[] stringLongArr = inputStr.split(";");
3791 if (stringLongArr.length != 2) {
3792 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3793 return result;
3794 }
3795
3796 String[] stringArr = stringLongArr[0].split(",");
3797 String[] longArr = stringLongArr[1].split(",");
3798 if (stringArr.length != longArr.length) {
3799 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3800 return result;
3801 }
3802
3803 for (int i = 0; i < stringArr.length; i++) {
3804 try {
3805 result.put(stringArr[i], Long.parseLong(longArr[i]));
3806 } catch (Exception ex) {
3807 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3808 + ", ex=" + ex);
3809 return result;
3810 }
3811 }
3812 }
3813 return result;
3814 }
3815
arunvoddud7401012022-12-15 16:08:12 +00003816 private int handleCarrierRestrictionStatusCommand() {
3817 try {
3818 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3819 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3820 mInterface.getModemService()))) {
3821 Log.v(LOG_TAG,
3822 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3823 + " checkShellUid fails");
3824 return -1;
3825 }
3826 } catch (RemoteException ex) {
3827 ex.printStackTrace();
3828 }
3829 String callerInfo = getNextOption();
3830 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3831 if (TextUtils.isEmpty(callerInfo)) {
3832 // reset the Json content after testing
3833 allowListInfo.updateJsonForTest(null);
3834 return 0;
3835 }
3836 if (callerInfo.startsWith("--")) {
3837 callerInfo = callerInfo.replace("--", "");
3838 }
3839 String params[] = callerInfo.split(",");
3840 StringBuffer jsonStrBuffer = new StringBuffer();
3841 String tokens;
3842 for (int index = 0; index < params.length; index++) {
3843 tokens = convertToJsonString(index, params[index]);
3844 if (TextUtils.isEmpty(tokens)) {
3845 // received wrong format from CTS
3846 if (VDBG) {
3847 Log.v(LOG_TAG,
3848 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3849 }
3850 return -1;
3851 }
3852 jsonStrBuffer.append(tokens);
3853 }
3854 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3855 return result;
3856 }
3857
Benedict Wong66477622023-02-03 23:30:57 +00003858 // set-carrier-service-package-override
3859 private int setCarrierServicePackageOverride() {
3860 PrintWriter errPw = getErrPrintWriter();
3861 int subId = SubscriptionManager.getDefaultSubscriptionId();
3862
3863 String opt;
3864 while ((opt = getNextOption()) != null) {
3865 switch (opt) {
3866 case "-s":
3867 try {
3868 subId = Integer.parseInt(getNextArgRequired());
3869 } catch (NumberFormatException e) {
3870 errPw.println(
3871 "set-carrier-service-package-override requires an integer as a"
3872 + " subscription ID.");
3873 return -1;
3874 }
3875 break;
3876 }
3877 }
3878
3879 String packageName = getNextArg();
3880 if (packageName == null) {
3881 errPw.println("set-carrier-service-package-override requires a override package name.");
3882 return -1;
3883 }
3884
3885 try {
3886 mInterface.setCarrierServicePackageOverride(
3887 subId, packageName, mContext.getOpPackageName());
3888
3889 if (VDBG) {
3890 Log.v(
3891 LOG_TAG,
3892 "set-carrier-service-package-override -s " + subId + " " + packageName);
3893 }
3894 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3895 Log.w(
3896 LOG_TAG,
3897 "set-carrier-service-package-override -s "
3898 + subId
3899 + " "
3900 + packageName
3901 + ", error"
3902 + e.getMessage());
3903 errPw.println("Exception: " + e.getMessage());
3904 return -1;
3905 }
3906 return 0;
3907 }
3908
3909 // clear-carrier-service-package-override
3910 private int clearCarrierServicePackageOverride() {
3911 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003912 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003913
3914 String opt;
3915 while ((opt = getNextOption()) != null) {
3916 switch (opt) {
3917 case "-s":
3918 try {
3919 subId = Integer.parseInt(getNextArgRequired());
3920 } catch (NumberFormatException e) {
3921 errPw.println(
3922 "clear-carrier-service-package-override requires an integer as a"
3923 + " subscription ID.");
3924 return -1;
3925 }
3926 break;
3927 }
3928 }
3929
3930 try {
3931 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3932
3933 if (VDBG) {
3934 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3935 }
3936 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3937 Log.w(
3938 LOG_TAG,
3939 "clear-carrier-service-package-override -s "
3940 + subId
3941 + ", error"
3942 + e.getMessage());
3943 errPw.println("Exception: " + e.getMessage());
3944 return -1;
3945 }
3946 return 0;
3947 }
arunvoddud7401012022-12-15 16:08:12 +00003948
Hunsuk Choi13078be2023-09-13 10:55:21 +00003949 private int handleDomainSelectionCommand() {
3950 String arg = getNextArg();
3951 if (arg == null) {
3952 onHelpDomainSelection();
3953 return 0;
3954 }
3955
3956 switch (arg) {
3957 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3958 return handleDomainSelectionSetServiceOverrideCommand();
3959 }
3960 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3961 return handleDomainSelectionClearServiceOverrideCommand();
3962 }
3963 }
3964
3965 return -1;
3966 }
3967
3968 // domainselection set-dss-override
3969 private int handleDomainSelectionSetServiceOverrideCommand() {
3970 PrintWriter errPw = getErrPrintWriter();
3971
3972 String componentName = getNextArg();
3973
3974 try {
3975 boolean result = mInterface.setDomainSelectionServiceOverride(
3976 ComponentName.unflattenFromString(componentName));
3977 if (VDBG) {
3978 Log.v(LOG_TAG, "domainselection set-dss-override "
3979 + componentName + ", result=" + result);
3980 }
3981 getOutPrintWriter().println(result);
3982 } catch (Exception e) {
3983 Log.w(LOG_TAG, "domainselection set-dss-override "
3984 + componentName + ", error=" + e.getMessage());
3985 errPw.println("Exception: " + e.getMessage());
3986 return -1;
3987 }
3988 return 0;
3989 }
3990
3991 // domainselection clear-dss-override
3992 private int handleDomainSelectionClearServiceOverrideCommand() {
3993 PrintWriter errPw = getErrPrintWriter();
3994
3995 try {
3996 boolean result = mInterface.clearDomainSelectionServiceOverride();
3997 if (VDBG) {
3998 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
3999 }
4000 getOutPrintWriter().println(result);
4001 } catch (RemoteException e) {
4002 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4003 errPw.println("Exception: " + e.getMessage());
4004 return -1;
4005 }
4006 return 0;
4007 }
4008
arunvoddud7401012022-12-15 16:08:12 +00004009 /**
4010 * Building the string that can be used to build the JsonObject which supports to stub the data
4011 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004012 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004013 */
4014 private String convertToJsonString(int index, String param) {
4015
4016 String token[] = param.split(":");
4017 String jSonString;
4018 switch (index) {
4019 case 0:
4020 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4021 break;
4022 case 1:
4023 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004024 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004025 break;
4026 case 2:
4027 jSonString =
4028 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4029 break;
4030 default:
4031 jSonString = null;
4032 }
4033 return jSonString;
4034 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004035}