blob: df28131078264ab93ec907a5055c173aedcb98ae [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";
joonhunshinf46f0d62024-09-27 14:06:26 +0000193 private static final String SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE =
194 "set-satellite-ignore-cellular-service-state";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700195 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
196 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800197 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
198 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000199 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
200 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800201
202 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
203 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700204 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
205 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800206 private static final String SET_COUNTRY_CODES = "set-country-codes";
207 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
208 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800209 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
210 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000211 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
212 "set-should-send-datagram-to-modem-in-demo-mode";
Hakjun Choi4a832d12024-05-28 22:23:55 +0000213 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
214 "set-is-satellite-communication-allowed-for-current-location-cache";
Hyosund6aaf062024-08-23 23:02:10 +0000215 private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
216 "set-satellite-subscriberid-list-changed-intent-component";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800217
Hunsuk Choi13078be2023-09-13 10:55:21 +0000218 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
219 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
220 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
221
Grant Menke567d48f2022-08-18 20:19:10 +0000222 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
223 + "'*', '#' or '+') needs to be specified after -a in the command ";
224
225 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
226 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
227 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
228
SongFerngWang98dd5992021-05-13 17:50:00 +0800229 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
230 "get-allowed-network-types-for-users";
231 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
232 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000233 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000234 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700235 // Take advantage of existing methods that already contain permissions checks when possible.
236 private final ITelephony mInterface;
237
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100238 private SubscriptionManager mSubscriptionManager;
239 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700240 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700241 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100242
243 private enum CcType {
244 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000245 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100246 }
247
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100248 private class CcOptionParseResult {
249 public int mSubId;
250 public boolean mPersistent;
251 }
252
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100253 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
254 // keys by looking at the end of the string which usually tells the type.
255 // For instance: "xxxx_string", "xxxx_string_array", etc.
256 // The carrier config keys in this map does not follow this convention. It is therefore not
257 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700258 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
259 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
260 CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
266 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
267 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
268 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
269 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
270 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
271 CcType.STRING),
272 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
273 CcType.STRING_ARRAY),
274 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
275 CcType.STRING_ARRAY),
276 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
279 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
280 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
281 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
282 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
283 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100284
Brad Ebinger14d467f2021-02-12 06:18:28 +0000285 /**
286 * Map from a shorthand string to the feature tags required in registration required in order
287 * for the RCS feature to be considered "capable".
288 */
289 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
290 static {
291 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
292 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
293 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
294 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
295 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
296 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
297 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
298 FeatureTags.FEATURE_TAG_VIDEO)));
299 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
300 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
301 map.put("call_comp",
302 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
303 map.put("call_comp_mmtel",
304 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
305 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
306 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
307 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
308 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
309 // version
310 map.put("chatbot", new ArraySet<>(Arrays.asList(
311 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
312 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
313 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
314 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000315 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000316 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
317 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
318 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
319 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
320 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000321 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000322 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
323 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
324 }
325
326
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100327 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700328 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100329 mCarrierConfigManager =
330 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
331 mSubscriptionManager = (SubscriptionManager)
332 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700333 mTelephonyRegistryManager = (TelephonyRegistryManager)
334 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700335 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700336 }
337
338 @Override
339 public int onCommand(String cmd) {
340 if (cmd == null) {
341 return handleDefaultCommands(null);
342 }
343
344 switch (cmd) {
345 case IMS_SUBCOMMAND: {
346 return handleImsCommand();
347 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800348 case RCS_UCE_COMMAND:
349 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800350 case NUMBER_VERIFICATION_SUBCOMMAND:
351 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800352 case EMERGENCY_CALLBACK_MODE:
353 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800354 case EMERGENCY_NUMBER_TEST_MODE:
355 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100356 case CARRIER_CONFIG_SUBCOMMAND: {
357 return handleCcCommand();
358 }
Shuo Qianf5125122019-12-16 17:03:07 -0800359 case DATA_TEST_MODE:
360 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700361 case END_BLOCK_SUPPRESSION:
362 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000363 case EUICC_SUBCOMMAND:
364 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700365 case GBA_SUBCOMMAND:
366 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800367 case D2D_SUBCOMMAND:
368 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700369 case BARRING_SUBCOMMAND:
370 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000371 case SINGLE_REGISTATION_CONFIG:
372 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000373 case RESTART_MODEM:
374 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800375 case CALL_COMPOSER_SUBCOMMAND:
376 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000377 case UNATTENDED_REBOOT:
378 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800379 case HAS_CARRIER_PRIVILEGES_COMMAND:
380 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800381 case THERMAL_MITIGATION_COMMAND:
382 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700383 case DISABLE_PHYSICAL_SUBSCRIPTION:
384 return handleEnablePhysicalSubscription(false);
385 case ENABLE_PHYSICAL_SUBSCRIPTION:
386 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800387 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
388 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
389 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000390 case GET_IMEI:
391 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000392 case GET_SIM_SLOTS_MAPPING:
393 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800394 case RADIO_SUBCOMMAND:
395 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000396 case CARRIER_RESTRICTION_STATUS_TEST:
397 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000398 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
399 return setCarrierServicePackageOverride();
400 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
401 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000402 case DOMAIN_SELECTION_SUBCOMMAND:
403 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700404 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
405 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700406 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
407 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700408 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
409 return handleSetSatelliteListeningTimeoutDuration();
joonhunshinf46f0d62024-09-27 14:06:26 +0000410 case SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE:
411 return handleSetSatelliteIgnoreCellularServiceState();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700412 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
413 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800414 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
415 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000416 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
417 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800418 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
419 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700420 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
421 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000422 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
423 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800424 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
425 return handleSetSatelliteAccessControlOverlayConfigs();
426 case SET_COUNTRY_CODES:
427 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800428 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
429 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000430 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
431 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000432 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
433 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700434 default: {
435 return handleDefaultCommands(cmd);
436 }
437 }
438 }
439
440 @Override
441 public void onHelp() {
442 PrintWriter pw = getOutPrintWriter();
443 pw.println("Telephony Commands:");
444 pw.println(" help");
445 pw.println(" Print this help text.");
446 pw.println(" ims");
447 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800448 pw.println(" uce");
449 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800450 pw.println(" emergency-number-test-mode");
451 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700452 pw.println(" end-block-suppression");
453 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800454 pw.println(" data");
455 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100456 pw.println(" cc");
457 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700458 pw.println(" gba");
459 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000460 pw.println(" src");
461 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000462 pw.println(" restart-modem");
463 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000464 pw.println(" unattended-reboot");
465 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800466 pw.println(" has-carrier-privileges [package]");
467 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800468 pw.println(" get-allowed-network-types-for-users");
469 pw.println(" Get the Allowed Network Types.");
470 pw.println(" set-allowed-network-types-for-users");
471 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800472 pw.println(" radio");
473 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700474 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800475 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800476 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700477 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800478 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100479 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700480 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000481 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800482 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700483 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800484 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800485 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000486 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700487 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000488 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800489 }
490
491 private void onHelpD2D() {
492 PrintWriter pw = getOutPrintWriter();
493 pw.println("D2D Comms Commands:");
494 pw.println(" d2d send TYPE VALUE");
495 pw.println(" Sends a D2D message of specified type and value.");
496 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
497 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
498 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
499 MESSAGE_CALL_AUDIO_CODEC));
500 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
501 + Communicator.messageToString(
502 MESSAGE_DEVICE_BATTERY_STATE));
503 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
504 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800505 pw.println(" d2d transport TYPE");
506 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
507 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700508 pw.println(" d2d set-device-support true/default");
509 pw.println(" true - forces device support to be enabled for D2D.");
510 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
511 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700512 }
513
Nazanin014f41e2021-05-06 17:26:31 -0700514 private void onHelpBarring() {
515 PrintWriter pw = getOutPrintWriter();
516 pw.println("Barring Commands:");
517 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
518 + " -t CONDITIONAL_BARRING_TIME_SECS");
519 pw.println(" Notifies of a barring info change for the specified slot id.");
520 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
521 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
522 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
523 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
524 }
525
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700526 private void onHelpIms() {
527 PrintWriter pw = getOutPrintWriter();
528 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800529 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700530 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
531 pw.println(" ImsService. Options are:");
532 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
533 pw.println(" is specified, it will choose the default voice SIM slot.");
534 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
535 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800536 pw.println(" -f: Set the feature that this override if for, if no option is");
537 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700538 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
539 pw.println(" Gets the package name of the currently defined ImsService.");
540 pw.println(" Options are:");
541 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
543 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000544 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800545 pw.println(" -f: The feature type that the query will be requested for. If none is");
546 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800547 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
548 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
549 pw.println(" configuration overrides. Options are:");
550 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
551 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700552 pw.println(" ims enable [-s SLOT_ID]");
553 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
554 pw.println(" if none is specified.");
555 pw.println(" ims disable [-s SLOT_ID]");
556 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
557 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700558 pw.println(" ims conference-event-package [enable/disable]");
559 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700560 }
561
James.cf Linbcdf8b32021-01-14 16:44:13 +0800562 private void onHelpUce() {
563 PrintWriter pw = getOutPrintWriter();
564 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800565 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
566 pw.println(" Get the EAB contacts from the EAB database.");
567 pw.println(" Options are:");
568 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
569 pw.println(" Expected output format :");
570 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800571 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
572 pw.println(" Remove the EAB contacts from the EAB database.");
573 pw.println(" Options are:");
574 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
575 pw.println(" is specified, it will choose the default voice SIM slot.");
576 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800577 pw.println(" uce get-device-enabled");
578 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
579 pw.println(" uce set-device-enabled true|false");
580 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
581 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000582 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
583 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
584 pw.println(" Options are:");
585 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
586 pw.println(" is specified, it will choose the default voice SIM slot.");
587 pw.println(" add [CAPABILITY]: add a new capability");
588 pw.println(" remove [CAPABILITY]: remove a capability");
589 pw.println(" clear: clear all capability overrides");
590 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
591 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
592 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
593 pw.println(" chatbot_sa, chatbot_role] as well as full length");
594 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
595 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
596 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
597 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800598 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
599 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800600 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
601 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800602 }
603
Hall Liud892bec2018-11-30 14:51:45 -0800604 private void onHelpNumberVerification() {
605 PrintWriter pw = getOutPrintWriter();
606 pw.println("Number verification commands");
607 pw.println(" numverify override-package PACKAGE_NAME;");
608 pw.println(" Set the authorized package for number verification.");
609 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800610 pw.println(" numverify fake-call NUMBER;");
611 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
612 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800613 }
614
Jack Nudelman644b91a2021-03-12 14:09:48 -0800615 private void onHelpThermalMitigation() {
616 PrintWriter pw = getOutPrintWriter();
617 pw.println("Thermal mitigation commands");
618 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
619 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
620 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
621 pw.println(" Remove the package from one of the authorized packages for thermal "
622 + "mitigation.");
623 }
624
Jordan Liu0ccee222021-04-27 11:55:13 -0700625 private void onHelpDisableOrEnablePhysicalSubscription() {
626 PrintWriter pw = getOutPrintWriter();
627 pw.println("Disable or enable a physical subscription");
628 pw.println(" disable-physical-subscription SUB_ID");
629 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
630 pw.println(" enable-physical-subscription SUB_ID");
631 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
632 }
633
Shuo Qianf5125122019-12-16 17:03:07 -0800634 private void onHelpDataTestMode() {
635 PrintWriter pw = getOutPrintWriter();
636 pw.println("Mobile Data Test Mode Commands:");
637 pw.println(" data enable: enable mobile data connectivity");
638 pw.println(" data disable: disable mobile data connectivity");
639 }
640
sqian9d4df8b2019-01-15 18:32:07 -0800641 private void onHelpEmergencyNumber() {
642 PrintWriter pw = getOutPrintWriter();
643 pw.println("Emergency Number Test Mode Commands:");
644 pw.println(" emergency-number-test-mode ");
645 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
646 + " the test mode");
647 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700648 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800649 pw.println(" -c: clear the emergency number list in the test mode.");
650 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700651 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800652 pw.println(" -p: get the full emergency number list in the test mode.");
653 }
654
Shuo Qian489d9282020-07-09 11:30:03 -0700655 private void onHelpEndBlockSupperssion() {
656 PrintWriter pw = getOutPrintWriter();
657 pw.println("End Block Suppression command:");
658 pw.println(" end-block-suppression: disable suppressing blocking by contact");
659 pw.println(" with emergency services.");
660 }
661
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100662 private void onHelpCc() {
663 PrintWriter pw = getOutPrintWriter();
664 pw.println("Carrier Config Commands:");
665 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
666 pw.println(" Print carrier config values.");
667 pw.println(" Options are:");
668 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
669 pw.println(" is specified, it will choose the default voice SIM slot.");
670 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
671 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100672 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100673 pw.println(" Set carrier config KEY to NEW_VALUE.");
674 pw.println(" Options are:");
675 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
676 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100677 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100678 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
679 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
680 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
681 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000682 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
683 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
684 pw.println(" provided through standard input and follow CarrierConfig XML format.");
685 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
686 pw.println(" Options are:");
687 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
688 pw.println(" is specified, it will choose the default voice SIM slot.");
689 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100690 pw.println(" cc clear-values [-s SLOT_ID]");
691 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000692 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100693 pw.println(" Options are:");
694 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
695 pw.println(" is specified, it will choose the default voice SIM slot.");
696 }
697
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000698 private void onHelpEuicc() {
699 PrintWriter pw = getOutPrintWriter();
700 pw.println("Euicc Commands:");
701 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
702 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
703 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
704 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
705 }
706
Hui Wang641e81c2020-10-12 12:14:23 -0700707 private void onHelpGba() {
708 PrintWriter pw = getOutPrintWriter();
709 pw.println("Gba Commands:");
710 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
711 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
712 pw.println(" Options are:");
713 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
714 pw.println(" is specified, it will choose the default voice SIM slot.");
715 pw.println(" gba get-service [-s SLOT_ID]");
716 pw.println(" Gets the package name of the currently defined GbaService.");
717 pw.println(" Options are:");
718 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
719 pw.println(" is specified, it will choose the default voice SIM slot.");
720 pw.println(" gba set-release [-s SLOT_ID] n");
721 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
722 pw.println(" Do not release/unbind if n is -1.");
723 pw.println(" Options are:");
724 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
725 pw.println(" is specified, it will choose the default voice SIM slot.");
726 pw.println(" gba get-release [-s SLOT_ID]");
727 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
728 pw.println(" Options are:");
729 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
730 pw.println(" is specified, it will choose the default voice SIM slot.");
731 }
732
Hui Wang761a6682020-10-31 05:12:53 +0000733 private void onHelpSrc() {
734 PrintWriter pw = getOutPrintWriter();
735 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800736 pw.println(" src set-test-enabled true|false");
737 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
738 pw.println(" The value could be true, false, or null(undefined).");
739 pw.println(" src get-test-enabled");
740 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000741 pw.println(" src set-device-enabled true|false|null");
742 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
743 pw.println(" The value could be true, false, or null(undefined).");
744 pw.println(" src get-device-enabled");
745 pw.println(" Gets the device config for RCS VoLTE single registration.");
746 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
747 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
748 pw.println(" The value could be true, false, or null(undefined).");
749 pw.println(" Options are:");
750 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
751 pw.println(" is specified, it will choose the default voice SIM slot.");
752 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
753 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
754 pw.println(" Options are:");
755 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
756 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800757 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
758 pw.println(" Sets ims feature validation result.");
759 pw.println(" The value could be true, false, or null(undefined).");
760 pw.println(" Options are:");
761 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
762 pw.println(" is specified, it will choose the default voice SIM slot.");
763 pw.println(" src get-feature-validation [-s SLOT_ID]");
764 pw.println(" Gets ims feature validation override value.");
765 pw.println(" Options are:");
766 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
767 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000768 }
769
SongFerngWang98dd5992021-05-13 17:50:00 +0800770 private void onHelpAllowedNetworkTypes() {
771 PrintWriter pw = getOutPrintWriter();
772 pw.println("Allowed Network Types Commands:");
773 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
774 pw.println(" Print allowed network types value.");
775 pw.println(" Options are:");
776 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
777 pw.println(" option is specified, it will choose the default voice SIM slot.");
778 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
779 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
780 pw.println(" Options are:");
781 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
782 pw.println(" option is specified, it will choose the default voice SIM slot.");
783 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
784 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
785 pw.println(" at TelephonyManager.java");
786 pw.println(" For example:");
787 pw.println(" NR only : 10000000000000000000");
788 pw.println(" NR|LTE : 11000001000000000000");
789 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
790 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
791 pw.println(" LTE only : 01000001000000000000");
792 }
793
jimsun3b9ccac2021-10-26 15:01:23 +0800794 private void onHelpRadio() {
795 PrintWriter pw = getOutPrintWriter();
796 pw.println("Radio Commands:");
797 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
798 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
799 pw.println(" to be the bound. Options are:");
800 pw.println(" -s: the service name that the modem service should be bound for.");
801 pw.println(" If no option is specified, it will bind to the default.");
802 pw.println(" radio get-modem-service");
803 pw.println(" Gets the service name of the currently defined modem service.");
804 pw.println(" If it is binding to default, 'default' returns.");
805 pw.println(" If it doesn't bind to any modem service for some reasons,");
806 pw.println(" the result would be 'unknown'.");
807 }
808
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700809 private void onHelpSatellite() {
810 PrintWriter pw = getOutPrintWriter();
811 pw.println("Satellite Commands:");
812 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
813 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700814 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700815 pw.println(" -s: the satellite service package name that Telephony will bind to.");
816 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700817 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
818 pw.println(" Sets the package name of satellite gateway service defined in");
819 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
820 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
821 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700822 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
823 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
824 pw.println(" mode. Options are:");
825 pw.println(" -t: the timeout duration in milliseconds.");
826 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700827 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
828 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
829 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
830 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
831 pw.println(" launch. If no option is specified, it will launch the default.");
832 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
833 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700834 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
835 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
836 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
837 pw.println(" Options are:");
838 pw.println(" -t: the emergency call to satellite handover type.");
839 pw.println(" If no option is specified, override is disabled.");
840 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
841 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800842 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
843 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
844 pw.println(" configs of satellite access controller.");
845 pw.println(" Options are:");
846 pw.println(" -r: clear the overriding. Absent means enable overriding.");
847 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
848 pw.println(" -f: the satellite s2 file.");
849 pw.println(" -d: the location fresh duration nanos.");
850 pw.println(" -c: the list of satellite country codes separated by comma.");
851 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
852 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
853 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
854 pw.println(" Override the cached location country code and its update timestamp. ");
855 pw.println(" Options are:");
856 pw.println(" -r: clear the overriding. Absent means enable overriding.");
857 pw.println(" -n: the current network country code ISOs.");
858 pw.println(" -c: the cached network country code ISOs.");
859 pw.println(" -l: the location country code ISO.");
860 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800861 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
862 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
863 pw.println(" -p: the overriding satellite provision status. If no option is ");
864 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700865 }
866
Ling Ma4fbab492022-01-25 22:36:16 +0000867 private void onHelpImei() {
868 PrintWriter pw = getOutPrintWriter();
869 pw.println("IMEI Commands:");
870 pw.println(" get-imei [-s SLOT_ID]");
871 pw.println(" Gets the device IMEI. Options are:");
872 pw.println(" -s: the slot ID to get the IMEI. If no option");
873 pw.println(" is specified, it will choose the default voice SIM slot.");
874 }
875
Hunsuk Choi13078be2023-09-13 10:55:21 +0000876 private void onHelpDomainSelection() {
877 PrintWriter pw = getOutPrintWriter();
878 pw.println("Domain Selection Commands:");
879 pw.println(" domainselection set-dss-override COMPONENT_NAME");
880 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
881 pw.println(" domainselection clear-dss-override");
882 pw.println(" Clears DomainSelectionService override.");
883 }
884
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700885 private int handleImsCommand() {
886 String arg = getNextArg();
887 if (arg == null) {
888 onHelpIms();
889 return 0;
890 }
891
892 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800893 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700894 return handleImsSetServiceCommand();
895 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800896 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700897 return handleImsGetServiceCommand();
898 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800899 case IMS_CLEAR_SERVICE_OVERRIDE: {
900 return handleImsClearCarrierServiceCommand();
901 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800902 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700903 return handleEnableIms();
904 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800905 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700906 return handleDisableIms();
907 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700908 case IMS_CEP: {
909 return handleCepChange();
910 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700911 }
912
913 return -1;
914 }
915
Shuo Qianf5125122019-12-16 17:03:07 -0800916 private int handleDataTestModeCommand() {
917 PrintWriter errPw = getErrPrintWriter();
918 String arg = getNextArgRequired();
919 if (arg == null) {
920 onHelpDataTestMode();
921 return 0;
922 }
923 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800924 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800925 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700926 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800927 } catch (RemoteException ex) {
928 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
929 errPw.println("Exception: " + ex.getMessage());
930 return -1;
931 }
932 break;
933 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800934 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800935 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700936 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800937 } catch (RemoteException ex) {
938 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
939 errPw.println("Exception: " + ex.getMessage());
940 return -1;
941 }
942 break;
943 }
944 default:
945 onHelpDataTestMode();
946 break;
947 }
948 return 0;
949 }
950
Shuo Qianccbaf742021-02-22 18:32:21 -0800951 private int handleEmergencyCallbackModeCommand() {
952 PrintWriter errPw = getErrPrintWriter();
953 try {
954 mInterface.startEmergencyCallbackMode();
955 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
956 } catch (RemoteException ex) {
957 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
958 errPw.println("Exception: " + ex.getMessage());
959 return -1;
960 }
961 return 0;
962 }
963
Grant Menke567d48f2022-08-18 20:19:10 +0000964 private void removeEmergencyNumberTestMode(String emergencyNumber) {
965 PrintWriter errPw = getErrPrintWriter();
966 for (int routingType : ROUTING_TYPES) {
967 try {
968 mInterface.updateEmergencyNumberListTestMode(
969 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
970 new EmergencyNumber(emergencyNumber, "", "",
971 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
972 new ArrayList<String>(),
973 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
974 routingType));
975 } catch (RemoteException ex) {
976 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
977 errPw.println("Exception: " + ex.getMessage());
978 }
979 }
980 }
981
sqian9d4df8b2019-01-15 18:32:07 -0800982 private int handleEmergencyNumberTestModeCommand() {
983 PrintWriter errPw = getErrPrintWriter();
984 String opt = getNextOption();
985 if (opt == null) {
986 onHelpEmergencyNumber();
987 return 0;
988 }
sqian9d4df8b2019-01-15 18:32:07 -0800989 switch (opt) {
990 case "-a": {
991 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000992 if (emergencyNumberCmd == null){
993 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800994 return -1;
995 }
Grant Menke567d48f2022-08-18 20:19:10 +0000996 String[] params = emergencyNumberCmd.split(":");
997 String emergencyNumber;
998 if (params[0] == null ||
999 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
1000 errPw.println(INVALID_ENTRY_ERROR);
1001 return -1;
1002 } else {
1003 emergencyNumber = params[0];
1004 }
1005 removeEmergencyNumberTestMode(emergencyNumber);
1006 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
1007 if (params.length > 1) {
1008 switch (params[1].toLowerCase(Locale.ROOT)) {
1009 case "emergency":
1010 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1011 break;
1012 case "normal":
1013 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1014 break;
1015 case "unknown":
1016 break;
1017 default:
1018 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1019 + "emergency call routing. Please enter either \"normal\", "
1020 + "\"unknown\", or \"emergency\" for call routing. "
1021 + "(-a 1234:normal)");
1022 return -1;
1023 }
1024 }
sqian9d4df8b2019-01-15 18:32:07 -08001025 try {
1026 mInterface.updateEmergencyNumberListTestMode(
1027 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001028 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001029 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1030 new ArrayList<String>(),
1031 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001032 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001033 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001034 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001035 + ", error " + ex.getMessage());
1036 errPw.println("Exception: " + ex.getMessage());
1037 return -1;
1038 }
1039 break;
1040 }
1041 case "-c": {
1042 try {
1043 mInterface.updateEmergencyNumberListTestMode(
1044 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1045 } catch (RemoteException ex) {
1046 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1047 errPw.println("Exception: " + ex.getMessage());
1048 return -1;
1049 }
1050 break;
1051 }
1052 case "-r": {
1053 String emergencyNumberCmd = getNextArgRequired();
1054 if (emergencyNumberCmd == null
1055 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001056 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001057 + " to be specified after -r in the command ");
1058 return -1;
1059 }
Grant Menke567d48f2022-08-18 20:19:10 +00001060 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001061 break;
1062 }
1063 case "-p": {
1064 try {
1065 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1066 } catch (RemoteException ex) {
1067 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1068 errPw.println("Exception: " + ex.getMessage());
1069 return -1;
1070 }
1071 break;
1072 }
1073 default:
1074 onHelpEmergencyNumber();
1075 break;
1076 }
1077 return 0;
1078 }
1079
Hall Liud892bec2018-11-30 14:51:45 -08001080 private int handleNumberVerificationCommand() {
1081 String arg = getNextArg();
1082 if (arg == null) {
1083 onHelpNumberVerification();
1084 return 0;
1085 }
1086
Hall Liuca5af3a2018-12-04 16:58:23 -08001087 if (!checkShellUid()) {
1088 return -1;
1089 }
1090
Hall Liud892bec2018-11-30 14:51:45 -08001091 switch (arg) {
1092 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001093 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1094 return 0;
1095 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001096 case NUMBER_VERIFICATION_FAKE_CALL: {
1097 boolean val = NumberVerificationManager.getInstance()
1098 .checkIncomingCall(getNextArg());
1099 getOutPrintWriter().println(val ? "1" : "0");
1100 return 0;
1101 }
Hall Liud892bec2018-11-30 14:51:45 -08001102 }
1103
1104 return -1;
1105 }
1106
Jordan Liu0ccee222021-04-27 11:55:13 -07001107 private boolean subIsEsim(int subId) {
1108 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1109 if (info != null) {
1110 return info.isEmbedded();
1111 }
1112 return false;
1113 }
1114
1115 private int handleEnablePhysicalSubscription(boolean enable) {
1116 PrintWriter errPw = getErrPrintWriter();
1117 int subId = 0;
1118 try {
1119 subId = Integer.parseInt(getNextArgRequired());
1120 } catch (NumberFormatException e) {
1121 errPw.println((enable ? "enable" : "disable")
1122 + "-physical-subscription requires an integer as a subId.");
1123 return -1;
1124 }
1125 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1126 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001127 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1128 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001129 errPw.println("cc: Permission denied.");
1130 return -1;
1131 }
1132 // Verify that the subId represents a physical sub
1133 if (subIsEsim(subId)) {
1134 errPw.println("SubId " + subId + " is not for a physical subscription");
1135 return -1;
1136 }
1137 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1138 + " physical subscription with subId=" + subId);
1139 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1140 return 0;
1141 }
1142
Jack Nudelman644b91a2021-03-12 14:09:48 -08001143 private int handleThermalMitigationCommand() {
1144 String arg = getNextArg();
1145 String packageName = getNextArg();
1146 if (arg == null || packageName == null) {
1147 onHelpThermalMitigation();
1148 return 0;
1149 }
1150
1151 if (!checkShellUid()) {
1152 return -1;
1153 }
1154
1155 switch (arg) {
1156 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1157 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1158 return 0;
1159 }
1160 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1161 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1162 mContext);
1163 return 0;
1164 }
1165 default:
1166 onHelpThermalMitigation();
1167 }
1168
1169 return -1;
1170
1171 }
1172
Tyler Gunn92479152021-01-20 16:30:10 -08001173 private int handleD2dCommand() {
1174 String arg = getNextArg();
1175 if (arg == null) {
1176 onHelpD2D();
1177 return 0;
1178 }
1179
1180 switch (arg) {
1181 case D2D_SEND: {
1182 return handleD2dSendCommand();
1183 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001184 case D2D_TRANSPORT: {
1185 return handleD2dTransportCommand();
1186 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001187 case D2D_SET_DEVICE_SUPPORT: {
1188 return handleD2dDeviceSupportedCommand();
1189 }
Tyler Gunn92479152021-01-20 16:30:10 -08001190 }
1191
1192 return -1;
1193 }
1194
1195 private int handleD2dSendCommand() {
1196 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001197 int messageType = -1;
1198 int messageValue = -1;
1199
Tyler Gunn92479152021-01-20 16:30:10 -08001200 String arg = getNextArg();
1201 if (arg == null) {
1202 onHelpD2D();
1203 return 0;
1204 }
1205 try {
1206 messageType = Integer.parseInt(arg);
1207 } catch (NumberFormatException e) {
1208 errPw.println("message type must be a valid integer");
1209 return -1;
1210 }
1211
1212 arg = getNextArg();
1213 if (arg == null) {
1214 onHelpD2D();
1215 return 0;
1216 }
1217 try {
1218 messageValue = Integer.parseInt(arg);
1219 } catch (NumberFormatException e) {
1220 errPw.println("message value must be a valid integer");
1221 return -1;
1222 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001223
Tyler Gunn92479152021-01-20 16:30:10 -08001224 try {
1225 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1226 } catch (RemoteException e) {
1227 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1228 errPw.println("Exception: " + e.getMessage());
1229 return -1;
1230 }
1231
1232 return 0;
1233 }
1234
Tyler Gunnbabbda02021-02-10 11:05:02 -08001235 private int handleD2dTransportCommand() {
1236 PrintWriter errPw = getErrPrintWriter();
1237
1238 String arg = getNextArg();
1239 if (arg == null) {
1240 onHelpD2D();
1241 return 0;
1242 }
1243
1244 try {
1245 mInterface.setActiveDeviceToDeviceTransport(arg);
1246 } catch (RemoteException e) {
1247 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1248 errPw.println("Exception: " + e.getMessage());
1249 return -1;
1250 }
1251 return 0;
1252 }
Nazanin014f41e2021-05-06 17:26:31 -07001253 private int handleBarringCommand() {
1254 String arg = getNextArg();
1255 if (arg == null) {
1256 onHelpBarring();
1257 return 0;
1258 }
1259
1260 switch (arg) {
1261 case BARRING_SEND_INFO: {
1262 return handleBarringSendCommand();
1263 }
1264 }
1265 return -1;
1266 }
1267
1268 private int handleBarringSendCommand() {
1269 PrintWriter errPw = getErrPrintWriter();
1270 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001271 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001272 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1273 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1274 boolean isConditionallyBarred = false;
1275 int conditionalBarringTimeSeconds = 0;
1276
1277 String opt;
1278 while ((opt = getNextOption()) != null) {
1279 switch (opt) {
1280 case "-s": {
1281 try {
1282 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001283 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001284 } catch (NumberFormatException e) {
1285 errPw.println("barring send requires an integer as a SLOT_ID.");
1286 return -1;
1287 }
1288 break;
1289 }
1290 case "-b": {
1291 try {
1292 barringType = Integer.parseInt(getNextArgRequired());
1293 if (barringType < -1 || barringType > 2) {
1294 throw new NumberFormatException();
1295 }
1296
1297 } catch (NumberFormatException e) {
1298 errPw.println("barring send requires an integer in range [-1,2] as "
1299 + "a BARRING_TYPE.");
1300 return -1;
1301 }
1302 break;
1303 }
1304 case "-c": {
1305 try {
1306 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1307 } catch (Exception e) {
1308 errPw.println("barring send requires a boolean after -c indicating"
1309 + " conditional barring");
1310 return -1;
1311 }
1312 break;
1313 }
1314 case "-t": {
1315 try {
1316 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1317 } catch (NumberFormatException e) {
1318 errPw.println("barring send requires an integer for time of barring"
1319 + " in seconds after -t for conditional barring");
1320 return -1;
1321 }
1322 break;
1323 }
1324 }
1325 }
1326 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1327 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1328 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1329 barringServiceInfos.append(0, bsi);
1330 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1331 try {
1332 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1333 } catch (Exception e) {
1334 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1335 errPw.println("Exception: " + e.getMessage());
1336 return -1;
1337 }
1338 return 0;
1339 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001340
Tyler Gunnd4575212021-05-03 14:46:49 -07001341 private int handleD2dDeviceSupportedCommand() {
1342 PrintWriter errPw = getErrPrintWriter();
1343
1344 String arg = getNextArg();
1345 if (arg == null) {
1346 onHelpD2D();
1347 return 0;
1348 }
1349
Jack Yua533d632022-09-30 13:53:46 -07001350 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001351 try {
1352 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1353 } catch (RemoteException e) {
1354 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1355 errPw.println("Exception: " + e.getMessage());
1356 return -1;
1357 }
1358 return 0;
1359 }
1360
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001361 // ims set-ims-service
1362 private int handleImsSetServiceCommand() {
1363 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001364 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001365 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001366 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001367
1368 String opt;
1369 while ((opt = getNextOption()) != null) {
1370 switch (opt) {
1371 case "-s": {
1372 try {
1373 slotId = Integer.parseInt(getNextArgRequired());
1374 } catch (NumberFormatException e) {
1375 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1376 return -1;
1377 }
1378 break;
1379 }
1380 case "-c": {
1381 isCarrierService = true;
1382 break;
1383 }
1384 case "-d": {
1385 isCarrierService = false;
1386 break;
1387 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001388 case "-f": {
1389 String featureString = getNextArgRequired();
1390 String[] features = featureString.split(",");
1391 for (int i = 0; i < features.length; i++) {
1392 try {
1393 Integer result = Integer.parseInt(features[i]);
1394 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1395 || result >= ImsFeature.FEATURE_MAX) {
1396 errPw.println("ims set-ims-service -f " + result
1397 + " is an invalid feature.");
1398 return -1;
1399 }
1400 featuresList.add(result);
1401 } catch (NumberFormatException e) {
1402 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1403 + " as an integer.");
1404 return -1;
1405 }
1406 }
1407 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001408 }
1409 }
1410 // Mandatory param, either -c or -d
1411 if (isCarrierService == null) {
1412 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1413 return -1;
1414 }
1415
1416 String packageName = getNextArg();
1417
1418 try {
1419 if (packageName == null) {
1420 packageName = "";
1421 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001422 int[] featureArray = new int[featuresList.size()];
1423 for (int i = 0; i < featuresList.size(); i++) {
1424 featureArray[i] = featuresList.get(i);
1425 }
1426 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1427 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001428 if (VDBG) {
1429 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001430 + (isCarrierService ? "-c " : "-d ")
1431 + "-f " + featuresList + " "
1432 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001433 }
1434 getOutPrintWriter().println(result);
1435 } catch (RemoteException e) {
1436 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001437 + (isCarrierService ? "-c " : "-d ")
1438 + "-f " + featuresList + " "
1439 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001440 errPw.println("Exception: " + e.getMessage());
1441 return -1;
1442 }
1443 return 0;
1444 }
1445
Brad Ebinger999d3302020-11-25 14:31:39 -08001446 // ims clear-ims-service-override
1447 private int handleImsClearCarrierServiceCommand() {
1448 PrintWriter errPw = getErrPrintWriter();
1449 int slotId = getDefaultSlot();
1450
1451 String opt;
1452 while ((opt = getNextOption()) != null) {
1453 switch (opt) {
1454 case "-s": {
1455 try {
1456 slotId = Integer.parseInt(getNextArgRequired());
1457 } catch (NumberFormatException e) {
1458 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1459 return -1;
1460 }
1461 break;
1462 }
1463 }
1464 }
1465
1466 try {
1467 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1468 if (VDBG) {
1469 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1470 + ", result=" + result);
1471 }
1472 getOutPrintWriter().println(result);
1473 } catch (RemoteException e) {
1474 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1475 + ", error" + e.getMessage());
1476 errPw.println("Exception: " + e.getMessage());
1477 return -1;
1478 }
1479 return 0;
1480 }
1481
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001482 // ims get-ims-service
1483 private int handleImsGetServiceCommand() {
1484 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001485 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001486 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001487 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001488
1489 String opt;
1490 while ((opt = getNextOption()) != null) {
1491 switch (opt) {
1492 case "-s": {
1493 try {
1494 slotId = Integer.parseInt(getNextArgRequired());
1495 } catch (NumberFormatException e) {
1496 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1497 return -1;
1498 }
1499 break;
1500 }
1501 case "-c": {
1502 isCarrierService = true;
1503 break;
1504 }
1505 case "-d": {
1506 isCarrierService = false;
1507 break;
1508 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001509 case "-f": {
1510 try {
1511 featureType = Integer.parseInt(getNextArg());
1512 } catch (NumberFormatException e) {
1513 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1514 return -1;
1515 }
1516 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1517 || featureType >= ImsFeature.FEATURE_MAX) {
1518 errPw.println("ims get-ims-service -f invalid feature.");
1519 return -1;
1520 }
1521 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001522 }
1523 }
1524 // Mandatory param, either -c or -d
1525 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001526 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001527 return -1;
1528 }
1529
1530 String result;
1531 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001532 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001533 } catch (RemoteException e) {
1534 return -1;
1535 }
1536 if (VDBG) {
1537 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001538 + (isCarrierService ? "-c " : "-d ")
1539 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1540 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001541 }
1542 getOutPrintWriter().println(result);
1543 return 0;
1544 }
1545
1546 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001547 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001548 String opt;
1549 while ((opt = getNextOption()) != null) {
1550 switch (opt) {
1551 case "-s": {
1552 try {
1553 slotId = Integer.parseInt(getNextArgRequired());
1554 } catch (NumberFormatException e) {
1555 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1556 return -1;
1557 }
1558 break;
1559 }
1560 }
1561 }
1562 try {
1563 mInterface.enableIms(slotId);
1564 } catch (RemoteException e) {
1565 return -1;
1566 }
1567 if (VDBG) {
1568 Log.v(LOG_TAG, "ims enable -s " + slotId);
1569 }
1570 return 0;
1571 }
1572
1573 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001574 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001575 String opt;
1576 while ((opt = getNextOption()) != null) {
1577 switch (opt) {
1578 case "-s": {
1579 try {
1580 slotId = Integer.parseInt(getNextArgRequired());
1581 } catch (NumberFormatException e) {
1582 getErrPrintWriter().println(
1583 "ims disable requires an integer as a SLOT_ID.");
1584 return -1;
1585 }
1586 break;
1587 }
1588 }
1589 }
1590 try {
1591 mInterface.disableIms(slotId);
1592 } catch (RemoteException e) {
1593 return -1;
1594 }
1595 if (VDBG) {
1596 Log.v(LOG_TAG, "ims disable -s " + slotId);
1597 }
1598 return 0;
1599 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001600
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001601 private int handleCepChange() {
1602 Log.i(LOG_TAG, "handleCepChange");
1603 String opt = getNextArg();
1604 if (opt == null) {
1605 return -1;
1606 }
1607 boolean isCepEnabled = opt.equals("enable");
1608
1609 try {
1610 mInterface.setCepEnabled(isCepEnabled);
1611 } catch (RemoteException e) {
1612 return -1;
1613 }
1614 return 0;
1615 }
1616
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001617 private int getDefaultSlot() {
1618 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1619 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1620 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1621 // If there is no default, default to slot 0.
1622 slotId = DEFAULT_PHONE_ID;
1623 }
1624 return slotId;
1625 }
sqian2fff4a32018-11-05 14:18:37 -08001626
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001627 // Parse options related to Carrier Config Commands.
1628 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001629 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 CcOptionParseResult result = new CcOptionParseResult();
1631 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1632 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001633
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001635 while ((opt = getNextOption()) != null) {
1636 switch (opt) {
1637 case "-s": {
1638 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001639 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1640 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1641 errPw.println(tag + "No valid subscription found.");
1642 return null;
1643 }
1644
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001645 } catch (IllegalArgumentException e) {
1646 // Missing slot id
1647 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001648 return null;
1649 }
1650 break;
1651 }
1652 case "-p": {
1653 if (allowOptionPersistent) {
1654 result.mPersistent = true;
1655 } else {
1656 errPw.println(tag + "Unexpected option " + opt);
1657 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001658 }
1659 break;
1660 }
1661 default: {
1662 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001663 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001664 }
1665 }
1666 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001667 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001668 }
1669
1670 private int slotStringToSubId(String tag, String slotString) {
1671 int slotId = -1;
1672 try {
1673 slotId = Integer.parseInt(slotString);
1674 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001675 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1676 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1677 }
1678
1679 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001680 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1681 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1682 }
1683
Qiong Liuf25799b2020-09-10 10:13:46 +08001684 Phone phone = PhoneFactory.getPhone(slotId);
1685 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001686 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1687 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1688 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001689 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001690 }
1691
Hall Liud892bec2018-11-30 14:51:45 -08001692 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001693 // adb can run as root or as shell, depending on whether the device is rooted.
Jack Yu86374492024-09-16 13:05:44 -07001694 return UserHandle.isSameApp(Binder.getCallingUid(), Process.SHELL_UID)
1695 || UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID);
Hall Liud892bec2018-11-30 14:51:45 -08001696 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001697
1698 private int handleCcCommand() {
1699 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1700 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001701 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1702 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001703 getErrPrintWriter().println("cc: Permission denied.");
1704 return -1;
1705 }
1706
1707 String arg = getNextArg();
1708 if (arg == null) {
1709 onHelpCc();
1710 return 0;
1711 }
1712
1713 switch (arg) {
1714 case CC_GET_VALUE: {
1715 return handleCcGetValue();
1716 }
1717 case CC_SET_VALUE: {
1718 return handleCcSetValue();
1719 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001720 case CC_SET_VALUES_FROM_XML: {
1721 return handleCcSetValuesFromXml();
1722 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001723 case CC_CLEAR_VALUES: {
1724 return handleCcClearValues();
1725 }
1726 default: {
1727 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1728 }
1729 }
1730 return -1;
1731 }
1732
1733 // cc get-value
1734 private int handleCcGetValue() {
1735 PrintWriter errPw = getErrPrintWriter();
1736 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1737 String key = null;
1738
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001739 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001740 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001741 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001742 return -1;
1743 }
1744
1745 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001746 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001747 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001748 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001749 return -1;
1750 }
1751
1752 // Get the key.
1753 key = getNextArg();
1754 if (key != null) {
1755 // A key was provided. Verify if it is a valid key
1756 if (!bundle.containsKey(key)) {
1757 errPw.println(tag + key + " is not a valid key.");
1758 return -1;
1759 }
1760
1761 // Print the carrier config value for key.
1762 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1763 } else {
1764 // No key provided. Show all values.
1765 // Iterate over a sorted list of all carrier config keys and print them.
1766 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1767 for (String k : sortedSet) {
1768 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1769 }
1770 }
1771 return 0;
1772 }
1773
1774 // cc set-value
1775 private int handleCcSetValue() {
1776 PrintWriter errPw = getErrPrintWriter();
1777 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1778
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001779 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001780 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001781 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001782 return -1;
1783 }
1784
1785 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001786 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001787 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001788 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001789 return -1;
1790 }
1791
1792 // Get the key.
1793 String key = getNextArg();
1794 if (key == null || key.equals("")) {
1795 errPw.println(tag + "KEY is missing");
1796 return -1;
1797 }
1798
1799 // Verify if the key is valid
1800 if (!originalValues.containsKey(key)) {
1801 errPw.println(tag + key + " is not a valid key.");
1802 return -1;
1803 }
1804
1805 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1806 ArrayList<String> valueList = new ArrayList<String>();
1807 while (peekNextArg() != null) {
1808 valueList.add(getNextArg());
1809 }
1810
1811 // Find the type of the carrier config value
1812 CcType type = getType(tag, key, originalValues);
1813 if (type == CcType.UNKNOWN) {
1814 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1815 return -1;
1816 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001817 if (type == CcType.PERSISTABLE_BUNDLE) {
1818 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1819 + "Use set-values-from-xml instead.");
1820 return -1;
1821 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001822
1823 // Create an override bundle containing the key and value that should be overriden.
1824 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1825 if (overrideBundle == null) {
1826 return -1;
1827 }
1828
1829 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001830 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001831
1832 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001833 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001834 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001835 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001836 return -1;
1837 }
1838
1839 // Print the original and new value.
1840 String originalValueString = ccValueToString(key, type, originalValues);
1841 String newValueString = ccValueToString(key, type, newValues);
1842 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1843 getOutPrintWriter().println("New value: \n" + newValueString);
1844
1845 return 0;
1846 }
1847
Allen Xuee00f0e2022-03-14 21:04:49 +00001848 // cc set-values-from-xml
1849 private int handleCcSetValuesFromXml() {
1850 PrintWriter errPw = getErrPrintWriter();
1851 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1852
1853 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001854 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001855 if (options == null) {
1856 return -1;
1857 }
1858
1859 // Get bundle containing all current carrier configuration values.
1860 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1861 if (originalValues == null) {
1862 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1863 return -1;
1864 }
1865
1866 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1867 if (overrideBundle == null) {
1868 return -1;
1869 }
1870
1871 // Verify all values are valid types
1872 for (String key : overrideBundle.keySet()) {
1873 CcType type = getType(tag, key, originalValues);
1874 if (type == CcType.UNKNOWN) {
1875 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1876 return -1;
1877 }
1878 }
1879
1880 // Override the value
1881 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1882
1883 // Find bundle containing all new carrier configuration values after the override.
1884 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1885 if (newValues == null) {
1886 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1887 return -1;
1888 }
1889
1890 // Print the original and new values
1891 overrideBundle.keySet().forEach(key -> {
1892 CcType type = getType(tag, key, originalValues);
1893 String originalValueString = ccValueToString(key, type, originalValues);
1894 String newValueString = ccValueToString(key, type, newValues);
1895 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1896 getOutPrintWriter().println("New value: \n" + newValueString);
1897 });
1898
1899 return 0;
1900 }
1901
1902 private PersistableBundle readPersistableBundleFromXml(String tag) {
1903 PersistableBundle subIdBundles;
1904 try {
1905 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1906 } catch (IOException | RuntimeException e) {
1907 PrintWriter errPw = getErrPrintWriter();
1908 errPw.println(tag + e);
1909 return null;
1910 }
1911
1912 return subIdBundles;
1913 }
1914
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001915 // cc clear-values
1916 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001917 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1918
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001919 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001920 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001921 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001922 return -1;
1923 }
1924
1925 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001926 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001927 getOutPrintWriter()
1928 .println("All previously set carrier config override values has been cleared");
1929 return 0;
1930 }
1931
1932 private CcType getType(String tag, String key, PersistableBundle bundle) {
1933 // Find the type by checking the type of the current value stored in the bundle.
1934 Object value = bundle.get(key);
1935
1936 if (CC_TYPE_MAP.containsKey(key)) {
1937 return CC_TYPE_MAP.get(key);
1938 } else if (value != null) {
1939 if (value instanceof Boolean) {
1940 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001941 }
1942 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001943 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001944 }
1945 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001946 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001947 }
1948 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001949 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001950 }
1951 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001952 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001953 }
1954 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001955 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001956 }
1957 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001958 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001959 }
1960 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001961 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001962 }
1963 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001964 return CcType.STRING_ARRAY;
1965 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001966 if (value instanceof PersistableBundle) {
1967 return CcType.PERSISTABLE_BUNDLE;
1968 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001969 } else {
1970 // Current value was null and can therefore not be used in order to find the type.
1971 // Check the name of the key to infer the type. This check is not needed for primitive
1972 // data types (boolean, double, int and long), since they can not be null.
1973 if (key.endsWith("double_array")) {
1974 return CcType.DOUBLE_ARRAY;
1975 }
1976 if (key.endsWith("int_array")) {
1977 return CcType.INT_ARRAY;
1978 }
1979 if (key.endsWith("long_array")) {
1980 return CcType.LONG_ARRAY;
1981 }
1982 if (key.endsWith("string")) {
1983 return CcType.STRING;
1984 }
1985 if (key.endsWith("string_array") || key.endsWith("strings")) {
1986 return CcType.STRING_ARRAY;
1987 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001988 if (key.endsWith("bundle")) {
1989 return CcType.PERSISTABLE_BUNDLE;
1990 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001991 }
1992
1993 // Not possible to infer the type by looking at the current value or the key.
1994 PrintWriter errPw = getErrPrintWriter();
1995 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1996 return CcType.UNKNOWN;
1997 }
1998
1999 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
2000 String result;
2001 StringBuilder valueString = new StringBuilder();
2002 String typeString = type.toString();
2003 Object value = bundle.get(key);
2004
2005 if (value == null) {
2006 valueString.append("null");
2007 } else {
2008 switch (type) {
2009 case DOUBLE_ARRAY: {
2010 // Format the string representation of the int array as value1 value2......
2011 double[] valueArray = (double[]) value;
2012 for (int i = 0; i < valueArray.length; i++) {
2013 if (i != 0) {
2014 valueString.append(" ");
2015 }
2016 valueString.append(valueArray[i]);
2017 }
2018 break;
2019 }
2020 case INT_ARRAY: {
2021 // Format the string representation of the int array as value1 value2......
2022 int[] valueArray = (int[]) value;
2023 for (int i = 0; i < valueArray.length; i++) {
2024 if (i != 0) {
2025 valueString.append(" ");
2026 }
2027 valueString.append(valueArray[i]);
2028 }
2029 break;
2030 }
2031 case LONG_ARRAY: {
2032 // Format the string representation of the int array as value1 value2......
2033 long[] valueArray = (long[]) value;
2034 for (int i = 0; i < valueArray.length; i++) {
2035 if (i != 0) {
2036 valueString.append(" ");
2037 }
2038 valueString.append(valueArray[i]);
2039 }
2040 break;
2041 }
2042 case STRING: {
2043 valueString.append("\"" + value.toString() + "\"");
2044 break;
2045 }
2046 case STRING_ARRAY: {
2047 // Format the string representation of the string array as "value1" "value2"....
2048 String[] valueArray = (String[]) value;
2049 for (int i = 0; i < valueArray.length; i++) {
2050 if (i != 0) {
2051 valueString.append(" ");
2052 }
2053 if (valueArray[i] != null) {
2054 valueString.append("\"" + valueArray[i] + "\"");
2055 } else {
2056 valueString.append("null");
2057 }
2058 }
2059 break;
2060 }
2061 default: {
2062 valueString.append(value.toString());
2063 }
2064 }
2065 }
2066 return String.format("%-70s %-15s %s", key, typeString, valueString);
2067 }
2068
2069 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2070 ArrayList<String> valueList) {
2071 PrintWriter errPw = getErrPrintWriter();
2072 PersistableBundle bundle = new PersistableBundle();
2073
2074 // First verify that a valid number of values has been provided for the type.
2075 switch (type) {
2076 case BOOLEAN:
2077 case DOUBLE:
2078 case INT:
2079 case LONG: {
2080 if (valueList.size() != 1) {
2081 errPw.println(tag + "Expected 1 value for type " + type
2082 + ". Found: " + valueList.size());
2083 return null;
2084 }
2085 break;
2086 }
2087 case STRING: {
2088 if (valueList.size() > 1) {
2089 errPw.println(tag + "Expected 0 or 1 values for type " + type
2090 + ". Found: " + valueList.size());
2091 return null;
2092 }
2093 break;
2094 }
2095 }
2096
2097 // Parse the value according to type and add it to the Bundle.
2098 switch (type) {
2099 case BOOLEAN: {
2100 if ("true".equalsIgnoreCase(valueList.get(0))) {
2101 bundle.putBoolean(key, true);
2102 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2103 bundle.putBoolean(key, false);
2104 } else {
2105 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2106 return null;
2107 }
2108 break;
2109 }
2110 case DOUBLE: {
2111 try {
2112 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2113 } catch (NumberFormatException nfe) {
2114 // Not a valid double
2115 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2116 return null;
2117 }
2118 break;
2119 }
2120 case DOUBLE_ARRAY: {
2121 double[] valueDoubleArray = null;
2122 if (valueList.size() > 0) {
2123 valueDoubleArray = new double[valueList.size()];
2124 for (int i = 0; i < valueList.size(); i++) {
2125 try {
2126 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2127 } catch (NumberFormatException nfe) {
2128 // Not a valid double
2129 errPw.println(
2130 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2131 return null;
2132 }
2133 }
2134 }
2135 bundle.putDoubleArray(key, valueDoubleArray);
2136 break;
2137 }
2138 case INT: {
2139 try {
2140 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2141 } catch (NumberFormatException nfe) {
2142 // Not a valid integer
2143 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2144 return null;
2145 }
2146 break;
2147 }
2148 case INT_ARRAY: {
2149 int[] valueIntArray = null;
2150 if (valueList.size() > 0) {
2151 valueIntArray = new int[valueList.size()];
2152 for (int i = 0; i < valueList.size(); i++) {
2153 try {
2154 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2155 } catch (NumberFormatException nfe) {
2156 // Not a valid integer
2157 errPw.println(tag
2158 + "Unable to parse " + valueList.get(i) + " as an integer.");
2159 return null;
2160 }
2161 }
2162 }
2163 bundle.putIntArray(key, valueIntArray);
2164 break;
2165 }
2166 case LONG: {
2167 try {
2168 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2169 } catch (NumberFormatException nfe) {
2170 // Not a valid long
2171 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2172 return null;
2173 }
2174 break;
2175 }
2176 case LONG_ARRAY: {
2177 long[] valueLongArray = null;
2178 if (valueList.size() > 0) {
2179 valueLongArray = new long[valueList.size()];
2180 for (int i = 0; i < valueList.size(); i++) {
2181 try {
2182 valueLongArray[i] = Long.parseLong(valueList.get(i));
2183 } catch (NumberFormatException nfe) {
2184 // Not a valid long
2185 errPw.println(
2186 tag + "Unable to parse " + valueList.get(i) + " as a long");
2187 return null;
2188 }
2189 }
2190 }
2191 bundle.putLongArray(key, valueLongArray);
2192 break;
2193 }
2194 case STRING: {
2195 String value = null;
2196 if (valueList.size() > 0) {
2197 value = valueList.get(0);
2198 }
2199 bundle.putString(key, value);
2200 break;
2201 }
2202 case STRING_ARRAY: {
2203 String[] valueStringArray = null;
2204 if (valueList.size() > 0) {
2205 valueStringArray = new String[valueList.size()];
2206 valueList.toArray(valueStringArray);
2207 }
2208 bundle.putStringArray(key, valueStringArray);
2209 break;
2210 }
2211 }
2212 return bundle;
2213 }
Shuo Qian489d9282020-07-09 11:30:03 -07002214
2215 private int handleEndBlockSuppressionCommand() {
2216 if (!checkShellUid()) {
2217 return -1;
2218 }
2219
2220 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2221 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2222 }
2223 return 0;
2224 }
Hui Wang641e81c2020-10-12 12:14:23 -07002225
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002226 private int handleEuiccCommand() {
2227 String arg = getNextArg();
2228 if (arg == null) {
2229 onHelpEuicc();
2230 return 0;
2231 }
2232
2233 switch (arg) {
2234 case EUICC_SET_UI_COMPONENT: {
2235 return handleEuiccServiceCommand();
2236 }
2237 }
2238 return -1;
2239 }
2240
2241 private int handleEuiccServiceCommand() {
2242 String uiComponent = getNextArg();
2243 String packageName = getNextArg();
2244 if (packageName == null || uiComponent == null) {
2245 return -1;
2246 }
2247 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2248 if (VDBG) {
2249 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2250 + packageName);
2251 }
2252 return 0;
2253 }
2254
Michele Berionne54af4632020-12-28 20:23:16 +00002255 private int handleRestartModemCommand() {
2256 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2257 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002258 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2259 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002260 getErrPrintWriter().println("RestartModem: Permission denied.");
2261 return -1;
2262 }
2263
2264 boolean result = TelephonyManager.getDefault().rebootRadio();
2265 getOutPrintWriter().println(result);
2266
2267 return result ? 0 : -1;
2268 }
2269
Ling Ma4fbab492022-01-25 22:36:16 +00002270 private int handleGetImei() {
2271 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2272 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002273 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2274 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002275 getErrPrintWriter().println("Device IMEI: Permission denied.");
2276 return -1;
2277 }
2278
2279 final long identity = Binder.clearCallingIdentity();
2280
2281 String imei = null;
2282 String arg = getNextArg();
2283 if (arg != null) {
2284 try {
2285 int specifiedSlotIndex = Integer.parseInt(arg);
2286 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2287 } catch (NumberFormatException exception) {
2288 PrintWriter errPw = getErrPrintWriter();
2289 errPw.println("-s requires an integer as slot index.");
2290 return -1;
2291 }
2292
2293 } else {
2294 imei = TelephonyManager.from(mContext).getImei();
2295 }
2296 getOutPrintWriter().println("Device IMEI: " + imei);
2297
2298 Binder.restoreCallingIdentity(identity);
2299 return 0;
2300 }
2301
Michele Berionne5e411512020-11-13 02:36:59 +00002302 private int handleUnattendedReboot() {
2303 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2304 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002305 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2306 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002307 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2308 return -1;
2309 }
2310
2311 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2312 getOutPrintWriter().println("result: " + result);
2313
2314 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2315 }
2316
Aman Gupta07124872022-02-09 08:02:14 +00002317 private int handleGetSimSlotsMapping() {
2318 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2319 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002320 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2321 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002322 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2323 return -1;
2324 }
2325 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2326 String result = telephonyManager.getSimSlotMapping().toString();
2327 getOutPrintWriter().println("simSlotsMapping: " + result);
2328
2329 return 0;
2330 }
2331
Hui Wang641e81c2020-10-12 12:14:23 -07002332 private int handleGbaCommand() {
2333 String arg = getNextArg();
2334 if (arg == null) {
2335 onHelpGba();
2336 return 0;
2337 }
2338
2339 switch (arg) {
2340 case GBA_SET_SERVICE: {
2341 return handleGbaSetServiceCommand();
2342 }
2343 case GBA_GET_SERVICE: {
2344 return handleGbaGetServiceCommand();
2345 }
2346 case GBA_SET_RELEASE_TIME: {
2347 return handleGbaSetReleaseCommand();
2348 }
2349 case GBA_GET_RELEASE_TIME: {
2350 return handleGbaGetReleaseCommand();
2351 }
2352 }
2353
2354 return -1;
2355 }
2356
2357 private int getSubId(String cmd) {
2358 int slotId = getDefaultSlot();
2359 String opt = getNextOption();
2360 if (opt != null && opt.equals("-s")) {
2361 try {
2362 slotId = Integer.parseInt(getNextArgRequired());
2363 } catch (NumberFormatException e) {
2364 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2365 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2366 }
2367 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002368 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002369 }
2370
2371 private int handleGbaSetServiceCommand() {
2372 int subId = getSubId("gba set-service");
2373 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2374 return -1;
2375 }
2376
2377 String packageName = getNextArg();
2378 try {
2379 if (packageName == null) {
2380 packageName = "";
2381 }
2382 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2383 if (VDBG) {
2384 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2385 + packageName + ", result=" + result);
2386 }
2387 getOutPrintWriter().println(result);
2388 } catch (RemoteException e) {
2389 Log.w(LOG_TAG, "gba set-service " + subId + " "
2390 + packageName + ", error" + e.getMessage());
2391 getErrPrintWriter().println("Exception: " + e.getMessage());
2392 return -1;
2393 }
2394 return 0;
2395 }
2396
2397 private int handleGbaGetServiceCommand() {
2398 String result;
2399
2400 int subId = getSubId("gba get-service");
2401 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2402 return -1;
2403 }
2404
2405 try {
2406 result = mInterface.getBoundGbaService(subId);
2407 } catch (RemoteException e) {
2408 return -1;
2409 }
2410 if (VDBG) {
2411 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2412 }
2413 getOutPrintWriter().println(result);
2414 return 0;
2415 }
2416
2417 private int handleGbaSetReleaseCommand() {
2418 //the release time value could be -1
2419 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2420 : SubscriptionManager.getDefaultSubscriptionId();
2421 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2422 return -1;
2423 }
2424
2425 String intervalStr = getNextArg();
2426 if (intervalStr == null) {
2427 return -1;
2428 }
2429
2430 try {
2431 int interval = Integer.parseInt(intervalStr);
2432 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2433 if (VDBG) {
2434 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2435 + intervalStr + ", result=" + result);
2436 }
2437 getOutPrintWriter().println(result);
2438 } catch (NumberFormatException | RemoteException e) {
2439 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2440 + intervalStr + ", error" + e.getMessage());
2441 getErrPrintWriter().println("Exception: " + e.getMessage());
2442 return -1;
2443 }
2444 return 0;
2445 }
2446
2447 private int handleGbaGetReleaseCommand() {
2448 int subId = getSubId("gba get-release");
2449 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2450 return -1;
2451 }
2452
2453 int result = 0;
2454 try {
2455 result = mInterface.getGbaReleaseTime(subId);
2456 } catch (RemoteException e) {
2457 return -1;
2458 }
2459 if (VDBG) {
2460 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2461 }
2462 getOutPrintWriter().println(result);
2463 return 0;
2464 }
Hui Wang761a6682020-10-31 05:12:53 +00002465
2466 private int handleSingleRegistrationConfigCommand() {
2467 String arg = getNextArg();
2468 if (arg == null) {
2469 onHelpSrc();
2470 return 0;
2471 }
2472
2473 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002474 case SRC_SET_TEST_ENABLED: {
2475 return handleSrcSetTestEnabledCommand();
2476 }
2477 case SRC_GET_TEST_ENABLED: {
2478 return handleSrcGetTestEnabledCommand();
2479 }
Hui Wang761a6682020-10-31 05:12:53 +00002480 case SRC_SET_DEVICE_ENABLED: {
2481 return handleSrcSetDeviceEnabledCommand();
2482 }
2483 case SRC_GET_DEVICE_ENABLED: {
2484 return handleSrcGetDeviceEnabledCommand();
2485 }
2486 case SRC_SET_CARRIER_ENABLED: {
2487 return handleSrcSetCarrierEnabledCommand();
2488 }
2489 case SRC_GET_CARRIER_ENABLED: {
2490 return handleSrcGetCarrierEnabledCommand();
2491 }
Hui Wangb647abe2021-02-26 09:33:38 -08002492 case SRC_SET_FEATURE_ENABLED: {
2493 return handleSrcSetFeatureValidationCommand();
2494 }
2495 case SRC_GET_FEATURE_ENABLED: {
2496 return handleSrcGetFeatureValidationCommand();
2497 }
Hui Wang761a6682020-10-31 05:12:53 +00002498 }
2499
2500 return -1;
2501 }
2502
James.cf Linbcdf8b32021-01-14 16:44:13 +08002503 private int handleRcsUceCommand() {
2504 String arg = getNextArg();
2505 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002506 onHelpUce();
2507 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002508 }
2509
2510 switch (arg) {
2511 case UCE_REMOVE_EAB_CONTACT:
2512 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002513 case UCE_GET_EAB_CONTACT:
2514 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002515 case UCE_GET_EAB_CAPABILITY:
2516 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002517 case UCE_GET_DEVICE_ENABLED:
2518 return handleUceGetDeviceEnabledCommand();
2519 case UCE_SET_DEVICE_ENABLED:
2520 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002521 case UCE_OVERRIDE_PUBLISH_CAPS:
2522 return handleUceOverridePublishCaps();
2523 case UCE_GET_LAST_PIDF_XML:
2524 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002525 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2526 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002527 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2528 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002529 }
2530 return -1;
2531 }
2532
2533 private int handleRemovingEabContactCommand() {
2534 int subId = getSubId("uce remove-eab-contact");
2535 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2536 return -1;
2537 }
2538
2539 String phoneNumber = getNextArgRequired();
2540 if (TextUtils.isEmpty(phoneNumber)) {
2541 return -1;
2542 }
2543 int result = 0;
2544 try {
2545 result = mInterface.removeContactFromEab(subId, phoneNumber);
2546 } catch (RemoteException e) {
2547 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2548 getErrPrintWriter().println("Exception: " + e.getMessage());
2549 return -1;
2550 }
2551
2552 if (VDBG) {
2553 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2554 }
calvinpan293ea1b2021-02-04 17:52:13 +08002555 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002556 }
2557
calvinpane4a8a1d2021-01-25 13:51:18 +08002558 private int handleGettingEabContactCommand() {
2559 String phoneNumber = getNextArgRequired();
2560 if (TextUtils.isEmpty(phoneNumber)) {
2561 return -1;
2562 }
2563 String result = "";
2564 try {
2565 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002566 } catch (RemoteException e) {
2567 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2568 getErrPrintWriter().println("Exception: " + e.getMessage());
2569 return -1;
2570 }
2571
2572 if (VDBG) {
2573 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2574 }
calvinpan293ea1b2021-02-04 17:52:13 +08002575 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002576 return 0;
2577 }
2578
Calvin Pana1434322021-07-01 19:27:01 +08002579 private int handleGettingEabCapabilityCommand() {
2580 String phoneNumber = getNextArgRequired();
2581 if (TextUtils.isEmpty(phoneNumber)) {
2582 return -1;
2583 }
2584 String result = "";
2585 try {
2586 result = mInterface.getCapabilityFromEab(phoneNumber);
2587 } catch (RemoteException e) {
2588 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2589 getErrPrintWriter().println("Exception: " + e.getMessage());
2590 return -1;
2591 }
2592
2593 if (VDBG) {
2594 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2595 }
2596 getOutPrintWriter().println(result);
2597 return 0;
2598 }
2599
James.cf Lin4b784aa2021-01-31 03:25:15 +08002600 private int handleUceGetDeviceEnabledCommand() {
2601 boolean result = false;
2602 try {
2603 result = mInterface.getDeviceUceEnabled();
2604 } catch (RemoteException e) {
2605 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2606 return -1;
2607 }
2608 if (VDBG) {
2609 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2610 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002611 getOutPrintWriter().println(result);
2612 return 0;
2613 }
2614
James.cf Lin4b784aa2021-01-31 03:25:15 +08002615 private int handleUceSetDeviceEnabledCommand() {
2616 String enabledStr = getNextArg();
2617 if (TextUtils.isEmpty(enabledStr)) {
2618 return -1;
2619 }
2620
2621 try {
2622 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2623 mInterface.setDeviceUceEnabled(isEnabled);
2624 if (VDBG) {
2625 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2626 }
2627 } catch (NumberFormatException | RemoteException e) {
2628 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2629 getErrPrintWriter().println("Exception: " + e.getMessage());
2630 return -1;
2631 }
2632 return 0;
2633 }
2634
James.cf Line8713a42021-04-29 16:04:26 +08002635 private int handleUceRemoveRequestDisallowedStatus() {
2636 int subId = getSubId("uce remove-request-disallowed-status");
2637 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2638 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2639 return -1;
2640 }
2641 boolean result;
2642 try {
2643 result = mInterface.removeUceRequestDisallowedStatus(subId);
2644 } catch (RemoteException e) {
2645 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2646 return -1;
2647 }
2648 if (VDBG) {
2649 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2650 }
2651 getOutPrintWriter().println(result);
2652 return 0;
2653 }
2654
James.cf Lin0fc71b02021-05-25 01:37:38 +08002655 private int handleUceSetCapRequestTimeout() {
2656 int subId = getSubId("uce set-capabilities-request-timeout");
2657 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2658 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2659 return -1;
2660 }
2661 long timeoutAfterMs = Long.valueOf(getNextArg());
2662 boolean result;
2663 try {
2664 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2665 } catch (RemoteException e) {
2666 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2667 return -1;
2668 }
2669 if (VDBG) {
2670 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2671 }
2672 getOutPrintWriter().println(result);
2673 return 0;
2674 }
2675
Hui Wangbaaee6a2021-02-19 20:45:36 -08002676 private int handleSrcSetTestEnabledCommand() {
2677 String enabledStr = getNextArg();
2678 if (enabledStr == null) {
2679 return -1;
2680 }
2681
2682 try {
2683 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2684 if (VDBG) {
2685 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2686 }
2687 getOutPrintWriter().println("Done");
2688 } catch (NumberFormatException | RemoteException e) {
2689 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2690 getErrPrintWriter().println("Exception: " + e.getMessage());
2691 return -1;
2692 }
2693 return 0;
2694 }
2695
2696 private int handleSrcGetTestEnabledCommand() {
2697 boolean result = false;
2698 try {
2699 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2700 } catch (RemoteException e) {
2701 return -1;
2702 }
2703 if (VDBG) {
2704 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2705 }
2706 getOutPrintWriter().println(result);
2707 return 0;
2708 }
2709
Brad Ebinger14d467f2021-02-12 06:18:28 +00002710 private int handleUceOverridePublishCaps() {
2711 int subId = getSubId("uce override-published-caps");
2712 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2713 return -1;
2714 }
2715 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2716 String operation = getNextArgRequired();
2717 String caps = getNextArg();
2718 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2719 && !"list".equals(operation)) {
2720 getErrPrintWriter().println("Invalid operation: " + operation);
2721 return -1;
2722 }
2723
2724 // add/remove requires capabilities to be specified.
2725 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2726 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2727 + "specified");
2728 return -1;
2729 }
2730
2731 ArraySet<String> capSet = new ArraySet<>();
2732 if (!TextUtils.isEmpty(caps)) {
2733 String[] capArray = caps.split(":");
2734 for (String cap : capArray) {
2735 // Allow unknown tags to be passed in as well.
2736 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2737 }
2738 }
2739
2740 RcsContactUceCapability result = null;
2741 try {
2742 switch (operation) {
2743 case "add":
2744 result = mInterface.addUceRegistrationOverrideShell(subId,
2745 new ArrayList<>(capSet));
2746 break;
2747 case "remove":
2748 result = mInterface.removeUceRegistrationOverrideShell(subId,
2749 new ArrayList<>(capSet));
2750 break;
2751 case "clear":
2752 result = mInterface.clearUceRegistrationOverrideShell(subId);
2753 break;
2754 case "list":
2755 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2756 break;
2757 }
2758 } catch (RemoteException e) {
2759 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2760 getErrPrintWriter().println("Exception: " + e.getMessage());
2761 return -1;
2762 } catch (ServiceSpecificException sse) {
2763 // Reconstruct ImsException
2764 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2765 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2766 getErrPrintWriter().println("Exception: " + imsException);
2767 return -1;
2768 }
2769 if (result == null) {
2770 getErrPrintWriter().println("Service not available");
2771 return -1;
2772 }
2773 getOutPrintWriter().println(result);
2774 return 0;
2775 }
2776
2777 private int handleUceGetPidfXml() {
2778 int subId = getSubId("uce get-last-publish-pidf");
2779 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2780 return -1;
2781 }
2782
2783 String result;
2784 try {
2785 result = mInterface.getLastUcePidfXmlShell(subId);
2786 } catch (RemoteException e) {
2787 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2788 getErrPrintWriter().println("Exception: " + e.getMessage());
2789 return -1;
2790 } catch (ServiceSpecificException sse) {
2791 // Reconstruct ImsException
2792 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2793 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2794 getErrPrintWriter().println("Exception: " + imsException);
2795 return -1;
2796 }
2797 if (result == null) {
2798 getErrPrintWriter().println("Service not available");
2799 return -1;
2800 }
2801 getOutPrintWriter().println(result);
2802 return 0;
2803 }
2804
Hui Wang761a6682020-10-31 05:12:53 +00002805 private int handleSrcSetDeviceEnabledCommand() {
2806 String enabledStr = getNextArg();
2807 if (enabledStr == null) {
2808 return -1;
2809 }
2810
2811 try {
2812 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2813 if (VDBG) {
2814 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2815 }
2816 getOutPrintWriter().println("Done");
2817 } catch (NumberFormatException | RemoteException e) {
2818 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2819 getErrPrintWriter().println("Exception: " + e.getMessage());
2820 return -1;
2821 }
2822 return 0;
2823 }
2824
2825 private int handleSrcGetDeviceEnabledCommand() {
2826 boolean result = false;
2827 try {
2828 result = mInterface.getDeviceSingleRegistrationEnabled();
2829 } catch (RemoteException e) {
2830 return -1;
2831 }
2832 if (VDBG) {
2833 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2834 }
2835 getOutPrintWriter().println(result);
2836 return 0;
2837 }
2838
2839 private int handleSrcSetCarrierEnabledCommand() {
2840 //the release time value could be -1
2841 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2842 : SubscriptionManager.getDefaultSubscriptionId();
2843 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2844 return -1;
2845 }
2846
2847 String enabledStr = getNextArg();
2848 if (enabledStr == null) {
2849 return -1;
2850 }
2851
2852 try {
2853 boolean result =
2854 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2855 if (VDBG) {
2856 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2857 + enabledStr + ", result=" + result);
2858 }
2859 getOutPrintWriter().println(result);
2860 } catch (NumberFormatException | RemoteException e) {
2861 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2862 + enabledStr + ", error" + e.getMessage());
2863 getErrPrintWriter().println("Exception: " + e.getMessage());
2864 return -1;
2865 }
2866 return 0;
2867 }
2868
2869 private int handleSrcGetCarrierEnabledCommand() {
2870 int subId = getSubId("src get-carrier-enabled");
2871 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2872 return -1;
2873 }
2874
2875 boolean result = false;
2876 try {
2877 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2878 } catch (RemoteException e) {
2879 return -1;
2880 }
2881 if (VDBG) {
2882 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2883 }
2884 getOutPrintWriter().println(result);
2885 return 0;
2886 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002887
Hui Wangb647abe2021-02-26 09:33:38 -08002888 private int handleSrcSetFeatureValidationCommand() {
2889 //the release time value could be -1
2890 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2891 : SubscriptionManager.getDefaultSubscriptionId();
2892 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2893 return -1;
2894 }
2895
2896 String enabledStr = getNextArg();
2897 if (enabledStr == null) {
2898 return -1;
2899 }
2900
2901 try {
2902 boolean result =
2903 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2904 if (VDBG) {
2905 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2906 + enabledStr + ", result=" + result);
2907 }
2908 getOutPrintWriter().println(result);
2909 } catch (NumberFormatException | RemoteException e) {
2910 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2911 + enabledStr + ", error" + e.getMessage());
2912 getErrPrintWriter().println("Exception: " + e.getMessage());
2913 return -1;
2914 }
2915 return 0;
2916 }
2917
2918 private int handleSrcGetFeatureValidationCommand() {
2919 int subId = getSubId("src get-feature-validation");
2920 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2921 return -1;
2922 }
2923
2924 Boolean result = false;
2925 try {
2926 result = mInterface.getImsFeatureValidationOverride(subId);
2927 } catch (RemoteException e) {
2928 return -1;
2929 }
2930 if (VDBG) {
2931 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2932 }
2933 getOutPrintWriter().println(result);
2934 return 0;
2935 }
2936
2937
Hall Liuaa4211e2021-01-20 15:43:39 -08002938 private void onHelpCallComposer() {
2939 PrintWriter pw = getOutPrintWriter();
2940 pw.println("Call composer commands");
2941 pw.println(" callcomposer test-mode enable|disable|query");
2942 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2943 pw.println(" upload/download from carrier servers is disabled, and operations are");
2944 pw.println(" performed using emulated local files instead.");
2945 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2946 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2947 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002948 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2949 pw.println(" Enables or disables the user setting for call composer, as set by");
2950 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002951 }
2952
2953 private int handleCallComposerCommand() {
2954 String arg = getNextArg();
2955 if (arg == null) {
2956 onHelpCallComposer();
2957 return 0;
2958 }
2959
2960 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2961 "MODIFY_PHONE_STATE required for call composer shell cmds");
2962 switch (arg) {
2963 case CALL_COMPOSER_TEST_MODE: {
2964 String enabledStr = getNextArg();
2965 if (ENABLE.equals(enabledStr)) {
2966 CallComposerPictureManager.sTestMode = true;
2967 } else if (DISABLE.equals(enabledStr)) {
2968 CallComposerPictureManager.sTestMode = false;
2969 } else if (QUERY.equals(enabledStr)) {
2970 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2971 } else {
2972 onHelpCallComposer();
2973 return 1;
2974 }
2975 break;
2976 }
2977 case CALL_COMPOSER_SIMULATE_CALL: {
2978 int subscriptionId = Integer.valueOf(getNextArg());
2979 String uuidString = getNextArg();
2980 UUID uuid = UUID.fromString(uuidString);
2981 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2982 Binder.withCleanCallingIdentity(() -> {
2983 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2984 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2985 });
2986 try {
2987 Uri uri = storageUriFuture.get();
2988 getOutPrintWriter().println(String.valueOf(uri));
2989 } catch (Exception e) {
2990 throw new RuntimeException(e);
2991 }
2992 break;
2993 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002994 case CALL_COMPOSER_USER_SETTING: {
2995 try {
2996 int subscriptionId = Integer.valueOf(getNextArg());
2997 String enabledStr = getNextArg();
2998 if (ENABLE.equals(enabledStr)) {
2999 mInterface.setCallComposerStatus(subscriptionId,
3000 TelephonyManager.CALL_COMPOSER_STATUS_ON);
3001 } else if (DISABLE.equals(enabledStr)) {
3002 mInterface.setCallComposerStatus(subscriptionId,
3003 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
3004 } else if (QUERY.equals(enabledStr)) {
3005 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
3006 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
3007 } else {
3008 onHelpCallComposer();
3009 return 1;
3010 }
3011 } catch (RemoteException e) {
3012 e.printStackTrace(getOutPrintWriter());
3013 return 1;
3014 }
3015 break;
3016 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003017 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003018 return 0;
3019 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003020
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003021 private int handleHasCarrierPrivilegesCommand() {
3022 String packageName = getNextArgRequired();
3023
3024 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003025 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003026 try {
3027 hasCarrierPrivileges =
3028 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3029 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3030 } catch (RemoteException e) {
3031 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3032 getErrPrintWriter().println("Exception: " + e.getMessage());
3033 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003034 } finally {
3035 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003036 }
3037
3038 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003039 return 0;
3040 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003041
3042 private int handleAllowedNetworkTypesCommand(String command) {
3043 if (!checkShellUid()) {
3044 return -1;
3045 }
3046
3047 PrintWriter errPw = getErrPrintWriter();
3048 String tag = command + ": ";
3049 String opt;
3050 int subId = -1;
3051 Log.v(LOG_TAG, command + " start");
3052
3053 while ((opt = getNextOption()) != null) {
3054 if (opt.equals("-s")) {
3055 try {
3056 subId = slotStringToSubId(tag, getNextArgRequired());
3057 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3058 errPw.println(tag + "No valid subscription found.");
3059 return -1;
3060 }
3061 } catch (IllegalArgumentException e) {
3062 // Missing slot id
3063 errPw.println(tag + "SLOT_ID expected after -s.");
3064 return -1;
3065 }
3066 } else {
3067 errPw.println(tag + "Unknown option " + opt);
3068 return -1;
3069 }
3070 }
3071
3072 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3073 return handleGetAllowedNetworkTypesCommand(subId);
3074 }
3075 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3076 return handleSetAllowedNetworkTypesCommand(subId);
3077 }
3078 return -1;
3079 }
3080
3081 private int handleGetAllowedNetworkTypesCommand(int subId) {
3082 PrintWriter errPw = getErrPrintWriter();
3083
3084 long result = -1;
3085 try {
3086 if (mInterface != null) {
3087 result = mInterface.getAllowedNetworkTypesForReason(subId,
3088 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3089 } else {
3090 throw new IllegalStateException("telephony service is null.");
3091 }
3092 } catch (RemoteException e) {
3093 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3094 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3095 return -1;
3096 }
3097
3098 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3099 return 0;
3100 }
3101
3102 private int handleSetAllowedNetworkTypesCommand(int subId) {
3103 PrintWriter errPw = getErrPrintWriter();
3104
3105 String bitmaskString = getNextArg();
3106 if (TextUtils.isEmpty(bitmaskString)) {
3107 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3108 return -1;
3109 }
3110 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3111 if (allowedNetworkTypes < 0) {
3112 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3113 return -1;
3114 }
3115 boolean result = false;
3116 try {
3117 if (mInterface != null) {
3118 result = mInterface.setAllowedNetworkTypesForReason(subId,
3119 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3120 } else {
3121 throw new IllegalStateException("telephony service is null.");
3122 }
3123 } catch (RemoteException e) {
3124 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3125 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3126 return -1;
3127 }
3128
3129 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3130 if (result) {
3131 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3132 }
3133 getOutPrintWriter().println(resultMessage);
3134 return 0;
3135 }
3136
3137 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3138 if (TextUtils.isEmpty(bitmaskString)) {
3139 return -1;
3140 }
3141 if (VDBG) {
3142 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3143 + ", length: " + bitmaskString.length());
3144 }
3145 try {
3146 return Long.parseLong(bitmaskString, 2);
3147 } catch (NumberFormatException e) {
3148 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3149 return -1;
3150 }
3151 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003152
jimsun3b9ccac2021-10-26 15:01:23 +08003153 private int handleRadioSetModemServiceCommand() {
3154 PrintWriter errPw = getErrPrintWriter();
3155 String serviceName = null;
3156
3157 String opt;
3158 while ((opt = getNextOption()) != null) {
3159 switch (opt) {
3160 case "-s": {
3161 serviceName = getNextArgRequired();
3162 break;
3163 }
3164 }
3165 }
3166
3167 try {
3168 boolean result = mInterface.setModemService(serviceName);
3169 if (VDBG) {
3170 Log.v(LOG_TAG,
3171 "RadioSetModemService " + serviceName + ", result = " + result);
3172 }
3173 getOutPrintWriter().println(result);
3174 } catch (RemoteException e) {
3175 Log.w(LOG_TAG,
3176 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3177 errPw.println("Exception: " + e.getMessage());
3178 return -1;
3179 }
3180 return 0;
3181 }
3182
3183 private int handleRadioGetModemServiceCommand() {
3184 PrintWriter errPw = getErrPrintWriter();
3185 String result;
3186
3187 try {
3188 result = mInterface.getModemService();
3189 getOutPrintWriter().println(result);
3190 } catch (RemoteException e) {
3191 errPw.println("Exception: " + e.getMessage());
3192 return -1;
3193 }
3194 if (VDBG) {
3195 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3196 }
3197 return 0;
3198 }
3199
3200 private int handleRadioCommand() {
3201 String arg = getNextArg();
3202 if (arg == null) {
3203 onHelpRadio();
3204 return 0;
3205 }
3206
3207 switch (arg) {
3208 case RADIO_SET_MODEM_SERVICE:
3209 return handleRadioSetModemServiceCommand();
3210
3211 case RADIO_GET_MODEM_SERVICE:
3212 return handleRadioGetModemServiceCommand();
3213 }
3214
3215 return -1;
3216 }
arunvoddud7401012022-12-15 16:08:12 +00003217
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003218 private int handleSetSatelliteServicePackageNameCommand() {
3219 PrintWriter errPw = getErrPrintWriter();
3220 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003221 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003222
3223 String opt;
3224 while ((opt = getNextOption()) != null) {
3225 switch (opt) {
3226 case "-s": {
3227 serviceName = getNextArgRequired();
3228 break;
3229 }
Hakjun Choic3393242024-06-26 18:02:08 +00003230
3231 case "-p": {
3232 provisioned = getNextArgRequired();
3233 break;
3234 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003235 }
3236 }
3237 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003238 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003239
3240 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003241 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003242 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003243 Log.v(LOG_TAG,
3244 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3245 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003246 }
3247 getOutPrintWriter().println(result);
3248 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003249 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3250 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003251 errPw.println("Exception: " + e.getMessage());
3252 return -1;
3253 }
Hakjun Choic3393242024-06-26 18:02:08 +00003254
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003255 return 0;
3256 }
3257
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003258 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3259 PrintWriter errPw = getErrPrintWriter();
3260 String serviceName = null;
3261
3262 String opt;
3263 while ((opt = getNextOption()) != null) {
3264 switch (opt) {
3265 case "-s": {
3266 serviceName = getNextArgRequired();
3267 break;
3268 }
3269 }
3270 }
3271 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3272 + serviceName);
3273
3274 try {
3275 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3276 if (VDBG) {
3277 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3278 + ", result = " + result);
3279 }
3280 getOutPrintWriter().println(result);
3281 } catch (RemoteException e) {
3282 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3283 + ", error = " + e.getMessage());
3284 errPw.println("Exception: " + e.getMessage());
3285 return -1;
3286 }
3287 return 0;
3288 }
3289
Thomas Nguyen87dce732023-04-20 18:27:16 -07003290 private int handleSetSatellitePointingUiClassNameCommand() {
3291 PrintWriter errPw = getErrPrintWriter();
3292 String packageName = null;
3293 String className = null;
3294
3295 String opt;
3296 while ((opt = getNextOption()) != null) {
3297 switch (opt) {
3298 case "-p": {
3299 packageName = getNextArgRequired();
3300 break;
3301 }
3302 case "-c": {
3303 className = getNextArgRequired();
3304 break;
3305 }
3306 }
3307 }
3308 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3309 + packageName + ", className=" + className);
3310
3311 try {
3312 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3313 if (VDBG) {
3314 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3315 }
3316 getOutPrintWriter().println(result);
3317 } catch (RemoteException e) {
3318 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3319 + ", error = " + e.getMessage());
3320 errPw.println("Exception: " + e.getMessage());
3321 return -1;
3322 }
3323 return 0;
3324 }
3325
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003326 private int handleSetEmergencyCallToSatelliteHandoverType() {
3327 PrintWriter errPw = getErrPrintWriter();
3328 int handoverType = -1;
3329 int delaySeconds = 0;
3330
3331 String opt;
3332 while ((opt = getNextOption()) != null) {
3333 switch (opt) {
3334 case "-t": {
3335 try {
3336 handoverType = Integer.parseInt(getNextArgRequired());
3337 } catch (NumberFormatException e) {
3338 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3339 + " for handoverType");
3340 return -1;
3341 }
3342 break;
3343 }
3344 case "-d": {
3345 try {
3346 delaySeconds = Integer.parseInt(getNextArgRequired());
3347 } catch (NumberFormatException e) {
3348 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3349 + " for delaySeconds");
3350 return -1;
3351 }
3352 break;
3353 }
3354 }
3355 }
3356 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3357 + handoverType + ", delaySeconds=" + delaySeconds);
3358
3359 try {
3360 boolean result =
3361 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3362 if (VDBG) {
3363 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3364 }
3365 getOutPrintWriter().println(result);
3366 } catch (RemoteException e) {
3367 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3368 + ", error = " + e.getMessage());
3369 errPw.println("Exception: " + e.getMessage());
3370 return -1;
3371 }
3372 return 0;
3373 }
3374
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003375 private int handleSetSatelliteListeningTimeoutDuration() {
3376 PrintWriter errPw = getErrPrintWriter();
3377 long timeoutMillis = 0;
3378
3379 String opt;
3380 while ((opt = getNextOption()) != null) {
3381 switch (opt) {
3382 case "-t": {
3383 timeoutMillis = Long.parseLong(getNextArgRequired());
3384 break;
3385 }
3386 }
3387 }
3388 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3389 + timeoutMillis);
3390
3391 try {
3392 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3393 if (VDBG) {
3394 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3395 + ", result = " + result);
3396 }
3397 getOutPrintWriter().println(result);
3398 } catch (RemoteException e) {
3399 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3400 + ", error = " + e.getMessage());
3401 errPw.println("Exception: " + e.getMessage());
3402 return -1;
3403 }
3404 return 0;
3405 }
3406
joonhunshinf46f0d62024-09-27 14:06:26 +00003407 private int handleSetSatelliteIgnoreCellularServiceState() {
3408 PrintWriter errPw = getErrPrintWriter();
3409 boolean enabled = false;
3410
3411 String opt;
3412 while ((opt = getNextOption()) != null) {
3413 switch (opt) {
3414 case "-d": {
3415 enabled = Boolean.parseBoolean(getNextArgRequired());
3416 break;
3417 }
3418 }
3419 }
3420 Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
3421
3422 try {
3423 boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
3424 if (VDBG) {
3425 Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
3426 + ", result = " + result);
3427 }
3428 getOutPrintWriter().println(result);
3429 } catch (RemoteException e) {
3430 Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
3431 + ", error = " + e.getMessage());
3432 errPw.println("Exception: " + e.getMessage());
3433 return -1;
3434 }
3435 return 0;
3436 }
3437
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003438 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003439 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003440 boolean reset = false;
3441 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003442 long timeoutMillis = 0;
3443
3444 String opt;
3445 while ((opt = getNextOption()) != null) {
3446 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003447 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003448 timeoutMillis = Long.parseLong(getNextArgRequired());
3449 break;
3450 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003451 case "-r": {
3452 reset = true;
3453 break;
3454 }
3455 case "-t": {
3456 timeoutType = Integer.parseInt(getNextArgRequired());
3457 break;
3458 }
Hakjun Choiae365972023-04-25 11:00:31 +00003459 }
3460 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003461 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3462 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003463
3464 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003465 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3466 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003467 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003468 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003469 + ", result = " + result);
3470 }
3471 getOutPrintWriter().println(result);
3472 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003473 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3474 + ", error = " + e.getMessage());
3475 errPw.println("Exception: " + e.getMessage());
3476 return -1;
3477 }
3478 return 0;
3479 }
3480
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003481 private int handleSetDatagramControllerBooleanConfig() {
3482 PrintWriter errPw = getErrPrintWriter();
3483 boolean reset = false;
3484 int booleanType = 0;
3485 boolean enable = false;
3486
3487 String opt;
3488 while ((opt = getNextOption()) != null) {
3489 switch (opt) {
3490 case "-d": {
3491 enable = Boolean.parseBoolean(getNextArgRequired());
3492 break;
3493 }
3494 case "-r": {
3495 reset = true;
3496 break;
3497 }
3498 case "-t": {
3499 booleanType = Integer.parseInt(getNextArgRequired());
3500 break;
3501 }
3502 }
3503 }
3504 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3505 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3506
3507 try {
3508 boolean result = mInterface.setDatagramControllerBooleanConfig(
3509 reset, booleanType, enable);
3510 if (VDBG) {
3511 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3512 }
3513 getOutPrintWriter().println(result);
3514 } catch (RemoteException e) {
3515 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3516 errPw.println("Exception: " + e.getMessage());
3517 return -1;
3518 }
3519 return 0;
3520 }
3521
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003522 private int handleSetSatelliteControllerTimeoutDuration() {
3523 PrintWriter errPw = getErrPrintWriter();
3524 boolean reset = false;
3525 int timeoutType = 0;
3526 long timeoutMillis = 0;
3527
3528 String opt;
3529 while ((opt = getNextOption()) != null) {
3530 switch (opt) {
3531 case "-d": {
3532 timeoutMillis = Long.parseLong(getNextArgRequired());
3533 break;
3534 }
3535 case "-r": {
3536 reset = true;
3537 break;
3538 }
3539 case "-t": {
3540 timeoutType = Integer.parseInt(getNextArgRequired());
3541 break;
3542 }
3543 }
3544 }
3545 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3546 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3547
3548 try {
3549 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3550 reset, timeoutType, timeoutMillis);
3551 if (VDBG) {
3552 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3553 + ", result = " + result);
3554 }
3555 getOutPrintWriter().println(result);
3556 } catch (RemoteException e) {
3557 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003558 + ", error = " + e.getMessage());
3559 errPw.println("Exception: " + e.getMessage());
3560 return -1;
3561 }
3562 return 0;
3563 }
3564
Hakjun Choibc6ce992023-11-07 16:04:33 +00003565 private int handleSetShouldSendDatagramToModemInDemoMode() {
3566 PrintWriter errPw = getErrPrintWriter();
3567 String opt;
3568 boolean shouldSendToDemoMode;
3569
3570 if ((opt = getNextArg()) == null) {
3571 errPw.println(
3572 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3573 + " Invalid Argument");
3574 return -1;
3575 } else {
3576 switch (opt) {
3577 case "true": {
3578 shouldSendToDemoMode = true;
3579 break;
3580 }
3581 case "false": {
3582 shouldSendToDemoMode = false;
3583 break;
3584 }
3585 default:
3586 errPw.println(
3587 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3588 + " Invalid Argument");
3589 return -1;
3590 }
3591 }
3592
3593 Log.d(LOG_TAG,
3594 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3595
3596 try {
3597 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3598 shouldSendToDemoMode);
3599 if (VDBG) {
3600 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3601 + result);
3602 }
3603 getOutPrintWriter().println(false);
3604 } catch (RemoteException e) {
3605 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3606 + "), error = " + e.getMessage());
3607 errPw.println("Exception: " + e.getMessage());
3608 return -1;
3609 }
3610 return 0;
3611 }
3612
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003613 private int handleSetSatelliteAccessControlOverlayConfigs() {
3614 PrintWriter errPw = getErrPrintWriter();
3615 boolean reset = false;
3616 boolean isAllowed = false;
3617 String s2CellFile = null;
3618 long locationFreshDurationNanos = 0;
3619 List<String> satelliteCountryCodes = null;
3620
3621 String opt;
3622 while ((opt = getNextOption()) != null) {
3623 switch (opt) {
3624 case "-r": {
3625 reset = true;
3626 break;
3627 }
3628 case "-a": {
3629 isAllowed = true;
3630 break;
3631 }
3632 case "-f": {
3633 s2CellFile = getNextArgRequired();
3634 break;
3635 }
3636 case "-d": {
3637 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3638 break;
3639 }
3640 case "-c": {
3641 String countryCodeStr = getNextArgRequired();
3642 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3643 break;
3644 }
3645 }
3646 }
3647 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3648 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3649 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3650 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3651
3652 try {
3653 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3654 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3655 if (VDBG) {
3656 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3657 }
3658 getOutPrintWriter().println(result);
3659 } catch (RemoteException e) {
3660 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3661 errPw.println("Exception: " + e.getMessage());
3662 return -1;
3663 }
3664 return 0;
3665 }
3666
3667 private int handleSetCountryCodes() {
3668 PrintWriter errPw = getErrPrintWriter();
3669 List<String> currentNetworkCountryCodes = new ArrayList<>();
3670 String locationCountryCode = null;
3671 long locationCountryCodeTimestampNanos = 0;
3672 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3673 boolean reset = false;
3674
3675 String opt;
3676 while ((opt = getNextOption()) != null) {
3677 switch (opt) {
3678 case "-r": {
3679 reset = true;
3680 break;
3681 }
3682 case "-n": {
3683 String countryCodeStr = getNextArgRequired();
3684 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3685 break;
3686 }
3687 case "-c": {
3688 String cachedNetworkCountryCodeStr = getNextArgRequired();
3689 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3690 break;
3691 }
3692 case "-l": {
3693 locationCountryCode = getNextArgRequired();
3694 break;
3695 }
3696 case "-t": {
3697 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3698 break;
3699 }
3700 }
3701 }
3702 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3703 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3704 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3705 + currentNetworkCountryCodes);
3706
3707 try {
3708 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3709 cachedNetworkCountryCodes, locationCountryCode,
3710 locationCountryCodeTimestampNanos);
3711 if (VDBG) {
3712 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3713 }
3714 getOutPrintWriter().println(result);
3715 } catch (RemoteException e) {
3716 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3717 errPw.println("Exception: " + e.getMessage());
3718 return -1;
3719 }
3720 return 0;
3721 }
3722
Thomas Nguyen3d602742024-01-19 11:29:35 -08003723 private int handleSetOemEnabledSatelliteProvisionStatus() {
3724 PrintWriter errPw = getErrPrintWriter();
3725 boolean isProvisioned = false;
3726 boolean reset = true;
3727
3728 String opt;
3729 while ((opt = getNextOption()) != null) {
3730 switch (opt) {
3731 case "-p": {
3732 try {
3733 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3734 reset = false;
3735 } catch (Exception e) {
3736 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3737 + "after -p indicating provision status");
3738 return -1;
3739 }
3740 }
3741 }
3742 }
3743 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3744 + ", isProvisioned=" + isProvisioned);
3745
3746 try {
3747 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3748 if (VDBG) {
3749 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3750 }
3751 getOutPrintWriter().println(result);
3752 } catch (RemoteException e) {
3753 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3754 errPw.println("Exception: " + e.getMessage());
3755 return -1;
3756 }
3757 return 0;
3758 }
3759
Hakjun Choi4a832d12024-05-28 22:23:55 +00003760 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3761 PrintWriter errPw = getErrPrintWriter();
3762 String opt;
3763 String state;
3764
3765 if ((opt = getNextArg()) == null) {
3766 errPw.println(
3767 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3768 + "-location-cache :"
3769 + " Invalid Argument");
3770 return -1;
3771 } else {
3772 switch (opt) {
3773 case "-a": {
3774 state = "cache_allowed";
3775 break;
3776 }
3777 case "-n": {
3778 state = "cache_clear_and_not_allowed";
3779 break;
3780 }
3781 case "-c": {
3782 state = "clear_cache_only";
3783 break;
3784 }
3785 default:
3786 errPw.println(
3787 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3788 + "-location-cache :"
3789 + " Invalid Argument");
3790 return -1;
3791 }
3792 }
3793
3794 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3795 + state + ")");
3796
3797 try {
3798 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3799 state);
3800 if (VDBG) {
3801 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3802 + "returns: "
3803 + result);
3804 }
3805 getOutPrintWriter().println(result);
3806 } catch (RemoteException e) {
3807 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3808 + state + "), error = " + e.getMessage());
3809 errPw.println("Exception: " + e.getMessage());
3810 return -1;
3811 }
3812 return 0;
3813 }
3814
Hyosund6aaf062024-08-23 23:02:10 +00003815 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3816 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3817 PrintWriter errPw = getErrPrintWriter();
3818 String opt;
3819 String name;
3820
3821 if ((opt = getNextArg()) == null) {
3822 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3823 return -1;
3824 } else {
3825 switch (opt) {
3826 case "-p": {
3827 name = opt + "/" + "android.telephony.cts";
3828 break;
3829 }
3830 case "-c": {
3831 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3832 break;
3833 }
3834 case "-r": {
3835 name = "reset";
3836 break;
3837 }
3838 default:
3839 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3840 return -1;
3841 }
3842 }
3843
3844 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3845 + name + ")");
3846
3847 try {
3848 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3849 if (VDBG) {
3850 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3851 + "returns: " + result);
3852 }
3853 getOutPrintWriter().println(result);
3854 } catch (RemoteException e) {
3855 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3856 + name + "), error = " + e.getMessage());
3857 errPw.println("Exception: " + e.getMessage());
3858 return -1;
3859 }
3860 return 0;
3861 }
3862
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003863 /**
3864 * Sample inputStr = "US,UK,CA;2,1,3"
3865 * Sample output: {[US,2], [UK,1], [CA,3]}
3866 */
3867 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3868 Map<String, Long> result = new HashMap<>();
3869 if (!TextUtils.isEmpty(inputStr)) {
3870 String[] stringLongArr = inputStr.split(";");
3871 if (stringLongArr.length != 2) {
3872 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3873 return result;
3874 }
3875
3876 String[] stringArr = stringLongArr[0].split(",");
3877 String[] longArr = stringLongArr[1].split(",");
3878 if (stringArr.length != longArr.length) {
3879 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3880 return result;
3881 }
3882
3883 for (int i = 0; i < stringArr.length; i++) {
3884 try {
3885 result.put(stringArr[i], Long.parseLong(longArr[i]));
3886 } catch (Exception ex) {
3887 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3888 + ", ex=" + ex);
3889 return result;
3890 }
3891 }
3892 }
3893 return result;
3894 }
3895
arunvoddud7401012022-12-15 16:08:12 +00003896 private int handleCarrierRestrictionStatusCommand() {
3897 try {
3898 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3899 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3900 mInterface.getModemService()))) {
3901 Log.v(LOG_TAG,
3902 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3903 + " checkShellUid fails");
3904 return -1;
3905 }
3906 } catch (RemoteException ex) {
3907 ex.printStackTrace();
3908 }
3909 String callerInfo = getNextOption();
3910 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3911 if (TextUtils.isEmpty(callerInfo)) {
3912 // reset the Json content after testing
3913 allowListInfo.updateJsonForTest(null);
3914 return 0;
3915 }
3916 if (callerInfo.startsWith("--")) {
3917 callerInfo = callerInfo.replace("--", "");
3918 }
3919 String params[] = callerInfo.split(",");
3920 StringBuffer jsonStrBuffer = new StringBuffer();
3921 String tokens;
3922 for (int index = 0; index < params.length; index++) {
3923 tokens = convertToJsonString(index, params[index]);
3924 if (TextUtils.isEmpty(tokens)) {
3925 // received wrong format from CTS
3926 if (VDBG) {
3927 Log.v(LOG_TAG,
3928 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3929 }
3930 return -1;
3931 }
3932 jsonStrBuffer.append(tokens);
3933 }
3934 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3935 return result;
3936 }
3937
Benedict Wong66477622023-02-03 23:30:57 +00003938 // set-carrier-service-package-override
3939 private int setCarrierServicePackageOverride() {
3940 PrintWriter errPw = getErrPrintWriter();
3941 int subId = SubscriptionManager.getDefaultSubscriptionId();
3942
3943 String opt;
3944 while ((opt = getNextOption()) != null) {
3945 switch (opt) {
3946 case "-s":
3947 try {
3948 subId = Integer.parseInt(getNextArgRequired());
3949 } catch (NumberFormatException e) {
3950 errPw.println(
3951 "set-carrier-service-package-override requires an integer as a"
3952 + " subscription ID.");
3953 return -1;
3954 }
3955 break;
3956 }
3957 }
3958
3959 String packageName = getNextArg();
3960 if (packageName == null) {
3961 errPw.println("set-carrier-service-package-override requires a override package name.");
3962 return -1;
3963 }
3964
3965 try {
3966 mInterface.setCarrierServicePackageOverride(
3967 subId, packageName, mContext.getOpPackageName());
3968
3969 if (VDBG) {
3970 Log.v(
3971 LOG_TAG,
3972 "set-carrier-service-package-override -s " + subId + " " + packageName);
3973 }
3974 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3975 Log.w(
3976 LOG_TAG,
3977 "set-carrier-service-package-override -s "
3978 + subId
3979 + " "
3980 + packageName
3981 + ", error"
3982 + e.getMessage());
3983 errPw.println("Exception: " + e.getMessage());
3984 return -1;
3985 }
3986 return 0;
3987 }
3988
3989 // clear-carrier-service-package-override
3990 private int clearCarrierServicePackageOverride() {
3991 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003992 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003993
3994 String opt;
3995 while ((opt = getNextOption()) != null) {
3996 switch (opt) {
3997 case "-s":
3998 try {
3999 subId = Integer.parseInt(getNextArgRequired());
4000 } catch (NumberFormatException e) {
4001 errPw.println(
4002 "clear-carrier-service-package-override requires an integer as a"
4003 + " subscription ID.");
4004 return -1;
4005 }
4006 break;
4007 }
4008 }
4009
4010 try {
4011 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
4012
4013 if (VDBG) {
4014 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
4015 }
4016 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
4017 Log.w(
4018 LOG_TAG,
4019 "clear-carrier-service-package-override -s "
4020 + subId
4021 + ", error"
4022 + e.getMessage());
4023 errPw.println("Exception: " + e.getMessage());
4024 return -1;
4025 }
4026 return 0;
4027 }
arunvoddud7401012022-12-15 16:08:12 +00004028
Hunsuk Choi13078be2023-09-13 10:55:21 +00004029 private int handleDomainSelectionCommand() {
4030 String arg = getNextArg();
4031 if (arg == null) {
4032 onHelpDomainSelection();
4033 return 0;
4034 }
4035
4036 switch (arg) {
4037 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
4038 return handleDomainSelectionSetServiceOverrideCommand();
4039 }
4040 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4041 return handleDomainSelectionClearServiceOverrideCommand();
4042 }
4043 }
4044
4045 return -1;
4046 }
4047
4048 // domainselection set-dss-override
4049 private int handleDomainSelectionSetServiceOverrideCommand() {
4050 PrintWriter errPw = getErrPrintWriter();
4051
4052 String componentName = getNextArg();
4053
4054 try {
4055 boolean result = mInterface.setDomainSelectionServiceOverride(
4056 ComponentName.unflattenFromString(componentName));
4057 if (VDBG) {
4058 Log.v(LOG_TAG, "domainselection set-dss-override "
4059 + componentName + ", result=" + result);
4060 }
4061 getOutPrintWriter().println(result);
4062 } catch (Exception e) {
4063 Log.w(LOG_TAG, "domainselection set-dss-override "
4064 + componentName + ", error=" + e.getMessage());
4065 errPw.println("Exception: " + e.getMessage());
4066 return -1;
4067 }
4068 return 0;
4069 }
4070
4071 // domainselection clear-dss-override
4072 private int handleDomainSelectionClearServiceOverrideCommand() {
4073 PrintWriter errPw = getErrPrintWriter();
4074
4075 try {
4076 boolean result = mInterface.clearDomainSelectionServiceOverride();
4077 if (VDBG) {
4078 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4079 }
4080 getOutPrintWriter().println(result);
4081 } catch (RemoteException e) {
4082 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4083 errPw.println("Exception: " + e.getMessage());
4084 return -1;
4085 }
4086 return 0;
4087 }
4088
arunvoddud7401012022-12-15 16:08:12 +00004089 /**
4090 * Building the string that can be used to build the JsonObject which supports to stub the data
4091 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004092 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004093 */
4094 private String convertToJsonString(int index, String param) {
4095
4096 String token[] = param.split(":");
4097 String jSonString;
4098 switch (index) {
4099 case 0:
4100 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4101 break;
4102 case 1:
4103 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004104 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004105 break;
4106 case 2:
4107 jSonString =
4108 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4109 break;
4110 default:
4111 jSonString = null;
4112 }
4113 return jSonString;
4114 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004115}