blob: bfc93e0eda07aa96ca1e0918c2bcd07f55b6e653 [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;
Tyler Gunn92479152021-01-20 16:30:10 -080059import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080060import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080061import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080062import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080063import com.android.phone.callcomposer.CallComposerPictureManager;
Shivakumar Neginal9cd61892022-12-19 04:38:52 +000064import com.android.phone.euicc.EuiccUiDispatcherActivity;
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
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000134 private static final String EUICC_SUBCOMMAND = "euicc";
135 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
136
Hui Wang641e81c2020-10-12 12:14:23 -0700137 private static final String GBA_SUBCOMMAND = "gba";
138 private static final String GBA_SET_SERVICE = "set-service";
139 private static final String GBA_GET_SERVICE = "get-service";
140 private static final String GBA_SET_RELEASE_TIME = "set-release";
141 private static final String GBA_GET_RELEASE_TIME = "get-release";
142
Hui Wang761a6682020-10-31 05:12:53 +0000143 private static final String SINGLE_REGISTATION_CONFIG = "src";
144 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
145 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
146 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
147 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800148 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
149 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800150 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
151 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000152
Tyler Gunn92479152021-01-20 16:30:10 -0800153 private static final String D2D_SUBCOMMAND = "d2d";
154 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800155 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700156 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800157
Nazanin014f41e2021-05-06 17:26:31 -0700158 private static final String BARRING_SUBCOMMAND = "barring";
159 private static final String BARRING_SEND_INFO = "send";
160
James.cf Linbcdf8b32021-01-14 16:44:13 +0800161 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800162 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800163 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800164 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800165 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
166 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000167 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
168 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800169 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
170 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800171 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
172 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800173
jimsun3b9ccac2021-10-26 15:01:23 +0800174 private static final String RADIO_SUBCOMMAND = "radio";
175 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
176 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
177
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800178 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
179 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
180
Jordan Liu0ccee222021-04-27 11:55:13 -0700181 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
182 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
183
Jack Nudelman644b91a2021-03-12 14:09:48 -0800184 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
185 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
186 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700187 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
188 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700189 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
190 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700191 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
192 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700193 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
194 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800195 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
196 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000197 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
198 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800199
200 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
201 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700202 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
203 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800204 private static final String SET_COUNTRY_CODES = "set-country-codes";
205 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
206 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800207 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
208 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000209 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
210 "set-should-send-datagram-to-modem-in-demo-mode";
Hakjun Choi4a832d12024-05-28 22:23:55 +0000211 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
212 "set-is-satellite-communication-allowed-for-current-location-cache";
Hyosund6aaf062024-08-23 23:02:10 +0000213 private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
214 "set-satellite-subscriberid-list-changed-intent-component";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800215
Hunsuk Choi13078be2023-09-13 10:55:21 +0000216 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
217 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
218 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
219
Grant Menke567d48f2022-08-18 20:19:10 +0000220 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
221 + "'*', '#' or '+') needs to be specified after -a in the command ";
222
223 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
224 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
225 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
226
SongFerngWang98dd5992021-05-13 17:50:00 +0800227 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
228 "get-allowed-network-types-for-users";
229 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
230 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000231 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000232 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700233 // Take advantage of existing methods that already contain permissions checks when possible.
234 private final ITelephony mInterface;
235
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100236 private SubscriptionManager mSubscriptionManager;
237 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700238 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700239 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100240
241 private enum CcType {
242 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000243 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100244 }
245
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100246 private class CcOptionParseResult {
247 public int mSubId;
248 public boolean mPersistent;
249 }
250
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100251 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
252 // keys by looking at the end of the string which usually tells the type.
253 // For instance: "xxxx_string", "xxxx_string_array", etc.
254 // The carrier config keys in this map does not follow this convention. It is therefore not
255 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700256 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
257 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
258 CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
266 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
267 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
268 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
269 CcType.STRING),
270 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
271 CcType.STRING_ARRAY),
272 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
273 CcType.STRING_ARRAY),
274 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
275 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
276 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
279 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
280 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
281 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100282
Brad Ebinger14d467f2021-02-12 06:18:28 +0000283 /**
284 * Map from a shorthand string to the feature tags required in registration required in order
285 * for the RCS feature to be considered "capable".
286 */
287 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
288 static {
289 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
290 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
291 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
292 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
293 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
294 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
295 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
296 FeatureTags.FEATURE_TAG_VIDEO)));
297 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
298 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
299 map.put("call_comp",
300 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
301 map.put("call_comp_mmtel",
302 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
303 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
304 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
305 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
306 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
307 // version
308 map.put("chatbot", new ArraySet<>(Arrays.asList(
309 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
310 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
311 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
312 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000313 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000314 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
315 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
316 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
317 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
318 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000319 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000320 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
321 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
322 }
323
324
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100325 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700326 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100327 mCarrierConfigManager =
328 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
329 mSubscriptionManager = (SubscriptionManager)
330 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700331 mTelephonyRegistryManager = (TelephonyRegistryManager)
332 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700333 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700334 }
335
336 @Override
337 public int onCommand(String cmd) {
338 if (cmd == null) {
339 return handleDefaultCommands(null);
340 }
341
342 switch (cmd) {
343 case IMS_SUBCOMMAND: {
344 return handleImsCommand();
345 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800346 case RCS_UCE_COMMAND:
347 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800348 case NUMBER_VERIFICATION_SUBCOMMAND:
349 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800350 case EMERGENCY_CALLBACK_MODE:
351 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800352 case EMERGENCY_NUMBER_TEST_MODE:
353 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100354 case CARRIER_CONFIG_SUBCOMMAND: {
355 return handleCcCommand();
356 }
Shuo Qianf5125122019-12-16 17:03:07 -0800357 case DATA_TEST_MODE:
358 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700359 case END_BLOCK_SUPPRESSION:
360 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000361 case EUICC_SUBCOMMAND:
362 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700363 case GBA_SUBCOMMAND:
364 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800365 case D2D_SUBCOMMAND:
366 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700367 case BARRING_SUBCOMMAND:
368 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000369 case SINGLE_REGISTATION_CONFIG:
370 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000371 case RESTART_MODEM:
372 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800373 case CALL_COMPOSER_SUBCOMMAND:
374 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000375 case UNATTENDED_REBOOT:
376 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800377 case HAS_CARRIER_PRIVILEGES_COMMAND:
378 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800379 case THERMAL_MITIGATION_COMMAND:
380 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700381 case DISABLE_PHYSICAL_SUBSCRIPTION:
382 return handleEnablePhysicalSubscription(false);
383 case ENABLE_PHYSICAL_SUBSCRIPTION:
384 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800385 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
386 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
387 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000388 case GET_IMEI:
389 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000390 case GET_SIM_SLOTS_MAPPING:
391 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800392 case RADIO_SUBCOMMAND:
393 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000394 case CARRIER_RESTRICTION_STATUS_TEST:
395 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000396 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
397 return setCarrierServicePackageOverride();
398 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
399 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000400 case DOMAIN_SELECTION_SUBCOMMAND:
401 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700402 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
403 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700404 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
405 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700406 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
407 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700408 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
409 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800410 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
411 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000412 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
413 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800414 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
415 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700416 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
417 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000418 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
419 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800420 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
421 return handleSetSatelliteAccessControlOverlayConfigs();
422 case SET_COUNTRY_CODES:
423 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800424 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
425 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000426 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
427 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000428 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
429 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700430 default: {
431 return handleDefaultCommands(cmd);
432 }
433 }
434 }
435
436 @Override
437 public void onHelp() {
438 PrintWriter pw = getOutPrintWriter();
439 pw.println("Telephony Commands:");
440 pw.println(" help");
441 pw.println(" Print this help text.");
442 pw.println(" ims");
443 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800444 pw.println(" uce");
445 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800446 pw.println(" emergency-number-test-mode");
447 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700448 pw.println(" end-block-suppression");
449 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800450 pw.println(" data");
451 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100452 pw.println(" cc");
453 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700454 pw.println(" gba");
455 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000456 pw.println(" src");
457 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000458 pw.println(" restart-modem");
459 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000460 pw.println(" unattended-reboot");
461 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800462 pw.println(" has-carrier-privileges [package]");
463 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800464 pw.println(" get-allowed-network-types-for-users");
465 pw.println(" Get the Allowed Network Types.");
466 pw.println(" set-allowed-network-types-for-users");
467 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800468 pw.println(" radio");
469 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700470 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800471 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800472 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700473 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800474 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100475 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700476 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000477 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800478 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700479 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800480 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800481 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000482 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700483 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000484 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800485 }
486
487 private void onHelpD2D() {
488 PrintWriter pw = getOutPrintWriter();
489 pw.println("D2D Comms Commands:");
490 pw.println(" d2d send TYPE VALUE");
491 pw.println(" Sends a D2D message of specified type and value.");
492 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
493 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
494 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
495 MESSAGE_CALL_AUDIO_CODEC));
496 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
497 + Communicator.messageToString(
498 MESSAGE_DEVICE_BATTERY_STATE));
499 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
500 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800501 pw.println(" d2d transport TYPE");
502 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
503 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700504 pw.println(" d2d set-device-support true/default");
505 pw.println(" true - forces device support to be enabled for D2D.");
506 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
507 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700508 }
509
Nazanin014f41e2021-05-06 17:26:31 -0700510 private void onHelpBarring() {
511 PrintWriter pw = getOutPrintWriter();
512 pw.println("Barring Commands:");
513 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
514 + " -t CONDITIONAL_BARRING_TIME_SECS");
515 pw.println(" Notifies of a barring info change for the specified slot id.");
516 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
517 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
518 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
519 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
520 }
521
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700522 private void onHelpIms() {
523 PrintWriter pw = getOutPrintWriter();
524 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800525 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700526 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
527 pw.println(" ImsService. Options are:");
528 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
529 pw.println(" is specified, it will choose the default voice SIM slot.");
530 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
531 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800532 pw.println(" -f: Set the feature that this override if for, if no option is");
533 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700534 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
535 pw.println(" Gets the package name of the currently defined ImsService.");
536 pw.println(" Options are:");
537 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
538 pw.println(" is specified, it will choose the default voice SIM slot.");
539 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000540 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800541 pw.println(" -f: The feature type that the query will be requested for. If none is");
542 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800543 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
544 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
545 pw.println(" configuration overrides. Options are:");
546 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
547 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700548 pw.println(" ims enable [-s SLOT_ID]");
549 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
550 pw.println(" if none is specified.");
551 pw.println(" ims disable [-s SLOT_ID]");
552 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
553 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700554 pw.println(" ims conference-event-package [enable/disable]");
555 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700556 }
557
James.cf Linbcdf8b32021-01-14 16:44:13 +0800558 private void onHelpUce() {
559 PrintWriter pw = getOutPrintWriter();
560 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800561 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
562 pw.println(" Get the EAB contacts from the EAB database.");
563 pw.println(" Options are:");
564 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
565 pw.println(" Expected output format :");
566 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800567 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
568 pw.println(" Remove the EAB contacts from the EAB database.");
569 pw.println(" Options are:");
570 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
571 pw.println(" is specified, it will choose the default voice SIM slot.");
572 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800573 pw.println(" uce get-device-enabled");
574 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
575 pw.println(" uce set-device-enabled true|false");
576 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
577 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000578 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
579 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
580 pw.println(" Options are:");
581 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
582 pw.println(" is specified, it will choose the default voice SIM slot.");
583 pw.println(" add [CAPABILITY]: add a new capability");
584 pw.println(" remove [CAPABILITY]: remove a capability");
585 pw.println(" clear: clear all capability overrides");
586 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
587 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
588 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
589 pw.println(" chatbot_sa, chatbot_role] as well as full length");
590 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
591 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
592 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
593 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800594 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
595 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800596 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
597 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800598 }
599
Hall Liud892bec2018-11-30 14:51:45 -0800600 private void onHelpNumberVerification() {
601 PrintWriter pw = getOutPrintWriter();
602 pw.println("Number verification commands");
603 pw.println(" numverify override-package PACKAGE_NAME;");
604 pw.println(" Set the authorized package for number verification.");
605 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800606 pw.println(" numverify fake-call NUMBER;");
607 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
608 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800609 }
610
Jack Nudelman644b91a2021-03-12 14:09:48 -0800611 private void onHelpThermalMitigation() {
612 PrintWriter pw = getOutPrintWriter();
613 pw.println("Thermal mitigation commands");
614 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
615 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
616 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
617 pw.println(" Remove the package from one of the authorized packages for thermal "
618 + "mitigation.");
619 }
620
Jordan Liu0ccee222021-04-27 11:55:13 -0700621 private void onHelpDisableOrEnablePhysicalSubscription() {
622 PrintWriter pw = getOutPrintWriter();
623 pw.println("Disable or enable a physical subscription");
624 pw.println(" disable-physical-subscription SUB_ID");
625 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
626 pw.println(" enable-physical-subscription SUB_ID");
627 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
628 }
629
Shuo Qianf5125122019-12-16 17:03:07 -0800630 private void onHelpDataTestMode() {
631 PrintWriter pw = getOutPrintWriter();
632 pw.println("Mobile Data Test Mode Commands:");
633 pw.println(" data enable: enable mobile data connectivity");
634 pw.println(" data disable: disable mobile data connectivity");
635 }
636
sqian9d4df8b2019-01-15 18:32:07 -0800637 private void onHelpEmergencyNumber() {
638 PrintWriter pw = getOutPrintWriter();
639 pw.println("Emergency Number Test Mode Commands:");
640 pw.println(" emergency-number-test-mode ");
641 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
642 + " the test mode");
643 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700644 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800645 pw.println(" -c: clear the emergency number list in the test mode.");
646 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700647 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800648 pw.println(" -p: get the full emergency number list in the test mode.");
649 }
650
Shuo Qian489d9282020-07-09 11:30:03 -0700651 private void onHelpEndBlockSupperssion() {
652 PrintWriter pw = getOutPrintWriter();
653 pw.println("End Block Suppression command:");
654 pw.println(" end-block-suppression: disable suppressing blocking by contact");
655 pw.println(" with emergency services.");
656 }
657
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100658 private void onHelpCc() {
659 PrintWriter pw = getOutPrintWriter();
660 pw.println("Carrier Config Commands:");
661 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
662 pw.println(" Print carrier config values.");
663 pw.println(" Options are:");
664 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
665 pw.println(" is specified, it will choose the default voice SIM slot.");
666 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
667 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100668 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100669 pw.println(" Set carrier config KEY to NEW_VALUE.");
670 pw.println(" Options are:");
671 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
672 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100673 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100674 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
675 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
676 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
677 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000678 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
679 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
680 pw.println(" provided through standard input and follow CarrierConfig XML format.");
681 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
682 pw.println(" Options are:");
683 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
684 pw.println(" is specified, it will choose the default voice SIM slot.");
685 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100686 pw.println(" cc clear-values [-s SLOT_ID]");
687 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000688 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100689 pw.println(" Options are:");
690 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
691 pw.println(" is specified, it will choose the default voice SIM slot.");
692 }
693
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000694 private void onHelpEuicc() {
695 PrintWriter pw = getOutPrintWriter();
696 pw.println("Euicc Commands:");
697 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
698 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
699 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
700 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
701 }
702
Hui Wang641e81c2020-10-12 12:14:23 -0700703 private void onHelpGba() {
704 PrintWriter pw = getOutPrintWriter();
705 pw.println("Gba Commands:");
706 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
707 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
708 pw.println(" Options are:");
709 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
710 pw.println(" is specified, it will choose the default voice SIM slot.");
711 pw.println(" gba get-service [-s SLOT_ID]");
712 pw.println(" Gets the package name of the currently defined GbaService.");
713 pw.println(" Options are:");
714 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
715 pw.println(" is specified, it will choose the default voice SIM slot.");
716 pw.println(" gba set-release [-s SLOT_ID] n");
717 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
718 pw.println(" Do not release/unbind if n is -1.");
719 pw.println(" Options are:");
720 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
721 pw.println(" is specified, it will choose the default voice SIM slot.");
722 pw.println(" gba get-release [-s SLOT_ID]");
723 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
724 pw.println(" Options are:");
725 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
726 pw.println(" is specified, it will choose the default voice SIM slot.");
727 }
728
Hui Wang761a6682020-10-31 05:12:53 +0000729 private void onHelpSrc() {
730 PrintWriter pw = getOutPrintWriter();
731 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800732 pw.println(" src set-test-enabled true|false");
733 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
734 pw.println(" The value could be true, false, or null(undefined).");
735 pw.println(" src get-test-enabled");
736 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000737 pw.println(" src set-device-enabled true|false|null");
738 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
739 pw.println(" The value could be true, false, or null(undefined).");
740 pw.println(" src get-device-enabled");
741 pw.println(" Gets the device config for RCS VoLTE single registration.");
742 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
743 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
744 pw.println(" The value could be true, false, or null(undefined).");
745 pw.println(" Options are:");
746 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
747 pw.println(" is specified, it will choose the default voice SIM slot.");
748 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
749 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
750 pw.println(" Options are:");
751 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
752 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800753 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
754 pw.println(" Sets ims feature validation result.");
755 pw.println(" The value could be true, false, or null(undefined).");
756 pw.println(" Options are:");
757 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
758 pw.println(" is specified, it will choose the default voice SIM slot.");
759 pw.println(" src get-feature-validation [-s SLOT_ID]");
760 pw.println(" Gets ims feature validation override value.");
761 pw.println(" Options are:");
762 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
763 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000764 }
765
SongFerngWang98dd5992021-05-13 17:50:00 +0800766 private void onHelpAllowedNetworkTypes() {
767 PrintWriter pw = getOutPrintWriter();
768 pw.println("Allowed Network Types Commands:");
769 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
770 pw.println(" Print allowed network types value.");
771 pw.println(" Options are:");
772 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
773 pw.println(" option is specified, it will choose the default voice SIM slot.");
774 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
775 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
776 pw.println(" Options are:");
777 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
778 pw.println(" option is specified, it will choose the default voice SIM slot.");
779 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
780 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
781 pw.println(" at TelephonyManager.java");
782 pw.println(" For example:");
783 pw.println(" NR only : 10000000000000000000");
784 pw.println(" NR|LTE : 11000001000000000000");
785 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
786 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
787 pw.println(" LTE only : 01000001000000000000");
788 }
789
jimsun3b9ccac2021-10-26 15:01:23 +0800790 private void onHelpRadio() {
791 PrintWriter pw = getOutPrintWriter();
792 pw.println("Radio Commands:");
793 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
794 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
795 pw.println(" to be the bound. Options are:");
796 pw.println(" -s: the service name that the modem service should be bound for.");
797 pw.println(" If no option is specified, it will bind to the default.");
798 pw.println(" radio get-modem-service");
799 pw.println(" Gets the service name of the currently defined modem service.");
800 pw.println(" If it is binding to default, 'default' returns.");
801 pw.println(" If it doesn't bind to any modem service for some reasons,");
802 pw.println(" the result would be 'unknown'.");
803 }
804
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700805 private void onHelpSatellite() {
806 PrintWriter pw = getOutPrintWriter();
807 pw.println("Satellite Commands:");
808 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
809 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700810 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700811 pw.println(" -s: the satellite service package name that Telephony will bind to.");
812 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700813 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
814 pw.println(" Sets the package name of satellite gateway service defined in");
815 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
816 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
817 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700818 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
819 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
820 pw.println(" mode. Options are:");
821 pw.println(" -t: the timeout duration in milliseconds.");
822 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700823 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
824 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
825 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
826 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
827 pw.println(" launch. If no option is specified, it will launch the default.");
828 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
829 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700830 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
831 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
832 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
833 pw.println(" Options are:");
834 pw.println(" -t: the emergency call to satellite handover type.");
835 pw.println(" If no option is specified, override is disabled.");
836 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
837 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800838 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
839 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
840 pw.println(" configs of satellite access controller.");
841 pw.println(" Options are:");
842 pw.println(" -r: clear the overriding. Absent means enable overriding.");
843 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
844 pw.println(" -f: the satellite s2 file.");
845 pw.println(" -d: the location fresh duration nanos.");
846 pw.println(" -c: the list of satellite country codes separated by comma.");
847 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
848 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
849 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
850 pw.println(" Override the cached location country code and its update timestamp. ");
851 pw.println(" Options are:");
852 pw.println(" -r: clear the overriding. Absent means enable overriding.");
853 pw.println(" -n: the current network country code ISOs.");
854 pw.println(" -c: the cached network country code ISOs.");
855 pw.println(" -l: the location country code ISO.");
856 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800857 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
858 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
859 pw.println(" -p: the overriding satellite provision status. If no option is ");
860 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700861 }
862
Ling Ma4fbab492022-01-25 22:36:16 +0000863 private void onHelpImei() {
864 PrintWriter pw = getOutPrintWriter();
865 pw.println("IMEI Commands:");
866 pw.println(" get-imei [-s SLOT_ID]");
867 pw.println(" Gets the device IMEI. Options are:");
868 pw.println(" -s: the slot ID to get the IMEI. If no option");
869 pw.println(" is specified, it will choose the default voice SIM slot.");
870 }
871
Hunsuk Choi13078be2023-09-13 10:55:21 +0000872 private void onHelpDomainSelection() {
873 PrintWriter pw = getOutPrintWriter();
874 pw.println("Domain Selection Commands:");
875 pw.println(" domainselection set-dss-override COMPONENT_NAME");
876 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
877 pw.println(" domainselection clear-dss-override");
878 pw.println(" Clears DomainSelectionService override.");
879 }
880
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700881 private int handleImsCommand() {
882 String arg = getNextArg();
883 if (arg == null) {
884 onHelpIms();
885 return 0;
886 }
887
888 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800889 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700890 return handleImsSetServiceCommand();
891 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800892 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700893 return handleImsGetServiceCommand();
894 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800895 case IMS_CLEAR_SERVICE_OVERRIDE: {
896 return handleImsClearCarrierServiceCommand();
897 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800898 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700899 return handleEnableIms();
900 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800901 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700902 return handleDisableIms();
903 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700904 case IMS_CEP: {
905 return handleCepChange();
906 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700907 }
908
909 return -1;
910 }
911
Shuo Qianf5125122019-12-16 17:03:07 -0800912 private int handleDataTestModeCommand() {
913 PrintWriter errPw = getErrPrintWriter();
914 String arg = getNextArgRequired();
915 if (arg == null) {
916 onHelpDataTestMode();
917 return 0;
918 }
919 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800920 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800921 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700922 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800923 } catch (RemoteException ex) {
924 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
925 errPw.println("Exception: " + ex.getMessage());
926 return -1;
927 }
928 break;
929 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800930 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800931 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700932 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800933 } catch (RemoteException ex) {
934 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
935 errPw.println("Exception: " + ex.getMessage());
936 return -1;
937 }
938 break;
939 }
940 default:
941 onHelpDataTestMode();
942 break;
943 }
944 return 0;
945 }
946
Shuo Qianccbaf742021-02-22 18:32:21 -0800947 private int handleEmergencyCallbackModeCommand() {
948 PrintWriter errPw = getErrPrintWriter();
949 try {
950 mInterface.startEmergencyCallbackMode();
951 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
952 } catch (RemoteException ex) {
953 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
954 errPw.println("Exception: " + ex.getMessage());
955 return -1;
956 }
957 return 0;
958 }
959
Grant Menke567d48f2022-08-18 20:19:10 +0000960 private void removeEmergencyNumberTestMode(String emergencyNumber) {
961 PrintWriter errPw = getErrPrintWriter();
962 for (int routingType : ROUTING_TYPES) {
963 try {
964 mInterface.updateEmergencyNumberListTestMode(
965 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
966 new EmergencyNumber(emergencyNumber, "", "",
967 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
968 new ArrayList<String>(),
969 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
970 routingType));
971 } catch (RemoteException ex) {
972 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
973 errPw.println("Exception: " + ex.getMessage());
974 }
975 }
976 }
977
sqian9d4df8b2019-01-15 18:32:07 -0800978 private int handleEmergencyNumberTestModeCommand() {
979 PrintWriter errPw = getErrPrintWriter();
980 String opt = getNextOption();
981 if (opt == null) {
982 onHelpEmergencyNumber();
983 return 0;
984 }
sqian9d4df8b2019-01-15 18:32:07 -0800985 switch (opt) {
986 case "-a": {
987 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000988 if (emergencyNumberCmd == null){
989 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800990 return -1;
991 }
Grant Menke567d48f2022-08-18 20:19:10 +0000992 String[] params = emergencyNumberCmd.split(":");
993 String emergencyNumber;
994 if (params[0] == null ||
995 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
996 errPw.println(INVALID_ENTRY_ERROR);
997 return -1;
998 } else {
999 emergencyNumber = params[0];
1000 }
1001 removeEmergencyNumberTestMode(emergencyNumber);
1002 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
1003 if (params.length > 1) {
1004 switch (params[1].toLowerCase(Locale.ROOT)) {
1005 case "emergency":
1006 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1007 break;
1008 case "normal":
1009 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1010 break;
1011 case "unknown":
1012 break;
1013 default:
1014 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1015 + "emergency call routing. Please enter either \"normal\", "
1016 + "\"unknown\", or \"emergency\" for call routing. "
1017 + "(-a 1234:normal)");
1018 return -1;
1019 }
1020 }
sqian9d4df8b2019-01-15 18:32:07 -08001021 try {
1022 mInterface.updateEmergencyNumberListTestMode(
1023 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001024 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001025 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1026 new ArrayList<String>(),
1027 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001028 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001029 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001030 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001031 + ", error " + ex.getMessage());
1032 errPw.println("Exception: " + ex.getMessage());
1033 return -1;
1034 }
1035 break;
1036 }
1037 case "-c": {
1038 try {
1039 mInterface.updateEmergencyNumberListTestMode(
1040 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1041 } catch (RemoteException ex) {
1042 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1043 errPw.println("Exception: " + ex.getMessage());
1044 return -1;
1045 }
1046 break;
1047 }
1048 case "-r": {
1049 String emergencyNumberCmd = getNextArgRequired();
1050 if (emergencyNumberCmd == null
1051 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001052 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001053 + " to be specified after -r in the command ");
1054 return -1;
1055 }
Grant Menke567d48f2022-08-18 20:19:10 +00001056 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001057 break;
1058 }
1059 case "-p": {
1060 try {
1061 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1062 } catch (RemoteException ex) {
1063 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1064 errPw.println("Exception: " + ex.getMessage());
1065 return -1;
1066 }
1067 break;
1068 }
1069 default:
1070 onHelpEmergencyNumber();
1071 break;
1072 }
1073 return 0;
1074 }
1075
Hall Liud892bec2018-11-30 14:51:45 -08001076 private int handleNumberVerificationCommand() {
1077 String arg = getNextArg();
1078 if (arg == null) {
1079 onHelpNumberVerification();
1080 return 0;
1081 }
1082
Hall Liuca5af3a2018-12-04 16:58:23 -08001083 if (!checkShellUid()) {
1084 return -1;
1085 }
1086
Hall Liud892bec2018-11-30 14:51:45 -08001087 switch (arg) {
1088 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001089 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1090 return 0;
1091 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001092 case NUMBER_VERIFICATION_FAKE_CALL: {
1093 boolean val = NumberVerificationManager.getInstance()
1094 .checkIncomingCall(getNextArg());
1095 getOutPrintWriter().println(val ? "1" : "0");
1096 return 0;
1097 }
Hall Liud892bec2018-11-30 14:51:45 -08001098 }
1099
1100 return -1;
1101 }
1102
Jordan Liu0ccee222021-04-27 11:55:13 -07001103 private boolean subIsEsim(int subId) {
1104 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1105 if (info != null) {
1106 return info.isEmbedded();
1107 }
1108 return false;
1109 }
1110
1111 private int handleEnablePhysicalSubscription(boolean enable) {
1112 PrintWriter errPw = getErrPrintWriter();
1113 int subId = 0;
1114 try {
1115 subId = Integer.parseInt(getNextArgRequired());
1116 } catch (NumberFormatException e) {
1117 errPw.println((enable ? "enable" : "disable")
1118 + "-physical-subscription requires an integer as a subId.");
1119 return -1;
1120 }
1121 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1122 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001123 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1124 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001125 errPw.println("cc: Permission denied.");
1126 return -1;
1127 }
1128 // Verify that the subId represents a physical sub
1129 if (subIsEsim(subId)) {
1130 errPw.println("SubId " + subId + " is not for a physical subscription");
1131 return -1;
1132 }
1133 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1134 + " physical subscription with subId=" + subId);
1135 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1136 return 0;
1137 }
1138
Jack Nudelman644b91a2021-03-12 14:09:48 -08001139 private int handleThermalMitigationCommand() {
1140 String arg = getNextArg();
1141 String packageName = getNextArg();
1142 if (arg == null || packageName == null) {
1143 onHelpThermalMitigation();
1144 return 0;
1145 }
1146
1147 if (!checkShellUid()) {
1148 return -1;
1149 }
1150
1151 switch (arg) {
1152 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1153 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1154 return 0;
1155 }
1156 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1157 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1158 mContext);
1159 return 0;
1160 }
1161 default:
1162 onHelpThermalMitigation();
1163 }
1164
1165 return -1;
1166
1167 }
1168
Tyler Gunn92479152021-01-20 16:30:10 -08001169 private int handleD2dCommand() {
1170 String arg = getNextArg();
1171 if (arg == null) {
1172 onHelpD2D();
1173 return 0;
1174 }
1175
1176 switch (arg) {
1177 case D2D_SEND: {
1178 return handleD2dSendCommand();
1179 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001180 case D2D_TRANSPORT: {
1181 return handleD2dTransportCommand();
1182 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001183 case D2D_SET_DEVICE_SUPPORT: {
1184 return handleD2dDeviceSupportedCommand();
1185 }
Tyler Gunn92479152021-01-20 16:30:10 -08001186 }
1187
1188 return -1;
1189 }
1190
1191 private int handleD2dSendCommand() {
1192 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001193 int messageType = -1;
1194 int messageValue = -1;
1195
Tyler Gunn92479152021-01-20 16:30:10 -08001196 String arg = getNextArg();
1197 if (arg == null) {
1198 onHelpD2D();
1199 return 0;
1200 }
1201 try {
1202 messageType = Integer.parseInt(arg);
1203 } catch (NumberFormatException e) {
1204 errPw.println("message type must be a valid integer");
1205 return -1;
1206 }
1207
1208 arg = getNextArg();
1209 if (arg == null) {
1210 onHelpD2D();
1211 return 0;
1212 }
1213 try {
1214 messageValue = Integer.parseInt(arg);
1215 } catch (NumberFormatException e) {
1216 errPw.println("message value must be a valid integer");
1217 return -1;
1218 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001219
Tyler Gunn92479152021-01-20 16:30:10 -08001220 try {
1221 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1222 } catch (RemoteException e) {
1223 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1224 errPw.println("Exception: " + e.getMessage());
1225 return -1;
1226 }
1227
1228 return 0;
1229 }
1230
Tyler Gunnbabbda02021-02-10 11:05:02 -08001231 private int handleD2dTransportCommand() {
1232 PrintWriter errPw = getErrPrintWriter();
1233
1234 String arg = getNextArg();
1235 if (arg == null) {
1236 onHelpD2D();
1237 return 0;
1238 }
1239
1240 try {
1241 mInterface.setActiveDeviceToDeviceTransport(arg);
1242 } catch (RemoteException e) {
1243 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1244 errPw.println("Exception: " + e.getMessage());
1245 return -1;
1246 }
1247 return 0;
1248 }
Nazanin014f41e2021-05-06 17:26:31 -07001249 private int handleBarringCommand() {
1250 String arg = getNextArg();
1251 if (arg == null) {
1252 onHelpBarring();
1253 return 0;
1254 }
1255
1256 switch (arg) {
1257 case BARRING_SEND_INFO: {
1258 return handleBarringSendCommand();
1259 }
1260 }
1261 return -1;
1262 }
1263
1264 private int handleBarringSendCommand() {
1265 PrintWriter errPw = getErrPrintWriter();
1266 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001267 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001268 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1269 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1270 boolean isConditionallyBarred = false;
1271 int conditionalBarringTimeSeconds = 0;
1272
1273 String opt;
1274 while ((opt = getNextOption()) != null) {
1275 switch (opt) {
1276 case "-s": {
1277 try {
1278 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001279 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001280 } catch (NumberFormatException e) {
1281 errPw.println("barring send requires an integer as a SLOT_ID.");
1282 return -1;
1283 }
1284 break;
1285 }
1286 case "-b": {
1287 try {
1288 barringType = Integer.parseInt(getNextArgRequired());
1289 if (barringType < -1 || barringType > 2) {
1290 throw new NumberFormatException();
1291 }
1292
1293 } catch (NumberFormatException e) {
1294 errPw.println("barring send requires an integer in range [-1,2] as "
1295 + "a BARRING_TYPE.");
1296 return -1;
1297 }
1298 break;
1299 }
1300 case "-c": {
1301 try {
1302 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1303 } catch (Exception e) {
1304 errPw.println("barring send requires a boolean after -c indicating"
1305 + " conditional barring");
1306 return -1;
1307 }
1308 break;
1309 }
1310 case "-t": {
1311 try {
1312 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1313 } catch (NumberFormatException e) {
1314 errPw.println("barring send requires an integer for time of barring"
1315 + " in seconds after -t for conditional barring");
1316 return -1;
1317 }
1318 break;
1319 }
1320 }
1321 }
1322 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1323 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1324 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1325 barringServiceInfos.append(0, bsi);
1326 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1327 try {
1328 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1329 } catch (Exception e) {
1330 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1331 errPw.println("Exception: " + e.getMessage());
1332 return -1;
1333 }
1334 return 0;
1335 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001336
Tyler Gunnd4575212021-05-03 14:46:49 -07001337 private int handleD2dDeviceSupportedCommand() {
1338 PrintWriter errPw = getErrPrintWriter();
1339
1340 String arg = getNextArg();
1341 if (arg == null) {
1342 onHelpD2D();
1343 return 0;
1344 }
1345
Jack Yua533d632022-09-30 13:53:46 -07001346 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001347 try {
1348 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1349 } catch (RemoteException e) {
1350 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1351 errPw.println("Exception: " + e.getMessage());
1352 return -1;
1353 }
1354 return 0;
1355 }
1356
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001357 // ims set-ims-service
1358 private int handleImsSetServiceCommand() {
1359 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001360 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001361 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001362 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001363
1364 String opt;
1365 while ((opt = getNextOption()) != null) {
1366 switch (opt) {
1367 case "-s": {
1368 try {
1369 slotId = Integer.parseInt(getNextArgRequired());
1370 } catch (NumberFormatException e) {
1371 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1372 return -1;
1373 }
1374 break;
1375 }
1376 case "-c": {
1377 isCarrierService = true;
1378 break;
1379 }
1380 case "-d": {
1381 isCarrierService = false;
1382 break;
1383 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001384 case "-f": {
1385 String featureString = getNextArgRequired();
1386 String[] features = featureString.split(",");
1387 for (int i = 0; i < features.length; i++) {
1388 try {
1389 Integer result = Integer.parseInt(features[i]);
1390 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1391 || result >= ImsFeature.FEATURE_MAX) {
1392 errPw.println("ims set-ims-service -f " + result
1393 + " is an invalid feature.");
1394 return -1;
1395 }
1396 featuresList.add(result);
1397 } catch (NumberFormatException e) {
1398 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1399 + " as an integer.");
1400 return -1;
1401 }
1402 }
1403 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001404 }
1405 }
1406 // Mandatory param, either -c or -d
1407 if (isCarrierService == null) {
1408 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1409 return -1;
1410 }
1411
1412 String packageName = getNextArg();
1413
1414 try {
1415 if (packageName == null) {
1416 packageName = "";
1417 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001418 int[] featureArray = new int[featuresList.size()];
1419 for (int i = 0; i < featuresList.size(); i++) {
1420 featureArray[i] = featuresList.get(i);
1421 }
1422 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1423 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001424 if (VDBG) {
1425 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001426 + (isCarrierService ? "-c " : "-d ")
1427 + "-f " + featuresList + " "
1428 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001429 }
1430 getOutPrintWriter().println(result);
1431 } catch (RemoteException e) {
1432 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001433 + (isCarrierService ? "-c " : "-d ")
1434 + "-f " + featuresList + " "
1435 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001436 errPw.println("Exception: " + e.getMessage());
1437 return -1;
1438 }
1439 return 0;
1440 }
1441
Brad Ebinger999d3302020-11-25 14:31:39 -08001442 // ims clear-ims-service-override
1443 private int handleImsClearCarrierServiceCommand() {
1444 PrintWriter errPw = getErrPrintWriter();
1445 int slotId = getDefaultSlot();
1446
1447 String opt;
1448 while ((opt = getNextOption()) != null) {
1449 switch (opt) {
1450 case "-s": {
1451 try {
1452 slotId = Integer.parseInt(getNextArgRequired());
1453 } catch (NumberFormatException e) {
1454 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1455 return -1;
1456 }
1457 break;
1458 }
1459 }
1460 }
1461
1462 try {
1463 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1464 if (VDBG) {
1465 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1466 + ", result=" + result);
1467 }
1468 getOutPrintWriter().println(result);
1469 } catch (RemoteException e) {
1470 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1471 + ", error" + e.getMessage());
1472 errPw.println("Exception: " + e.getMessage());
1473 return -1;
1474 }
1475 return 0;
1476 }
1477
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001478 // ims get-ims-service
1479 private int handleImsGetServiceCommand() {
1480 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001481 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001482 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001483 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001484
1485 String opt;
1486 while ((opt = getNextOption()) != null) {
1487 switch (opt) {
1488 case "-s": {
1489 try {
1490 slotId = Integer.parseInt(getNextArgRequired());
1491 } catch (NumberFormatException e) {
1492 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1493 return -1;
1494 }
1495 break;
1496 }
1497 case "-c": {
1498 isCarrierService = true;
1499 break;
1500 }
1501 case "-d": {
1502 isCarrierService = false;
1503 break;
1504 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001505 case "-f": {
1506 try {
1507 featureType = Integer.parseInt(getNextArg());
1508 } catch (NumberFormatException e) {
1509 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1510 return -1;
1511 }
1512 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1513 || featureType >= ImsFeature.FEATURE_MAX) {
1514 errPw.println("ims get-ims-service -f invalid feature.");
1515 return -1;
1516 }
1517 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001518 }
1519 }
1520 // Mandatory param, either -c or -d
1521 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001522 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001523 return -1;
1524 }
1525
1526 String result;
1527 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001528 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001529 } catch (RemoteException e) {
1530 return -1;
1531 }
1532 if (VDBG) {
1533 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001534 + (isCarrierService ? "-c " : "-d ")
1535 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1536 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001537 }
1538 getOutPrintWriter().println(result);
1539 return 0;
1540 }
1541
1542 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001543 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001544 String opt;
1545 while ((opt = getNextOption()) != null) {
1546 switch (opt) {
1547 case "-s": {
1548 try {
1549 slotId = Integer.parseInt(getNextArgRequired());
1550 } catch (NumberFormatException e) {
1551 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1552 return -1;
1553 }
1554 break;
1555 }
1556 }
1557 }
1558 try {
1559 mInterface.enableIms(slotId);
1560 } catch (RemoteException e) {
1561 return -1;
1562 }
1563 if (VDBG) {
1564 Log.v(LOG_TAG, "ims enable -s " + slotId);
1565 }
1566 return 0;
1567 }
1568
1569 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001570 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001571 String opt;
1572 while ((opt = getNextOption()) != null) {
1573 switch (opt) {
1574 case "-s": {
1575 try {
1576 slotId = Integer.parseInt(getNextArgRequired());
1577 } catch (NumberFormatException e) {
1578 getErrPrintWriter().println(
1579 "ims disable requires an integer as a SLOT_ID.");
1580 return -1;
1581 }
1582 break;
1583 }
1584 }
1585 }
1586 try {
1587 mInterface.disableIms(slotId);
1588 } catch (RemoteException e) {
1589 return -1;
1590 }
1591 if (VDBG) {
1592 Log.v(LOG_TAG, "ims disable -s " + slotId);
1593 }
1594 return 0;
1595 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001596
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001597 private int handleCepChange() {
1598 Log.i(LOG_TAG, "handleCepChange");
1599 String opt = getNextArg();
1600 if (opt == null) {
1601 return -1;
1602 }
1603 boolean isCepEnabled = opt.equals("enable");
1604
1605 try {
1606 mInterface.setCepEnabled(isCepEnabled);
1607 } catch (RemoteException e) {
1608 return -1;
1609 }
1610 return 0;
1611 }
1612
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001613 private int getDefaultSlot() {
1614 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1615 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1616 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1617 // If there is no default, default to slot 0.
1618 slotId = DEFAULT_PHONE_ID;
1619 }
1620 return slotId;
1621 }
sqian2fff4a32018-11-05 14:18:37 -08001622
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001623 // Parse options related to Carrier Config Commands.
1624 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001625 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001626 CcOptionParseResult result = new CcOptionParseResult();
1627 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1628 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001629
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001631 while ((opt = getNextOption()) != null) {
1632 switch (opt) {
1633 case "-s": {
1634 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001635 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1636 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1637 errPw.println(tag + "No valid subscription found.");
1638 return null;
1639 }
1640
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001641 } catch (IllegalArgumentException e) {
1642 // Missing slot id
1643 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001644 return null;
1645 }
1646 break;
1647 }
1648 case "-p": {
1649 if (allowOptionPersistent) {
1650 result.mPersistent = true;
1651 } else {
1652 errPw.println(tag + "Unexpected option " + opt);
1653 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001654 }
1655 break;
1656 }
1657 default: {
1658 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001659 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001660 }
1661 }
1662 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001663 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001664 }
1665
1666 private int slotStringToSubId(String tag, String slotString) {
1667 int slotId = -1;
1668 try {
1669 slotId = Integer.parseInt(slotString);
1670 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001671 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1672 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1673 }
1674
1675 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001676 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1677 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1678 }
1679
Qiong Liuf25799b2020-09-10 10:13:46 +08001680 Phone phone = PhoneFactory.getPhone(slotId);
1681 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001682 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1683 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1684 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001685 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001686 }
1687
Hall Liud892bec2018-11-30 14:51:45 -08001688 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001689 // adb can run as root or as shell, depending on whether the device is rooted.
Jack Yu86374492024-09-16 13:05:44 -07001690 return UserHandle.isSameApp(Binder.getCallingUid(), Process.SHELL_UID)
1691 || UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID);
Hall Liud892bec2018-11-30 14:51:45 -08001692 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001693
1694 private int handleCcCommand() {
1695 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1696 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001697 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1698 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001699 getErrPrintWriter().println("cc: Permission denied.");
1700 return -1;
1701 }
1702
1703 String arg = getNextArg();
1704 if (arg == null) {
1705 onHelpCc();
1706 return 0;
1707 }
1708
1709 switch (arg) {
1710 case CC_GET_VALUE: {
1711 return handleCcGetValue();
1712 }
1713 case CC_SET_VALUE: {
1714 return handleCcSetValue();
1715 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001716 case CC_SET_VALUES_FROM_XML: {
1717 return handleCcSetValuesFromXml();
1718 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001719 case CC_CLEAR_VALUES: {
1720 return handleCcClearValues();
1721 }
1722 default: {
1723 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1724 }
1725 }
1726 return -1;
1727 }
1728
1729 // cc get-value
1730 private int handleCcGetValue() {
1731 PrintWriter errPw = getErrPrintWriter();
1732 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1733 String key = null;
1734
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001735 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001736 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001737 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001738 return -1;
1739 }
1740
1741 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001742 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001743 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001744 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001745 return -1;
1746 }
1747
1748 // Get the key.
1749 key = getNextArg();
1750 if (key != null) {
1751 // A key was provided. Verify if it is a valid key
1752 if (!bundle.containsKey(key)) {
1753 errPw.println(tag + key + " is not a valid key.");
1754 return -1;
1755 }
1756
1757 // Print the carrier config value for key.
1758 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1759 } else {
1760 // No key provided. Show all values.
1761 // Iterate over a sorted list of all carrier config keys and print them.
1762 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1763 for (String k : sortedSet) {
1764 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1765 }
1766 }
1767 return 0;
1768 }
1769
1770 // cc set-value
1771 private int handleCcSetValue() {
1772 PrintWriter errPw = getErrPrintWriter();
1773 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1774
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001775 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001776 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001777 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001778 return -1;
1779 }
1780
1781 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001782 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001783 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001784 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001785 return -1;
1786 }
1787
1788 // Get the key.
1789 String key = getNextArg();
1790 if (key == null || key.equals("")) {
1791 errPw.println(tag + "KEY is missing");
1792 return -1;
1793 }
1794
1795 // Verify if the key is valid
1796 if (!originalValues.containsKey(key)) {
1797 errPw.println(tag + key + " is not a valid key.");
1798 return -1;
1799 }
1800
1801 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1802 ArrayList<String> valueList = new ArrayList<String>();
1803 while (peekNextArg() != null) {
1804 valueList.add(getNextArg());
1805 }
1806
1807 // Find the type of the carrier config value
1808 CcType type = getType(tag, key, originalValues);
1809 if (type == CcType.UNKNOWN) {
1810 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1811 return -1;
1812 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001813 if (type == CcType.PERSISTABLE_BUNDLE) {
1814 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1815 + "Use set-values-from-xml instead.");
1816 return -1;
1817 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001818
1819 // Create an override bundle containing the key and value that should be overriden.
1820 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1821 if (overrideBundle == null) {
1822 return -1;
1823 }
1824
1825 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001826 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001827
1828 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001829 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001830 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001831 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001832 return -1;
1833 }
1834
1835 // Print the original and new value.
1836 String originalValueString = ccValueToString(key, type, originalValues);
1837 String newValueString = ccValueToString(key, type, newValues);
1838 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1839 getOutPrintWriter().println("New value: \n" + newValueString);
1840
1841 return 0;
1842 }
1843
Allen Xuee00f0e2022-03-14 21:04:49 +00001844 // cc set-values-from-xml
1845 private int handleCcSetValuesFromXml() {
1846 PrintWriter errPw = getErrPrintWriter();
1847 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1848
1849 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001850 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001851 if (options == null) {
1852 return -1;
1853 }
1854
1855 // Get bundle containing all current carrier configuration values.
1856 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1857 if (originalValues == null) {
1858 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1859 return -1;
1860 }
1861
1862 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1863 if (overrideBundle == null) {
1864 return -1;
1865 }
1866
1867 // Verify all values are valid types
1868 for (String key : overrideBundle.keySet()) {
1869 CcType type = getType(tag, key, originalValues);
1870 if (type == CcType.UNKNOWN) {
1871 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1872 return -1;
1873 }
1874 }
1875
1876 // Override the value
1877 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1878
1879 // Find bundle containing all new carrier configuration values after the override.
1880 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1881 if (newValues == null) {
1882 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1883 return -1;
1884 }
1885
1886 // Print the original and new values
1887 overrideBundle.keySet().forEach(key -> {
1888 CcType type = getType(tag, key, originalValues);
1889 String originalValueString = ccValueToString(key, type, originalValues);
1890 String newValueString = ccValueToString(key, type, newValues);
1891 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1892 getOutPrintWriter().println("New value: \n" + newValueString);
1893 });
1894
1895 return 0;
1896 }
1897
1898 private PersistableBundle readPersistableBundleFromXml(String tag) {
1899 PersistableBundle subIdBundles;
1900 try {
1901 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1902 } catch (IOException | RuntimeException e) {
1903 PrintWriter errPw = getErrPrintWriter();
1904 errPw.println(tag + e);
1905 return null;
1906 }
1907
1908 return subIdBundles;
1909 }
1910
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001911 // cc clear-values
1912 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001913 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1914
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001915 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001916 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001917 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001918 return -1;
1919 }
1920
1921 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001922 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001923 getOutPrintWriter()
1924 .println("All previously set carrier config override values has been cleared");
1925 return 0;
1926 }
1927
1928 private CcType getType(String tag, String key, PersistableBundle bundle) {
1929 // Find the type by checking the type of the current value stored in the bundle.
1930 Object value = bundle.get(key);
1931
1932 if (CC_TYPE_MAP.containsKey(key)) {
1933 return CC_TYPE_MAP.get(key);
1934 } else if (value != null) {
1935 if (value instanceof Boolean) {
1936 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001937 }
1938 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001939 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001940 }
1941 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001942 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001943 }
1944 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001945 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 }
1947 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001948 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001949 }
1950 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001951 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001952 }
1953 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001954 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 }
1956 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001957 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001958 }
1959 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001960 return CcType.STRING_ARRAY;
1961 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001962 if (value instanceof PersistableBundle) {
1963 return CcType.PERSISTABLE_BUNDLE;
1964 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001965 } else {
1966 // Current value was null and can therefore not be used in order to find the type.
1967 // Check the name of the key to infer the type. This check is not needed for primitive
1968 // data types (boolean, double, int and long), since they can not be null.
1969 if (key.endsWith("double_array")) {
1970 return CcType.DOUBLE_ARRAY;
1971 }
1972 if (key.endsWith("int_array")) {
1973 return CcType.INT_ARRAY;
1974 }
1975 if (key.endsWith("long_array")) {
1976 return CcType.LONG_ARRAY;
1977 }
1978 if (key.endsWith("string")) {
1979 return CcType.STRING;
1980 }
1981 if (key.endsWith("string_array") || key.endsWith("strings")) {
1982 return CcType.STRING_ARRAY;
1983 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001984 if (key.endsWith("bundle")) {
1985 return CcType.PERSISTABLE_BUNDLE;
1986 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001987 }
1988
1989 // Not possible to infer the type by looking at the current value or the key.
1990 PrintWriter errPw = getErrPrintWriter();
1991 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1992 return CcType.UNKNOWN;
1993 }
1994
1995 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1996 String result;
1997 StringBuilder valueString = new StringBuilder();
1998 String typeString = type.toString();
1999 Object value = bundle.get(key);
2000
2001 if (value == null) {
2002 valueString.append("null");
2003 } else {
2004 switch (type) {
2005 case DOUBLE_ARRAY: {
2006 // Format the string representation of the int array as value1 value2......
2007 double[] valueArray = (double[]) value;
2008 for (int i = 0; i < valueArray.length; i++) {
2009 if (i != 0) {
2010 valueString.append(" ");
2011 }
2012 valueString.append(valueArray[i]);
2013 }
2014 break;
2015 }
2016 case INT_ARRAY: {
2017 // Format the string representation of the int array as value1 value2......
2018 int[] valueArray = (int[]) value;
2019 for (int i = 0; i < valueArray.length; i++) {
2020 if (i != 0) {
2021 valueString.append(" ");
2022 }
2023 valueString.append(valueArray[i]);
2024 }
2025 break;
2026 }
2027 case LONG_ARRAY: {
2028 // Format the string representation of the int array as value1 value2......
2029 long[] valueArray = (long[]) value;
2030 for (int i = 0; i < valueArray.length; i++) {
2031 if (i != 0) {
2032 valueString.append(" ");
2033 }
2034 valueString.append(valueArray[i]);
2035 }
2036 break;
2037 }
2038 case STRING: {
2039 valueString.append("\"" + value.toString() + "\"");
2040 break;
2041 }
2042 case STRING_ARRAY: {
2043 // Format the string representation of the string array as "value1" "value2"....
2044 String[] valueArray = (String[]) value;
2045 for (int i = 0; i < valueArray.length; i++) {
2046 if (i != 0) {
2047 valueString.append(" ");
2048 }
2049 if (valueArray[i] != null) {
2050 valueString.append("\"" + valueArray[i] + "\"");
2051 } else {
2052 valueString.append("null");
2053 }
2054 }
2055 break;
2056 }
2057 default: {
2058 valueString.append(value.toString());
2059 }
2060 }
2061 }
2062 return String.format("%-70s %-15s %s", key, typeString, valueString);
2063 }
2064
2065 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2066 ArrayList<String> valueList) {
2067 PrintWriter errPw = getErrPrintWriter();
2068 PersistableBundle bundle = new PersistableBundle();
2069
2070 // First verify that a valid number of values has been provided for the type.
2071 switch (type) {
2072 case BOOLEAN:
2073 case DOUBLE:
2074 case INT:
2075 case LONG: {
2076 if (valueList.size() != 1) {
2077 errPw.println(tag + "Expected 1 value for type " + type
2078 + ". Found: " + valueList.size());
2079 return null;
2080 }
2081 break;
2082 }
2083 case STRING: {
2084 if (valueList.size() > 1) {
2085 errPw.println(tag + "Expected 0 or 1 values for type " + type
2086 + ". Found: " + valueList.size());
2087 return null;
2088 }
2089 break;
2090 }
2091 }
2092
2093 // Parse the value according to type and add it to the Bundle.
2094 switch (type) {
2095 case BOOLEAN: {
2096 if ("true".equalsIgnoreCase(valueList.get(0))) {
2097 bundle.putBoolean(key, true);
2098 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2099 bundle.putBoolean(key, false);
2100 } else {
2101 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2102 return null;
2103 }
2104 break;
2105 }
2106 case DOUBLE: {
2107 try {
2108 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2109 } catch (NumberFormatException nfe) {
2110 // Not a valid double
2111 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2112 return null;
2113 }
2114 break;
2115 }
2116 case DOUBLE_ARRAY: {
2117 double[] valueDoubleArray = null;
2118 if (valueList.size() > 0) {
2119 valueDoubleArray = new double[valueList.size()];
2120 for (int i = 0; i < valueList.size(); i++) {
2121 try {
2122 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2123 } catch (NumberFormatException nfe) {
2124 // Not a valid double
2125 errPw.println(
2126 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2127 return null;
2128 }
2129 }
2130 }
2131 bundle.putDoubleArray(key, valueDoubleArray);
2132 break;
2133 }
2134 case INT: {
2135 try {
2136 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2137 } catch (NumberFormatException nfe) {
2138 // Not a valid integer
2139 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2140 return null;
2141 }
2142 break;
2143 }
2144 case INT_ARRAY: {
2145 int[] valueIntArray = null;
2146 if (valueList.size() > 0) {
2147 valueIntArray = new int[valueList.size()];
2148 for (int i = 0; i < valueList.size(); i++) {
2149 try {
2150 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2151 } catch (NumberFormatException nfe) {
2152 // Not a valid integer
2153 errPw.println(tag
2154 + "Unable to parse " + valueList.get(i) + " as an integer.");
2155 return null;
2156 }
2157 }
2158 }
2159 bundle.putIntArray(key, valueIntArray);
2160 break;
2161 }
2162 case LONG: {
2163 try {
2164 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2165 } catch (NumberFormatException nfe) {
2166 // Not a valid long
2167 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2168 return null;
2169 }
2170 break;
2171 }
2172 case LONG_ARRAY: {
2173 long[] valueLongArray = null;
2174 if (valueList.size() > 0) {
2175 valueLongArray = new long[valueList.size()];
2176 for (int i = 0; i < valueList.size(); i++) {
2177 try {
2178 valueLongArray[i] = Long.parseLong(valueList.get(i));
2179 } catch (NumberFormatException nfe) {
2180 // Not a valid long
2181 errPw.println(
2182 tag + "Unable to parse " + valueList.get(i) + " as a long");
2183 return null;
2184 }
2185 }
2186 }
2187 bundle.putLongArray(key, valueLongArray);
2188 break;
2189 }
2190 case STRING: {
2191 String value = null;
2192 if (valueList.size() > 0) {
2193 value = valueList.get(0);
2194 }
2195 bundle.putString(key, value);
2196 break;
2197 }
2198 case STRING_ARRAY: {
2199 String[] valueStringArray = null;
2200 if (valueList.size() > 0) {
2201 valueStringArray = new String[valueList.size()];
2202 valueList.toArray(valueStringArray);
2203 }
2204 bundle.putStringArray(key, valueStringArray);
2205 break;
2206 }
2207 }
2208 return bundle;
2209 }
Shuo Qian489d9282020-07-09 11:30:03 -07002210
2211 private int handleEndBlockSuppressionCommand() {
2212 if (!checkShellUid()) {
2213 return -1;
2214 }
2215
2216 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2217 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2218 }
2219 return 0;
2220 }
Hui Wang641e81c2020-10-12 12:14:23 -07002221
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002222 private int handleEuiccCommand() {
2223 String arg = getNextArg();
2224 if (arg == null) {
2225 onHelpEuicc();
2226 return 0;
2227 }
2228
2229 switch (arg) {
2230 case EUICC_SET_UI_COMPONENT: {
2231 return handleEuiccServiceCommand();
2232 }
2233 }
2234 return -1;
2235 }
2236
2237 private int handleEuiccServiceCommand() {
2238 String uiComponent = getNextArg();
2239 String packageName = getNextArg();
2240 if (packageName == null || uiComponent == null) {
2241 return -1;
2242 }
2243 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2244 if (VDBG) {
2245 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2246 + packageName);
2247 }
2248 return 0;
2249 }
2250
Michele Berionne54af4632020-12-28 20:23:16 +00002251 private int handleRestartModemCommand() {
2252 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2253 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002254 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2255 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002256 getErrPrintWriter().println("RestartModem: Permission denied.");
2257 return -1;
2258 }
2259
2260 boolean result = TelephonyManager.getDefault().rebootRadio();
2261 getOutPrintWriter().println(result);
2262
2263 return result ? 0 : -1;
2264 }
2265
Ling Ma4fbab492022-01-25 22:36:16 +00002266 private int handleGetImei() {
2267 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2268 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002269 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2270 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002271 getErrPrintWriter().println("Device IMEI: Permission denied.");
2272 return -1;
2273 }
2274
2275 final long identity = Binder.clearCallingIdentity();
2276
2277 String imei = null;
2278 String arg = getNextArg();
2279 if (arg != null) {
2280 try {
2281 int specifiedSlotIndex = Integer.parseInt(arg);
2282 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2283 } catch (NumberFormatException exception) {
2284 PrintWriter errPw = getErrPrintWriter();
2285 errPw.println("-s requires an integer as slot index.");
2286 return -1;
2287 }
2288
2289 } else {
2290 imei = TelephonyManager.from(mContext).getImei();
2291 }
2292 getOutPrintWriter().println("Device IMEI: " + imei);
2293
2294 Binder.restoreCallingIdentity(identity);
2295 return 0;
2296 }
2297
Michele Berionne5e411512020-11-13 02:36:59 +00002298 private int handleUnattendedReboot() {
2299 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2300 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002301 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2302 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002303 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2304 return -1;
2305 }
2306
2307 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2308 getOutPrintWriter().println("result: " + result);
2309
2310 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2311 }
2312
Aman Gupta07124872022-02-09 08:02:14 +00002313 private int handleGetSimSlotsMapping() {
2314 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2315 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002316 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2317 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002318 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2319 return -1;
2320 }
2321 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2322 String result = telephonyManager.getSimSlotMapping().toString();
2323 getOutPrintWriter().println("simSlotsMapping: " + result);
2324
2325 return 0;
2326 }
2327
Hui Wang641e81c2020-10-12 12:14:23 -07002328 private int handleGbaCommand() {
2329 String arg = getNextArg();
2330 if (arg == null) {
2331 onHelpGba();
2332 return 0;
2333 }
2334
2335 switch (arg) {
2336 case GBA_SET_SERVICE: {
2337 return handleGbaSetServiceCommand();
2338 }
2339 case GBA_GET_SERVICE: {
2340 return handleGbaGetServiceCommand();
2341 }
2342 case GBA_SET_RELEASE_TIME: {
2343 return handleGbaSetReleaseCommand();
2344 }
2345 case GBA_GET_RELEASE_TIME: {
2346 return handleGbaGetReleaseCommand();
2347 }
2348 }
2349
2350 return -1;
2351 }
2352
2353 private int getSubId(String cmd) {
2354 int slotId = getDefaultSlot();
2355 String opt = getNextOption();
2356 if (opt != null && opt.equals("-s")) {
2357 try {
2358 slotId = Integer.parseInt(getNextArgRequired());
2359 } catch (NumberFormatException e) {
2360 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2361 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2362 }
2363 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002364 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002365 }
2366
2367 private int handleGbaSetServiceCommand() {
2368 int subId = getSubId("gba set-service");
2369 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2370 return -1;
2371 }
2372
2373 String packageName = getNextArg();
2374 try {
2375 if (packageName == null) {
2376 packageName = "";
2377 }
2378 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2379 if (VDBG) {
2380 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2381 + packageName + ", result=" + result);
2382 }
2383 getOutPrintWriter().println(result);
2384 } catch (RemoteException e) {
2385 Log.w(LOG_TAG, "gba set-service " + subId + " "
2386 + packageName + ", error" + e.getMessage());
2387 getErrPrintWriter().println("Exception: " + e.getMessage());
2388 return -1;
2389 }
2390 return 0;
2391 }
2392
2393 private int handleGbaGetServiceCommand() {
2394 String result;
2395
2396 int subId = getSubId("gba get-service");
2397 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2398 return -1;
2399 }
2400
2401 try {
2402 result = mInterface.getBoundGbaService(subId);
2403 } catch (RemoteException e) {
2404 return -1;
2405 }
2406 if (VDBG) {
2407 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2408 }
2409 getOutPrintWriter().println(result);
2410 return 0;
2411 }
2412
2413 private int handleGbaSetReleaseCommand() {
2414 //the release time value could be -1
2415 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2416 : SubscriptionManager.getDefaultSubscriptionId();
2417 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2418 return -1;
2419 }
2420
2421 String intervalStr = getNextArg();
2422 if (intervalStr == null) {
2423 return -1;
2424 }
2425
2426 try {
2427 int interval = Integer.parseInt(intervalStr);
2428 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2429 if (VDBG) {
2430 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2431 + intervalStr + ", result=" + result);
2432 }
2433 getOutPrintWriter().println(result);
2434 } catch (NumberFormatException | RemoteException e) {
2435 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2436 + intervalStr + ", error" + e.getMessage());
2437 getErrPrintWriter().println("Exception: " + e.getMessage());
2438 return -1;
2439 }
2440 return 0;
2441 }
2442
2443 private int handleGbaGetReleaseCommand() {
2444 int subId = getSubId("gba get-release");
2445 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2446 return -1;
2447 }
2448
2449 int result = 0;
2450 try {
2451 result = mInterface.getGbaReleaseTime(subId);
2452 } catch (RemoteException e) {
2453 return -1;
2454 }
2455 if (VDBG) {
2456 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2457 }
2458 getOutPrintWriter().println(result);
2459 return 0;
2460 }
Hui Wang761a6682020-10-31 05:12:53 +00002461
2462 private int handleSingleRegistrationConfigCommand() {
2463 String arg = getNextArg();
2464 if (arg == null) {
2465 onHelpSrc();
2466 return 0;
2467 }
2468
2469 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002470 case SRC_SET_TEST_ENABLED: {
2471 return handleSrcSetTestEnabledCommand();
2472 }
2473 case SRC_GET_TEST_ENABLED: {
2474 return handleSrcGetTestEnabledCommand();
2475 }
Hui Wang761a6682020-10-31 05:12:53 +00002476 case SRC_SET_DEVICE_ENABLED: {
2477 return handleSrcSetDeviceEnabledCommand();
2478 }
2479 case SRC_GET_DEVICE_ENABLED: {
2480 return handleSrcGetDeviceEnabledCommand();
2481 }
2482 case SRC_SET_CARRIER_ENABLED: {
2483 return handleSrcSetCarrierEnabledCommand();
2484 }
2485 case SRC_GET_CARRIER_ENABLED: {
2486 return handleSrcGetCarrierEnabledCommand();
2487 }
Hui Wangb647abe2021-02-26 09:33:38 -08002488 case SRC_SET_FEATURE_ENABLED: {
2489 return handleSrcSetFeatureValidationCommand();
2490 }
2491 case SRC_GET_FEATURE_ENABLED: {
2492 return handleSrcGetFeatureValidationCommand();
2493 }
Hui Wang761a6682020-10-31 05:12:53 +00002494 }
2495
2496 return -1;
2497 }
2498
James.cf Linbcdf8b32021-01-14 16:44:13 +08002499 private int handleRcsUceCommand() {
2500 String arg = getNextArg();
2501 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002502 onHelpUce();
2503 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002504 }
2505
2506 switch (arg) {
2507 case UCE_REMOVE_EAB_CONTACT:
2508 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002509 case UCE_GET_EAB_CONTACT:
2510 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002511 case UCE_GET_EAB_CAPABILITY:
2512 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002513 case UCE_GET_DEVICE_ENABLED:
2514 return handleUceGetDeviceEnabledCommand();
2515 case UCE_SET_DEVICE_ENABLED:
2516 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002517 case UCE_OVERRIDE_PUBLISH_CAPS:
2518 return handleUceOverridePublishCaps();
2519 case UCE_GET_LAST_PIDF_XML:
2520 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002521 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2522 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002523 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2524 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002525 }
2526 return -1;
2527 }
2528
2529 private int handleRemovingEabContactCommand() {
2530 int subId = getSubId("uce remove-eab-contact");
2531 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2532 return -1;
2533 }
2534
2535 String phoneNumber = getNextArgRequired();
2536 if (TextUtils.isEmpty(phoneNumber)) {
2537 return -1;
2538 }
2539 int result = 0;
2540 try {
2541 result = mInterface.removeContactFromEab(subId, phoneNumber);
2542 } catch (RemoteException e) {
2543 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2544 getErrPrintWriter().println("Exception: " + e.getMessage());
2545 return -1;
2546 }
2547
2548 if (VDBG) {
2549 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2550 }
calvinpan293ea1b2021-02-04 17:52:13 +08002551 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002552 }
2553
calvinpane4a8a1d2021-01-25 13:51:18 +08002554 private int handleGettingEabContactCommand() {
2555 String phoneNumber = getNextArgRequired();
2556 if (TextUtils.isEmpty(phoneNumber)) {
2557 return -1;
2558 }
2559 String result = "";
2560 try {
2561 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002562 } catch (RemoteException e) {
2563 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2564 getErrPrintWriter().println("Exception: " + e.getMessage());
2565 return -1;
2566 }
2567
2568 if (VDBG) {
2569 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2570 }
calvinpan293ea1b2021-02-04 17:52:13 +08002571 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002572 return 0;
2573 }
2574
Calvin Pana1434322021-07-01 19:27:01 +08002575 private int handleGettingEabCapabilityCommand() {
2576 String phoneNumber = getNextArgRequired();
2577 if (TextUtils.isEmpty(phoneNumber)) {
2578 return -1;
2579 }
2580 String result = "";
2581 try {
2582 result = mInterface.getCapabilityFromEab(phoneNumber);
2583 } catch (RemoteException e) {
2584 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2585 getErrPrintWriter().println("Exception: " + e.getMessage());
2586 return -1;
2587 }
2588
2589 if (VDBG) {
2590 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2591 }
2592 getOutPrintWriter().println(result);
2593 return 0;
2594 }
2595
James.cf Lin4b784aa2021-01-31 03:25:15 +08002596 private int handleUceGetDeviceEnabledCommand() {
2597 boolean result = false;
2598 try {
2599 result = mInterface.getDeviceUceEnabled();
2600 } catch (RemoteException e) {
2601 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2602 return -1;
2603 }
2604 if (VDBG) {
2605 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2606 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002607 getOutPrintWriter().println(result);
2608 return 0;
2609 }
2610
James.cf Lin4b784aa2021-01-31 03:25:15 +08002611 private int handleUceSetDeviceEnabledCommand() {
2612 String enabledStr = getNextArg();
2613 if (TextUtils.isEmpty(enabledStr)) {
2614 return -1;
2615 }
2616
2617 try {
2618 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2619 mInterface.setDeviceUceEnabled(isEnabled);
2620 if (VDBG) {
2621 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2622 }
2623 } catch (NumberFormatException | RemoteException e) {
2624 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2625 getErrPrintWriter().println("Exception: " + e.getMessage());
2626 return -1;
2627 }
2628 return 0;
2629 }
2630
James.cf Line8713a42021-04-29 16:04:26 +08002631 private int handleUceRemoveRequestDisallowedStatus() {
2632 int subId = getSubId("uce remove-request-disallowed-status");
2633 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2634 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2635 return -1;
2636 }
2637 boolean result;
2638 try {
2639 result = mInterface.removeUceRequestDisallowedStatus(subId);
2640 } catch (RemoteException e) {
2641 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2642 return -1;
2643 }
2644 if (VDBG) {
2645 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2646 }
2647 getOutPrintWriter().println(result);
2648 return 0;
2649 }
2650
James.cf Lin0fc71b02021-05-25 01:37:38 +08002651 private int handleUceSetCapRequestTimeout() {
2652 int subId = getSubId("uce set-capabilities-request-timeout");
2653 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2654 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2655 return -1;
2656 }
2657 long timeoutAfterMs = Long.valueOf(getNextArg());
2658 boolean result;
2659 try {
2660 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2661 } catch (RemoteException e) {
2662 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2663 return -1;
2664 }
2665 if (VDBG) {
2666 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2667 }
2668 getOutPrintWriter().println(result);
2669 return 0;
2670 }
2671
Hui Wangbaaee6a2021-02-19 20:45:36 -08002672 private int handleSrcSetTestEnabledCommand() {
2673 String enabledStr = getNextArg();
2674 if (enabledStr == null) {
2675 return -1;
2676 }
2677
2678 try {
2679 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2680 if (VDBG) {
2681 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2682 }
2683 getOutPrintWriter().println("Done");
2684 } catch (NumberFormatException | RemoteException e) {
2685 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2686 getErrPrintWriter().println("Exception: " + e.getMessage());
2687 return -1;
2688 }
2689 return 0;
2690 }
2691
2692 private int handleSrcGetTestEnabledCommand() {
2693 boolean result = false;
2694 try {
2695 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2696 } catch (RemoteException e) {
2697 return -1;
2698 }
2699 if (VDBG) {
2700 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2701 }
2702 getOutPrintWriter().println(result);
2703 return 0;
2704 }
2705
Brad Ebinger14d467f2021-02-12 06:18:28 +00002706 private int handleUceOverridePublishCaps() {
2707 int subId = getSubId("uce override-published-caps");
2708 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2709 return -1;
2710 }
2711 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2712 String operation = getNextArgRequired();
2713 String caps = getNextArg();
2714 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2715 && !"list".equals(operation)) {
2716 getErrPrintWriter().println("Invalid operation: " + operation);
2717 return -1;
2718 }
2719
2720 // add/remove requires capabilities to be specified.
2721 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2722 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2723 + "specified");
2724 return -1;
2725 }
2726
2727 ArraySet<String> capSet = new ArraySet<>();
2728 if (!TextUtils.isEmpty(caps)) {
2729 String[] capArray = caps.split(":");
2730 for (String cap : capArray) {
2731 // Allow unknown tags to be passed in as well.
2732 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2733 }
2734 }
2735
2736 RcsContactUceCapability result = null;
2737 try {
2738 switch (operation) {
2739 case "add":
2740 result = mInterface.addUceRegistrationOverrideShell(subId,
2741 new ArrayList<>(capSet));
2742 break;
2743 case "remove":
2744 result = mInterface.removeUceRegistrationOverrideShell(subId,
2745 new ArrayList<>(capSet));
2746 break;
2747 case "clear":
2748 result = mInterface.clearUceRegistrationOverrideShell(subId);
2749 break;
2750 case "list":
2751 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2752 break;
2753 }
2754 } catch (RemoteException e) {
2755 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2756 getErrPrintWriter().println("Exception: " + e.getMessage());
2757 return -1;
2758 } catch (ServiceSpecificException sse) {
2759 // Reconstruct ImsException
2760 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2761 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2762 getErrPrintWriter().println("Exception: " + imsException);
2763 return -1;
2764 }
2765 if (result == null) {
2766 getErrPrintWriter().println("Service not available");
2767 return -1;
2768 }
2769 getOutPrintWriter().println(result);
2770 return 0;
2771 }
2772
2773 private int handleUceGetPidfXml() {
2774 int subId = getSubId("uce get-last-publish-pidf");
2775 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2776 return -1;
2777 }
2778
2779 String result;
2780 try {
2781 result = mInterface.getLastUcePidfXmlShell(subId);
2782 } catch (RemoteException e) {
2783 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2784 getErrPrintWriter().println("Exception: " + e.getMessage());
2785 return -1;
2786 } catch (ServiceSpecificException sse) {
2787 // Reconstruct ImsException
2788 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2789 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2790 getErrPrintWriter().println("Exception: " + imsException);
2791 return -1;
2792 }
2793 if (result == null) {
2794 getErrPrintWriter().println("Service not available");
2795 return -1;
2796 }
2797 getOutPrintWriter().println(result);
2798 return 0;
2799 }
2800
Hui Wang761a6682020-10-31 05:12:53 +00002801 private int handleSrcSetDeviceEnabledCommand() {
2802 String enabledStr = getNextArg();
2803 if (enabledStr == null) {
2804 return -1;
2805 }
2806
2807 try {
2808 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2809 if (VDBG) {
2810 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2811 }
2812 getOutPrintWriter().println("Done");
2813 } catch (NumberFormatException | RemoteException e) {
2814 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2815 getErrPrintWriter().println("Exception: " + e.getMessage());
2816 return -1;
2817 }
2818 return 0;
2819 }
2820
2821 private int handleSrcGetDeviceEnabledCommand() {
2822 boolean result = false;
2823 try {
2824 result = mInterface.getDeviceSingleRegistrationEnabled();
2825 } catch (RemoteException e) {
2826 return -1;
2827 }
2828 if (VDBG) {
2829 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2830 }
2831 getOutPrintWriter().println(result);
2832 return 0;
2833 }
2834
2835 private int handleSrcSetCarrierEnabledCommand() {
2836 //the release time value could be -1
2837 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2838 : SubscriptionManager.getDefaultSubscriptionId();
2839 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2840 return -1;
2841 }
2842
2843 String enabledStr = getNextArg();
2844 if (enabledStr == null) {
2845 return -1;
2846 }
2847
2848 try {
2849 boolean result =
2850 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2851 if (VDBG) {
2852 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2853 + enabledStr + ", result=" + result);
2854 }
2855 getOutPrintWriter().println(result);
2856 } catch (NumberFormatException | RemoteException e) {
2857 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2858 + enabledStr + ", error" + e.getMessage());
2859 getErrPrintWriter().println("Exception: " + e.getMessage());
2860 return -1;
2861 }
2862 return 0;
2863 }
2864
2865 private int handleSrcGetCarrierEnabledCommand() {
2866 int subId = getSubId("src get-carrier-enabled");
2867 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2868 return -1;
2869 }
2870
2871 boolean result = false;
2872 try {
2873 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2874 } catch (RemoteException e) {
2875 return -1;
2876 }
2877 if (VDBG) {
2878 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2879 }
2880 getOutPrintWriter().println(result);
2881 return 0;
2882 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002883
Hui Wangb647abe2021-02-26 09:33:38 -08002884 private int handleSrcSetFeatureValidationCommand() {
2885 //the release time value could be -1
2886 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2887 : SubscriptionManager.getDefaultSubscriptionId();
2888 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2889 return -1;
2890 }
2891
2892 String enabledStr = getNextArg();
2893 if (enabledStr == null) {
2894 return -1;
2895 }
2896
2897 try {
2898 boolean result =
2899 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2900 if (VDBG) {
2901 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2902 + enabledStr + ", result=" + result);
2903 }
2904 getOutPrintWriter().println(result);
2905 } catch (NumberFormatException | RemoteException e) {
2906 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2907 + enabledStr + ", error" + e.getMessage());
2908 getErrPrintWriter().println("Exception: " + e.getMessage());
2909 return -1;
2910 }
2911 return 0;
2912 }
2913
2914 private int handleSrcGetFeatureValidationCommand() {
2915 int subId = getSubId("src get-feature-validation");
2916 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2917 return -1;
2918 }
2919
2920 Boolean result = false;
2921 try {
2922 result = mInterface.getImsFeatureValidationOverride(subId);
2923 } catch (RemoteException e) {
2924 return -1;
2925 }
2926 if (VDBG) {
2927 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2928 }
2929 getOutPrintWriter().println(result);
2930 return 0;
2931 }
2932
2933
Hall Liuaa4211e2021-01-20 15:43:39 -08002934 private void onHelpCallComposer() {
2935 PrintWriter pw = getOutPrintWriter();
2936 pw.println("Call composer commands");
2937 pw.println(" callcomposer test-mode enable|disable|query");
2938 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2939 pw.println(" upload/download from carrier servers is disabled, and operations are");
2940 pw.println(" performed using emulated local files instead.");
2941 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2942 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2943 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002944 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2945 pw.println(" Enables or disables the user setting for call composer, as set by");
2946 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002947 }
2948
2949 private int handleCallComposerCommand() {
2950 String arg = getNextArg();
2951 if (arg == null) {
2952 onHelpCallComposer();
2953 return 0;
2954 }
2955
2956 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2957 "MODIFY_PHONE_STATE required for call composer shell cmds");
2958 switch (arg) {
2959 case CALL_COMPOSER_TEST_MODE: {
2960 String enabledStr = getNextArg();
2961 if (ENABLE.equals(enabledStr)) {
2962 CallComposerPictureManager.sTestMode = true;
2963 } else if (DISABLE.equals(enabledStr)) {
2964 CallComposerPictureManager.sTestMode = false;
2965 } else if (QUERY.equals(enabledStr)) {
2966 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2967 } else {
2968 onHelpCallComposer();
2969 return 1;
2970 }
2971 break;
2972 }
2973 case CALL_COMPOSER_SIMULATE_CALL: {
2974 int subscriptionId = Integer.valueOf(getNextArg());
2975 String uuidString = getNextArg();
2976 UUID uuid = UUID.fromString(uuidString);
2977 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2978 Binder.withCleanCallingIdentity(() -> {
2979 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2980 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2981 });
2982 try {
2983 Uri uri = storageUriFuture.get();
2984 getOutPrintWriter().println(String.valueOf(uri));
2985 } catch (Exception e) {
2986 throw new RuntimeException(e);
2987 }
2988 break;
2989 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002990 case CALL_COMPOSER_USER_SETTING: {
2991 try {
2992 int subscriptionId = Integer.valueOf(getNextArg());
2993 String enabledStr = getNextArg();
2994 if (ENABLE.equals(enabledStr)) {
2995 mInterface.setCallComposerStatus(subscriptionId,
2996 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2997 } else if (DISABLE.equals(enabledStr)) {
2998 mInterface.setCallComposerStatus(subscriptionId,
2999 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
3000 } else if (QUERY.equals(enabledStr)) {
3001 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
3002 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
3003 } else {
3004 onHelpCallComposer();
3005 return 1;
3006 }
3007 } catch (RemoteException e) {
3008 e.printStackTrace(getOutPrintWriter());
3009 return 1;
3010 }
3011 break;
3012 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003013 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003014 return 0;
3015 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003016
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003017 private int handleHasCarrierPrivilegesCommand() {
3018 String packageName = getNextArgRequired();
3019
3020 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003021 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003022 try {
3023 hasCarrierPrivileges =
3024 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3025 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3026 } catch (RemoteException e) {
3027 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3028 getErrPrintWriter().println("Exception: " + e.getMessage());
3029 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003030 } finally {
3031 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003032 }
3033
3034 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003035 return 0;
3036 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003037
3038 private int handleAllowedNetworkTypesCommand(String command) {
3039 if (!checkShellUid()) {
3040 return -1;
3041 }
3042
3043 PrintWriter errPw = getErrPrintWriter();
3044 String tag = command + ": ";
3045 String opt;
3046 int subId = -1;
3047 Log.v(LOG_TAG, command + " start");
3048
3049 while ((opt = getNextOption()) != null) {
3050 if (opt.equals("-s")) {
3051 try {
3052 subId = slotStringToSubId(tag, getNextArgRequired());
3053 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3054 errPw.println(tag + "No valid subscription found.");
3055 return -1;
3056 }
3057 } catch (IllegalArgumentException e) {
3058 // Missing slot id
3059 errPw.println(tag + "SLOT_ID expected after -s.");
3060 return -1;
3061 }
3062 } else {
3063 errPw.println(tag + "Unknown option " + opt);
3064 return -1;
3065 }
3066 }
3067
3068 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3069 return handleGetAllowedNetworkTypesCommand(subId);
3070 }
3071 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3072 return handleSetAllowedNetworkTypesCommand(subId);
3073 }
3074 return -1;
3075 }
3076
3077 private int handleGetAllowedNetworkTypesCommand(int subId) {
3078 PrintWriter errPw = getErrPrintWriter();
3079
3080 long result = -1;
3081 try {
3082 if (mInterface != null) {
3083 result = mInterface.getAllowedNetworkTypesForReason(subId,
3084 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3085 } else {
3086 throw new IllegalStateException("telephony service is null.");
3087 }
3088 } catch (RemoteException e) {
3089 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3090 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3091 return -1;
3092 }
3093
3094 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3095 return 0;
3096 }
3097
3098 private int handleSetAllowedNetworkTypesCommand(int subId) {
3099 PrintWriter errPw = getErrPrintWriter();
3100
3101 String bitmaskString = getNextArg();
3102 if (TextUtils.isEmpty(bitmaskString)) {
3103 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3104 return -1;
3105 }
3106 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3107 if (allowedNetworkTypes < 0) {
3108 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3109 return -1;
3110 }
3111 boolean result = false;
3112 try {
3113 if (mInterface != null) {
3114 result = mInterface.setAllowedNetworkTypesForReason(subId,
3115 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3116 } else {
3117 throw new IllegalStateException("telephony service is null.");
3118 }
3119 } catch (RemoteException e) {
3120 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3121 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3122 return -1;
3123 }
3124
3125 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3126 if (result) {
3127 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3128 }
3129 getOutPrintWriter().println(resultMessage);
3130 return 0;
3131 }
3132
3133 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3134 if (TextUtils.isEmpty(bitmaskString)) {
3135 return -1;
3136 }
3137 if (VDBG) {
3138 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3139 + ", length: " + bitmaskString.length());
3140 }
3141 try {
3142 return Long.parseLong(bitmaskString, 2);
3143 } catch (NumberFormatException e) {
3144 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3145 return -1;
3146 }
3147 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003148
jimsun3b9ccac2021-10-26 15:01:23 +08003149 private int handleRadioSetModemServiceCommand() {
3150 PrintWriter errPw = getErrPrintWriter();
3151 String serviceName = null;
3152
3153 String opt;
3154 while ((opt = getNextOption()) != null) {
3155 switch (opt) {
3156 case "-s": {
3157 serviceName = getNextArgRequired();
3158 break;
3159 }
3160 }
3161 }
3162
3163 try {
3164 boolean result = mInterface.setModemService(serviceName);
3165 if (VDBG) {
3166 Log.v(LOG_TAG,
3167 "RadioSetModemService " + serviceName + ", result = " + result);
3168 }
3169 getOutPrintWriter().println(result);
3170 } catch (RemoteException e) {
3171 Log.w(LOG_TAG,
3172 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3173 errPw.println("Exception: " + e.getMessage());
3174 return -1;
3175 }
3176 return 0;
3177 }
3178
3179 private int handleRadioGetModemServiceCommand() {
3180 PrintWriter errPw = getErrPrintWriter();
3181 String result;
3182
3183 try {
3184 result = mInterface.getModemService();
3185 getOutPrintWriter().println(result);
3186 } catch (RemoteException e) {
3187 errPw.println("Exception: " + e.getMessage());
3188 return -1;
3189 }
3190 if (VDBG) {
3191 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3192 }
3193 return 0;
3194 }
3195
3196 private int handleRadioCommand() {
3197 String arg = getNextArg();
3198 if (arg == null) {
3199 onHelpRadio();
3200 return 0;
3201 }
3202
3203 switch (arg) {
3204 case RADIO_SET_MODEM_SERVICE:
3205 return handleRadioSetModemServiceCommand();
3206
3207 case RADIO_GET_MODEM_SERVICE:
3208 return handleRadioGetModemServiceCommand();
3209 }
3210
3211 return -1;
3212 }
arunvoddud7401012022-12-15 16:08:12 +00003213
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003214 private int handleSetSatelliteServicePackageNameCommand() {
3215 PrintWriter errPw = getErrPrintWriter();
3216 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003217 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003218
3219 String opt;
3220 while ((opt = getNextOption()) != null) {
3221 switch (opt) {
3222 case "-s": {
3223 serviceName = getNextArgRequired();
3224 break;
3225 }
Hakjun Choic3393242024-06-26 18:02:08 +00003226
3227 case "-p": {
3228 provisioned = getNextArgRequired();
3229 break;
3230 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003231 }
3232 }
3233 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003234 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003235
3236 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003237 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003238 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003239 Log.v(LOG_TAG,
3240 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3241 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003242 }
3243 getOutPrintWriter().println(result);
3244 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003245 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3246 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003247 errPw.println("Exception: " + e.getMessage());
3248 return -1;
3249 }
Hakjun Choic3393242024-06-26 18:02:08 +00003250
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003251 return 0;
3252 }
3253
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003254 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3255 PrintWriter errPw = getErrPrintWriter();
3256 String serviceName = null;
3257
3258 String opt;
3259 while ((opt = getNextOption()) != null) {
3260 switch (opt) {
3261 case "-s": {
3262 serviceName = getNextArgRequired();
3263 break;
3264 }
3265 }
3266 }
3267 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3268 + serviceName);
3269
3270 try {
3271 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3272 if (VDBG) {
3273 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3274 + ", result = " + result);
3275 }
3276 getOutPrintWriter().println(result);
3277 } catch (RemoteException e) {
3278 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3279 + ", error = " + e.getMessage());
3280 errPw.println("Exception: " + e.getMessage());
3281 return -1;
3282 }
3283 return 0;
3284 }
3285
Thomas Nguyen87dce732023-04-20 18:27:16 -07003286 private int handleSetSatellitePointingUiClassNameCommand() {
3287 PrintWriter errPw = getErrPrintWriter();
3288 String packageName = null;
3289 String className = null;
3290
3291 String opt;
3292 while ((opt = getNextOption()) != null) {
3293 switch (opt) {
3294 case "-p": {
3295 packageName = getNextArgRequired();
3296 break;
3297 }
3298 case "-c": {
3299 className = getNextArgRequired();
3300 break;
3301 }
3302 }
3303 }
3304 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3305 + packageName + ", className=" + className);
3306
3307 try {
3308 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3309 if (VDBG) {
3310 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3311 }
3312 getOutPrintWriter().println(result);
3313 } catch (RemoteException e) {
3314 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3315 + ", error = " + e.getMessage());
3316 errPw.println("Exception: " + e.getMessage());
3317 return -1;
3318 }
3319 return 0;
3320 }
3321
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003322 private int handleSetEmergencyCallToSatelliteHandoverType() {
3323 PrintWriter errPw = getErrPrintWriter();
3324 int handoverType = -1;
3325 int delaySeconds = 0;
3326
3327 String opt;
3328 while ((opt = getNextOption()) != null) {
3329 switch (opt) {
3330 case "-t": {
3331 try {
3332 handoverType = Integer.parseInt(getNextArgRequired());
3333 } catch (NumberFormatException e) {
3334 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3335 + " for handoverType");
3336 return -1;
3337 }
3338 break;
3339 }
3340 case "-d": {
3341 try {
3342 delaySeconds = Integer.parseInt(getNextArgRequired());
3343 } catch (NumberFormatException e) {
3344 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3345 + " for delaySeconds");
3346 return -1;
3347 }
3348 break;
3349 }
3350 }
3351 }
3352 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3353 + handoverType + ", delaySeconds=" + delaySeconds);
3354
3355 try {
3356 boolean result =
3357 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3358 if (VDBG) {
3359 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3360 }
3361 getOutPrintWriter().println(result);
3362 } catch (RemoteException e) {
3363 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3364 + ", error = " + e.getMessage());
3365 errPw.println("Exception: " + e.getMessage());
3366 return -1;
3367 }
3368 return 0;
3369 }
3370
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003371 private int handleSetSatelliteListeningTimeoutDuration() {
3372 PrintWriter errPw = getErrPrintWriter();
3373 long timeoutMillis = 0;
3374
3375 String opt;
3376 while ((opt = getNextOption()) != null) {
3377 switch (opt) {
3378 case "-t": {
3379 timeoutMillis = Long.parseLong(getNextArgRequired());
3380 break;
3381 }
3382 }
3383 }
3384 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3385 + timeoutMillis);
3386
3387 try {
3388 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3389 if (VDBG) {
3390 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3391 + ", result = " + result);
3392 }
3393 getOutPrintWriter().println(result);
3394 } catch (RemoteException e) {
3395 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3396 + ", error = " + e.getMessage());
3397 errPw.println("Exception: " + e.getMessage());
3398 return -1;
3399 }
3400 return 0;
3401 }
3402
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003403 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003404 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003405 boolean reset = false;
3406 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003407 long timeoutMillis = 0;
3408
3409 String opt;
3410 while ((opt = getNextOption()) != null) {
3411 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003412 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003413 timeoutMillis = Long.parseLong(getNextArgRequired());
3414 break;
3415 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003416 case "-r": {
3417 reset = true;
3418 break;
3419 }
3420 case "-t": {
3421 timeoutType = Integer.parseInt(getNextArgRequired());
3422 break;
3423 }
Hakjun Choiae365972023-04-25 11:00:31 +00003424 }
3425 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003426 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3427 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003428
3429 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003430 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3431 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003432 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003433 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003434 + ", result = " + result);
3435 }
3436 getOutPrintWriter().println(result);
3437 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003438 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3439 + ", error = " + e.getMessage());
3440 errPw.println("Exception: " + e.getMessage());
3441 return -1;
3442 }
3443 return 0;
3444 }
3445
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003446 private int handleSetDatagramControllerBooleanConfig() {
3447 PrintWriter errPw = getErrPrintWriter();
3448 boolean reset = false;
3449 int booleanType = 0;
3450 boolean enable = false;
3451
3452 String opt;
3453 while ((opt = getNextOption()) != null) {
3454 switch (opt) {
3455 case "-d": {
3456 enable = Boolean.parseBoolean(getNextArgRequired());
3457 break;
3458 }
3459 case "-r": {
3460 reset = true;
3461 break;
3462 }
3463 case "-t": {
3464 booleanType = Integer.parseInt(getNextArgRequired());
3465 break;
3466 }
3467 }
3468 }
3469 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3470 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3471
3472 try {
3473 boolean result = mInterface.setDatagramControllerBooleanConfig(
3474 reset, booleanType, enable);
3475 if (VDBG) {
3476 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3477 }
3478 getOutPrintWriter().println(result);
3479 } catch (RemoteException e) {
3480 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3481 errPw.println("Exception: " + e.getMessage());
3482 return -1;
3483 }
3484 return 0;
3485 }
3486
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003487 private int handleSetSatelliteControllerTimeoutDuration() {
3488 PrintWriter errPw = getErrPrintWriter();
3489 boolean reset = false;
3490 int timeoutType = 0;
3491 long timeoutMillis = 0;
3492
3493 String opt;
3494 while ((opt = getNextOption()) != null) {
3495 switch (opt) {
3496 case "-d": {
3497 timeoutMillis = Long.parseLong(getNextArgRequired());
3498 break;
3499 }
3500 case "-r": {
3501 reset = true;
3502 break;
3503 }
3504 case "-t": {
3505 timeoutType = Integer.parseInt(getNextArgRequired());
3506 break;
3507 }
3508 }
3509 }
3510 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3511 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3512
3513 try {
3514 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3515 reset, timeoutType, timeoutMillis);
3516 if (VDBG) {
3517 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3518 + ", result = " + result);
3519 }
3520 getOutPrintWriter().println(result);
3521 } catch (RemoteException e) {
3522 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003523 + ", error = " + e.getMessage());
3524 errPw.println("Exception: " + e.getMessage());
3525 return -1;
3526 }
3527 return 0;
3528 }
3529
Hakjun Choibc6ce992023-11-07 16:04:33 +00003530 private int handleSetShouldSendDatagramToModemInDemoMode() {
3531 PrintWriter errPw = getErrPrintWriter();
3532 String opt;
3533 boolean shouldSendToDemoMode;
3534
3535 if ((opt = getNextArg()) == null) {
3536 errPw.println(
3537 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3538 + " Invalid Argument");
3539 return -1;
3540 } else {
3541 switch (opt) {
3542 case "true": {
3543 shouldSendToDemoMode = true;
3544 break;
3545 }
3546 case "false": {
3547 shouldSendToDemoMode = false;
3548 break;
3549 }
3550 default:
3551 errPw.println(
3552 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3553 + " Invalid Argument");
3554 return -1;
3555 }
3556 }
3557
3558 Log.d(LOG_TAG,
3559 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3560
3561 try {
3562 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3563 shouldSendToDemoMode);
3564 if (VDBG) {
3565 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3566 + result);
3567 }
3568 getOutPrintWriter().println(false);
3569 } catch (RemoteException e) {
3570 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3571 + "), error = " + e.getMessage());
3572 errPw.println("Exception: " + e.getMessage());
3573 return -1;
3574 }
3575 return 0;
3576 }
3577
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003578 private int handleSetSatelliteAccessControlOverlayConfigs() {
3579 PrintWriter errPw = getErrPrintWriter();
3580 boolean reset = false;
3581 boolean isAllowed = false;
3582 String s2CellFile = null;
3583 long locationFreshDurationNanos = 0;
3584 List<String> satelliteCountryCodes = null;
3585
3586 String opt;
3587 while ((opt = getNextOption()) != null) {
3588 switch (opt) {
3589 case "-r": {
3590 reset = true;
3591 break;
3592 }
3593 case "-a": {
3594 isAllowed = true;
3595 break;
3596 }
3597 case "-f": {
3598 s2CellFile = getNextArgRequired();
3599 break;
3600 }
3601 case "-d": {
3602 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3603 break;
3604 }
3605 case "-c": {
3606 String countryCodeStr = getNextArgRequired();
3607 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3608 break;
3609 }
3610 }
3611 }
3612 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3613 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3614 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3615 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3616
3617 try {
3618 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3619 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3620 if (VDBG) {
3621 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3622 }
3623 getOutPrintWriter().println(result);
3624 } catch (RemoteException e) {
3625 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3626 errPw.println("Exception: " + e.getMessage());
3627 return -1;
3628 }
3629 return 0;
3630 }
3631
3632 private int handleSetCountryCodes() {
3633 PrintWriter errPw = getErrPrintWriter();
3634 List<String> currentNetworkCountryCodes = new ArrayList<>();
3635 String locationCountryCode = null;
3636 long locationCountryCodeTimestampNanos = 0;
3637 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3638 boolean reset = false;
3639
3640 String opt;
3641 while ((opt = getNextOption()) != null) {
3642 switch (opt) {
3643 case "-r": {
3644 reset = true;
3645 break;
3646 }
3647 case "-n": {
3648 String countryCodeStr = getNextArgRequired();
3649 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3650 break;
3651 }
3652 case "-c": {
3653 String cachedNetworkCountryCodeStr = getNextArgRequired();
3654 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3655 break;
3656 }
3657 case "-l": {
3658 locationCountryCode = getNextArgRequired();
3659 break;
3660 }
3661 case "-t": {
3662 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3663 break;
3664 }
3665 }
3666 }
3667 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3668 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3669 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3670 + currentNetworkCountryCodes);
3671
3672 try {
3673 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3674 cachedNetworkCountryCodes, locationCountryCode,
3675 locationCountryCodeTimestampNanos);
3676 if (VDBG) {
3677 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3678 }
3679 getOutPrintWriter().println(result);
3680 } catch (RemoteException e) {
3681 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3682 errPw.println("Exception: " + e.getMessage());
3683 return -1;
3684 }
3685 return 0;
3686 }
3687
Thomas Nguyen3d602742024-01-19 11:29:35 -08003688 private int handleSetOemEnabledSatelliteProvisionStatus() {
3689 PrintWriter errPw = getErrPrintWriter();
3690 boolean isProvisioned = false;
3691 boolean reset = true;
3692
3693 String opt;
3694 while ((opt = getNextOption()) != null) {
3695 switch (opt) {
3696 case "-p": {
3697 try {
3698 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3699 reset = false;
3700 } catch (Exception e) {
3701 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3702 + "after -p indicating provision status");
3703 return -1;
3704 }
3705 }
3706 }
3707 }
3708 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3709 + ", isProvisioned=" + isProvisioned);
3710
3711 try {
3712 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3713 if (VDBG) {
3714 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3715 }
3716 getOutPrintWriter().println(result);
3717 } catch (RemoteException e) {
3718 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3719 errPw.println("Exception: " + e.getMessage());
3720 return -1;
3721 }
3722 return 0;
3723 }
3724
Hakjun Choi4a832d12024-05-28 22:23:55 +00003725 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3726 PrintWriter errPw = getErrPrintWriter();
3727 String opt;
3728 String state;
3729
3730 if ((opt = getNextArg()) == null) {
3731 errPw.println(
3732 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3733 + "-location-cache :"
3734 + " Invalid Argument");
3735 return -1;
3736 } else {
3737 switch (opt) {
3738 case "-a": {
3739 state = "cache_allowed";
3740 break;
3741 }
3742 case "-n": {
3743 state = "cache_clear_and_not_allowed";
3744 break;
3745 }
3746 case "-c": {
3747 state = "clear_cache_only";
3748 break;
3749 }
3750 default:
3751 errPw.println(
3752 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3753 + "-location-cache :"
3754 + " Invalid Argument");
3755 return -1;
3756 }
3757 }
3758
3759 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3760 + state + ")");
3761
3762 try {
3763 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3764 state);
3765 if (VDBG) {
3766 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3767 + "returns: "
3768 + result);
3769 }
3770 getOutPrintWriter().println(result);
3771 } catch (RemoteException e) {
3772 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3773 + state + "), error = " + e.getMessage());
3774 errPw.println("Exception: " + e.getMessage());
3775 return -1;
3776 }
3777 return 0;
3778 }
3779
Hyosund6aaf062024-08-23 23:02:10 +00003780 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3781 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3782 PrintWriter errPw = getErrPrintWriter();
3783 String opt;
3784 String name;
3785
3786 if ((opt = getNextArg()) == null) {
3787 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3788 return -1;
3789 } else {
3790 switch (opt) {
3791 case "-p": {
3792 name = opt + "/" + "android.telephony.cts";
3793 break;
3794 }
3795 case "-c": {
3796 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3797 break;
3798 }
3799 case "-r": {
3800 name = "reset";
3801 break;
3802 }
3803 default:
3804 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3805 return -1;
3806 }
3807 }
3808
3809 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3810 + name + ")");
3811
3812 try {
3813 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3814 if (VDBG) {
3815 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3816 + "returns: " + result);
3817 }
3818 getOutPrintWriter().println(result);
3819 } catch (RemoteException e) {
3820 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3821 + name + "), error = " + e.getMessage());
3822 errPw.println("Exception: " + e.getMessage());
3823 return -1;
3824 }
3825 return 0;
3826 }
3827
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003828 /**
3829 * Sample inputStr = "US,UK,CA;2,1,3"
3830 * Sample output: {[US,2], [UK,1], [CA,3]}
3831 */
3832 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3833 Map<String, Long> result = new HashMap<>();
3834 if (!TextUtils.isEmpty(inputStr)) {
3835 String[] stringLongArr = inputStr.split(";");
3836 if (stringLongArr.length != 2) {
3837 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3838 return result;
3839 }
3840
3841 String[] stringArr = stringLongArr[0].split(",");
3842 String[] longArr = stringLongArr[1].split(",");
3843 if (stringArr.length != longArr.length) {
3844 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3845 return result;
3846 }
3847
3848 for (int i = 0; i < stringArr.length; i++) {
3849 try {
3850 result.put(stringArr[i], Long.parseLong(longArr[i]));
3851 } catch (Exception ex) {
3852 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3853 + ", ex=" + ex);
3854 return result;
3855 }
3856 }
3857 }
3858 return result;
3859 }
3860
arunvoddud7401012022-12-15 16:08:12 +00003861 private int handleCarrierRestrictionStatusCommand() {
3862 try {
3863 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3864 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3865 mInterface.getModemService()))) {
3866 Log.v(LOG_TAG,
3867 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3868 + " checkShellUid fails");
3869 return -1;
3870 }
3871 } catch (RemoteException ex) {
3872 ex.printStackTrace();
3873 }
3874 String callerInfo = getNextOption();
3875 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3876 if (TextUtils.isEmpty(callerInfo)) {
3877 // reset the Json content after testing
3878 allowListInfo.updateJsonForTest(null);
3879 return 0;
3880 }
3881 if (callerInfo.startsWith("--")) {
3882 callerInfo = callerInfo.replace("--", "");
3883 }
3884 String params[] = callerInfo.split(",");
3885 StringBuffer jsonStrBuffer = new StringBuffer();
3886 String tokens;
3887 for (int index = 0; index < params.length; index++) {
3888 tokens = convertToJsonString(index, params[index]);
3889 if (TextUtils.isEmpty(tokens)) {
3890 // received wrong format from CTS
3891 if (VDBG) {
3892 Log.v(LOG_TAG,
3893 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3894 }
3895 return -1;
3896 }
3897 jsonStrBuffer.append(tokens);
3898 }
3899 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3900 return result;
3901 }
3902
Benedict Wong66477622023-02-03 23:30:57 +00003903 // set-carrier-service-package-override
3904 private int setCarrierServicePackageOverride() {
3905 PrintWriter errPw = getErrPrintWriter();
3906 int subId = SubscriptionManager.getDefaultSubscriptionId();
3907
3908 String opt;
3909 while ((opt = getNextOption()) != null) {
3910 switch (opt) {
3911 case "-s":
3912 try {
3913 subId = Integer.parseInt(getNextArgRequired());
3914 } catch (NumberFormatException e) {
3915 errPw.println(
3916 "set-carrier-service-package-override requires an integer as a"
3917 + " subscription ID.");
3918 return -1;
3919 }
3920 break;
3921 }
3922 }
3923
3924 String packageName = getNextArg();
3925 if (packageName == null) {
3926 errPw.println("set-carrier-service-package-override requires a override package name.");
3927 return -1;
3928 }
3929
3930 try {
3931 mInterface.setCarrierServicePackageOverride(
3932 subId, packageName, mContext.getOpPackageName());
3933
3934 if (VDBG) {
3935 Log.v(
3936 LOG_TAG,
3937 "set-carrier-service-package-override -s " + subId + " " + packageName);
3938 }
3939 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3940 Log.w(
3941 LOG_TAG,
3942 "set-carrier-service-package-override -s "
3943 + subId
3944 + " "
3945 + packageName
3946 + ", error"
3947 + e.getMessage());
3948 errPw.println("Exception: " + e.getMessage());
3949 return -1;
3950 }
3951 return 0;
3952 }
3953
3954 // clear-carrier-service-package-override
3955 private int clearCarrierServicePackageOverride() {
3956 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003957 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003958
3959 String opt;
3960 while ((opt = getNextOption()) != null) {
3961 switch (opt) {
3962 case "-s":
3963 try {
3964 subId = Integer.parseInt(getNextArgRequired());
3965 } catch (NumberFormatException e) {
3966 errPw.println(
3967 "clear-carrier-service-package-override requires an integer as a"
3968 + " subscription ID.");
3969 return -1;
3970 }
3971 break;
3972 }
3973 }
3974
3975 try {
3976 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3977
3978 if (VDBG) {
3979 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3980 }
3981 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3982 Log.w(
3983 LOG_TAG,
3984 "clear-carrier-service-package-override -s "
3985 + subId
3986 + ", error"
3987 + e.getMessage());
3988 errPw.println("Exception: " + e.getMessage());
3989 return -1;
3990 }
3991 return 0;
3992 }
arunvoddud7401012022-12-15 16:08:12 +00003993
Hunsuk Choi13078be2023-09-13 10:55:21 +00003994 private int handleDomainSelectionCommand() {
3995 String arg = getNextArg();
3996 if (arg == null) {
3997 onHelpDomainSelection();
3998 return 0;
3999 }
4000
4001 switch (arg) {
4002 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
4003 return handleDomainSelectionSetServiceOverrideCommand();
4004 }
4005 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4006 return handleDomainSelectionClearServiceOverrideCommand();
4007 }
4008 }
4009
4010 return -1;
4011 }
4012
4013 // domainselection set-dss-override
4014 private int handleDomainSelectionSetServiceOverrideCommand() {
4015 PrintWriter errPw = getErrPrintWriter();
4016
4017 String componentName = getNextArg();
4018
4019 try {
4020 boolean result = mInterface.setDomainSelectionServiceOverride(
4021 ComponentName.unflattenFromString(componentName));
4022 if (VDBG) {
4023 Log.v(LOG_TAG, "domainselection set-dss-override "
4024 + componentName + ", result=" + result);
4025 }
4026 getOutPrintWriter().println(result);
4027 } catch (Exception e) {
4028 Log.w(LOG_TAG, "domainselection set-dss-override "
4029 + componentName + ", error=" + e.getMessage());
4030 errPw.println("Exception: " + e.getMessage());
4031 return -1;
4032 }
4033 return 0;
4034 }
4035
4036 // domainselection clear-dss-override
4037 private int handleDomainSelectionClearServiceOverrideCommand() {
4038 PrintWriter errPw = getErrPrintWriter();
4039
4040 try {
4041 boolean result = mInterface.clearDomainSelectionServiceOverride();
4042 if (VDBG) {
4043 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4044 }
4045 getOutPrintWriter().println(result);
4046 } catch (RemoteException e) {
4047 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4048 errPw.println("Exception: " + e.getMessage());
4049 return -1;
4050 }
4051 return 0;
4052 }
4053
arunvoddud7401012022-12-15 16:08:12 +00004054 /**
4055 * Building the string that can be used to build the JsonObject which supports to stub the data
4056 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004057 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004058 */
4059 private String convertToJsonString(int index, String param) {
4060
4061 String token[] = param.split(":");
4062 String jSonString;
4063 switch (index) {
4064 case 0:
4065 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4066 break;
4067 case 1:
4068 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004069 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004070 break;
4071 case 2:
4072 jSonString =
4073 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4074 break;
4075 default:
4076 jSonString = null;
4077 }
4078 return jSonString;
4079 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004080}