blob: 08b041b80957ce5a985aeb13494acec2cba5d61c [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080027import android.annotation.NonNull;
28import android.annotation.Nullable;
Hunsuk Choi13078be2023-09-13 10:55:21 +000029import android.content.ComponentName;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080031import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080032import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010033import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080034import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000036import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070037import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070038import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010039import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070040import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070041import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000042import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070043import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080044import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000045import android.telephony.ims.ImsException;
46import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080047import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080048import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000049import android.util.ArrayMap;
50import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070052import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070053
Brad Ebinger14d467f2021-02-12 06:18:28 +000054import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070055import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080056import com.android.internal.telephony.Phone;
57import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080058import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080059import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080060import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080061import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080062import com.android.phone.callcomposer.CallComposerPictureManager;
Shivakumar Neginal9cd61892022-12-19 04:38:52 +000063import com.android.phone.euicc.EuiccUiDispatcherActivity;
arunvoddud7401012022-12-15 16:08:12 +000064import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070065
Allen Xuee00f0e2022-03-14 21:04:49 +000066import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070067import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080068import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000069import java.util.Arrays;
70import java.util.Collections;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080071import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080072import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000073import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010074import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000075import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010076import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080077import java.util.UUID;
78import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070079
80/**
81 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
82 * permission checks have been done before onCommand was called. Make sure any commands processed
83 * here also contain the appropriate permissions checks.
84 */
85
Hall Liua1548bd2019-12-24 14:14:12 -080086public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087
88 private static final String LOG_TAG = "TelephonyShellCommand";
89 // Don't commit with this true.
90 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070091 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070092
Hall Liuaa4211e2021-01-20 15:43:39 -080093 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070094 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080095 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080096 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080097 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070098 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000099 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +0000100 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100101 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -0800102 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -0800103 private static final String ENABLE = "enable";
104 private static final String DISABLE = "disable";
105 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000106 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000107 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
108 "set-carrier-service-package-override";
109 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
110 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000111 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800112
Hall Liu7135e502021-02-04 16:58:17 -0800113 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800114 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800115 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800116
Brad Ebinger999d3302020-11-25 14:31:39 -0800117 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
118 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
119 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700120 // Used to disable or enable processing of conference event package data from the network.
121 // This is handy for testing scenarios where CEP data does not exist on a network which does
122 // support CEP data.
123 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700124
Hall Liud892bec2018-11-30 14:51:45 -0800125 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800126 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800127
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100128 private static final String CC_GET_VALUE = "get-value";
129 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000130 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100131 private static final String CC_CLEAR_VALUES = "clear-values";
132
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000133 private static final String EUICC_SUBCOMMAND = "euicc";
134 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
135
Hui Wang641e81c2020-10-12 12:14:23 -0700136 private static final String GBA_SUBCOMMAND = "gba";
137 private static final String GBA_SET_SERVICE = "set-service";
138 private static final String GBA_GET_SERVICE = "get-service";
139 private static final String GBA_SET_RELEASE_TIME = "set-release";
140 private static final String GBA_GET_RELEASE_TIME = "get-release";
141
Hui Wang761a6682020-10-31 05:12:53 +0000142 private static final String SINGLE_REGISTATION_CONFIG = "src";
143 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
144 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
145 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
146 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800147 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
148 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800149 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
150 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000151
Tyler Gunn92479152021-01-20 16:30:10 -0800152 private static final String D2D_SUBCOMMAND = "d2d";
153 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800154 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700155 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800156
Nazanin014f41e2021-05-06 17:26:31 -0700157 private static final String BARRING_SUBCOMMAND = "barring";
158 private static final String BARRING_SEND_INFO = "send";
159
James.cf Linbcdf8b32021-01-14 16:44:13 +0800160 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800161 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800162 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800163 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800164 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
165 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000166 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
167 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800168 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
169 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800170 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
171 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800172
jimsun3b9ccac2021-10-26 15:01:23 +0800173 private static final String RADIO_SUBCOMMAND = "radio";
174 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
175 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
176
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800177 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
178 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
179
Jordan Liu0ccee222021-04-27 11:55:13 -0700180 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
181 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
182
Jack Nudelman644b91a2021-03-12 14:09:48 -0800183 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
184 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
185 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700186 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
187 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700188 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
189 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700190 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
191 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700192 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
193 "set-satellite-pointing-ui-class-name";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800194 private static final String SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION =
195 "set-datagram-controller-timeout-duration";
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000196 private static final String SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG =
197 "set-datagram-controller-boolean-config";
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800198
199 private static final String SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION =
200 "set-satellite-controller-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700201 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
202 "set-emergency-call-to-satellite-handover-type";
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800203 private static final String SET_COUNTRY_CODES = "set-country-codes";
204 private static final String SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS =
205 "set-satellite-access-control-overlay-configs";
Thomas Nguyen3d602742024-01-19 11:29:35 -0800206 private static final String SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS =
207 "set-oem-enabled-satellite-provision-status";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000208 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
209 "set-should-send-datagram-to-modem-in-demo-mode";
Hakjun Choi4a832d12024-05-28 22:23:55 +0000210 private static final String SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE =
211 "set-is-satellite-communication-allowed-for-current-location-cache";
Hyosund6aaf062024-08-23 23:02:10 +0000212 private static final String SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT =
213 "set-satellite-subscriberid-list-changed-intent-component";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800214
Hunsuk Choi13078be2023-09-13 10:55:21 +0000215 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
216 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
217 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
218
Grant Menke567d48f2022-08-18 20:19:10 +0000219 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
220 + "'*', '#' or '+') needs to be specified after -a in the command ";
221
222 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
223 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
224 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
225
SongFerngWang98dd5992021-05-13 17:50:00 +0800226 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
227 "get-allowed-network-types-for-users";
228 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
229 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000230 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000231 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700232 // Take advantage of existing methods that already contain permissions checks when possible.
233 private final ITelephony mInterface;
234
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100235 private SubscriptionManager mSubscriptionManager;
236 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700237 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700238 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100239
240 private enum CcType {
241 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000242 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100243 }
244
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100245 private class CcOptionParseResult {
246 public int mSubId;
247 public boolean mPersistent;
248 }
249
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100250 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
251 // keys by looking at the end of the string which usually tells the type.
252 // For instance: "xxxx_string", "xxxx_string_array", etc.
253 // The carrier config keys in this map does not follow this convention. It is therefore not
254 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700255 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
256 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
257 CcType.STRING),
258 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
259 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
260 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
266 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
267 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
268 CcType.STRING),
269 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
270 CcType.STRING_ARRAY),
271 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
272 CcType.STRING_ARRAY),
273 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
274 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
275 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
276 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
279 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
280 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100281
Brad Ebinger14d467f2021-02-12 06:18:28 +0000282 /**
283 * Map from a shorthand string to the feature tags required in registration required in order
284 * for the RCS feature to be considered "capable".
285 */
286 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
287 static {
288 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
289 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
290 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
291 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
292 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
293 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
294 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
295 FeatureTags.FEATURE_TAG_VIDEO)));
296 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
297 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
298 map.put("call_comp",
299 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
300 map.put("call_comp_mmtel",
301 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
302 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
303 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
304 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
305 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
306 // version
307 map.put("chatbot", new ArraySet<>(Arrays.asList(
308 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
309 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
310 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
311 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000312 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000313 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
314 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
315 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
316 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
317 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000318 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000319 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
320 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
321 }
322
323
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100324 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700325 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100326 mCarrierConfigManager =
327 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
328 mSubscriptionManager = (SubscriptionManager)
329 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700330 mTelephonyRegistryManager = (TelephonyRegistryManager)
331 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700332 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700333 }
334
335 @Override
336 public int onCommand(String cmd) {
337 if (cmd == null) {
338 return handleDefaultCommands(null);
339 }
340
341 switch (cmd) {
342 case IMS_SUBCOMMAND: {
343 return handleImsCommand();
344 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800345 case RCS_UCE_COMMAND:
346 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800347 case NUMBER_VERIFICATION_SUBCOMMAND:
348 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800349 case EMERGENCY_CALLBACK_MODE:
350 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800351 case EMERGENCY_NUMBER_TEST_MODE:
352 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100353 case CARRIER_CONFIG_SUBCOMMAND: {
354 return handleCcCommand();
355 }
Shuo Qianf5125122019-12-16 17:03:07 -0800356 case DATA_TEST_MODE:
357 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700358 case END_BLOCK_SUPPRESSION:
359 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000360 case EUICC_SUBCOMMAND:
361 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700362 case GBA_SUBCOMMAND:
363 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800364 case D2D_SUBCOMMAND:
365 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700366 case BARRING_SUBCOMMAND:
367 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000368 case SINGLE_REGISTATION_CONFIG:
369 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000370 case RESTART_MODEM:
371 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800372 case CALL_COMPOSER_SUBCOMMAND:
373 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000374 case UNATTENDED_REBOOT:
375 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800376 case HAS_CARRIER_PRIVILEGES_COMMAND:
377 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800378 case THERMAL_MITIGATION_COMMAND:
379 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700380 case DISABLE_PHYSICAL_SUBSCRIPTION:
381 return handleEnablePhysicalSubscription(false);
382 case ENABLE_PHYSICAL_SUBSCRIPTION:
383 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800384 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
385 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
386 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000387 case GET_IMEI:
388 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000389 case GET_SIM_SLOTS_MAPPING:
390 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800391 case RADIO_SUBCOMMAND:
392 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000393 case CARRIER_RESTRICTION_STATUS_TEST:
394 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000395 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
396 return setCarrierServicePackageOverride();
397 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
398 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000399 case DOMAIN_SELECTION_SUBCOMMAND:
400 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700401 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
402 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700403 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
404 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700405 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
406 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700407 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
408 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800409 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
410 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000411 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
412 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800413 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
414 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700415 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
416 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000417 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
418 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800419 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
420 return handleSetSatelliteAccessControlOverlayConfigs();
421 case SET_COUNTRY_CODES:
422 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800423 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
424 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000425 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
426 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000427 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
428 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700429 default: {
430 return handleDefaultCommands(cmd);
431 }
432 }
433 }
434
435 @Override
436 public void onHelp() {
437 PrintWriter pw = getOutPrintWriter();
438 pw.println("Telephony Commands:");
439 pw.println(" help");
440 pw.println(" Print this help text.");
441 pw.println(" ims");
442 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800443 pw.println(" uce");
444 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800445 pw.println(" emergency-number-test-mode");
446 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700447 pw.println(" end-block-suppression");
448 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800449 pw.println(" data");
450 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100451 pw.println(" cc");
452 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700453 pw.println(" gba");
454 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000455 pw.println(" src");
456 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000457 pw.println(" restart-modem");
458 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000459 pw.println(" unattended-reboot");
460 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800461 pw.println(" has-carrier-privileges [package]");
462 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800463 pw.println(" get-allowed-network-types-for-users");
464 pw.println(" Get the Allowed Network Types.");
465 pw.println(" set-allowed-network-types-for-users");
466 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800467 pw.println(" radio");
468 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700469 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800470 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800471 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700472 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800473 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100474 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700475 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000476 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800477 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700478 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800479 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800480 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000481 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700482 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000483 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800484 }
485
486 private void onHelpD2D() {
487 PrintWriter pw = getOutPrintWriter();
488 pw.println("D2D Comms Commands:");
489 pw.println(" d2d send TYPE VALUE");
490 pw.println(" Sends a D2D message of specified type and value.");
491 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
492 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
493 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
494 MESSAGE_CALL_AUDIO_CODEC));
495 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
496 + Communicator.messageToString(
497 MESSAGE_DEVICE_BATTERY_STATE));
498 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
499 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800500 pw.println(" d2d transport TYPE");
501 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
502 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700503 pw.println(" d2d set-device-support true/default");
504 pw.println(" true - forces device support to be enabled for D2D.");
505 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
506 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700507 }
508
Nazanin014f41e2021-05-06 17:26:31 -0700509 private void onHelpBarring() {
510 PrintWriter pw = getOutPrintWriter();
511 pw.println("Barring Commands:");
512 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
513 + " -t CONDITIONAL_BARRING_TIME_SECS");
514 pw.println(" Notifies of a barring info change for the specified slot id.");
515 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
516 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
517 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
518 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
519 }
520
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700521 private void onHelpIms() {
522 PrintWriter pw = getOutPrintWriter();
523 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800524 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700525 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
526 pw.println(" ImsService. Options are:");
527 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
528 pw.println(" is specified, it will choose the default voice SIM slot.");
529 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
530 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800531 pw.println(" -f: Set the feature that this override if for, if no option is");
532 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700533 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
534 pw.println(" Gets the package name of the currently defined ImsService.");
535 pw.println(" Options are:");
536 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
537 pw.println(" is specified, it will choose the default voice SIM slot.");
538 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000539 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800540 pw.println(" -f: The feature type that the query will be requested for. If none is");
541 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800542 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
543 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
544 pw.println(" configuration overrides. Options are:");
545 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
546 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700547 pw.println(" ims enable [-s SLOT_ID]");
548 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
549 pw.println(" if none is specified.");
550 pw.println(" ims disable [-s SLOT_ID]");
551 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
552 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700553 pw.println(" ims conference-event-package [enable/disable]");
554 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700555 }
556
James.cf Linbcdf8b32021-01-14 16:44:13 +0800557 private void onHelpUce() {
558 PrintWriter pw = getOutPrintWriter();
559 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800560 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
561 pw.println(" Get the EAB contacts from the EAB database.");
562 pw.println(" Options are:");
563 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
564 pw.println(" Expected output format :");
565 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800566 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
567 pw.println(" Remove the EAB contacts from the EAB database.");
568 pw.println(" Options are:");
569 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
570 pw.println(" is specified, it will choose the default voice SIM slot.");
571 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800572 pw.println(" uce get-device-enabled");
573 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
574 pw.println(" uce set-device-enabled true|false");
575 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
576 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000577 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
578 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
579 pw.println(" Options are:");
580 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
581 pw.println(" is specified, it will choose the default voice SIM slot.");
582 pw.println(" add [CAPABILITY]: add a new capability");
583 pw.println(" remove [CAPABILITY]: remove a capability");
584 pw.println(" clear: clear all capability overrides");
585 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
586 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
587 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
588 pw.println(" chatbot_sa, chatbot_role] as well as full length");
589 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
590 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
591 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
592 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800593 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
594 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800595 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
596 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800597 }
598
Hall Liud892bec2018-11-30 14:51:45 -0800599 private void onHelpNumberVerification() {
600 PrintWriter pw = getOutPrintWriter();
601 pw.println("Number verification commands");
602 pw.println(" numverify override-package PACKAGE_NAME;");
603 pw.println(" Set the authorized package for number verification.");
604 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800605 pw.println(" numverify fake-call NUMBER;");
606 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
607 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800608 }
609
Jack Nudelman644b91a2021-03-12 14:09:48 -0800610 private void onHelpThermalMitigation() {
611 PrintWriter pw = getOutPrintWriter();
612 pw.println("Thermal mitigation commands");
613 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
614 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
615 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
616 pw.println(" Remove the package from one of the authorized packages for thermal "
617 + "mitigation.");
618 }
619
Jordan Liu0ccee222021-04-27 11:55:13 -0700620 private void onHelpDisableOrEnablePhysicalSubscription() {
621 PrintWriter pw = getOutPrintWriter();
622 pw.println("Disable or enable a physical subscription");
623 pw.println(" disable-physical-subscription SUB_ID");
624 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
625 pw.println(" enable-physical-subscription SUB_ID");
626 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
627 }
628
Shuo Qianf5125122019-12-16 17:03:07 -0800629 private void onHelpDataTestMode() {
630 PrintWriter pw = getOutPrintWriter();
631 pw.println("Mobile Data Test Mode Commands:");
632 pw.println(" data enable: enable mobile data connectivity");
633 pw.println(" data disable: disable mobile data connectivity");
634 }
635
sqian9d4df8b2019-01-15 18:32:07 -0800636 private void onHelpEmergencyNumber() {
637 PrintWriter pw = getOutPrintWriter();
638 pw.println("Emergency Number Test Mode Commands:");
639 pw.println(" emergency-number-test-mode ");
640 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
641 + " the test mode");
642 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700643 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800644 pw.println(" -c: clear the emergency number list in the test mode.");
645 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700646 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800647 pw.println(" -p: get the full emergency number list in the test mode.");
648 }
649
Shuo Qian489d9282020-07-09 11:30:03 -0700650 private void onHelpEndBlockSupperssion() {
651 PrintWriter pw = getOutPrintWriter();
652 pw.println("End Block Suppression command:");
653 pw.println(" end-block-suppression: disable suppressing blocking by contact");
654 pw.println(" with emergency services.");
655 }
656
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100657 private void onHelpCc() {
658 PrintWriter pw = getOutPrintWriter();
659 pw.println("Carrier Config Commands:");
660 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
661 pw.println(" Print carrier config values.");
662 pw.println(" Options are:");
663 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
664 pw.println(" is specified, it will choose the default voice SIM slot.");
665 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
666 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100667 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100668 pw.println(" Set carrier config KEY to NEW_VALUE.");
669 pw.println(" Options are:");
670 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
671 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100672 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100673 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
674 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
675 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
676 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000677 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
678 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
679 pw.println(" provided through standard input and follow CarrierConfig XML format.");
680 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
681 pw.println(" Options are:");
682 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
683 pw.println(" is specified, it will choose the default voice SIM slot.");
684 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100685 pw.println(" cc clear-values [-s SLOT_ID]");
686 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000687 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100688 pw.println(" Options are:");
689 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
690 pw.println(" is specified, it will choose the default voice SIM slot.");
691 }
692
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000693 private void onHelpEuicc() {
694 PrintWriter pw = getOutPrintWriter();
695 pw.println("Euicc Commands:");
696 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
697 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
698 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
699 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
700 }
701
Hui Wang641e81c2020-10-12 12:14:23 -0700702 private void onHelpGba() {
703 PrintWriter pw = getOutPrintWriter();
704 pw.println("Gba Commands:");
705 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
706 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
707 pw.println(" Options are:");
708 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
709 pw.println(" is specified, it will choose the default voice SIM slot.");
710 pw.println(" gba get-service [-s SLOT_ID]");
711 pw.println(" Gets the package name of the currently defined GbaService.");
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 set-release [-s SLOT_ID] n");
716 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
717 pw.println(" Do not release/unbind if n is -1.");
718 pw.println(" Options are:");
719 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
720 pw.println(" is specified, it will choose the default voice SIM slot.");
721 pw.println(" gba get-release [-s SLOT_ID]");
722 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
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 }
727
Hui Wang761a6682020-10-31 05:12:53 +0000728 private void onHelpSrc() {
729 PrintWriter pw = getOutPrintWriter();
730 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800731 pw.println(" src set-test-enabled true|false");
732 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
733 pw.println(" The value could be true, false, or null(undefined).");
734 pw.println(" src get-test-enabled");
735 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000736 pw.println(" src set-device-enabled true|false|null");
737 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
738 pw.println(" The value could be true, false, or null(undefined).");
739 pw.println(" src get-device-enabled");
740 pw.println(" Gets the device config for RCS VoLTE single registration.");
741 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
742 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
743 pw.println(" The value could be true, false, or null(undefined).");
744 pw.println(" Options are:");
745 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
746 pw.println(" is specified, it will choose the default voice SIM slot.");
747 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
748 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
749 pw.println(" Options are:");
750 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
751 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800752 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
753 pw.println(" Sets ims feature validation result.");
754 pw.println(" The value could be true, false, or null(undefined).");
755 pw.println(" Options are:");
756 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
757 pw.println(" is specified, it will choose the default voice SIM slot.");
758 pw.println(" src get-feature-validation [-s SLOT_ID]");
759 pw.println(" Gets ims feature validation override value.");
760 pw.println(" Options are:");
761 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
762 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000763 }
764
SongFerngWang98dd5992021-05-13 17:50:00 +0800765 private void onHelpAllowedNetworkTypes() {
766 PrintWriter pw = getOutPrintWriter();
767 pw.println("Allowed Network Types Commands:");
768 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
769 pw.println(" Print allowed network types value.");
770 pw.println(" Options are:");
771 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
772 pw.println(" option is specified, it will choose the default voice SIM slot.");
773 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
774 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
775 pw.println(" Options are:");
776 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
777 pw.println(" option is specified, it will choose the default voice SIM slot.");
778 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
779 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
780 pw.println(" at TelephonyManager.java");
781 pw.println(" For example:");
782 pw.println(" NR only : 10000000000000000000");
783 pw.println(" NR|LTE : 11000001000000000000");
784 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
785 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
786 pw.println(" LTE only : 01000001000000000000");
787 }
788
jimsun3b9ccac2021-10-26 15:01:23 +0800789 private void onHelpRadio() {
790 PrintWriter pw = getOutPrintWriter();
791 pw.println("Radio Commands:");
792 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
793 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
794 pw.println(" to be the bound. Options are:");
795 pw.println(" -s: the service name that the modem service should be bound for.");
796 pw.println(" If no option is specified, it will bind to the default.");
797 pw.println(" radio get-modem-service");
798 pw.println(" Gets the service name of the currently defined modem service.");
799 pw.println(" If it is binding to default, 'default' returns.");
800 pw.println(" If it doesn't bind to any modem service for some reasons,");
801 pw.println(" the result would be 'unknown'.");
802 }
803
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700804 private void onHelpSatellite() {
805 PrintWriter pw = getOutPrintWriter();
806 pw.println("Satellite Commands:");
807 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
808 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700809 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700810 pw.println(" -s: the satellite service package name that Telephony will bind to.");
811 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700812 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
813 pw.println(" Sets the package name of satellite gateway service defined in");
814 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
815 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
816 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700817 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
818 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
819 pw.println(" mode. Options are:");
820 pw.println(" -t: the timeout duration in milliseconds.");
821 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700822 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
823 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
824 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
825 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
826 pw.println(" launch. If no option is specified, it will launch the default.");
827 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
828 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700829 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
830 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
831 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
832 pw.println(" Options are:");
833 pw.println(" -t: the emergency call to satellite handover type.");
834 pw.println(" If no option is specified, override is disabled.");
835 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
836 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800837 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
838 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
839 pw.println(" configs of satellite access controller.");
840 pw.println(" Options are:");
841 pw.println(" -r: clear the overriding. Absent means enable overriding.");
842 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
843 pw.println(" -f: the satellite s2 file.");
844 pw.println(" -d: the location fresh duration nanos.");
845 pw.println(" -c: the list of satellite country codes separated by comma.");
846 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
847 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
848 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
849 pw.println(" Override the cached location country code and its update timestamp. ");
850 pw.println(" Options are:");
851 pw.println(" -r: clear the overriding. Absent means enable overriding.");
852 pw.println(" -n: the current network country code ISOs.");
853 pw.println(" -c: the cached network country code ISOs.");
854 pw.println(" -l: the location country code ISO.");
855 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800856 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
857 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
858 pw.println(" -p: the overriding satellite provision status. If no option is ");
859 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700860 }
861
Ling Ma4fbab492022-01-25 22:36:16 +0000862 private void onHelpImei() {
863 PrintWriter pw = getOutPrintWriter();
864 pw.println("IMEI Commands:");
865 pw.println(" get-imei [-s SLOT_ID]");
866 pw.println(" Gets the device IMEI. Options are:");
867 pw.println(" -s: the slot ID to get the IMEI. If no option");
868 pw.println(" is specified, it will choose the default voice SIM slot.");
869 }
870
Hunsuk Choi13078be2023-09-13 10:55:21 +0000871 private void onHelpDomainSelection() {
872 PrintWriter pw = getOutPrintWriter();
873 pw.println("Domain Selection Commands:");
874 pw.println(" domainselection set-dss-override COMPONENT_NAME");
875 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
876 pw.println(" domainselection clear-dss-override");
877 pw.println(" Clears DomainSelectionService override.");
878 }
879
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700880 private int handleImsCommand() {
881 String arg = getNextArg();
882 if (arg == null) {
883 onHelpIms();
884 return 0;
885 }
886
887 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800888 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700889 return handleImsSetServiceCommand();
890 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800891 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700892 return handleImsGetServiceCommand();
893 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800894 case IMS_CLEAR_SERVICE_OVERRIDE: {
895 return handleImsClearCarrierServiceCommand();
896 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800897 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700898 return handleEnableIms();
899 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800900 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700901 return handleDisableIms();
902 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700903 case IMS_CEP: {
904 return handleCepChange();
905 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700906 }
907
908 return -1;
909 }
910
Shuo Qianf5125122019-12-16 17:03:07 -0800911 private int handleDataTestModeCommand() {
912 PrintWriter errPw = getErrPrintWriter();
913 String arg = getNextArgRequired();
914 if (arg == null) {
915 onHelpDataTestMode();
916 return 0;
917 }
918 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800919 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800920 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700921 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800922 } catch (RemoteException ex) {
923 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
924 errPw.println("Exception: " + ex.getMessage());
925 return -1;
926 }
927 break;
928 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800929 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800930 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700931 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800932 } catch (RemoteException ex) {
933 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
934 errPw.println("Exception: " + ex.getMessage());
935 return -1;
936 }
937 break;
938 }
939 default:
940 onHelpDataTestMode();
941 break;
942 }
943 return 0;
944 }
945
Shuo Qianccbaf742021-02-22 18:32:21 -0800946 private int handleEmergencyCallbackModeCommand() {
947 PrintWriter errPw = getErrPrintWriter();
948 try {
949 mInterface.startEmergencyCallbackMode();
950 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
951 } catch (RemoteException ex) {
952 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
953 errPw.println("Exception: " + ex.getMessage());
954 return -1;
955 }
956 return 0;
957 }
958
Grant Menke567d48f2022-08-18 20:19:10 +0000959 private void removeEmergencyNumberTestMode(String emergencyNumber) {
960 PrintWriter errPw = getErrPrintWriter();
961 for (int routingType : ROUTING_TYPES) {
962 try {
963 mInterface.updateEmergencyNumberListTestMode(
964 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
965 new EmergencyNumber(emergencyNumber, "", "",
966 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
967 new ArrayList<String>(),
968 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
969 routingType));
970 } catch (RemoteException ex) {
971 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
972 errPw.println("Exception: " + ex.getMessage());
973 }
974 }
975 }
976
sqian9d4df8b2019-01-15 18:32:07 -0800977 private int handleEmergencyNumberTestModeCommand() {
978 PrintWriter errPw = getErrPrintWriter();
979 String opt = getNextOption();
980 if (opt == null) {
981 onHelpEmergencyNumber();
982 return 0;
983 }
sqian9d4df8b2019-01-15 18:32:07 -0800984 switch (opt) {
985 case "-a": {
986 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000987 if (emergencyNumberCmd == null){
988 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800989 return -1;
990 }
Grant Menke567d48f2022-08-18 20:19:10 +0000991 String[] params = emergencyNumberCmd.split(":");
992 String emergencyNumber;
993 if (params[0] == null ||
994 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
995 errPw.println(INVALID_ENTRY_ERROR);
996 return -1;
997 } else {
998 emergencyNumber = params[0];
999 }
1000 removeEmergencyNumberTestMode(emergencyNumber);
1001 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
1002 if (params.length > 1) {
1003 switch (params[1].toLowerCase(Locale.ROOT)) {
1004 case "emergency":
1005 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1006 break;
1007 case "normal":
1008 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1009 break;
1010 case "unknown":
1011 break;
1012 default:
1013 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1014 + "emergency call routing. Please enter either \"normal\", "
1015 + "\"unknown\", or \"emergency\" for call routing. "
1016 + "(-a 1234:normal)");
1017 return -1;
1018 }
1019 }
sqian9d4df8b2019-01-15 18:32:07 -08001020 try {
1021 mInterface.updateEmergencyNumberListTestMode(
1022 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001023 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001024 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1025 new ArrayList<String>(),
1026 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001027 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001028 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001029 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001030 + ", error " + ex.getMessage());
1031 errPw.println("Exception: " + ex.getMessage());
1032 return -1;
1033 }
1034 break;
1035 }
1036 case "-c": {
1037 try {
1038 mInterface.updateEmergencyNumberListTestMode(
1039 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1040 } catch (RemoteException ex) {
1041 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1042 errPw.println("Exception: " + ex.getMessage());
1043 return -1;
1044 }
1045 break;
1046 }
1047 case "-r": {
1048 String emergencyNumberCmd = getNextArgRequired();
1049 if (emergencyNumberCmd == null
1050 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001051 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001052 + " to be specified after -r in the command ");
1053 return -1;
1054 }
Grant Menke567d48f2022-08-18 20:19:10 +00001055 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001056 break;
1057 }
1058 case "-p": {
1059 try {
1060 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1061 } catch (RemoteException ex) {
1062 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1063 errPw.println("Exception: " + ex.getMessage());
1064 return -1;
1065 }
1066 break;
1067 }
1068 default:
1069 onHelpEmergencyNumber();
1070 break;
1071 }
1072 return 0;
1073 }
1074
Hall Liud892bec2018-11-30 14:51:45 -08001075 private int handleNumberVerificationCommand() {
1076 String arg = getNextArg();
1077 if (arg == null) {
1078 onHelpNumberVerification();
1079 return 0;
1080 }
1081
Hall Liuca5af3a2018-12-04 16:58:23 -08001082 if (!checkShellUid()) {
1083 return -1;
1084 }
1085
Hall Liud892bec2018-11-30 14:51:45 -08001086 switch (arg) {
1087 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001088 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1089 return 0;
1090 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001091 case NUMBER_VERIFICATION_FAKE_CALL: {
1092 boolean val = NumberVerificationManager.getInstance()
1093 .checkIncomingCall(getNextArg());
1094 getOutPrintWriter().println(val ? "1" : "0");
1095 return 0;
1096 }
Hall Liud892bec2018-11-30 14:51:45 -08001097 }
1098
1099 return -1;
1100 }
1101
Jordan Liu0ccee222021-04-27 11:55:13 -07001102 private boolean subIsEsim(int subId) {
1103 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1104 if (info != null) {
1105 return info.isEmbedded();
1106 }
1107 return false;
1108 }
1109
1110 private int handleEnablePhysicalSubscription(boolean enable) {
1111 PrintWriter errPw = getErrPrintWriter();
1112 int subId = 0;
1113 try {
1114 subId = Integer.parseInt(getNextArgRequired());
1115 } catch (NumberFormatException e) {
1116 errPw.println((enable ? "enable" : "disable")
1117 + "-physical-subscription requires an integer as a subId.");
1118 return -1;
1119 }
1120 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1121 // non user build.
1122 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1123 errPw.println("cc: Permission denied.");
1124 return -1;
1125 }
1126 // Verify that the subId represents a physical sub
1127 if (subIsEsim(subId)) {
1128 errPw.println("SubId " + subId + " is not for a physical subscription");
1129 return -1;
1130 }
1131 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1132 + " physical subscription with subId=" + subId);
1133 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1134 return 0;
1135 }
1136
Jack Nudelman644b91a2021-03-12 14:09:48 -08001137 private int handleThermalMitigationCommand() {
1138 String arg = getNextArg();
1139 String packageName = getNextArg();
1140 if (arg == null || packageName == null) {
1141 onHelpThermalMitigation();
1142 return 0;
1143 }
1144
1145 if (!checkShellUid()) {
1146 return -1;
1147 }
1148
1149 switch (arg) {
1150 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1151 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1152 return 0;
1153 }
1154 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1155 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1156 mContext);
1157 return 0;
1158 }
1159 default:
1160 onHelpThermalMitigation();
1161 }
1162
1163 return -1;
1164
1165 }
1166
Tyler Gunn92479152021-01-20 16:30:10 -08001167 private int handleD2dCommand() {
1168 String arg = getNextArg();
1169 if (arg == null) {
1170 onHelpD2D();
1171 return 0;
1172 }
1173
1174 switch (arg) {
1175 case D2D_SEND: {
1176 return handleD2dSendCommand();
1177 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001178 case D2D_TRANSPORT: {
1179 return handleD2dTransportCommand();
1180 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001181 case D2D_SET_DEVICE_SUPPORT: {
1182 return handleD2dDeviceSupportedCommand();
1183 }
Tyler Gunn92479152021-01-20 16:30:10 -08001184 }
1185
1186 return -1;
1187 }
1188
1189 private int handleD2dSendCommand() {
1190 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001191 int messageType = -1;
1192 int messageValue = -1;
1193
Tyler Gunn92479152021-01-20 16:30:10 -08001194 String arg = getNextArg();
1195 if (arg == null) {
1196 onHelpD2D();
1197 return 0;
1198 }
1199 try {
1200 messageType = Integer.parseInt(arg);
1201 } catch (NumberFormatException e) {
1202 errPw.println("message type must be a valid integer");
1203 return -1;
1204 }
1205
1206 arg = getNextArg();
1207 if (arg == null) {
1208 onHelpD2D();
1209 return 0;
1210 }
1211 try {
1212 messageValue = Integer.parseInt(arg);
1213 } catch (NumberFormatException e) {
1214 errPw.println("message value must be a valid integer");
1215 return -1;
1216 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001217
Tyler Gunn92479152021-01-20 16:30:10 -08001218 try {
1219 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1220 } catch (RemoteException e) {
1221 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1222 errPw.println("Exception: " + e.getMessage());
1223 return -1;
1224 }
1225
1226 return 0;
1227 }
1228
Tyler Gunnbabbda02021-02-10 11:05:02 -08001229 private int handleD2dTransportCommand() {
1230 PrintWriter errPw = getErrPrintWriter();
1231
1232 String arg = getNextArg();
1233 if (arg == null) {
1234 onHelpD2D();
1235 return 0;
1236 }
1237
1238 try {
1239 mInterface.setActiveDeviceToDeviceTransport(arg);
1240 } catch (RemoteException e) {
1241 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1242 errPw.println("Exception: " + e.getMessage());
1243 return -1;
1244 }
1245 return 0;
1246 }
Nazanin014f41e2021-05-06 17:26:31 -07001247 private int handleBarringCommand() {
1248 String arg = getNextArg();
1249 if (arg == null) {
1250 onHelpBarring();
1251 return 0;
1252 }
1253
1254 switch (arg) {
1255 case BARRING_SEND_INFO: {
1256 return handleBarringSendCommand();
1257 }
1258 }
1259 return -1;
1260 }
1261
1262 private int handleBarringSendCommand() {
1263 PrintWriter errPw = getErrPrintWriter();
1264 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001265 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001266 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1267 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1268 boolean isConditionallyBarred = false;
1269 int conditionalBarringTimeSeconds = 0;
1270
1271 String opt;
1272 while ((opt = getNextOption()) != null) {
1273 switch (opt) {
1274 case "-s": {
1275 try {
1276 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001277 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001278 } catch (NumberFormatException e) {
1279 errPw.println("barring send requires an integer as a SLOT_ID.");
1280 return -1;
1281 }
1282 break;
1283 }
1284 case "-b": {
1285 try {
1286 barringType = Integer.parseInt(getNextArgRequired());
1287 if (barringType < -1 || barringType > 2) {
1288 throw new NumberFormatException();
1289 }
1290
1291 } catch (NumberFormatException e) {
1292 errPw.println("barring send requires an integer in range [-1,2] as "
1293 + "a BARRING_TYPE.");
1294 return -1;
1295 }
1296 break;
1297 }
1298 case "-c": {
1299 try {
1300 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1301 } catch (Exception e) {
1302 errPw.println("barring send requires a boolean after -c indicating"
1303 + " conditional barring");
1304 return -1;
1305 }
1306 break;
1307 }
1308 case "-t": {
1309 try {
1310 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1311 } catch (NumberFormatException e) {
1312 errPw.println("barring send requires an integer for time of barring"
1313 + " in seconds after -t for conditional barring");
1314 return -1;
1315 }
1316 break;
1317 }
1318 }
1319 }
1320 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1321 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1322 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1323 barringServiceInfos.append(0, bsi);
1324 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1325 try {
1326 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1327 } catch (Exception e) {
1328 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1329 errPw.println("Exception: " + e.getMessage());
1330 return -1;
1331 }
1332 return 0;
1333 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001334
Tyler Gunnd4575212021-05-03 14:46:49 -07001335 private int handleD2dDeviceSupportedCommand() {
1336 PrintWriter errPw = getErrPrintWriter();
1337
1338 String arg = getNextArg();
1339 if (arg == null) {
1340 onHelpD2D();
1341 return 0;
1342 }
1343
Jack Yua533d632022-09-30 13:53:46 -07001344 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001345 try {
1346 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1347 } catch (RemoteException e) {
1348 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1349 errPw.println("Exception: " + e.getMessage());
1350 return -1;
1351 }
1352 return 0;
1353 }
1354
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001355 // ims set-ims-service
1356 private int handleImsSetServiceCommand() {
1357 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001358 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001359 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001360 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001361
1362 String opt;
1363 while ((opt = getNextOption()) != null) {
1364 switch (opt) {
1365 case "-s": {
1366 try {
1367 slotId = Integer.parseInt(getNextArgRequired());
1368 } catch (NumberFormatException e) {
1369 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1370 return -1;
1371 }
1372 break;
1373 }
1374 case "-c": {
1375 isCarrierService = true;
1376 break;
1377 }
1378 case "-d": {
1379 isCarrierService = false;
1380 break;
1381 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001382 case "-f": {
1383 String featureString = getNextArgRequired();
1384 String[] features = featureString.split(",");
1385 for (int i = 0; i < features.length; i++) {
1386 try {
1387 Integer result = Integer.parseInt(features[i]);
1388 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1389 || result >= ImsFeature.FEATURE_MAX) {
1390 errPw.println("ims set-ims-service -f " + result
1391 + " is an invalid feature.");
1392 return -1;
1393 }
1394 featuresList.add(result);
1395 } catch (NumberFormatException e) {
1396 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1397 + " as an integer.");
1398 return -1;
1399 }
1400 }
1401 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001402 }
1403 }
1404 // Mandatory param, either -c or -d
1405 if (isCarrierService == null) {
1406 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1407 return -1;
1408 }
1409
1410 String packageName = getNextArg();
1411
1412 try {
1413 if (packageName == null) {
1414 packageName = "";
1415 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001416 int[] featureArray = new int[featuresList.size()];
1417 for (int i = 0; i < featuresList.size(); i++) {
1418 featureArray[i] = featuresList.get(i);
1419 }
1420 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1421 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001422 if (VDBG) {
1423 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001424 + (isCarrierService ? "-c " : "-d ")
1425 + "-f " + featuresList + " "
1426 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001427 }
1428 getOutPrintWriter().println(result);
1429 } catch (RemoteException e) {
1430 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001431 + (isCarrierService ? "-c " : "-d ")
1432 + "-f " + featuresList + " "
1433 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001434 errPw.println("Exception: " + e.getMessage());
1435 return -1;
1436 }
1437 return 0;
1438 }
1439
Brad Ebinger999d3302020-11-25 14:31:39 -08001440 // ims clear-ims-service-override
1441 private int handleImsClearCarrierServiceCommand() {
1442 PrintWriter errPw = getErrPrintWriter();
1443 int slotId = getDefaultSlot();
1444
1445 String opt;
1446 while ((opt = getNextOption()) != null) {
1447 switch (opt) {
1448 case "-s": {
1449 try {
1450 slotId = Integer.parseInt(getNextArgRequired());
1451 } catch (NumberFormatException e) {
1452 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1453 return -1;
1454 }
1455 break;
1456 }
1457 }
1458 }
1459
1460 try {
1461 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1462 if (VDBG) {
1463 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1464 + ", result=" + result);
1465 }
1466 getOutPrintWriter().println(result);
1467 } catch (RemoteException e) {
1468 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1469 + ", error" + e.getMessage());
1470 errPw.println("Exception: " + e.getMessage());
1471 return -1;
1472 }
1473 return 0;
1474 }
1475
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001476 // ims get-ims-service
1477 private int handleImsGetServiceCommand() {
1478 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001479 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001480 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001481 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001482
1483 String opt;
1484 while ((opt = getNextOption()) != null) {
1485 switch (opt) {
1486 case "-s": {
1487 try {
1488 slotId = Integer.parseInt(getNextArgRequired());
1489 } catch (NumberFormatException e) {
1490 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1491 return -1;
1492 }
1493 break;
1494 }
1495 case "-c": {
1496 isCarrierService = true;
1497 break;
1498 }
1499 case "-d": {
1500 isCarrierService = false;
1501 break;
1502 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001503 case "-f": {
1504 try {
1505 featureType = Integer.parseInt(getNextArg());
1506 } catch (NumberFormatException e) {
1507 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1508 return -1;
1509 }
1510 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1511 || featureType >= ImsFeature.FEATURE_MAX) {
1512 errPw.println("ims get-ims-service -f invalid feature.");
1513 return -1;
1514 }
1515 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001516 }
1517 }
1518 // Mandatory param, either -c or -d
1519 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001520 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001521 return -1;
1522 }
1523
1524 String result;
1525 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001526 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001527 } catch (RemoteException e) {
1528 return -1;
1529 }
1530 if (VDBG) {
1531 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001532 + (isCarrierService ? "-c " : "-d ")
1533 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1534 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001535 }
1536 getOutPrintWriter().println(result);
1537 return 0;
1538 }
1539
1540 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001541 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001542 String opt;
1543 while ((opt = getNextOption()) != null) {
1544 switch (opt) {
1545 case "-s": {
1546 try {
1547 slotId = Integer.parseInt(getNextArgRequired());
1548 } catch (NumberFormatException e) {
1549 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1550 return -1;
1551 }
1552 break;
1553 }
1554 }
1555 }
1556 try {
1557 mInterface.enableIms(slotId);
1558 } catch (RemoteException e) {
1559 return -1;
1560 }
1561 if (VDBG) {
1562 Log.v(LOG_TAG, "ims enable -s " + slotId);
1563 }
1564 return 0;
1565 }
1566
1567 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001568 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001569 String opt;
1570 while ((opt = getNextOption()) != null) {
1571 switch (opt) {
1572 case "-s": {
1573 try {
1574 slotId = Integer.parseInt(getNextArgRequired());
1575 } catch (NumberFormatException e) {
1576 getErrPrintWriter().println(
1577 "ims disable requires an integer as a SLOT_ID.");
1578 return -1;
1579 }
1580 break;
1581 }
1582 }
1583 }
1584 try {
1585 mInterface.disableIms(slotId);
1586 } catch (RemoteException e) {
1587 return -1;
1588 }
1589 if (VDBG) {
1590 Log.v(LOG_TAG, "ims disable -s " + slotId);
1591 }
1592 return 0;
1593 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001594
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001595 private int handleCepChange() {
1596 Log.i(LOG_TAG, "handleCepChange");
1597 String opt = getNextArg();
1598 if (opt == null) {
1599 return -1;
1600 }
1601 boolean isCepEnabled = opt.equals("enable");
1602
1603 try {
1604 mInterface.setCepEnabled(isCepEnabled);
1605 } catch (RemoteException e) {
1606 return -1;
1607 }
1608 return 0;
1609 }
1610
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001611 private int getDefaultSlot() {
1612 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1613 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1614 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1615 // If there is no default, default to slot 0.
1616 slotId = DEFAULT_PHONE_ID;
1617 }
1618 return slotId;
1619 }
sqian2fff4a32018-11-05 14:18:37 -08001620
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001621 // Parse options related to Carrier Config Commands.
1622 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001623 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001624 CcOptionParseResult result = new CcOptionParseResult();
1625 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1626 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001627
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001628 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001629 while ((opt = getNextOption()) != null) {
1630 switch (opt) {
1631 case "-s": {
1632 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001633 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1634 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1635 errPw.println(tag + "No valid subscription found.");
1636 return null;
1637 }
1638
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001639 } catch (IllegalArgumentException e) {
1640 // Missing slot id
1641 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001642 return null;
1643 }
1644 break;
1645 }
1646 case "-p": {
1647 if (allowOptionPersistent) {
1648 result.mPersistent = true;
1649 } else {
1650 errPw.println(tag + "Unexpected option " + opt);
1651 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001652 }
1653 break;
1654 }
1655 default: {
1656 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001657 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001658 }
1659 }
1660 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001661 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001662 }
1663
1664 private int slotStringToSubId(String tag, String slotString) {
1665 int slotId = -1;
1666 try {
1667 slotId = Integer.parseInt(slotString);
1668 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001669 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1670 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1671 }
1672
1673 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001674 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1675 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1676 }
1677
Qiong Liuf25799b2020-09-10 10:13:46 +08001678 Phone phone = PhoneFactory.getPhone(slotId);
1679 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001680 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1681 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1682 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001683 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001684 }
1685
Hall Liud892bec2018-11-30 14:51:45 -08001686 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001687 // adb can run as root or as shell, depending on whether the device is rooted.
1688 return Binder.getCallingUid() == Process.SHELL_UID
1689 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001690 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001691
1692 private int handleCcCommand() {
1693 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1694 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001695 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001696 getErrPrintWriter().println("cc: Permission denied.");
1697 return -1;
1698 }
1699
1700 String arg = getNextArg();
1701 if (arg == null) {
1702 onHelpCc();
1703 return 0;
1704 }
1705
1706 switch (arg) {
1707 case CC_GET_VALUE: {
1708 return handleCcGetValue();
1709 }
1710 case CC_SET_VALUE: {
1711 return handleCcSetValue();
1712 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001713 case CC_SET_VALUES_FROM_XML: {
1714 return handleCcSetValuesFromXml();
1715 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001716 case CC_CLEAR_VALUES: {
1717 return handleCcClearValues();
1718 }
1719 default: {
1720 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1721 }
1722 }
1723 return -1;
1724 }
1725
1726 // cc get-value
1727 private int handleCcGetValue() {
1728 PrintWriter errPw = getErrPrintWriter();
1729 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1730 String key = null;
1731
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001732 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001733 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001734 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001735 return -1;
1736 }
1737
1738 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001739 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001740 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001741 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001742 return -1;
1743 }
1744
1745 // Get the key.
1746 key = getNextArg();
1747 if (key != null) {
1748 // A key was provided. Verify if it is a valid key
1749 if (!bundle.containsKey(key)) {
1750 errPw.println(tag + key + " is not a valid key.");
1751 return -1;
1752 }
1753
1754 // Print the carrier config value for key.
1755 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1756 } else {
1757 // No key provided. Show all values.
1758 // Iterate over a sorted list of all carrier config keys and print them.
1759 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1760 for (String k : sortedSet) {
1761 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1762 }
1763 }
1764 return 0;
1765 }
1766
1767 // cc set-value
1768 private int handleCcSetValue() {
1769 PrintWriter errPw = getErrPrintWriter();
1770 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1771
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001772 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001773 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001774 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001775 return -1;
1776 }
1777
1778 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001779 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001780 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001781 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001782 return -1;
1783 }
1784
1785 // Get the key.
1786 String key = getNextArg();
1787 if (key == null || key.equals("")) {
1788 errPw.println(tag + "KEY is missing");
1789 return -1;
1790 }
1791
1792 // Verify if the key is valid
1793 if (!originalValues.containsKey(key)) {
1794 errPw.println(tag + key + " is not a valid key.");
1795 return -1;
1796 }
1797
1798 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1799 ArrayList<String> valueList = new ArrayList<String>();
1800 while (peekNextArg() != null) {
1801 valueList.add(getNextArg());
1802 }
1803
1804 // Find the type of the carrier config value
1805 CcType type = getType(tag, key, originalValues);
1806 if (type == CcType.UNKNOWN) {
1807 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1808 return -1;
1809 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001810 if (type == CcType.PERSISTABLE_BUNDLE) {
1811 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1812 + "Use set-values-from-xml instead.");
1813 return -1;
1814 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001815
1816 // Create an override bundle containing the key and value that should be overriden.
1817 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1818 if (overrideBundle == null) {
1819 return -1;
1820 }
1821
1822 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001823 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001824
1825 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001826 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001827 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001828 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001829 return -1;
1830 }
1831
1832 // Print the original and new value.
1833 String originalValueString = ccValueToString(key, type, originalValues);
1834 String newValueString = ccValueToString(key, type, newValues);
1835 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1836 getOutPrintWriter().println("New value: \n" + newValueString);
1837
1838 return 0;
1839 }
1840
Allen Xuee00f0e2022-03-14 21:04:49 +00001841 // cc set-values-from-xml
1842 private int handleCcSetValuesFromXml() {
1843 PrintWriter errPw = getErrPrintWriter();
1844 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1845
1846 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001847 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001848 if (options == null) {
1849 return -1;
1850 }
1851
1852 // Get bundle containing all current carrier configuration values.
1853 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1854 if (originalValues == null) {
1855 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1856 return -1;
1857 }
1858
1859 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1860 if (overrideBundle == null) {
1861 return -1;
1862 }
1863
1864 // Verify all values are valid types
1865 for (String key : overrideBundle.keySet()) {
1866 CcType type = getType(tag, key, originalValues);
1867 if (type == CcType.UNKNOWN) {
1868 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1869 return -1;
1870 }
1871 }
1872
1873 // Override the value
1874 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1875
1876 // Find bundle containing all new carrier configuration values after the override.
1877 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1878 if (newValues == null) {
1879 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1880 return -1;
1881 }
1882
1883 // Print the original and new values
1884 overrideBundle.keySet().forEach(key -> {
1885 CcType type = getType(tag, key, originalValues);
1886 String originalValueString = ccValueToString(key, type, originalValues);
1887 String newValueString = ccValueToString(key, type, newValues);
1888 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1889 getOutPrintWriter().println("New value: \n" + newValueString);
1890 });
1891
1892 return 0;
1893 }
1894
1895 private PersistableBundle readPersistableBundleFromXml(String tag) {
1896 PersistableBundle subIdBundles;
1897 try {
1898 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1899 } catch (IOException | RuntimeException e) {
1900 PrintWriter errPw = getErrPrintWriter();
1901 errPw.println(tag + e);
1902 return null;
1903 }
1904
1905 return subIdBundles;
1906 }
1907
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001908 // cc clear-values
1909 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001910 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1911
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001912 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001913 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001914 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001915 return -1;
1916 }
1917
1918 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001919 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001920 getOutPrintWriter()
1921 .println("All previously set carrier config override values has been cleared");
1922 return 0;
1923 }
1924
1925 private CcType getType(String tag, String key, PersistableBundle bundle) {
1926 // Find the type by checking the type of the current value stored in the bundle.
1927 Object value = bundle.get(key);
1928
1929 if (CC_TYPE_MAP.containsKey(key)) {
1930 return CC_TYPE_MAP.get(key);
1931 } else if (value != null) {
1932 if (value instanceof Boolean) {
1933 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001934 }
1935 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001936 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001937 }
1938 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001939 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001940 }
1941 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001942 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001943 }
1944 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001945 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 }
1947 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001948 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001949 }
1950 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001951 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001952 }
1953 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001954 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 }
1956 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001957 return CcType.STRING_ARRAY;
1958 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001959 if (value instanceof PersistableBundle) {
1960 return CcType.PERSISTABLE_BUNDLE;
1961 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001962 } else {
1963 // Current value was null and can therefore not be used in order to find the type.
1964 // Check the name of the key to infer the type. This check is not needed for primitive
1965 // data types (boolean, double, int and long), since they can not be null.
1966 if (key.endsWith("double_array")) {
1967 return CcType.DOUBLE_ARRAY;
1968 }
1969 if (key.endsWith("int_array")) {
1970 return CcType.INT_ARRAY;
1971 }
1972 if (key.endsWith("long_array")) {
1973 return CcType.LONG_ARRAY;
1974 }
1975 if (key.endsWith("string")) {
1976 return CcType.STRING;
1977 }
1978 if (key.endsWith("string_array") || key.endsWith("strings")) {
1979 return CcType.STRING_ARRAY;
1980 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001981 if (key.endsWith("bundle")) {
1982 return CcType.PERSISTABLE_BUNDLE;
1983 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001984 }
1985
1986 // Not possible to infer the type by looking at the current value or the key.
1987 PrintWriter errPw = getErrPrintWriter();
1988 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1989 return CcType.UNKNOWN;
1990 }
1991
1992 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1993 String result;
1994 StringBuilder valueString = new StringBuilder();
1995 String typeString = type.toString();
1996 Object value = bundle.get(key);
1997
1998 if (value == null) {
1999 valueString.append("null");
2000 } else {
2001 switch (type) {
2002 case DOUBLE_ARRAY: {
2003 // Format the string representation of the int array as value1 value2......
2004 double[] valueArray = (double[]) value;
2005 for (int i = 0; i < valueArray.length; i++) {
2006 if (i != 0) {
2007 valueString.append(" ");
2008 }
2009 valueString.append(valueArray[i]);
2010 }
2011 break;
2012 }
2013 case INT_ARRAY: {
2014 // Format the string representation of the int array as value1 value2......
2015 int[] valueArray = (int[]) value;
2016 for (int i = 0; i < valueArray.length; i++) {
2017 if (i != 0) {
2018 valueString.append(" ");
2019 }
2020 valueString.append(valueArray[i]);
2021 }
2022 break;
2023 }
2024 case LONG_ARRAY: {
2025 // Format the string representation of the int array as value1 value2......
2026 long[] valueArray = (long[]) value;
2027 for (int i = 0; i < valueArray.length; i++) {
2028 if (i != 0) {
2029 valueString.append(" ");
2030 }
2031 valueString.append(valueArray[i]);
2032 }
2033 break;
2034 }
2035 case STRING: {
2036 valueString.append("\"" + value.toString() + "\"");
2037 break;
2038 }
2039 case STRING_ARRAY: {
2040 // Format the string representation of the string array as "value1" "value2"....
2041 String[] valueArray = (String[]) value;
2042 for (int i = 0; i < valueArray.length; i++) {
2043 if (i != 0) {
2044 valueString.append(" ");
2045 }
2046 if (valueArray[i] != null) {
2047 valueString.append("\"" + valueArray[i] + "\"");
2048 } else {
2049 valueString.append("null");
2050 }
2051 }
2052 break;
2053 }
2054 default: {
2055 valueString.append(value.toString());
2056 }
2057 }
2058 }
2059 return String.format("%-70s %-15s %s", key, typeString, valueString);
2060 }
2061
2062 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2063 ArrayList<String> valueList) {
2064 PrintWriter errPw = getErrPrintWriter();
2065 PersistableBundle bundle = new PersistableBundle();
2066
2067 // First verify that a valid number of values has been provided for the type.
2068 switch (type) {
2069 case BOOLEAN:
2070 case DOUBLE:
2071 case INT:
2072 case LONG: {
2073 if (valueList.size() != 1) {
2074 errPw.println(tag + "Expected 1 value for type " + type
2075 + ". Found: " + valueList.size());
2076 return null;
2077 }
2078 break;
2079 }
2080 case STRING: {
2081 if (valueList.size() > 1) {
2082 errPw.println(tag + "Expected 0 or 1 values for type " + type
2083 + ". Found: " + valueList.size());
2084 return null;
2085 }
2086 break;
2087 }
2088 }
2089
2090 // Parse the value according to type and add it to the Bundle.
2091 switch (type) {
2092 case BOOLEAN: {
2093 if ("true".equalsIgnoreCase(valueList.get(0))) {
2094 bundle.putBoolean(key, true);
2095 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2096 bundle.putBoolean(key, false);
2097 } else {
2098 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2099 return null;
2100 }
2101 break;
2102 }
2103 case DOUBLE: {
2104 try {
2105 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2106 } catch (NumberFormatException nfe) {
2107 // Not a valid double
2108 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2109 return null;
2110 }
2111 break;
2112 }
2113 case DOUBLE_ARRAY: {
2114 double[] valueDoubleArray = null;
2115 if (valueList.size() > 0) {
2116 valueDoubleArray = new double[valueList.size()];
2117 for (int i = 0; i < valueList.size(); i++) {
2118 try {
2119 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2120 } catch (NumberFormatException nfe) {
2121 // Not a valid double
2122 errPw.println(
2123 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2124 return null;
2125 }
2126 }
2127 }
2128 bundle.putDoubleArray(key, valueDoubleArray);
2129 break;
2130 }
2131 case INT: {
2132 try {
2133 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2134 } catch (NumberFormatException nfe) {
2135 // Not a valid integer
2136 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2137 return null;
2138 }
2139 break;
2140 }
2141 case INT_ARRAY: {
2142 int[] valueIntArray = null;
2143 if (valueList.size() > 0) {
2144 valueIntArray = new int[valueList.size()];
2145 for (int i = 0; i < valueList.size(); i++) {
2146 try {
2147 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2148 } catch (NumberFormatException nfe) {
2149 // Not a valid integer
2150 errPw.println(tag
2151 + "Unable to parse " + valueList.get(i) + " as an integer.");
2152 return null;
2153 }
2154 }
2155 }
2156 bundle.putIntArray(key, valueIntArray);
2157 break;
2158 }
2159 case LONG: {
2160 try {
2161 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2162 } catch (NumberFormatException nfe) {
2163 // Not a valid long
2164 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2165 return null;
2166 }
2167 break;
2168 }
2169 case LONG_ARRAY: {
2170 long[] valueLongArray = null;
2171 if (valueList.size() > 0) {
2172 valueLongArray = new long[valueList.size()];
2173 for (int i = 0; i < valueList.size(); i++) {
2174 try {
2175 valueLongArray[i] = Long.parseLong(valueList.get(i));
2176 } catch (NumberFormatException nfe) {
2177 // Not a valid long
2178 errPw.println(
2179 tag + "Unable to parse " + valueList.get(i) + " as a long");
2180 return null;
2181 }
2182 }
2183 }
2184 bundle.putLongArray(key, valueLongArray);
2185 break;
2186 }
2187 case STRING: {
2188 String value = null;
2189 if (valueList.size() > 0) {
2190 value = valueList.get(0);
2191 }
2192 bundle.putString(key, value);
2193 break;
2194 }
2195 case STRING_ARRAY: {
2196 String[] valueStringArray = null;
2197 if (valueList.size() > 0) {
2198 valueStringArray = new String[valueList.size()];
2199 valueList.toArray(valueStringArray);
2200 }
2201 bundle.putStringArray(key, valueStringArray);
2202 break;
2203 }
2204 }
2205 return bundle;
2206 }
Shuo Qian489d9282020-07-09 11:30:03 -07002207
2208 private int handleEndBlockSuppressionCommand() {
2209 if (!checkShellUid()) {
2210 return -1;
2211 }
2212
2213 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2214 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2215 }
2216 return 0;
2217 }
Hui Wang641e81c2020-10-12 12:14:23 -07002218
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002219 private int handleEuiccCommand() {
2220 String arg = getNextArg();
2221 if (arg == null) {
2222 onHelpEuicc();
2223 return 0;
2224 }
2225
2226 switch (arg) {
2227 case EUICC_SET_UI_COMPONENT: {
2228 return handleEuiccServiceCommand();
2229 }
2230 }
2231 return -1;
2232 }
2233
2234 private int handleEuiccServiceCommand() {
2235 String uiComponent = getNextArg();
2236 String packageName = getNextArg();
2237 if (packageName == null || uiComponent == null) {
2238 return -1;
2239 }
2240 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2241 if (VDBG) {
2242 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2243 + packageName);
2244 }
2245 return 0;
2246 }
2247
Michele Berionne54af4632020-12-28 20:23:16 +00002248 private int handleRestartModemCommand() {
2249 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2250 // non user build.
2251 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2252 getErrPrintWriter().println("RestartModem: Permission denied.");
2253 return -1;
2254 }
2255
2256 boolean result = TelephonyManager.getDefault().rebootRadio();
2257 getOutPrintWriter().println(result);
2258
2259 return result ? 0 : -1;
2260 }
2261
Ling Ma4fbab492022-01-25 22:36:16 +00002262 private int handleGetImei() {
2263 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2264 // non user build.
2265 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2266 getErrPrintWriter().println("Device IMEI: Permission denied.");
2267 return -1;
2268 }
2269
2270 final long identity = Binder.clearCallingIdentity();
2271
2272 String imei = null;
2273 String arg = getNextArg();
2274 if (arg != null) {
2275 try {
2276 int specifiedSlotIndex = Integer.parseInt(arg);
2277 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2278 } catch (NumberFormatException exception) {
2279 PrintWriter errPw = getErrPrintWriter();
2280 errPw.println("-s requires an integer as slot index.");
2281 return -1;
2282 }
2283
2284 } else {
2285 imei = TelephonyManager.from(mContext).getImei();
2286 }
2287 getOutPrintWriter().println("Device IMEI: " + imei);
2288
2289 Binder.restoreCallingIdentity(identity);
2290 return 0;
2291 }
2292
Michele Berionne5e411512020-11-13 02:36:59 +00002293 private int handleUnattendedReboot() {
2294 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2295 // non user build.
2296 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2297 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2298 return -1;
2299 }
2300
2301 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2302 getOutPrintWriter().println("result: " + result);
2303
2304 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2305 }
2306
Aman Gupta07124872022-02-09 08:02:14 +00002307 private int handleGetSimSlotsMapping() {
2308 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2309 // non user build.
2310 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2311 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2312 return -1;
2313 }
2314 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2315 String result = telephonyManager.getSimSlotMapping().toString();
2316 getOutPrintWriter().println("simSlotsMapping: " + result);
2317
2318 return 0;
2319 }
2320
Hui Wang641e81c2020-10-12 12:14:23 -07002321 private int handleGbaCommand() {
2322 String arg = getNextArg();
2323 if (arg == null) {
2324 onHelpGba();
2325 return 0;
2326 }
2327
2328 switch (arg) {
2329 case GBA_SET_SERVICE: {
2330 return handleGbaSetServiceCommand();
2331 }
2332 case GBA_GET_SERVICE: {
2333 return handleGbaGetServiceCommand();
2334 }
2335 case GBA_SET_RELEASE_TIME: {
2336 return handleGbaSetReleaseCommand();
2337 }
2338 case GBA_GET_RELEASE_TIME: {
2339 return handleGbaGetReleaseCommand();
2340 }
2341 }
2342
2343 return -1;
2344 }
2345
2346 private int getSubId(String cmd) {
2347 int slotId = getDefaultSlot();
2348 String opt = getNextOption();
2349 if (opt != null && opt.equals("-s")) {
2350 try {
2351 slotId = Integer.parseInt(getNextArgRequired());
2352 } catch (NumberFormatException e) {
2353 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2354 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2355 }
2356 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002357 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002358 }
2359
2360 private int handleGbaSetServiceCommand() {
2361 int subId = getSubId("gba set-service");
2362 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2363 return -1;
2364 }
2365
2366 String packageName = getNextArg();
2367 try {
2368 if (packageName == null) {
2369 packageName = "";
2370 }
2371 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2372 if (VDBG) {
2373 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2374 + packageName + ", result=" + result);
2375 }
2376 getOutPrintWriter().println(result);
2377 } catch (RemoteException e) {
2378 Log.w(LOG_TAG, "gba set-service " + subId + " "
2379 + packageName + ", error" + e.getMessage());
2380 getErrPrintWriter().println("Exception: " + e.getMessage());
2381 return -1;
2382 }
2383 return 0;
2384 }
2385
2386 private int handleGbaGetServiceCommand() {
2387 String result;
2388
2389 int subId = getSubId("gba get-service");
2390 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2391 return -1;
2392 }
2393
2394 try {
2395 result = mInterface.getBoundGbaService(subId);
2396 } catch (RemoteException e) {
2397 return -1;
2398 }
2399 if (VDBG) {
2400 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2401 }
2402 getOutPrintWriter().println(result);
2403 return 0;
2404 }
2405
2406 private int handleGbaSetReleaseCommand() {
2407 //the release time value could be -1
2408 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2409 : SubscriptionManager.getDefaultSubscriptionId();
2410 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2411 return -1;
2412 }
2413
2414 String intervalStr = getNextArg();
2415 if (intervalStr == null) {
2416 return -1;
2417 }
2418
2419 try {
2420 int interval = Integer.parseInt(intervalStr);
2421 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2422 if (VDBG) {
2423 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2424 + intervalStr + ", result=" + result);
2425 }
2426 getOutPrintWriter().println(result);
2427 } catch (NumberFormatException | RemoteException e) {
2428 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2429 + intervalStr + ", error" + e.getMessage());
2430 getErrPrintWriter().println("Exception: " + e.getMessage());
2431 return -1;
2432 }
2433 return 0;
2434 }
2435
2436 private int handleGbaGetReleaseCommand() {
2437 int subId = getSubId("gba get-release");
2438 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2439 return -1;
2440 }
2441
2442 int result = 0;
2443 try {
2444 result = mInterface.getGbaReleaseTime(subId);
2445 } catch (RemoteException e) {
2446 return -1;
2447 }
2448 if (VDBG) {
2449 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2450 }
2451 getOutPrintWriter().println(result);
2452 return 0;
2453 }
Hui Wang761a6682020-10-31 05:12:53 +00002454
2455 private int handleSingleRegistrationConfigCommand() {
2456 String arg = getNextArg();
2457 if (arg == null) {
2458 onHelpSrc();
2459 return 0;
2460 }
2461
2462 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002463 case SRC_SET_TEST_ENABLED: {
2464 return handleSrcSetTestEnabledCommand();
2465 }
2466 case SRC_GET_TEST_ENABLED: {
2467 return handleSrcGetTestEnabledCommand();
2468 }
Hui Wang761a6682020-10-31 05:12:53 +00002469 case SRC_SET_DEVICE_ENABLED: {
2470 return handleSrcSetDeviceEnabledCommand();
2471 }
2472 case SRC_GET_DEVICE_ENABLED: {
2473 return handleSrcGetDeviceEnabledCommand();
2474 }
2475 case SRC_SET_CARRIER_ENABLED: {
2476 return handleSrcSetCarrierEnabledCommand();
2477 }
2478 case SRC_GET_CARRIER_ENABLED: {
2479 return handleSrcGetCarrierEnabledCommand();
2480 }
Hui Wangb647abe2021-02-26 09:33:38 -08002481 case SRC_SET_FEATURE_ENABLED: {
2482 return handleSrcSetFeatureValidationCommand();
2483 }
2484 case SRC_GET_FEATURE_ENABLED: {
2485 return handleSrcGetFeatureValidationCommand();
2486 }
Hui Wang761a6682020-10-31 05:12:53 +00002487 }
2488
2489 return -1;
2490 }
2491
James.cf Linbcdf8b32021-01-14 16:44:13 +08002492 private int handleRcsUceCommand() {
2493 String arg = getNextArg();
2494 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002495 onHelpUce();
2496 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002497 }
2498
2499 switch (arg) {
2500 case UCE_REMOVE_EAB_CONTACT:
2501 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002502 case UCE_GET_EAB_CONTACT:
2503 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002504 case UCE_GET_EAB_CAPABILITY:
2505 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002506 case UCE_GET_DEVICE_ENABLED:
2507 return handleUceGetDeviceEnabledCommand();
2508 case UCE_SET_DEVICE_ENABLED:
2509 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002510 case UCE_OVERRIDE_PUBLISH_CAPS:
2511 return handleUceOverridePublishCaps();
2512 case UCE_GET_LAST_PIDF_XML:
2513 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002514 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2515 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002516 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2517 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002518 }
2519 return -1;
2520 }
2521
2522 private int handleRemovingEabContactCommand() {
2523 int subId = getSubId("uce remove-eab-contact");
2524 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2525 return -1;
2526 }
2527
2528 String phoneNumber = getNextArgRequired();
2529 if (TextUtils.isEmpty(phoneNumber)) {
2530 return -1;
2531 }
2532 int result = 0;
2533 try {
2534 result = mInterface.removeContactFromEab(subId, phoneNumber);
2535 } catch (RemoteException e) {
2536 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2537 getErrPrintWriter().println("Exception: " + e.getMessage());
2538 return -1;
2539 }
2540
2541 if (VDBG) {
2542 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2543 }
calvinpan293ea1b2021-02-04 17:52:13 +08002544 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002545 }
2546
calvinpane4a8a1d2021-01-25 13:51:18 +08002547 private int handleGettingEabContactCommand() {
2548 String phoneNumber = getNextArgRequired();
2549 if (TextUtils.isEmpty(phoneNumber)) {
2550 return -1;
2551 }
2552 String result = "";
2553 try {
2554 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002555 } catch (RemoteException e) {
2556 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2557 getErrPrintWriter().println("Exception: " + e.getMessage());
2558 return -1;
2559 }
2560
2561 if (VDBG) {
2562 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2563 }
calvinpan293ea1b2021-02-04 17:52:13 +08002564 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002565 return 0;
2566 }
2567
Calvin Pana1434322021-07-01 19:27:01 +08002568 private int handleGettingEabCapabilityCommand() {
2569 String phoneNumber = getNextArgRequired();
2570 if (TextUtils.isEmpty(phoneNumber)) {
2571 return -1;
2572 }
2573 String result = "";
2574 try {
2575 result = mInterface.getCapabilityFromEab(phoneNumber);
2576 } catch (RemoteException e) {
2577 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2578 getErrPrintWriter().println("Exception: " + e.getMessage());
2579 return -1;
2580 }
2581
2582 if (VDBG) {
2583 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2584 }
2585 getOutPrintWriter().println(result);
2586 return 0;
2587 }
2588
James.cf Lin4b784aa2021-01-31 03:25:15 +08002589 private int handleUceGetDeviceEnabledCommand() {
2590 boolean result = false;
2591 try {
2592 result = mInterface.getDeviceUceEnabled();
2593 } catch (RemoteException e) {
2594 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2595 return -1;
2596 }
2597 if (VDBG) {
2598 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2599 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002600 getOutPrintWriter().println(result);
2601 return 0;
2602 }
2603
James.cf Lin4b784aa2021-01-31 03:25:15 +08002604 private int handleUceSetDeviceEnabledCommand() {
2605 String enabledStr = getNextArg();
2606 if (TextUtils.isEmpty(enabledStr)) {
2607 return -1;
2608 }
2609
2610 try {
2611 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2612 mInterface.setDeviceUceEnabled(isEnabled);
2613 if (VDBG) {
2614 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2615 }
2616 } catch (NumberFormatException | RemoteException e) {
2617 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2618 getErrPrintWriter().println("Exception: " + e.getMessage());
2619 return -1;
2620 }
2621 return 0;
2622 }
2623
James.cf Line8713a42021-04-29 16:04:26 +08002624 private int handleUceRemoveRequestDisallowedStatus() {
2625 int subId = getSubId("uce remove-request-disallowed-status");
2626 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2627 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2628 return -1;
2629 }
2630 boolean result;
2631 try {
2632 result = mInterface.removeUceRequestDisallowedStatus(subId);
2633 } catch (RemoteException e) {
2634 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2635 return -1;
2636 }
2637 if (VDBG) {
2638 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2639 }
2640 getOutPrintWriter().println(result);
2641 return 0;
2642 }
2643
James.cf Lin0fc71b02021-05-25 01:37:38 +08002644 private int handleUceSetCapRequestTimeout() {
2645 int subId = getSubId("uce set-capabilities-request-timeout");
2646 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2647 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2648 return -1;
2649 }
2650 long timeoutAfterMs = Long.valueOf(getNextArg());
2651 boolean result;
2652 try {
2653 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2654 } catch (RemoteException e) {
2655 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2656 return -1;
2657 }
2658 if (VDBG) {
2659 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2660 }
2661 getOutPrintWriter().println(result);
2662 return 0;
2663 }
2664
Hui Wangbaaee6a2021-02-19 20:45:36 -08002665 private int handleSrcSetTestEnabledCommand() {
2666 String enabledStr = getNextArg();
2667 if (enabledStr == null) {
2668 return -1;
2669 }
2670
2671 try {
2672 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2673 if (VDBG) {
2674 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2675 }
2676 getOutPrintWriter().println("Done");
2677 } catch (NumberFormatException | RemoteException e) {
2678 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2679 getErrPrintWriter().println("Exception: " + e.getMessage());
2680 return -1;
2681 }
2682 return 0;
2683 }
2684
2685 private int handleSrcGetTestEnabledCommand() {
2686 boolean result = false;
2687 try {
2688 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2689 } catch (RemoteException e) {
2690 return -1;
2691 }
2692 if (VDBG) {
2693 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2694 }
2695 getOutPrintWriter().println(result);
2696 return 0;
2697 }
2698
Brad Ebinger14d467f2021-02-12 06:18:28 +00002699 private int handleUceOverridePublishCaps() {
2700 int subId = getSubId("uce override-published-caps");
2701 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2702 return -1;
2703 }
2704 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2705 String operation = getNextArgRequired();
2706 String caps = getNextArg();
2707 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2708 && !"list".equals(operation)) {
2709 getErrPrintWriter().println("Invalid operation: " + operation);
2710 return -1;
2711 }
2712
2713 // add/remove requires capabilities to be specified.
2714 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2715 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2716 + "specified");
2717 return -1;
2718 }
2719
2720 ArraySet<String> capSet = new ArraySet<>();
2721 if (!TextUtils.isEmpty(caps)) {
2722 String[] capArray = caps.split(":");
2723 for (String cap : capArray) {
2724 // Allow unknown tags to be passed in as well.
2725 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2726 }
2727 }
2728
2729 RcsContactUceCapability result = null;
2730 try {
2731 switch (operation) {
2732 case "add":
2733 result = mInterface.addUceRegistrationOverrideShell(subId,
2734 new ArrayList<>(capSet));
2735 break;
2736 case "remove":
2737 result = mInterface.removeUceRegistrationOverrideShell(subId,
2738 new ArrayList<>(capSet));
2739 break;
2740 case "clear":
2741 result = mInterface.clearUceRegistrationOverrideShell(subId);
2742 break;
2743 case "list":
2744 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2745 break;
2746 }
2747 } catch (RemoteException e) {
2748 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2749 getErrPrintWriter().println("Exception: " + e.getMessage());
2750 return -1;
2751 } catch (ServiceSpecificException sse) {
2752 // Reconstruct ImsException
2753 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2754 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2755 getErrPrintWriter().println("Exception: " + imsException);
2756 return -1;
2757 }
2758 if (result == null) {
2759 getErrPrintWriter().println("Service not available");
2760 return -1;
2761 }
2762 getOutPrintWriter().println(result);
2763 return 0;
2764 }
2765
2766 private int handleUceGetPidfXml() {
2767 int subId = getSubId("uce get-last-publish-pidf");
2768 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2769 return -1;
2770 }
2771
2772 String result;
2773 try {
2774 result = mInterface.getLastUcePidfXmlShell(subId);
2775 } catch (RemoteException e) {
2776 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2777 getErrPrintWriter().println("Exception: " + e.getMessage());
2778 return -1;
2779 } catch (ServiceSpecificException sse) {
2780 // Reconstruct ImsException
2781 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2782 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2783 getErrPrintWriter().println("Exception: " + imsException);
2784 return -1;
2785 }
2786 if (result == null) {
2787 getErrPrintWriter().println("Service not available");
2788 return -1;
2789 }
2790 getOutPrintWriter().println(result);
2791 return 0;
2792 }
2793
Hui Wang761a6682020-10-31 05:12:53 +00002794 private int handleSrcSetDeviceEnabledCommand() {
2795 String enabledStr = getNextArg();
2796 if (enabledStr == null) {
2797 return -1;
2798 }
2799
2800 try {
2801 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2802 if (VDBG) {
2803 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2804 }
2805 getOutPrintWriter().println("Done");
2806 } catch (NumberFormatException | RemoteException e) {
2807 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2808 getErrPrintWriter().println("Exception: " + e.getMessage());
2809 return -1;
2810 }
2811 return 0;
2812 }
2813
2814 private int handleSrcGetDeviceEnabledCommand() {
2815 boolean result = false;
2816 try {
2817 result = mInterface.getDeviceSingleRegistrationEnabled();
2818 } catch (RemoteException e) {
2819 return -1;
2820 }
2821 if (VDBG) {
2822 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2823 }
2824 getOutPrintWriter().println(result);
2825 return 0;
2826 }
2827
2828 private int handleSrcSetCarrierEnabledCommand() {
2829 //the release time value could be -1
2830 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2831 : SubscriptionManager.getDefaultSubscriptionId();
2832 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2833 return -1;
2834 }
2835
2836 String enabledStr = getNextArg();
2837 if (enabledStr == null) {
2838 return -1;
2839 }
2840
2841 try {
2842 boolean result =
2843 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2844 if (VDBG) {
2845 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2846 + enabledStr + ", result=" + result);
2847 }
2848 getOutPrintWriter().println(result);
2849 } catch (NumberFormatException | RemoteException e) {
2850 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2851 + enabledStr + ", error" + e.getMessage());
2852 getErrPrintWriter().println("Exception: " + e.getMessage());
2853 return -1;
2854 }
2855 return 0;
2856 }
2857
2858 private int handleSrcGetCarrierEnabledCommand() {
2859 int subId = getSubId("src get-carrier-enabled");
2860 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2861 return -1;
2862 }
2863
2864 boolean result = false;
2865 try {
2866 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2867 } catch (RemoteException e) {
2868 return -1;
2869 }
2870 if (VDBG) {
2871 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2872 }
2873 getOutPrintWriter().println(result);
2874 return 0;
2875 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002876
Hui Wangb647abe2021-02-26 09:33:38 -08002877 private int handleSrcSetFeatureValidationCommand() {
2878 //the release time value could be -1
2879 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2880 : SubscriptionManager.getDefaultSubscriptionId();
2881 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2882 return -1;
2883 }
2884
2885 String enabledStr = getNextArg();
2886 if (enabledStr == null) {
2887 return -1;
2888 }
2889
2890 try {
2891 boolean result =
2892 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2893 if (VDBG) {
2894 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2895 + enabledStr + ", result=" + result);
2896 }
2897 getOutPrintWriter().println(result);
2898 } catch (NumberFormatException | RemoteException e) {
2899 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2900 + enabledStr + ", error" + e.getMessage());
2901 getErrPrintWriter().println("Exception: " + e.getMessage());
2902 return -1;
2903 }
2904 return 0;
2905 }
2906
2907 private int handleSrcGetFeatureValidationCommand() {
2908 int subId = getSubId("src get-feature-validation");
2909 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2910 return -1;
2911 }
2912
2913 Boolean result = false;
2914 try {
2915 result = mInterface.getImsFeatureValidationOverride(subId);
2916 } catch (RemoteException e) {
2917 return -1;
2918 }
2919 if (VDBG) {
2920 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2921 }
2922 getOutPrintWriter().println(result);
2923 return 0;
2924 }
2925
2926
Hall Liuaa4211e2021-01-20 15:43:39 -08002927 private void onHelpCallComposer() {
2928 PrintWriter pw = getOutPrintWriter();
2929 pw.println("Call composer commands");
2930 pw.println(" callcomposer test-mode enable|disable|query");
2931 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2932 pw.println(" upload/download from carrier servers is disabled, and operations are");
2933 pw.println(" performed using emulated local files instead.");
2934 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2935 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2936 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002937 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2938 pw.println(" Enables or disables the user setting for call composer, as set by");
2939 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002940 }
2941
2942 private int handleCallComposerCommand() {
2943 String arg = getNextArg();
2944 if (arg == null) {
2945 onHelpCallComposer();
2946 return 0;
2947 }
2948
2949 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2950 "MODIFY_PHONE_STATE required for call composer shell cmds");
2951 switch (arg) {
2952 case CALL_COMPOSER_TEST_MODE: {
2953 String enabledStr = getNextArg();
2954 if (ENABLE.equals(enabledStr)) {
2955 CallComposerPictureManager.sTestMode = true;
2956 } else if (DISABLE.equals(enabledStr)) {
2957 CallComposerPictureManager.sTestMode = false;
2958 } else if (QUERY.equals(enabledStr)) {
2959 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2960 } else {
2961 onHelpCallComposer();
2962 return 1;
2963 }
2964 break;
2965 }
2966 case CALL_COMPOSER_SIMULATE_CALL: {
2967 int subscriptionId = Integer.valueOf(getNextArg());
2968 String uuidString = getNextArg();
2969 UUID uuid = UUID.fromString(uuidString);
2970 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2971 Binder.withCleanCallingIdentity(() -> {
2972 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2973 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2974 });
2975 try {
2976 Uri uri = storageUriFuture.get();
2977 getOutPrintWriter().println(String.valueOf(uri));
2978 } catch (Exception e) {
2979 throw new RuntimeException(e);
2980 }
2981 break;
2982 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002983 case CALL_COMPOSER_USER_SETTING: {
2984 try {
2985 int subscriptionId = Integer.valueOf(getNextArg());
2986 String enabledStr = getNextArg();
2987 if (ENABLE.equals(enabledStr)) {
2988 mInterface.setCallComposerStatus(subscriptionId,
2989 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2990 } else if (DISABLE.equals(enabledStr)) {
2991 mInterface.setCallComposerStatus(subscriptionId,
2992 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2993 } else if (QUERY.equals(enabledStr)) {
2994 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2995 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2996 } else {
2997 onHelpCallComposer();
2998 return 1;
2999 }
3000 } catch (RemoteException e) {
3001 e.printStackTrace(getOutPrintWriter());
3002 return 1;
3003 }
3004 break;
3005 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003006 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003007 return 0;
3008 }
Hall Liuaa4211e2021-01-20 15:43:39 -08003009
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003010 private int handleHasCarrierPrivilegesCommand() {
3011 String packageName = getNextArgRequired();
3012
3013 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003014 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003015 try {
3016 hasCarrierPrivileges =
3017 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3018 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3019 } catch (RemoteException e) {
3020 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3021 getErrPrintWriter().println("Exception: " + e.getMessage());
3022 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003023 } finally {
3024 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003025 }
3026
3027 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003028 return 0;
3029 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003030
3031 private int handleAllowedNetworkTypesCommand(String command) {
3032 if (!checkShellUid()) {
3033 return -1;
3034 }
3035
3036 PrintWriter errPw = getErrPrintWriter();
3037 String tag = command + ": ";
3038 String opt;
3039 int subId = -1;
3040 Log.v(LOG_TAG, command + " start");
3041
3042 while ((opt = getNextOption()) != null) {
3043 if (opt.equals("-s")) {
3044 try {
3045 subId = slotStringToSubId(tag, getNextArgRequired());
3046 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3047 errPw.println(tag + "No valid subscription found.");
3048 return -1;
3049 }
3050 } catch (IllegalArgumentException e) {
3051 // Missing slot id
3052 errPw.println(tag + "SLOT_ID expected after -s.");
3053 return -1;
3054 }
3055 } else {
3056 errPw.println(tag + "Unknown option " + opt);
3057 return -1;
3058 }
3059 }
3060
3061 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3062 return handleGetAllowedNetworkTypesCommand(subId);
3063 }
3064 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3065 return handleSetAllowedNetworkTypesCommand(subId);
3066 }
3067 return -1;
3068 }
3069
3070 private int handleGetAllowedNetworkTypesCommand(int subId) {
3071 PrintWriter errPw = getErrPrintWriter();
3072
3073 long result = -1;
3074 try {
3075 if (mInterface != null) {
3076 result = mInterface.getAllowedNetworkTypesForReason(subId,
3077 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3078 } else {
3079 throw new IllegalStateException("telephony service is null.");
3080 }
3081 } catch (RemoteException e) {
3082 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3083 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3084 return -1;
3085 }
3086
3087 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3088 return 0;
3089 }
3090
3091 private int handleSetAllowedNetworkTypesCommand(int subId) {
3092 PrintWriter errPw = getErrPrintWriter();
3093
3094 String bitmaskString = getNextArg();
3095 if (TextUtils.isEmpty(bitmaskString)) {
3096 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3097 return -1;
3098 }
3099 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3100 if (allowedNetworkTypes < 0) {
3101 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3102 return -1;
3103 }
3104 boolean result = false;
3105 try {
3106 if (mInterface != null) {
3107 result = mInterface.setAllowedNetworkTypesForReason(subId,
3108 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3109 } else {
3110 throw new IllegalStateException("telephony service is null.");
3111 }
3112 } catch (RemoteException e) {
3113 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3114 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3115 return -1;
3116 }
3117
3118 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3119 if (result) {
3120 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3121 }
3122 getOutPrintWriter().println(resultMessage);
3123 return 0;
3124 }
3125
3126 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3127 if (TextUtils.isEmpty(bitmaskString)) {
3128 return -1;
3129 }
3130 if (VDBG) {
3131 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3132 + ", length: " + bitmaskString.length());
3133 }
3134 try {
3135 return Long.parseLong(bitmaskString, 2);
3136 } catch (NumberFormatException e) {
3137 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3138 return -1;
3139 }
3140 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003141
jimsun3b9ccac2021-10-26 15:01:23 +08003142 private int handleRadioSetModemServiceCommand() {
3143 PrintWriter errPw = getErrPrintWriter();
3144 String serviceName = null;
3145
3146 String opt;
3147 while ((opt = getNextOption()) != null) {
3148 switch (opt) {
3149 case "-s": {
3150 serviceName = getNextArgRequired();
3151 break;
3152 }
3153 }
3154 }
3155
3156 try {
3157 boolean result = mInterface.setModemService(serviceName);
3158 if (VDBG) {
3159 Log.v(LOG_TAG,
3160 "RadioSetModemService " + serviceName + ", result = " + result);
3161 }
3162 getOutPrintWriter().println(result);
3163 } catch (RemoteException e) {
3164 Log.w(LOG_TAG,
3165 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3166 errPw.println("Exception: " + e.getMessage());
3167 return -1;
3168 }
3169 return 0;
3170 }
3171
3172 private int handleRadioGetModemServiceCommand() {
3173 PrintWriter errPw = getErrPrintWriter();
3174 String result;
3175
3176 try {
3177 result = mInterface.getModemService();
3178 getOutPrintWriter().println(result);
3179 } catch (RemoteException e) {
3180 errPw.println("Exception: " + e.getMessage());
3181 return -1;
3182 }
3183 if (VDBG) {
3184 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3185 }
3186 return 0;
3187 }
3188
3189 private int handleRadioCommand() {
3190 String arg = getNextArg();
3191 if (arg == null) {
3192 onHelpRadio();
3193 return 0;
3194 }
3195
3196 switch (arg) {
3197 case RADIO_SET_MODEM_SERVICE:
3198 return handleRadioSetModemServiceCommand();
3199
3200 case RADIO_GET_MODEM_SERVICE:
3201 return handleRadioGetModemServiceCommand();
3202 }
3203
3204 return -1;
3205 }
arunvoddud7401012022-12-15 16:08:12 +00003206
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003207 private int handleSetSatelliteServicePackageNameCommand() {
3208 PrintWriter errPw = getErrPrintWriter();
3209 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003210 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003211
3212 String opt;
3213 while ((opt = getNextOption()) != null) {
3214 switch (opt) {
3215 case "-s": {
3216 serviceName = getNextArgRequired();
3217 break;
3218 }
Hakjun Choic3393242024-06-26 18:02:08 +00003219
3220 case "-p": {
3221 provisioned = getNextArgRequired();
3222 break;
3223 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003224 }
3225 }
3226 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003227 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003228
3229 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003230 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003231 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003232 Log.v(LOG_TAG,
3233 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3234 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003235 }
3236 getOutPrintWriter().println(result);
3237 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003238 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3239 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003240 errPw.println("Exception: " + e.getMessage());
3241 return -1;
3242 }
Hakjun Choic3393242024-06-26 18:02:08 +00003243
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003244 return 0;
3245 }
3246
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003247 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3248 PrintWriter errPw = getErrPrintWriter();
3249 String serviceName = null;
3250
3251 String opt;
3252 while ((opt = getNextOption()) != null) {
3253 switch (opt) {
3254 case "-s": {
3255 serviceName = getNextArgRequired();
3256 break;
3257 }
3258 }
3259 }
3260 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3261 + serviceName);
3262
3263 try {
3264 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3265 if (VDBG) {
3266 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3267 + ", result = " + result);
3268 }
3269 getOutPrintWriter().println(result);
3270 } catch (RemoteException e) {
3271 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3272 + ", error = " + e.getMessage());
3273 errPw.println("Exception: " + e.getMessage());
3274 return -1;
3275 }
3276 return 0;
3277 }
3278
Thomas Nguyen87dce732023-04-20 18:27:16 -07003279 private int handleSetSatellitePointingUiClassNameCommand() {
3280 PrintWriter errPw = getErrPrintWriter();
3281 String packageName = null;
3282 String className = null;
3283
3284 String opt;
3285 while ((opt = getNextOption()) != null) {
3286 switch (opt) {
3287 case "-p": {
3288 packageName = getNextArgRequired();
3289 break;
3290 }
3291 case "-c": {
3292 className = getNextArgRequired();
3293 break;
3294 }
3295 }
3296 }
3297 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3298 + packageName + ", className=" + className);
3299
3300 try {
3301 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3302 if (VDBG) {
3303 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3304 }
3305 getOutPrintWriter().println(result);
3306 } catch (RemoteException e) {
3307 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3308 + ", error = " + e.getMessage());
3309 errPw.println("Exception: " + e.getMessage());
3310 return -1;
3311 }
3312 return 0;
3313 }
3314
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003315 private int handleSetEmergencyCallToSatelliteHandoverType() {
3316 PrintWriter errPw = getErrPrintWriter();
3317 int handoverType = -1;
3318 int delaySeconds = 0;
3319
3320 String opt;
3321 while ((opt = getNextOption()) != null) {
3322 switch (opt) {
3323 case "-t": {
3324 try {
3325 handoverType = Integer.parseInt(getNextArgRequired());
3326 } catch (NumberFormatException e) {
3327 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3328 + " for handoverType");
3329 return -1;
3330 }
3331 break;
3332 }
3333 case "-d": {
3334 try {
3335 delaySeconds = Integer.parseInt(getNextArgRequired());
3336 } catch (NumberFormatException e) {
3337 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3338 + " for delaySeconds");
3339 return -1;
3340 }
3341 break;
3342 }
3343 }
3344 }
3345 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3346 + handoverType + ", delaySeconds=" + delaySeconds);
3347
3348 try {
3349 boolean result =
3350 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3351 if (VDBG) {
3352 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3353 }
3354 getOutPrintWriter().println(result);
3355 } catch (RemoteException e) {
3356 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3357 + ", error = " + e.getMessage());
3358 errPw.println("Exception: " + e.getMessage());
3359 return -1;
3360 }
3361 return 0;
3362 }
3363
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003364 private int handleSetSatelliteListeningTimeoutDuration() {
3365 PrintWriter errPw = getErrPrintWriter();
3366 long timeoutMillis = 0;
3367
3368 String opt;
3369 while ((opt = getNextOption()) != null) {
3370 switch (opt) {
3371 case "-t": {
3372 timeoutMillis = Long.parseLong(getNextArgRequired());
3373 break;
3374 }
3375 }
3376 }
3377 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3378 + timeoutMillis);
3379
3380 try {
3381 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3382 if (VDBG) {
3383 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3384 + ", result = " + result);
3385 }
3386 getOutPrintWriter().println(result);
3387 } catch (RemoteException e) {
3388 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3389 + ", error = " + e.getMessage());
3390 errPw.println("Exception: " + e.getMessage());
3391 return -1;
3392 }
3393 return 0;
3394 }
3395
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003396 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003397 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003398 boolean reset = false;
3399 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003400 long timeoutMillis = 0;
3401
3402 String opt;
3403 while ((opt = getNextOption()) != null) {
3404 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003405 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003406 timeoutMillis = Long.parseLong(getNextArgRequired());
3407 break;
3408 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003409 case "-r": {
3410 reset = true;
3411 break;
3412 }
3413 case "-t": {
3414 timeoutType = Integer.parseInt(getNextArgRequired());
3415 break;
3416 }
Hakjun Choiae365972023-04-25 11:00:31 +00003417 }
3418 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003419 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3420 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003421
3422 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003423 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3424 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003425 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003426 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003427 + ", result = " + result);
3428 }
3429 getOutPrintWriter().println(result);
3430 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003431 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3432 + ", error = " + e.getMessage());
3433 errPw.println("Exception: " + e.getMessage());
3434 return -1;
3435 }
3436 return 0;
3437 }
3438
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003439 private int handleSetDatagramControllerBooleanConfig() {
3440 PrintWriter errPw = getErrPrintWriter();
3441 boolean reset = false;
3442 int booleanType = 0;
3443 boolean enable = false;
3444
3445 String opt;
3446 while ((opt = getNextOption()) != null) {
3447 switch (opt) {
3448 case "-d": {
3449 enable = Boolean.parseBoolean(getNextArgRequired());
3450 break;
3451 }
3452 case "-r": {
3453 reset = true;
3454 break;
3455 }
3456 case "-t": {
3457 booleanType = Integer.parseInt(getNextArgRequired());
3458 break;
3459 }
3460 }
3461 }
3462 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3463 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3464
3465 try {
3466 boolean result = mInterface.setDatagramControllerBooleanConfig(
3467 reset, booleanType, enable);
3468 if (VDBG) {
3469 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3470 }
3471 getOutPrintWriter().println(result);
3472 } catch (RemoteException e) {
3473 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3474 errPw.println("Exception: " + e.getMessage());
3475 return -1;
3476 }
3477 return 0;
3478 }
3479
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003480 private int handleSetSatelliteControllerTimeoutDuration() {
3481 PrintWriter errPw = getErrPrintWriter();
3482 boolean reset = false;
3483 int timeoutType = 0;
3484 long timeoutMillis = 0;
3485
3486 String opt;
3487 while ((opt = getNextOption()) != null) {
3488 switch (opt) {
3489 case "-d": {
3490 timeoutMillis = Long.parseLong(getNextArgRequired());
3491 break;
3492 }
3493 case "-r": {
3494 reset = true;
3495 break;
3496 }
3497 case "-t": {
3498 timeoutType = Integer.parseInt(getNextArgRequired());
3499 break;
3500 }
3501 }
3502 }
3503 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3504 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3505
3506 try {
3507 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3508 reset, timeoutType, timeoutMillis);
3509 if (VDBG) {
3510 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3511 + ", result = " + result);
3512 }
3513 getOutPrintWriter().println(result);
3514 } catch (RemoteException e) {
3515 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003516 + ", error = " + e.getMessage());
3517 errPw.println("Exception: " + e.getMessage());
3518 return -1;
3519 }
3520 return 0;
3521 }
3522
Hakjun Choibc6ce992023-11-07 16:04:33 +00003523 private int handleSetShouldSendDatagramToModemInDemoMode() {
3524 PrintWriter errPw = getErrPrintWriter();
3525 String opt;
3526 boolean shouldSendToDemoMode;
3527
3528 if ((opt = getNextArg()) == null) {
3529 errPw.println(
3530 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3531 + " Invalid Argument");
3532 return -1;
3533 } else {
3534 switch (opt) {
3535 case "true": {
3536 shouldSendToDemoMode = true;
3537 break;
3538 }
3539 case "false": {
3540 shouldSendToDemoMode = false;
3541 break;
3542 }
3543 default:
3544 errPw.println(
3545 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3546 + " Invalid Argument");
3547 return -1;
3548 }
3549 }
3550
3551 Log.d(LOG_TAG,
3552 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3553
3554 try {
3555 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3556 shouldSendToDemoMode);
3557 if (VDBG) {
3558 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3559 + result);
3560 }
3561 getOutPrintWriter().println(false);
3562 } catch (RemoteException e) {
3563 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3564 + "), error = " + e.getMessage());
3565 errPw.println("Exception: " + e.getMessage());
3566 return -1;
3567 }
3568 return 0;
3569 }
3570
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003571 private int handleSetSatelliteAccessControlOverlayConfigs() {
3572 PrintWriter errPw = getErrPrintWriter();
3573 boolean reset = false;
3574 boolean isAllowed = false;
3575 String s2CellFile = null;
3576 long locationFreshDurationNanos = 0;
3577 List<String> satelliteCountryCodes = null;
3578
3579 String opt;
3580 while ((opt = getNextOption()) != null) {
3581 switch (opt) {
3582 case "-r": {
3583 reset = true;
3584 break;
3585 }
3586 case "-a": {
3587 isAllowed = true;
3588 break;
3589 }
3590 case "-f": {
3591 s2CellFile = getNextArgRequired();
3592 break;
3593 }
3594 case "-d": {
3595 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3596 break;
3597 }
3598 case "-c": {
3599 String countryCodeStr = getNextArgRequired();
3600 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3601 break;
3602 }
3603 }
3604 }
3605 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3606 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3607 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3608 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3609
3610 try {
3611 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3612 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3613 if (VDBG) {
3614 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3615 }
3616 getOutPrintWriter().println(result);
3617 } catch (RemoteException e) {
3618 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3619 errPw.println("Exception: " + e.getMessage());
3620 return -1;
3621 }
3622 return 0;
3623 }
3624
3625 private int handleSetCountryCodes() {
3626 PrintWriter errPw = getErrPrintWriter();
3627 List<String> currentNetworkCountryCodes = new ArrayList<>();
3628 String locationCountryCode = null;
3629 long locationCountryCodeTimestampNanos = 0;
3630 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3631 boolean reset = false;
3632
3633 String opt;
3634 while ((opt = getNextOption()) != null) {
3635 switch (opt) {
3636 case "-r": {
3637 reset = true;
3638 break;
3639 }
3640 case "-n": {
3641 String countryCodeStr = getNextArgRequired();
3642 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3643 break;
3644 }
3645 case "-c": {
3646 String cachedNetworkCountryCodeStr = getNextArgRequired();
3647 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3648 break;
3649 }
3650 case "-l": {
3651 locationCountryCode = getNextArgRequired();
3652 break;
3653 }
3654 case "-t": {
3655 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3656 break;
3657 }
3658 }
3659 }
3660 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3661 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3662 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3663 + currentNetworkCountryCodes);
3664
3665 try {
3666 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3667 cachedNetworkCountryCodes, locationCountryCode,
3668 locationCountryCodeTimestampNanos);
3669 if (VDBG) {
3670 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3671 }
3672 getOutPrintWriter().println(result);
3673 } catch (RemoteException e) {
3674 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3675 errPw.println("Exception: " + e.getMessage());
3676 return -1;
3677 }
3678 return 0;
3679 }
3680
Thomas Nguyen3d602742024-01-19 11:29:35 -08003681 private int handleSetOemEnabledSatelliteProvisionStatus() {
3682 PrintWriter errPw = getErrPrintWriter();
3683 boolean isProvisioned = false;
3684 boolean reset = true;
3685
3686 String opt;
3687 while ((opt = getNextOption()) != null) {
3688 switch (opt) {
3689 case "-p": {
3690 try {
3691 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3692 reset = false;
3693 } catch (Exception e) {
3694 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3695 + "after -p indicating provision status");
3696 return -1;
3697 }
3698 }
3699 }
3700 }
3701 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3702 + ", isProvisioned=" + isProvisioned);
3703
3704 try {
3705 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3706 if (VDBG) {
3707 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3708 }
3709 getOutPrintWriter().println(result);
3710 } catch (RemoteException e) {
3711 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3712 errPw.println("Exception: " + e.getMessage());
3713 return -1;
3714 }
3715 return 0;
3716 }
3717
Hakjun Choi4a832d12024-05-28 22:23:55 +00003718 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3719 PrintWriter errPw = getErrPrintWriter();
3720 String opt;
3721 String state;
3722
3723 if ((opt = getNextArg()) == null) {
3724 errPw.println(
3725 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3726 + "-location-cache :"
3727 + " Invalid Argument");
3728 return -1;
3729 } else {
3730 switch (opt) {
3731 case "-a": {
3732 state = "cache_allowed";
3733 break;
3734 }
3735 case "-n": {
3736 state = "cache_clear_and_not_allowed";
3737 break;
3738 }
3739 case "-c": {
3740 state = "clear_cache_only";
3741 break;
3742 }
3743 default:
3744 errPw.println(
3745 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3746 + "-location-cache :"
3747 + " Invalid Argument");
3748 return -1;
3749 }
3750 }
3751
3752 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3753 + state + ")");
3754
3755 try {
3756 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3757 state);
3758 if (VDBG) {
3759 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3760 + "returns: "
3761 + result);
3762 }
3763 getOutPrintWriter().println(result);
3764 } catch (RemoteException e) {
3765 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3766 + state + "), error = " + e.getMessage());
3767 errPw.println("Exception: " + e.getMessage());
3768 return -1;
3769 }
3770 return 0;
3771 }
3772
Hyosund6aaf062024-08-23 23:02:10 +00003773 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3774 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3775 PrintWriter errPw = getErrPrintWriter();
3776 String opt;
3777 String name;
3778
3779 if ((opt = getNextArg()) == null) {
3780 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3781 return -1;
3782 } else {
3783 switch (opt) {
3784 case "-p": {
3785 name = opt + "/" + "android.telephony.cts";
3786 break;
3787 }
3788 case "-c": {
3789 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3790 break;
3791 }
3792 case "-r": {
3793 name = "reset";
3794 break;
3795 }
3796 default:
3797 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3798 return -1;
3799 }
3800 }
3801
3802 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3803 + name + ")");
3804
3805 try {
3806 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3807 if (VDBG) {
3808 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3809 + "returns: " + result);
3810 }
3811 getOutPrintWriter().println(result);
3812 } catch (RemoteException e) {
3813 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3814 + name + "), error = " + e.getMessage());
3815 errPw.println("Exception: " + e.getMessage());
3816 return -1;
3817 }
3818 return 0;
3819 }
3820
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003821 /**
3822 * Sample inputStr = "US,UK,CA;2,1,3"
3823 * Sample output: {[US,2], [UK,1], [CA,3]}
3824 */
3825 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3826 Map<String, Long> result = new HashMap<>();
3827 if (!TextUtils.isEmpty(inputStr)) {
3828 String[] stringLongArr = inputStr.split(";");
3829 if (stringLongArr.length != 2) {
3830 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3831 return result;
3832 }
3833
3834 String[] stringArr = stringLongArr[0].split(",");
3835 String[] longArr = stringLongArr[1].split(",");
3836 if (stringArr.length != longArr.length) {
3837 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3838 return result;
3839 }
3840
3841 for (int i = 0; i < stringArr.length; i++) {
3842 try {
3843 result.put(stringArr[i], Long.parseLong(longArr[i]));
3844 } catch (Exception ex) {
3845 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3846 + ", ex=" + ex);
3847 return result;
3848 }
3849 }
3850 }
3851 return result;
3852 }
3853
arunvoddud7401012022-12-15 16:08:12 +00003854 private int handleCarrierRestrictionStatusCommand() {
3855 try {
3856 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3857 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3858 mInterface.getModemService()))) {
3859 Log.v(LOG_TAG,
3860 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3861 + " checkShellUid fails");
3862 return -1;
3863 }
3864 } catch (RemoteException ex) {
3865 ex.printStackTrace();
3866 }
3867 String callerInfo = getNextOption();
3868 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3869 if (TextUtils.isEmpty(callerInfo)) {
3870 // reset the Json content after testing
3871 allowListInfo.updateJsonForTest(null);
3872 return 0;
3873 }
3874 if (callerInfo.startsWith("--")) {
3875 callerInfo = callerInfo.replace("--", "");
3876 }
3877 String params[] = callerInfo.split(",");
3878 StringBuffer jsonStrBuffer = new StringBuffer();
3879 String tokens;
3880 for (int index = 0; index < params.length; index++) {
3881 tokens = convertToJsonString(index, params[index]);
3882 if (TextUtils.isEmpty(tokens)) {
3883 // received wrong format from CTS
3884 if (VDBG) {
3885 Log.v(LOG_TAG,
3886 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3887 }
3888 return -1;
3889 }
3890 jsonStrBuffer.append(tokens);
3891 }
3892 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3893 return result;
3894 }
3895
Benedict Wong66477622023-02-03 23:30:57 +00003896 // set-carrier-service-package-override
3897 private int setCarrierServicePackageOverride() {
3898 PrintWriter errPw = getErrPrintWriter();
3899 int subId = SubscriptionManager.getDefaultSubscriptionId();
3900
3901 String opt;
3902 while ((opt = getNextOption()) != null) {
3903 switch (opt) {
3904 case "-s":
3905 try {
3906 subId = Integer.parseInt(getNextArgRequired());
3907 } catch (NumberFormatException e) {
3908 errPw.println(
3909 "set-carrier-service-package-override requires an integer as a"
3910 + " subscription ID.");
3911 return -1;
3912 }
3913 break;
3914 }
3915 }
3916
3917 String packageName = getNextArg();
3918 if (packageName == null) {
3919 errPw.println("set-carrier-service-package-override requires a override package name.");
3920 return -1;
3921 }
3922
3923 try {
3924 mInterface.setCarrierServicePackageOverride(
3925 subId, packageName, mContext.getOpPackageName());
3926
3927 if (VDBG) {
3928 Log.v(
3929 LOG_TAG,
3930 "set-carrier-service-package-override -s " + subId + " " + packageName);
3931 }
3932 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3933 Log.w(
3934 LOG_TAG,
3935 "set-carrier-service-package-override -s "
3936 + subId
3937 + " "
3938 + packageName
3939 + ", error"
3940 + e.getMessage());
3941 errPw.println("Exception: " + e.getMessage());
3942 return -1;
3943 }
3944 return 0;
3945 }
3946
3947 // clear-carrier-service-package-override
3948 private int clearCarrierServicePackageOverride() {
3949 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003950 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003951
3952 String opt;
3953 while ((opt = getNextOption()) != null) {
3954 switch (opt) {
3955 case "-s":
3956 try {
3957 subId = Integer.parseInt(getNextArgRequired());
3958 } catch (NumberFormatException e) {
3959 errPw.println(
3960 "clear-carrier-service-package-override requires an integer as a"
3961 + " subscription ID.");
3962 return -1;
3963 }
3964 break;
3965 }
3966 }
3967
3968 try {
3969 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3970
3971 if (VDBG) {
3972 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3973 }
3974 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3975 Log.w(
3976 LOG_TAG,
3977 "clear-carrier-service-package-override -s "
3978 + subId
3979 + ", error"
3980 + e.getMessage());
3981 errPw.println("Exception: " + e.getMessage());
3982 return -1;
3983 }
3984 return 0;
3985 }
arunvoddud7401012022-12-15 16:08:12 +00003986
Hunsuk Choi13078be2023-09-13 10:55:21 +00003987 private int handleDomainSelectionCommand() {
3988 String arg = getNextArg();
3989 if (arg == null) {
3990 onHelpDomainSelection();
3991 return 0;
3992 }
3993
3994 switch (arg) {
3995 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3996 return handleDomainSelectionSetServiceOverrideCommand();
3997 }
3998 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
3999 return handleDomainSelectionClearServiceOverrideCommand();
4000 }
4001 }
4002
4003 return -1;
4004 }
4005
4006 // domainselection set-dss-override
4007 private int handleDomainSelectionSetServiceOverrideCommand() {
4008 PrintWriter errPw = getErrPrintWriter();
4009
4010 String componentName = getNextArg();
4011
4012 try {
4013 boolean result = mInterface.setDomainSelectionServiceOverride(
4014 ComponentName.unflattenFromString(componentName));
4015 if (VDBG) {
4016 Log.v(LOG_TAG, "domainselection set-dss-override "
4017 + componentName + ", result=" + result);
4018 }
4019 getOutPrintWriter().println(result);
4020 } catch (Exception e) {
4021 Log.w(LOG_TAG, "domainselection set-dss-override "
4022 + componentName + ", error=" + e.getMessage());
4023 errPw.println("Exception: " + e.getMessage());
4024 return -1;
4025 }
4026 return 0;
4027 }
4028
4029 // domainselection clear-dss-override
4030 private int handleDomainSelectionClearServiceOverrideCommand() {
4031 PrintWriter errPw = getErrPrintWriter();
4032
4033 try {
4034 boolean result = mInterface.clearDomainSelectionServiceOverride();
4035 if (VDBG) {
4036 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4037 }
4038 getOutPrintWriter().println(result);
4039 } catch (RemoteException e) {
4040 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4041 errPw.println("Exception: " + e.getMessage());
4042 return -1;
4043 }
4044 return 0;
4045 }
4046
arunvoddud7401012022-12-15 16:08:12 +00004047 /**
4048 * Building the string that can be used to build the JsonObject which supports to stub the data
4049 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004050 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004051 */
4052 private String convertToJsonString(int index, String param) {
4053
4054 String token[] = param.split(":");
4055 String jSonString;
4056 switch (index) {
4057 case 0:
4058 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4059 break;
4060 case 1:
4061 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004062 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004063 break;
4064 case 2:
4065 jSonString =
4066 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4067 break;
4068 default:
4069 jSonString = null;
4070 }
4071 return jSonString;
4072 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004073}