blob: b9b2f586682a3142775254178ed616e59f34c3b4 [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080027import android.annotation.NonNull;
28import android.annotation.Nullable;
Hunsuk Choi13078be2023-09-13 10:55:21 +000029import android.content.ComponentName;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080031import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080032import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010033import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080034import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000036import android.os.ServiceSpecificException;
Jack Yu86374492024-09-16 13:05:44 -070037import android.os.UserHandle;
Shuo Qian489d9282020-07-09 11:30:03 -070038import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070039import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010040import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070041import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070042import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000043import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070044import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080045import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import android.telephony.ims.ImsException;
47import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080048import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080049import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000050import android.util.ArrayMap;
51import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070053import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070054
Brad Ebinger14d467f2021-02-12 06:18:28 +000055import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070056import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080057import com.android.internal.telephony.Phone;
58import com.android.internal.telephony.PhoneFactory;
Jack Yu26735292024-09-25 14:33:49 -070059import com.android.internal.telephony.TelephonyPermissions;
Tyler Gunn92479152021-01-20 16:30:10 -080060import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080061import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080062import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080063import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080064import com.android.phone.callcomposer.CallComposerPictureManager;
arunvoddud7401012022-12-15 16:08:12 +000065import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070066
Allen Xuee00f0e2022-03-14 21:04:49 +000067import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070068import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080069import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000070import java.util.Arrays;
71import java.util.Collections;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -080072import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080073import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000074import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010075import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000076import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010077import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080078import java.util.UUID;
79import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81/**
82 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
83 * permission checks have been done before onCommand was called. Make sure any commands processed
84 * here also contain the appropriate permissions checks.
85 */
86
Hall Liua1548bd2019-12-24 14:14:12 -080087public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070088
89 private static final String LOG_TAG = "TelephonyShellCommand";
90 // Don't commit with this true.
91 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070092 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070093
Hall Liuaa4211e2021-01-20 15:43:39 -080094 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070095 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080096 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080097 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080098 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070099 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +0000100 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +0000101 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100102 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -0800103 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -0800104 private static final String ENABLE = "enable";
105 private static final String DISABLE = "disable";
106 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000107 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000108 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
109 "set-carrier-service-package-override";
110 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
111 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000112 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800113
Hall Liu7135e502021-02-04 16:58:17 -0800114 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800115 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800116 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800117
Brad Ebinger999d3302020-11-25 14:31:39 -0800118 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
119 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
120 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700121 // Used to disable or enable processing of conference event package data from the network.
122 // This is handy for testing scenarios where CEP data does not exist on a network which does
123 // support CEP data.
124 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700125
Hall Liud892bec2018-11-30 14:51:45 -0800126 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800127 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800128
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100129 private static final String CC_GET_VALUE = "get-value";
130 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000131 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100132 private static final String CC_CLEAR_VALUES = "clear-values";
133
Hui Wang641e81c2020-10-12 12:14:23 -0700134 private static final String GBA_SUBCOMMAND = "gba";
135 private static final String GBA_SET_SERVICE = "set-service";
136 private static final String GBA_GET_SERVICE = "get-service";
137 private static final String GBA_SET_RELEASE_TIME = "set-release";
138 private static final String GBA_GET_RELEASE_TIME = "get-release";
139
Hui Wang761a6682020-10-31 05:12:53 +0000140 private static final String SINGLE_REGISTATION_CONFIG = "src";
141 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
142 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
143 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
144 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800145 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
146 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800147 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
148 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000149
Tyler Gunn92479152021-01-20 16:30:10 -0800150 private static final String D2D_SUBCOMMAND = "d2d";
151 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800152 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700153 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800154
Nazanin014f41e2021-05-06 17:26:31 -0700155 private static final String BARRING_SUBCOMMAND = "barring";
156 private static final String BARRING_SEND_INFO = "send";
157
James.cf Linbcdf8b32021-01-14 16:44:13 +0800158 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800159 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800160 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800161 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800162 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
163 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000164 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
165 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800166 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
167 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800168 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
169 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800170
jimsun3b9ccac2021-10-26 15:01:23 +0800171 private static final String RADIO_SUBCOMMAND = "radio";
172 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
173 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
174
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800175 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
176 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
177
Jordan Liu0ccee222021-04-27 11:55:13 -0700178 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
179 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
180
Jack Nudelman644b91a2021-03-12 14:09:48 -0800181 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
182 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
183 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700184 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
185 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700186 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
187 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700188 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
189 "set-satellite-listening-timeout-duration";
joonhunshinf46f0d62024-09-27 14:06:26 +0000190 private static final String SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE =
191 "set-satellite-ignore-cellular-service-state";
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();
Hui Wang641e81c2020-10-12 12:14:23 -0700360 case GBA_SUBCOMMAND:
361 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800362 case D2D_SUBCOMMAND:
363 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700364 case BARRING_SUBCOMMAND:
365 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000366 case SINGLE_REGISTATION_CONFIG:
367 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000368 case RESTART_MODEM:
369 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800370 case CALL_COMPOSER_SUBCOMMAND:
371 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000372 case UNATTENDED_REBOOT:
373 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800374 case HAS_CARRIER_PRIVILEGES_COMMAND:
375 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800376 case THERMAL_MITIGATION_COMMAND:
377 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700378 case DISABLE_PHYSICAL_SUBSCRIPTION:
379 return handleEnablePhysicalSubscription(false);
380 case ENABLE_PHYSICAL_SUBSCRIPTION:
381 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800382 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
383 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
384 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000385 case GET_IMEI:
386 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000387 case GET_SIM_SLOTS_MAPPING:
388 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800389 case RADIO_SUBCOMMAND:
390 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000391 case CARRIER_RESTRICTION_STATUS_TEST:
392 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000393 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
394 return setCarrierServicePackageOverride();
395 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
396 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000397 case DOMAIN_SELECTION_SUBCOMMAND:
398 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700399 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
400 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700401 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
402 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700403 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
404 return handleSetSatelliteListeningTimeoutDuration();
joonhunshinf46f0d62024-09-27 14:06:26 +0000405 case SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE:
406 return handleSetSatelliteIgnoreCellularServiceState();
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
Hui Wang641e81c2020-10-12 12:14:23 -0700693 private void onHelpGba() {
694 PrintWriter pw = getOutPrintWriter();
695 pw.println("Gba Commands:");
696 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
697 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
698 pw.println(" Options are:");
699 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
700 pw.println(" is specified, it will choose the default voice SIM slot.");
701 pw.println(" gba get-service [-s SLOT_ID]");
702 pw.println(" Gets the package name of the currently defined GbaService.");
703 pw.println(" Options are:");
704 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
705 pw.println(" is specified, it will choose the default voice SIM slot.");
706 pw.println(" gba set-release [-s SLOT_ID] n");
707 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
708 pw.println(" Do not release/unbind if n is -1.");
709 pw.println(" Options are:");
710 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
711 pw.println(" is specified, it will choose the default voice SIM slot.");
712 pw.println(" gba get-release [-s SLOT_ID]");
713 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
714 pw.println(" Options are:");
715 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
716 pw.println(" is specified, it will choose the default voice SIM slot.");
717 }
718
Hui Wang761a6682020-10-31 05:12:53 +0000719 private void onHelpSrc() {
720 PrintWriter pw = getOutPrintWriter();
721 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800722 pw.println(" src set-test-enabled true|false");
723 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
724 pw.println(" The value could be true, false, or null(undefined).");
725 pw.println(" src get-test-enabled");
726 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000727 pw.println(" src set-device-enabled true|false|null");
728 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
729 pw.println(" The value could be true, false, or null(undefined).");
730 pw.println(" src get-device-enabled");
731 pw.println(" Gets the device config for RCS VoLTE single registration.");
732 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
733 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
734 pw.println(" The value could be true, false, or null(undefined).");
735 pw.println(" Options are:");
736 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
737 pw.println(" is specified, it will choose the default voice SIM slot.");
738 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
739 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
740 pw.println(" Options are:");
741 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
742 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800743 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
744 pw.println(" Sets ims feature validation result.");
745 pw.println(" The value could be true, false, or null(undefined).");
746 pw.println(" Options are:");
747 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
748 pw.println(" is specified, it will choose the default voice SIM slot.");
749 pw.println(" src get-feature-validation [-s SLOT_ID]");
750 pw.println(" Gets ims feature validation override value.");
751 pw.println(" Options are:");
752 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
753 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000754 }
755
SongFerngWang98dd5992021-05-13 17:50:00 +0800756 private void onHelpAllowedNetworkTypes() {
757 PrintWriter pw = getOutPrintWriter();
758 pw.println("Allowed Network Types Commands:");
759 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
760 pw.println(" Print allowed network types value.");
761 pw.println(" Options are:");
762 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
763 pw.println(" option is specified, it will choose the default voice SIM slot.");
764 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
765 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
766 pw.println(" Options are:");
767 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
768 pw.println(" option is specified, it will choose the default voice SIM slot.");
769 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
770 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
771 pw.println(" at TelephonyManager.java");
772 pw.println(" For example:");
773 pw.println(" NR only : 10000000000000000000");
774 pw.println(" NR|LTE : 11000001000000000000");
775 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
776 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
777 pw.println(" LTE only : 01000001000000000000");
778 }
779
jimsun3b9ccac2021-10-26 15:01:23 +0800780 private void onHelpRadio() {
781 PrintWriter pw = getOutPrintWriter();
782 pw.println("Radio Commands:");
783 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
784 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
785 pw.println(" to be the bound. Options are:");
786 pw.println(" -s: the service name that the modem service should be bound for.");
787 pw.println(" If no option is specified, it will bind to the default.");
788 pw.println(" radio get-modem-service");
789 pw.println(" Gets the service name of the currently defined modem service.");
790 pw.println(" If it is binding to default, 'default' returns.");
791 pw.println(" If it doesn't bind to any modem service for some reasons,");
792 pw.println(" the result would be 'unknown'.");
793 }
794
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700795 private void onHelpSatellite() {
796 PrintWriter pw = getOutPrintWriter();
797 pw.println("Satellite Commands:");
798 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
799 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700800 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700801 pw.println(" -s: the satellite service package name that Telephony will bind to.");
802 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700803 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
804 pw.println(" Sets the package name of satellite gateway service defined in");
805 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
806 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
807 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700808 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
809 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
810 pw.println(" mode. Options are:");
811 pw.println(" -t: the timeout duration in milliseconds.");
812 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700813 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
814 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
815 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
816 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
817 pw.println(" launch. If no option is specified, it will launch the default.");
818 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
819 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700820 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
821 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
822 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
823 pw.println(" Options are:");
824 pw.println(" -t: the emergency call to satellite handover type.");
825 pw.println(" If no option is specified, override is disabled.");
826 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
827 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800828 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
829 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
830 pw.println(" configs of satellite access controller.");
831 pw.println(" Options are:");
832 pw.println(" -r: clear the overriding. Absent means enable overriding.");
833 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
834 pw.println(" -f: the satellite s2 file.");
835 pw.println(" -d: the location fresh duration nanos.");
836 pw.println(" -c: the list of satellite country codes separated by comma.");
837 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
838 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
839 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
840 pw.println(" Override the cached location country code and its update timestamp. ");
841 pw.println(" Options are:");
842 pw.println(" -r: clear the overriding. Absent means enable overriding.");
843 pw.println(" -n: the current network country code ISOs.");
844 pw.println(" -c: the cached network country code ISOs.");
845 pw.println(" -l: the location country code ISO.");
846 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800847 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
848 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
849 pw.println(" -p: the overriding satellite provision status. If no option is ");
850 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700851 }
852
Ling Ma4fbab492022-01-25 22:36:16 +0000853 private void onHelpImei() {
854 PrintWriter pw = getOutPrintWriter();
855 pw.println("IMEI Commands:");
856 pw.println(" get-imei [-s SLOT_ID]");
857 pw.println(" Gets the device IMEI. Options are:");
858 pw.println(" -s: the slot ID to get the IMEI. If no option");
859 pw.println(" is specified, it will choose the default voice SIM slot.");
860 }
861
Hunsuk Choi13078be2023-09-13 10:55:21 +0000862 private void onHelpDomainSelection() {
863 PrintWriter pw = getOutPrintWriter();
864 pw.println("Domain Selection Commands:");
865 pw.println(" domainselection set-dss-override COMPONENT_NAME");
866 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
867 pw.println(" domainselection clear-dss-override");
868 pw.println(" Clears DomainSelectionService override.");
869 }
870
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700871 private int handleImsCommand() {
872 String arg = getNextArg();
873 if (arg == null) {
874 onHelpIms();
875 return 0;
876 }
877
878 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800879 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700880 return handleImsSetServiceCommand();
881 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800882 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700883 return handleImsGetServiceCommand();
884 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800885 case IMS_CLEAR_SERVICE_OVERRIDE: {
886 return handleImsClearCarrierServiceCommand();
887 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800888 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700889 return handleEnableIms();
890 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800891 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700892 return handleDisableIms();
893 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700894 case IMS_CEP: {
895 return handleCepChange();
896 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700897 }
898
899 return -1;
900 }
901
Shuo Qianf5125122019-12-16 17:03:07 -0800902 private int handleDataTestModeCommand() {
903 PrintWriter errPw = getErrPrintWriter();
904 String arg = getNextArgRequired();
905 if (arg == null) {
906 onHelpDataTestMode();
907 return 0;
908 }
909 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800910 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800911 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700912 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800913 } catch (RemoteException ex) {
914 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
915 errPw.println("Exception: " + ex.getMessage());
916 return -1;
917 }
918 break;
919 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800920 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800921 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700922 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800923 } catch (RemoteException ex) {
924 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
925 errPw.println("Exception: " + ex.getMessage());
926 return -1;
927 }
928 break;
929 }
930 default:
931 onHelpDataTestMode();
932 break;
933 }
934 return 0;
935 }
936
Shuo Qianccbaf742021-02-22 18:32:21 -0800937 private int handleEmergencyCallbackModeCommand() {
938 PrintWriter errPw = getErrPrintWriter();
939 try {
940 mInterface.startEmergencyCallbackMode();
941 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
942 } catch (RemoteException ex) {
943 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
944 errPw.println("Exception: " + ex.getMessage());
945 return -1;
946 }
947 return 0;
948 }
949
Grant Menke567d48f2022-08-18 20:19:10 +0000950 private void removeEmergencyNumberTestMode(String emergencyNumber) {
951 PrintWriter errPw = getErrPrintWriter();
952 for (int routingType : ROUTING_TYPES) {
953 try {
954 mInterface.updateEmergencyNumberListTestMode(
955 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
956 new EmergencyNumber(emergencyNumber, "", "",
957 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
958 new ArrayList<String>(),
959 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
960 routingType));
961 } catch (RemoteException ex) {
962 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
963 errPw.println("Exception: " + ex.getMessage());
964 }
965 }
966 }
967
sqian9d4df8b2019-01-15 18:32:07 -0800968 private int handleEmergencyNumberTestModeCommand() {
969 PrintWriter errPw = getErrPrintWriter();
970 String opt = getNextOption();
971 if (opt == null) {
972 onHelpEmergencyNumber();
973 return 0;
974 }
sqian9d4df8b2019-01-15 18:32:07 -0800975 switch (opt) {
976 case "-a": {
977 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000978 if (emergencyNumberCmd == null){
979 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800980 return -1;
981 }
Grant Menke567d48f2022-08-18 20:19:10 +0000982 String[] params = emergencyNumberCmd.split(":");
983 String emergencyNumber;
984 if (params[0] == null ||
985 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
986 errPw.println(INVALID_ENTRY_ERROR);
987 return -1;
988 } else {
989 emergencyNumber = params[0];
990 }
991 removeEmergencyNumberTestMode(emergencyNumber);
992 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
993 if (params.length > 1) {
994 switch (params[1].toLowerCase(Locale.ROOT)) {
995 case "emergency":
996 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
997 break;
998 case "normal":
999 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1000 break;
1001 case "unknown":
1002 break;
1003 default:
1004 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1005 + "emergency call routing. Please enter either \"normal\", "
1006 + "\"unknown\", or \"emergency\" for call routing. "
1007 + "(-a 1234:normal)");
1008 return -1;
1009 }
1010 }
sqian9d4df8b2019-01-15 18:32:07 -08001011 try {
1012 mInterface.updateEmergencyNumberListTestMode(
1013 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001014 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001015 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1016 new ArrayList<String>(),
1017 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001018 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001019 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001020 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001021 + ", error " + ex.getMessage());
1022 errPw.println("Exception: " + ex.getMessage());
1023 return -1;
1024 }
1025 break;
1026 }
1027 case "-c": {
1028 try {
1029 mInterface.updateEmergencyNumberListTestMode(
1030 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1031 } catch (RemoteException ex) {
1032 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1033 errPw.println("Exception: " + ex.getMessage());
1034 return -1;
1035 }
1036 break;
1037 }
1038 case "-r": {
1039 String emergencyNumberCmd = getNextArgRequired();
1040 if (emergencyNumberCmd == null
1041 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001042 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001043 + " to be specified after -r in the command ");
1044 return -1;
1045 }
Grant Menke567d48f2022-08-18 20:19:10 +00001046 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001047 break;
1048 }
1049 case "-p": {
1050 try {
1051 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1052 } catch (RemoteException ex) {
1053 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1054 errPw.println("Exception: " + ex.getMessage());
1055 return -1;
1056 }
1057 break;
1058 }
1059 default:
1060 onHelpEmergencyNumber();
1061 break;
1062 }
1063 return 0;
1064 }
1065
Hall Liud892bec2018-11-30 14:51:45 -08001066 private int handleNumberVerificationCommand() {
1067 String arg = getNextArg();
1068 if (arg == null) {
1069 onHelpNumberVerification();
1070 return 0;
1071 }
1072
Hall Liuca5af3a2018-12-04 16:58:23 -08001073 if (!checkShellUid()) {
1074 return -1;
1075 }
1076
Hall Liud892bec2018-11-30 14:51:45 -08001077 switch (arg) {
1078 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001079 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1080 return 0;
1081 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001082 case NUMBER_VERIFICATION_FAKE_CALL: {
1083 boolean val = NumberVerificationManager.getInstance()
1084 .checkIncomingCall(getNextArg());
1085 getOutPrintWriter().println(val ? "1" : "0");
1086 return 0;
1087 }
Hall Liud892bec2018-11-30 14:51:45 -08001088 }
1089
1090 return -1;
1091 }
1092
Jordan Liu0ccee222021-04-27 11:55:13 -07001093 private boolean subIsEsim(int subId) {
1094 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1095 if (info != null) {
1096 return info.isEmbedded();
1097 }
1098 return false;
1099 }
1100
1101 private int handleEnablePhysicalSubscription(boolean enable) {
1102 PrintWriter errPw = getErrPrintWriter();
1103 int subId = 0;
1104 try {
1105 subId = Integer.parseInt(getNextArgRequired());
1106 } catch (NumberFormatException e) {
1107 errPw.println((enable ? "enable" : "disable")
1108 + "-physical-subscription requires an integer as a subId.");
1109 return -1;
1110 }
1111 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1112 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001113 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1114 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001115 errPw.println("cc: Permission denied.");
1116 return -1;
1117 }
1118 // Verify that the subId represents a physical sub
1119 if (subIsEsim(subId)) {
1120 errPw.println("SubId " + subId + " is not for a physical subscription");
1121 return -1;
1122 }
1123 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1124 + " physical subscription with subId=" + subId);
1125 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1126 return 0;
1127 }
1128
Jack Nudelman644b91a2021-03-12 14:09:48 -08001129 private int handleThermalMitigationCommand() {
1130 String arg = getNextArg();
1131 String packageName = getNextArg();
1132 if (arg == null || packageName == null) {
1133 onHelpThermalMitigation();
1134 return 0;
1135 }
1136
1137 if (!checkShellUid()) {
1138 return -1;
1139 }
1140
1141 switch (arg) {
1142 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1143 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1144 return 0;
1145 }
1146 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1147 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1148 mContext);
1149 return 0;
1150 }
1151 default:
1152 onHelpThermalMitigation();
1153 }
1154
1155 return -1;
1156
1157 }
1158
Tyler Gunn92479152021-01-20 16:30:10 -08001159 private int handleD2dCommand() {
1160 String arg = getNextArg();
1161 if (arg == null) {
1162 onHelpD2D();
1163 return 0;
1164 }
1165
1166 switch (arg) {
1167 case D2D_SEND: {
1168 return handleD2dSendCommand();
1169 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001170 case D2D_TRANSPORT: {
1171 return handleD2dTransportCommand();
1172 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001173 case D2D_SET_DEVICE_SUPPORT: {
1174 return handleD2dDeviceSupportedCommand();
1175 }
Tyler Gunn92479152021-01-20 16:30:10 -08001176 }
1177
1178 return -1;
1179 }
1180
1181 private int handleD2dSendCommand() {
1182 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001183 int messageType = -1;
1184 int messageValue = -1;
1185
Tyler Gunn92479152021-01-20 16:30:10 -08001186 String arg = getNextArg();
1187 if (arg == null) {
1188 onHelpD2D();
1189 return 0;
1190 }
1191 try {
1192 messageType = Integer.parseInt(arg);
1193 } catch (NumberFormatException e) {
1194 errPw.println("message type must be a valid integer");
1195 return -1;
1196 }
1197
1198 arg = getNextArg();
1199 if (arg == null) {
1200 onHelpD2D();
1201 return 0;
1202 }
1203 try {
1204 messageValue = Integer.parseInt(arg);
1205 } catch (NumberFormatException e) {
1206 errPw.println("message value must be a valid integer");
1207 return -1;
1208 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001209
Tyler Gunn92479152021-01-20 16:30:10 -08001210 try {
1211 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1212 } catch (RemoteException e) {
1213 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1214 errPw.println("Exception: " + e.getMessage());
1215 return -1;
1216 }
1217
1218 return 0;
1219 }
1220
Tyler Gunnbabbda02021-02-10 11:05:02 -08001221 private int handleD2dTransportCommand() {
1222 PrintWriter errPw = getErrPrintWriter();
1223
1224 String arg = getNextArg();
1225 if (arg == null) {
1226 onHelpD2D();
1227 return 0;
1228 }
1229
1230 try {
1231 mInterface.setActiveDeviceToDeviceTransport(arg);
1232 } catch (RemoteException e) {
1233 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1234 errPw.println("Exception: " + e.getMessage());
1235 return -1;
1236 }
1237 return 0;
1238 }
Nazanin014f41e2021-05-06 17:26:31 -07001239 private int handleBarringCommand() {
1240 String arg = getNextArg();
1241 if (arg == null) {
1242 onHelpBarring();
1243 return 0;
1244 }
1245
1246 switch (arg) {
1247 case BARRING_SEND_INFO: {
1248 return handleBarringSendCommand();
1249 }
1250 }
1251 return -1;
1252 }
1253
1254 private int handleBarringSendCommand() {
1255 PrintWriter errPw = getErrPrintWriter();
1256 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001257 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001258 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1259 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1260 boolean isConditionallyBarred = false;
1261 int conditionalBarringTimeSeconds = 0;
1262
1263 String opt;
1264 while ((opt = getNextOption()) != null) {
1265 switch (opt) {
1266 case "-s": {
1267 try {
1268 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001269 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001270 } catch (NumberFormatException e) {
1271 errPw.println("barring send requires an integer as a SLOT_ID.");
1272 return -1;
1273 }
1274 break;
1275 }
1276 case "-b": {
1277 try {
1278 barringType = Integer.parseInt(getNextArgRequired());
1279 if (barringType < -1 || barringType > 2) {
1280 throw new NumberFormatException();
1281 }
1282
1283 } catch (NumberFormatException e) {
1284 errPw.println("barring send requires an integer in range [-1,2] as "
1285 + "a BARRING_TYPE.");
1286 return -1;
1287 }
1288 break;
1289 }
1290 case "-c": {
1291 try {
1292 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1293 } catch (Exception e) {
1294 errPw.println("barring send requires a boolean after -c indicating"
1295 + " conditional barring");
1296 return -1;
1297 }
1298 break;
1299 }
1300 case "-t": {
1301 try {
1302 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1303 } catch (NumberFormatException e) {
1304 errPw.println("barring send requires an integer for time of barring"
1305 + " in seconds after -t for conditional barring");
1306 return -1;
1307 }
1308 break;
1309 }
1310 }
1311 }
1312 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1313 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1314 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1315 barringServiceInfos.append(0, bsi);
1316 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1317 try {
1318 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1319 } catch (Exception e) {
1320 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1321 errPw.println("Exception: " + e.getMessage());
1322 return -1;
1323 }
1324 return 0;
1325 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001326
Tyler Gunnd4575212021-05-03 14:46:49 -07001327 private int handleD2dDeviceSupportedCommand() {
1328 PrintWriter errPw = getErrPrintWriter();
1329
1330 String arg = getNextArg();
1331 if (arg == null) {
1332 onHelpD2D();
1333 return 0;
1334 }
1335
Jack Yua533d632022-09-30 13:53:46 -07001336 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001337 try {
1338 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1339 } catch (RemoteException e) {
1340 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1341 errPw.println("Exception: " + e.getMessage());
1342 return -1;
1343 }
1344 return 0;
1345 }
1346
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 // ims set-ims-service
1348 private int handleImsSetServiceCommand() {
1349 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001350 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001351 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001352 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001353
1354 String opt;
1355 while ((opt = getNextOption()) != null) {
1356 switch (opt) {
1357 case "-s": {
1358 try {
1359 slotId = Integer.parseInt(getNextArgRequired());
1360 } catch (NumberFormatException e) {
1361 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1362 return -1;
1363 }
1364 break;
1365 }
1366 case "-c": {
1367 isCarrierService = true;
1368 break;
1369 }
1370 case "-d": {
1371 isCarrierService = false;
1372 break;
1373 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001374 case "-f": {
1375 String featureString = getNextArgRequired();
1376 String[] features = featureString.split(",");
1377 for (int i = 0; i < features.length; i++) {
1378 try {
1379 Integer result = Integer.parseInt(features[i]);
1380 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1381 || result >= ImsFeature.FEATURE_MAX) {
1382 errPw.println("ims set-ims-service -f " + result
1383 + " is an invalid feature.");
1384 return -1;
1385 }
1386 featuresList.add(result);
1387 } catch (NumberFormatException e) {
1388 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1389 + " as an integer.");
1390 return -1;
1391 }
1392 }
1393 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001394 }
1395 }
1396 // Mandatory param, either -c or -d
1397 if (isCarrierService == null) {
1398 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1399 return -1;
1400 }
1401
1402 String packageName = getNextArg();
1403
1404 try {
1405 if (packageName == null) {
1406 packageName = "";
1407 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001408 int[] featureArray = new int[featuresList.size()];
1409 for (int i = 0; i < featuresList.size(); i++) {
1410 featureArray[i] = featuresList.get(i);
1411 }
1412 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1413 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001414 if (VDBG) {
1415 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001416 + (isCarrierService ? "-c " : "-d ")
1417 + "-f " + featuresList + " "
1418 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001419 }
1420 getOutPrintWriter().println(result);
1421 } catch (RemoteException e) {
1422 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001423 + (isCarrierService ? "-c " : "-d ")
1424 + "-f " + featuresList + " "
1425 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001426 errPw.println("Exception: " + e.getMessage());
1427 return -1;
1428 }
1429 return 0;
1430 }
1431
Brad Ebinger999d3302020-11-25 14:31:39 -08001432 // ims clear-ims-service-override
1433 private int handleImsClearCarrierServiceCommand() {
1434 PrintWriter errPw = getErrPrintWriter();
1435 int slotId = getDefaultSlot();
1436
1437 String opt;
1438 while ((opt = getNextOption()) != null) {
1439 switch (opt) {
1440 case "-s": {
1441 try {
1442 slotId = Integer.parseInt(getNextArgRequired());
1443 } catch (NumberFormatException e) {
1444 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1445 return -1;
1446 }
1447 break;
1448 }
1449 }
1450 }
1451
1452 try {
1453 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1454 if (VDBG) {
1455 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1456 + ", result=" + result);
1457 }
1458 getOutPrintWriter().println(result);
1459 } catch (RemoteException e) {
1460 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1461 + ", error" + e.getMessage());
1462 errPw.println("Exception: " + e.getMessage());
1463 return -1;
1464 }
1465 return 0;
1466 }
1467
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001468 // ims get-ims-service
1469 private int handleImsGetServiceCommand() {
1470 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001471 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001472 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001473 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001474
1475 String opt;
1476 while ((opt = getNextOption()) != null) {
1477 switch (opt) {
1478 case "-s": {
1479 try {
1480 slotId = Integer.parseInt(getNextArgRequired());
1481 } catch (NumberFormatException e) {
1482 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1483 return -1;
1484 }
1485 break;
1486 }
1487 case "-c": {
1488 isCarrierService = true;
1489 break;
1490 }
1491 case "-d": {
1492 isCarrierService = false;
1493 break;
1494 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001495 case "-f": {
1496 try {
1497 featureType = Integer.parseInt(getNextArg());
1498 } catch (NumberFormatException e) {
1499 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1500 return -1;
1501 }
1502 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1503 || featureType >= ImsFeature.FEATURE_MAX) {
1504 errPw.println("ims get-ims-service -f invalid feature.");
1505 return -1;
1506 }
1507 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001508 }
1509 }
1510 // Mandatory param, either -c or -d
1511 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001512 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001513 return -1;
1514 }
1515
1516 String result;
1517 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001518 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001519 } catch (RemoteException e) {
1520 return -1;
1521 }
1522 if (VDBG) {
1523 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001524 + (isCarrierService ? "-c " : "-d ")
1525 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1526 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001527 }
1528 getOutPrintWriter().println(result);
1529 return 0;
1530 }
1531
1532 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001533 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001534 String opt;
1535 while ((opt = getNextOption()) != null) {
1536 switch (opt) {
1537 case "-s": {
1538 try {
1539 slotId = Integer.parseInt(getNextArgRequired());
1540 } catch (NumberFormatException e) {
1541 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1542 return -1;
1543 }
1544 break;
1545 }
1546 }
1547 }
1548 try {
1549 mInterface.enableIms(slotId);
1550 } catch (RemoteException e) {
1551 return -1;
1552 }
1553 if (VDBG) {
1554 Log.v(LOG_TAG, "ims enable -s " + slotId);
1555 }
1556 return 0;
1557 }
1558
1559 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001560 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001561 String opt;
1562 while ((opt = getNextOption()) != null) {
1563 switch (opt) {
1564 case "-s": {
1565 try {
1566 slotId = Integer.parseInt(getNextArgRequired());
1567 } catch (NumberFormatException e) {
1568 getErrPrintWriter().println(
1569 "ims disable requires an integer as a SLOT_ID.");
1570 return -1;
1571 }
1572 break;
1573 }
1574 }
1575 }
1576 try {
1577 mInterface.disableIms(slotId);
1578 } catch (RemoteException e) {
1579 return -1;
1580 }
1581 if (VDBG) {
1582 Log.v(LOG_TAG, "ims disable -s " + slotId);
1583 }
1584 return 0;
1585 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001586
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001587 private int handleCepChange() {
1588 Log.i(LOG_TAG, "handleCepChange");
1589 String opt = getNextArg();
1590 if (opt == null) {
1591 return -1;
1592 }
1593 boolean isCepEnabled = opt.equals("enable");
1594
1595 try {
1596 mInterface.setCepEnabled(isCepEnabled);
1597 } catch (RemoteException e) {
1598 return -1;
1599 }
1600 return 0;
1601 }
1602
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001603 private int getDefaultSlot() {
1604 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1605 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1606 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1607 // If there is no default, default to slot 0.
1608 slotId = DEFAULT_PHONE_ID;
1609 }
1610 return slotId;
1611 }
sqian2fff4a32018-11-05 14:18:37 -08001612
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001613 // Parse options related to Carrier Config Commands.
1614 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001615 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001616 CcOptionParseResult result = new CcOptionParseResult();
1617 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1618 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001619
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001620 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001621 while ((opt = getNextOption()) != null) {
1622 switch (opt) {
1623 case "-s": {
1624 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001625 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1626 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1627 errPw.println(tag + "No valid subscription found.");
1628 return null;
1629 }
1630
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001631 } catch (IllegalArgumentException e) {
1632 // Missing slot id
1633 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 return null;
1635 }
1636 break;
1637 }
1638 case "-p": {
1639 if (allowOptionPersistent) {
1640 result.mPersistent = true;
1641 } else {
1642 errPw.println(tag + "Unexpected option " + opt);
1643 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001644 }
1645 break;
1646 }
1647 default: {
1648 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001649 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001650 }
1651 }
1652 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001653 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001654 }
1655
1656 private int slotStringToSubId(String tag, String slotString) {
1657 int slotId = -1;
1658 try {
1659 slotId = Integer.parseInt(slotString);
1660 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001661 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1662 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1663 }
1664
1665 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001666 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1667 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1668 }
1669
Qiong Liuf25799b2020-09-10 10:13:46 +08001670 Phone phone = PhoneFactory.getPhone(slotId);
1671 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001672 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1673 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1674 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001675 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001676 }
1677
Hall Liud892bec2018-11-30 14:51:45 -08001678 private boolean checkShellUid() {
Jack Yu26735292024-09-25 14:33:49 -07001679 return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
Hall Liud892bec2018-11-30 14:51:45 -08001680 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001681
1682 private int handleCcCommand() {
1683 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1684 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001685 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1686 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001687 getErrPrintWriter().println("cc: Permission denied.");
1688 return -1;
1689 }
1690
1691 String arg = getNextArg();
1692 if (arg == null) {
1693 onHelpCc();
1694 return 0;
1695 }
1696
1697 switch (arg) {
1698 case CC_GET_VALUE: {
1699 return handleCcGetValue();
1700 }
1701 case CC_SET_VALUE: {
1702 return handleCcSetValue();
1703 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001704 case CC_SET_VALUES_FROM_XML: {
1705 return handleCcSetValuesFromXml();
1706 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001707 case CC_CLEAR_VALUES: {
1708 return handleCcClearValues();
1709 }
1710 default: {
1711 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1712 }
1713 }
1714 return -1;
1715 }
1716
1717 // cc get-value
1718 private int handleCcGetValue() {
1719 PrintWriter errPw = getErrPrintWriter();
1720 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1721 String key = null;
1722
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001723 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001724 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001725 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001726 return -1;
1727 }
1728
1729 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001730 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001731 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001732 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001733 return -1;
1734 }
1735
1736 // Get the key.
1737 key = getNextArg();
1738 if (key != null) {
1739 // A key was provided. Verify if it is a valid key
1740 if (!bundle.containsKey(key)) {
1741 errPw.println(tag + key + " is not a valid key.");
1742 return -1;
1743 }
1744
1745 // Print the carrier config value for key.
1746 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1747 } else {
1748 // No key provided. Show all values.
1749 // Iterate over a sorted list of all carrier config keys and print them.
1750 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1751 for (String k : sortedSet) {
1752 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1753 }
1754 }
1755 return 0;
1756 }
1757
1758 // cc set-value
1759 private int handleCcSetValue() {
1760 PrintWriter errPw = getErrPrintWriter();
1761 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1762
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001763 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001764 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001765 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001766 return -1;
1767 }
1768
1769 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001770 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001771 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001772 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001773 return -1;
1774 }
1775
1776 // Get the key.
1777 String key = getNextArg();
1778 if (key == null || key.equals("")) {
1779 errPw.println(tag + "KEY is missing");
1780 return -1;
1781 }
1782
1783 // Verify if the key is valid
1784 if (!originalValues.containsKey(key)) {
1785 errPw.println(tag + key + " is not a valid key.");
1786 return -1;
1787 }
1788
1789 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1790 ArrayList<String> valueList = new ArrayList<String>();
1791 while (peekNextArg() != null) {
1792 valueList.add(getNextArg());
1793 }
1794
1795 // Find the type of the carrier config value
1796 CcType type = getType(tag, key, originalValues);
1797 if (type == CcType.UNKNOWN) {
1798 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1799 return -1;
1800 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001801 if (type == CcType.PERSISTABLE_BUNDLE) {
1802 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1803 + "Use set-values-from-xml instead.");
1804 return -1;
1805 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001806
1807 // Create an override bundle containing the key and value that should be overriden.
1808 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1809 if (overrideBundle == null) {
1810 return -1;
1811 }
1812
1813 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001814 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001815
1816 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001817 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001818 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001819 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001820 return -1;
1821 }
1822
1823 // Print the original and new value.
1824 String originalValueString = ccValueToString(key, type, originalValues);
1825 String newValueString = ccValueToString(key, type, newValues);
1826 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1827 getOutPrintWriter().println("New value: \n" + newValueString);
1828
1829 return 0;
1830 }
1831
Allen Xuee00f0e2022-03-14 21:04:49 +00001832 // cc set-values-from-xml
1833 private int handleCcSetValuesFromXml() {
1834 PrintWriter errPw = getErrPrintWriter();
1835 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1836
1837 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001838 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001839 if (options == null) {
1840 return -1;
1841 }
1842
1843 // Get bundle containing all current carrier configuration values.
1844 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1845 if (originalValues == null) {
1846 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1847 return -1;
1848 }
1849
1850 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1851 if (overrideBundle == null) {
1852 return -1;
1853 }
1854
1855 // Verify all values are valid types
1856 for (String key : overrideBundle.keySet()) {
1857 CcType type = getType(tag, key, originalValues);
1858 if (type == CcType.UNKNOWN) {
1859 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1860 return -1;
1861 }
1862 }
1863
1864 // Override the value
1865 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1866
1867 // Find bundle containing all new carrier configuration values after the override.
1868 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1869 if (newValues == null) {
1870 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1871 return -1;
1872 }
1873
1874 // Print the original and new values
1875 overrideBundle.keySet().forEach(key -> {
1876 CcType type = getType(tag, key, originalValues);
1877 String originalValueString = ccValueToString(key, type, originalValues);
1878 String newValueString = ccValueToString(key, type, newValues);
1879 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1880 getOutPrintWriter().println("New value: \n" + newValueString);
1881 });
1882
1883 return 0;
1884 }
1885
1886 private PersistableBundle readPersistableBundleFromXml(String tag) {
1887 PersistableBundle subIdBundles;
1888 try {
1889 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1890 } catch (IOException | RuntimeException e) {
1891 PrintWriter errPw = getErrPrintWriter();
1892 errPw.println(tag + e);
1893 return null;
1894 }
1895
1896 return subIdBundles;
1897 }
1898
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001899 // cc clear-values
1900 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001901 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1902
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001903 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001904 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001905 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001906 return -1;
1907 }
1908
1909 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001910 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001911 getOutPrintWriter()
1912 .println("All previously set carrier config override values has been cleared");
1913 return 0;
1914 }
1915
1916 private CcType getType(String tag, String key, PersistableBundle bundle) {
1917 // Find the type by checking the type of the current value stored in the bundle.
1918 Object value = bundle.get(key);
1919
1920 if (CC_TYPE_MAP.containsKey(key)) {
1921 return CC_TYPE_MAP.get(key);
1922 } else if (value != null) {
1923 if (value instanceof Boolean) {
1924 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001925 }
1926 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001927 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001928 }
1929 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001930 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001931 }
1932 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001933 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001934 }
1935 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001936 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001937 }
1938 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001939 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001940 }
1941 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001942 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001943 }
1944 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001945 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 }
1947 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001948 return CcType.STRING_ARRAY;
1949 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001950 if (value instanceof PersistableBundle) {
1951 return CcType.PERSISTABLE_BUNDLE;
1952 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001953 } else {
1954 // Current value was null and can therefore not be used in order to find the type.
1955 // Check the name of the key to infer the type. This check is not needed for primitive
1956 // data types (boolean, double, int and long), since they can not be null.
1957 if (key.endsWith("double_array")) {
1958 return CcType.DOUBLE_ARRAY;
1959 }
1960 if (key.endsWith("int_array")) {
1961 return CcType.INT_ARRAY;
1962 }
1963 if (key.endsWith("long_array")) {
1964 return CcType.LONG_ARRAY;
1965 }
1966 if (key.endsWith("string")) {
1967 return CcType.STRING;
1968 }
1969 if (key.endsWith("string_array") || key.endsWith("strings")) {
1970 return CcType.STRING_ARRAY;
1971 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001972 if (key.endsWith("bundle")) {
1973 return CcType.PERSISTABLE_BUNDLE;
1974 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001975 }
1976
1977 // Not possible to infer the type by looking at the current value or the key.
1978 PrintWriter errPw = getErrPrintWriter();
1979 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1980 return CcType.UNKNOWN;
1981 }
1982
1983 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1984 String result;
1985 StringBuilder valueString = new StringBuilder();
1986 String typeString = type.toString();
1987 Object value = bundle.get(key);
1988
1989 if (value == null) {
1990 valueString.append("null");
1991 } else {
1992 switch (type) {
1993 case DOUBLE_ARRAY: {
1994 // Format the string representation of the int array as value1 value2......
1995 double[] valueArray = (double[]) value;
1996 for (int i = 0; i < valueArray.length; i++) {
1997 if (i != 0) {
1998 valueString.append(" ");
1999 }
2000 valueString.append(valueArray[i]);
2001 }
2002 break;
2003 }
2004 case INT_ARRAY: {
2005 // Format the string representation of the int array as value1 value2......
2006 int[] valueArray = (int[]) value;
2007 for (int i = 0; i < valueArray.length; i++) {
2008 if (i != 0) {
2009 valueString.append(" ");
2010 }
2011 valueString.append(valueArray[i]);
2012 }
2013 break;
2014 }
2015 case LONG_ARRAY: {
2016 // Format the string representation of the int array as value1 value2......
2017 long[] valueArray = (long[]) value;
2018 for (int i = 0; i < valueArray.length; i++) {
2019 if (i != 0) {
2020 valueString.append(" ");
2021 }
2022 valueString.append(valueArray[i]);
2023 }
2024 break;
2025 }
2026 case STRING: {
2027 valueString.append("\"" + value.toString() + "\"");
2028 break;
2029 }
2030 case STRING_ARRAY: {
2031 // Format the string representation of the string array as "value1" "value2"....
2032 String[] valueArray = (String[]) value;
2033 for (int i = 0; i < valueArray.length; i++) {
2034 if (i != 0) {
2035 valueString.append(" ");
2036 }
2037 if (valueArray[i] != null) {
2038 valueString.append("\"" + valueArray[i] + "\"");
2039 } else {
2040 valueString.append("null");
2041 }
2042 }
2043 break;
2044 }
2045 default: {
2046 valueString.append(value.toString());
2047 }
2048 }
2049 }
2050 return String.format("%-70s %-15s %s", key, typeString, valueString);
2051 }
2052
2053 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2054 ArrayList<String> valueList) {
2055 PrintWriter errPw = getErrPrintWriter();
2056 PersistableBundle bundle = new PersistableBundle();
2057
2058 // First verify that a valid number of values has been provided for the type.
2059 switch (type) {
2060 case BOOLEAN:
2061 case DOUBLE:
2062 case INT:
2063 case LONG: {
2064 if (valueList.size() != 1) {
2065 errPw.println(tag + "Expected 1 value for type " + type
2066 + ". Found: " + valueList.size());
2067 return null;
2068 }
2069 break;
2070 }
2071 case STRING: {
2072 if (valueList.size() > 1) {
2073 errPw.println(tag + "Expected 0 or 1 values for type " + type
2074 + ". Found: " + valueList.size());
2075 return null;
2076 }
2077 break;
2078 }
2079 }
2080
2081 // Parse the value according to type and add it to the Bundle.
2082 switch (type) {
2083 case BOOLEAN: {
2084 if ("true".equalsIgnoreCase(valueList.get(0))) {
2085 bundle.putBoolean(key, true);
2086 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2087 bundle.putBoolean(key, false);
2088 } else {
2089 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2090 return null;
2091 }
2092 break;
2093 }
2094 case DOUBLE: {
2095 try {
2096 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2097 } catch (NumberFormatException nfe) {
2098 // Not a valid double
2099 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2100 return null;
2101 }
2102 break;
2103 }
2104 case DOUBLE_ARRAY: {
2105 double[] valueDoubleArray = null;
2106 if (valueList.size() > 0) {
2107 valueDoubleArray = new double[valueList.size()];
2108 for (int i = 0; i < valueList.size(); i++) {
2109 try {
2110 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2111 } catch (NumberFormatException nfe) {
2112 // Not a valid double
2113 errPw.println(
2114 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2115 return null;
2116 }
2117 }
2118 }
2119 bundle.putDoubleArray(key, valueDoubleArray);
2120 break;
2121 }
2122 case INT: {
2123 try {
2124 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2125 } catch (NumberFormatException nfe) {
2126 // Not a valid integer
2127 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2128 return null;
2129 }
2130 break;
2131 }
2132 case INT_ARRAY: {
2133 int[] valueIntArray = null;
2134 if (valueList.size() > 0) {
2135 valueIntArray = new int[valueList.size()];
2136 for (int i = 0; i < valueList.size(); i++) {
2137 try {
2138 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2139 } catch (NumberFormatException nfe) {
2140 // Not a valid integer
2141 errPw.println(tag
2142 + "Unable to parse " + valueList.get(i) + " as an integer.");
2143 return null;
2144 }
2145 }
2146 }
2147 bundle.putIntArray(key, valueIntArray);
2148 break;
2149 }
2150 case LONG: {
2151 try {
2152 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2153 } catch (NumberFormatException nfe) {
2154 // Not a valid long
2155 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2156 return null;
2157 }
2158 break;
2159 }
2160 case LONG_ARRAY: {
2161 long[] valueLongArray = null;
2162 if (valueList.size() > 0) {
2163 valueLongArray = new long[valueList.size()];
2164 for (int i = 0; i < valueList.size(); i++) {
2165 try {
2166 valueLongArray[i] = Long.parseLong(valueList.get(i));
2167 } catch (NumberFormatException nfe) {
2168 // Not a valid long
2169 errPw.println(
2170 tag + "Unable to parse " + valueList.get(i) + " as a long");
2171 return null;
2172 }
2173 }
2174 }
2175 bundle.putLongArray(key, valueLongArray);
2176 break;
2177 }
2178 case STRING: {
2179 String value = null;
2180 if (valueList.size() > 0) {
2181 value = valueList.get(0);
2182 }
2183 bundle.putString(key, value);
2184 break;
2185 }
2186 case STRING_ARRAY: {
2187 String[] valueStringArray = null;
2188 if (valueList.size() > 0) {
2189 valueStringArray = new String[valueList.size()];
2190 valueList.toArray(valueStringArray);
2191 }
2192 bundle.putStringArray(key, valueStringArray);
2193 break;
2194 }
2195 }
2196 return bundle;
2197 }
Shuo Qian489d9282020-07-09 11:30:03 -07002198
2199 private int handleEndBlockSuppressionCommand() {
2200 if (!checkShellUid()) {
2201 return -1;
2202 }
2203
2204 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2205 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2206 }
2207 return 0;
2208 }
Hui Wang641e81c2020-10-12 12:14:23 -07002209
Michele Berionne54af4632020-12-28 20:23:16 +00002210 private int handleRestartModemCommand() {
2211 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2212 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002213 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2214 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002215 getErrPrintWriter().println("RestartModem: Permission denied.");
2216 return -1;
2217 }
2218
2219 boolean result = TelephonyManager.getDefault().rebootRadio();
2220 getOutPrintWriter().println(result);
2221
2222 return result ? 0 : -1;
2223 }
2224
Ling Ma4fbab492022-01-25 22:36:16 +00002225 private int handleGetImei() {
2226 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2227 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002228 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2229 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002230 getErrPrintWriter().println("Device IMEI: Permission denied.");
2231 return -1;
2232 }
2233
2234 final long identity = Binder.clearCallingIdentity();
2235
2236 String imei = null;
2237 String arg = getNextArg();
2238 if (arg != null) {
2239 try {
2240 int specifiedSlotIndex = Integer.parseInt(arg);
2241 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2242 } catch (NumberFormatException exception) {
2243 PrintWriter errPw = getErrPrintWriter();
2244 errPw.println("-s requires an integer as slot index.");
2245 return -1;
2246 }
2247
2248 } else {
2249 imei = TelephonyManager.from(mContext).getImei();
2250 }
2251 getOutPrintWriter().println("Device IMEI: " + imei);
2252
2253 Binder.restoreCallingIdentity(identity);
2254 return 0;
2255 }
2256
Michele Berionne5e411512020-11-13 02:36:59 +00002257 private int handleUnattendedReboot() {
2258 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2259 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002260 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2261 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002262 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2263 return -1;
2264 }
2265
2266 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2267 getOutPrintWriter().println("result: " + result);
2268
2269 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2270 }
2271
Aman Gupta07124872022-02-09 08:02:14 +00002272 private int handleGetSimSlotsMapping() {
2273 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2274 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002275 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2276 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002277 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2278 return -1;
2279 }
2280 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2281 String result = telephonyManager.getSimSlotMapping().toString();
2282 getOutPrintWriter().println("simSlotsMapping: " + result);
2283
2284 return 0;
2285 }
2286
Hui Wang641e81c2020-10-12 12:14:23 -07002287 private int handleGbaCommand() {
2288 String arg = getNextArg();
2289 if (arg == null) {
2290 onHelpGba();
2291 return 0;
2292 }
2293
2294 switch (arg) {
2295 case GBA_SET_SERVICE: {
2296 return handleGbaSetServiceCommand();
2297 }
2298 case GBA_GET_SERVICE: {
2299 return handleGbaGetServiceCommand();
2300 }
2301 case GBA_SET_RELEASE_TIME: {
2302 return handleGbaSetReleaseCommand();
2303 }
2304 case GBA_GET_RELEASE_TIME: {
2305 return handleGbaGetReleaseCommand();
2306 }
2307 }
2308
2309 return -1;
2310 }
2311
2312 private int getSubId(String cmd) {
2313 int slotId = getDefaultSlot();
2314 String opt = getNextOption();
2315 if (opt != null && opt.equals("-s")) {
2316 try {
2317 slotId = Integer.parseInt(getNextArgRequired());
2318 } catch (NumberFormatException e) {
2319 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2320 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2321 }
2322 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002323 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002324 }
2325
2326 private int handleGbaSetServiceCommand() {
2327 int subId = getSubId("gba set-service");
2328 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2329 return -1;
2330 }
2331
2332 String packageName = getNextArg();
2333 try {
2334 if (packageName == null) {
2335 packageName = "";
2336 }
2337 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2338 if (VDBG) {
2339 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2340 + packageName + ", result=" + result);
2341 }
2342 getOutPrintWriter().println(result);
2343 } catch (RemoteException e) {
2344 Log.w(LOG_TAG, "gba set-service " + subId + " "
2345 + packageName + ", error" + e.getMessage());
2346 getErrPrintWriter().println("Exception: " + e.getMessage());
2347 return -1;
2348 }
2349 return 0;
2350 }
2351
2352 private int handleGbaGetServiceCommand() {
2353 String result;
2354
2355 int subId = getSubId("gba get-service");
2356 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2357 return -1;
2358 }
2359
2360 try {
2361 result = mInterface.getBoundGbaService(subId);
2362 } catch (RemoteException e) {
2363 return -1;
2364 }
2365 if (VDBG) {
2366 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2367 }
2368 getOutPrintWriter().println(result);
2369 return 0;
2370 }
2371
2372 private int handleGbaSetReleaseCommand() {
2373 //the release time value could be -1
2374 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2375 : SubscriptionManager.getDefaultSubscriptionId();
2376 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2377 return -1;
2378 }
2379
2380 String intervalStr = getNextArg();
2381 if (intervalStr == null) {
2382 return -1;
2383 }
2384
2385 try {
2386 int interval = Integer.parseInt(intervalStr);
2387 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2388 if (VDBG) {
2389 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2390 + intervalStr + ", result=" + result);
2391 }
2392 getOutPrintWriter().println(result);
2393 } catch (NumberFormatException | RemoteException e) {
2394 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2395 + intervalStr + ", error" + e.getMessage());
2396 getErrPrintWriter().println("Exception: " + e.getMessage());
2397 return -1;
2398 }
2399 return 0;
2400 }
2401
2402 private int handleGbaGetReleaseCommand() {
2403 int subId = getSubId("gba get-release");
2404 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2405 return -1;
2406 }
2407
2408 int result = 0;
2409 try {
2410 result = mInterface.getGbaReleaseTime(subId);
2411 } catch (RemoteException e) {
2412 return -1;
2413 }
2414 if (VDBG) {
2415 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2416 }
2417 getOutPrintWriter().println(result);
2418 return 0;
2419 }
Hui Wang761a6682020-10-31 05:12:53 +00002420
2421 private int handleSingleRegistrationConfigCommand() {
2422 String arg = getNextArg();
2423 if (arg == null) {
2424 onHelpSrc();
2425 return 0;
2426 }
2427
2428 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002429 case SRC_SET_TEST_ENABLED: {
2430 return handleSrcSetTestEnabledCommand();
2431 }
2432 case SRC_GET_TEST_ENABLED: {
2433 return handleSrcGetTestEnabledCommand();
2434 }
Hui Wang761a6682020-10-31 05:12:53 +00002435 case SRC_SET_DEVICE_ENABLED: {
2436 return handleSrcSetDeviceEnabledCommand();
2437 }
2438 case SRC_GET_DEVICE_ENABLED: {
2439 return handleSrcGetDeviceEnabledCommand();
2440 }
2441 case SRC_SET_CARRIER_ENABLED: {
2442 return handleSrcSetCarrierEnabledCommand();
2443 }
2444 case SRC_GET_CARRIER_ENABLED: {
2445 return handleSrcGetCarrierEnabledCommand();
2446 }
Hui Wangb647abe2021-02-26 09:33:38 -08002447 case SRC_SET_FEATURE_ENABLED: {
2448 return handleSrcSetFeatureValidationCommand();
2449 }
2450 case SRC_GET_FEATURE_ENABLED: {
2451 return handleSrcGetFeatureValidationCommand();
2452 }
Hui Wang761a6682020-10-31 05:12:53 +00002453 }
2454
2455 return -1;
2456 }
2457
James.cf Linbcdf8b32021-01-14 16:44:13 +08002458 private int handleRcsUceCommand() {
2459 String arg = getNextArg();
2460 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002461 onHelpUce();
2462 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002463 }
2464
2465 switch (arg) {
2466 case UCE_REMOVE_EAB_CONTACT:
2467 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002468 case UCE_GET_EAB_CONTACT:
2469 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002470 case UCE_GET_EAB_CAPABILITY:
2471 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002472 case UCE_GET_DEVICE_ENABLED:
2473 return handleUceGetDeviceEnabledCommand();
2474 case UCE_SET_DEVICE_ENABLED:
2475 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002476 case UCE_OVERRIDE_PUBLISH_CAPS:
2477 return handleUceOverridePublishCaps();
2478 case UCE_GET_LAST_PIDF_XML:
2479 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002480 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2481 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002482 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2483 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002484 }
2485 return -1;
2486 }
2487
2488 private int handleRemovingEabContactCommand() {
2489 int subId = getSubId("uce remove-eab-contact");
2490 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2491 return -1;
2492 }
2493
2494 String phoneNumber = getNextArgRequired();
2495 if (TextUtils.isEmpty(phoneNumber)) {
2496 return -1;
2497 }
2498 int result = 0;
2499 try {
2500 result = mInterface.removeContactFromEab(subId, phoneNumber);
2501 } catch (RemoteException e) {
2502 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2503 getErrPrintWriter().println("Exception: " + e.getMessage());
2504 return -1;
2505 }
2506
2507 if (VDBG) {
2508 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2509 }
calvinpan293ea1b2021-02-04 17:52:13 +08002510 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002511 }
2512
calvinpane4a8a1d2021-01-25 13:51:18 +08002513 private int handleGettingEabContactCommand() {
2514 String phoneNumber = getNextArgRequired();
2515 if (TextUtils.isEmpty(phoneNumber)) {
2516 return -1;
2517 }
2518 String result = "";
2519 try {
2520 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002521 } catch (RemoteException e) {
2522 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2523 getErrPrintWriter().println("Exception: " + e.getMessage());
2524 return -1;
2525 }
2526
2527 if (VDBG) {
2528 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2529 }
calvinpan293ea1b2021-02-04 17:52:13 +08002530 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002531 return 0;
2532 }
2533
Calvin Pana1434322021-07-01 19:27:01 +08002534 private int handleGettingEabCapabilityCommand() {
2535 String phoneNumber = getNextArgRequired();
2536 if (TextUtils.isEmpty(phoneNumber)) {
2537 return -1;
2538 }
2539 String result = "";
2540 try {
2541 result = mInterface.getCapabilityFromEab(phoneNumber);
2542 } catch (RemoteException e) {
2543 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2544 getErrPrintWriter().println("Exception: " + e.getMessage());
2545 return -1;
2546 }
2547
2548 if (VDBG) {
2549 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2550 }
2551 getOutPrintWriter().println(result);
2552 return 0;
2553 }
2554
James.cf Lin4b784aa2021-01-31 03:25:15 +08002555 private int handleUceGetDeviceEnabledCommand() {
2556 boolean result = false;
2557 try {
2558 result = mInterface.getDeviceUceEnabled();
2559 } catch (RemoteException e) {
2560 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2561 return -1;
2562 }
2563 if (VDBG) {
2564 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2565 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002566 getOutPrintWriter().println(result);
2567 return 0;
2568 }
2569
James.cf Lin4b784aa2021-01-31 03:25:15 +08002570 private int handleUceSetDeviceEnabledCommand() {
2571 String enabledStr = getNextArg();
2572 if (TextUtils.isEmpty(enabledStr)) {
2573 return -1;
2574 }
2575
2576 try {
2577 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2578 mInterface.setDeviceUceEnabled(isEnabled);
2579 if (VDBG) {
2580 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2581 }
2582 } catch (NumberFormatException | RemoteException e) {
2583 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2584 getErrPrintWriter().println("Exception: " + e.getMessage());
2585 return -1;
2586 }
2587 return 0;
2588 }
2589
James.cf Line8713a42021-04-29 16:04:26 +08002590 private int handleUceRemoveRequestDisallowedStatus() {
2591 int subId = getSubId("uce remove-request-disallowed-status");
2592 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2593 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2594 return -1;
2595 }
2596 boolean result;
2597 try {
2598 result = mInterface.removeUceRequestDisallowedStatus(subId);
2599 } catch (RemoteException e) {
2600 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2601 return -1;
2602 }
2603 if (VDBG) {
2604 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2605 }
2606 getOutPrintWriter().println(result);
2607 return 0;
2608 }
2609
James.cf Lin0fc71b02021-05-25 01:37:38 +08002610 private int handleUceSetCapRequestTimeout() {
2611 int subId = getSubId("uce set-capabilities-request-timeout");
2612 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2613 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2614 return -1;
2615 }
2616 long timeoutAfterMs = Long.valueOf(getNextArg());
2617 boolean result;
2618 try {
2619 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2620 } catch (RemoteException e) {
2621 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2622 return -1;
2623 }
2624 if (VDBG) {
2625 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2626 }
2627 getOutPrintWriter().println(result);
2628 return 0;
2629 }
2630
Hui Wangbaaee6a2021-02-19 20:45:36 -08002631 private int handleSrcSetTestEnabledCommand() {
2632 String enabledStr = getNextArg();
2633 if (enabledStr == null) {
2634 return -1;
2635 }
2636
2637 try {
2638 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2639 if (VDBG) {
2640 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2641 }
2642 getOutPrintWriter().println("Done");
2643 } catch (NumberFormatException | RemoteException e) {
2644 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2645 getErrPrintWriter().println("Exception: " + e.getMessage());
2646 return -1;
2647 }
2648 return 0;
2649 }
2650
2651 private int handleSrcGetTestEnabledCommand() {
2652 boolean result = false;
2653 try {
2654 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2655 } catch (RemoteException e) {
2656 return -1;
2657 }
2658 if (VDBG) {
2659 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2660 }
2661 getOutPrintWriter().println(result);
2662 return 0;
2663 }
2664
Brad Ebinger14d467f2021-02-12 06:18:28 +00002665 private int handleUceOverridePublishCaps() {
2666 int subId = getSubId("uce override-published-caps");
2667 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2668 return -1;
2669 }
2670 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2671 String operation = getNextArgRequired();
2672 String caps = getNextArg();
2673 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2674 && !"list".equals(operation)) {
2675 getErrPrintWriter().println("Invalid operation: " + operation);
2676 return -1;
2677 }
2678
2679 // add/remove requires capabilities to be specified.
2680 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2681 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2682 + "specified");
2683 return -1;
2684 }
2685
2686 ArraySet<String> capSet = new ArraySet<>();
2687 if (!TextUtils.isEmpty(caps)) {
2688 String[] capArray = caps.split(":");
2689 for (String cap : capArray) {
2690 // Allow unknown tags to be passed in as well.
2691 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2692 }
2693 }
2694
2695 RcsContactUceCapability result = null;
2696 try {
2697 switch (operation) {
2698 case "add":
2699 result = mInterface.addUceRegistrationOverrideShell(subId,
2700 new ArrayList<>(capSet));
2701 break;
2702 case "remove":
2703 result = mInterface.removeUceRegistrationOverrideShell(subId,
2704 new ArrayList<>(capSet));
2705 break;
2706 case "clear":
2707 result = mInterface.clearUceRegistrationOverrideShell(subId);
2708 break;
2709 case "list":
2710 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2711 break;
2712 }
2713 } catch (RemoteException e) {
2714 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2715 getErrPrintWriter().println("Exception: " + e.getMessage());
2716 return -1;
2717 } catch (ServiceSpecificException sse) {
2718 // Reconstruct ImsException
2719 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2720 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2721 getErrPrintWriter().println("Exception: " + imsException);
2722 return -1;
2723 }
2724 if (result == null) {
2725 getErrPrintWriter().println("Service not available");
2726 return -1;
2727 }
2728 getOutPrintWriter().println(result);
2729 return 0;
2730 }
2731
2732 private int handleUceGetPidfXml() {
2733 int subId = getSubId("uce get-last-publish-pidf");
2734 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2735 return -1;
2736 }
2737
2738 String result;
2739 try {
2740 result = mInterface.getLastUcePidfXmlShell(subId);
2741 } catch (RemoteException e) {
2742 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2743 getErrPrintWriter().println("Exception: " + e.getMessage());
2744 return -1;
2745 } catch (ServiceSpecificException sse) {
2746 // Reconstruct ImsException
2747 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2748 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2749 getErrPrintWriter().println("Exception: " + imsException);
2750 return -1;
2751 }
2752 if (result == null) {
2753 getErrPrintWriter().println("Service not available");
2754 return -1;
2755 }
2756 getOutPrintWriter().println(result);
2757 return 0;
2758 }
2759
Hui Wang761a6682020-10-31 05:12:53 +00002760 private int handleSrcSetDeviceEnabledCommand() {
2761 String enabledStr = getNextArg();
2762 if (enabledStr == null) {
2763 return -1;
2764 }
2765
2766 try {
2767 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2768 if (VDBG) {
2769 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2770 }
2771 getOutPrintWriter().println("Done");
2772 } catch (NumberFormatException | RemoteException e) {
2773 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2774 getErrPrintWriter().println("Exception: " + e.getMessage());
2775 return -1;
2776 }
2777 return 0;
2778 }
2779
2780 private int handleSrcGetDeviceEnabledCommand() {
2781 boolean result = false;
2782 try {
2783 result = mInterface.getDeviceSingleRegistrationEnabled();
2784 } catch (RemoteException e) {
2785 return -1;
2786 }
2787 if (VDBG) {
2788 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2789 }
2790 getOutPrintWriter().println(result);
2791 return 0;
2792 }
2793
2794 private int handleSrcSetCarrierEnabledCommand() {
2795 //the release time value could be -1
2796 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2797 : SubscriptionManager.getDefaultSubscriptionId();
2798 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2799 return -1;
2800 }
2801
2802 String enabledStr = getNextArg();
2803 if (enabledStr == null) {
2804 return -1;
2805 }
2806
2807 try {
2808 boolean result =
2809 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2810 if (VDBG) {
2811 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2812 + enabledStr + ", result=" + result);
2813 }
2814 getOutPrintWriter().println(result);
2815 } catch (NumberFormatException | RemoteException e) {
2816 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2817 + enabledStr + ", error" + e.getMessage());
2818 getErrPrintWriter().println("Exception: " + e.getMessage());
2819 return -1;
2820 }
2821 return 0;
2822 }
2823
2824 private int handleSrcGetCarrierEnabledCommand() {
2825 int subId = getSubId("src get-carrier-enabled");
2826 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2827 return -1;
2828 }
2829
2830 boolean result = false;
2831 try {
2832 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2833 } catch (RemoteException e) {
2834 return -1;
2835 }
2836 if (VDBG) {
2837 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2838 }
2839 getOutPrintWriter().println(result);
2840 return 0;
2841 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002842
Hui Wangb647abe2021-02-26 09:33:38 -08002843 private int handleSrcSetFeatureValidationCommand() {
2844 //the release time value could be -1
2845 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2846 : SubscriptionManager.getDefaultSubscriptionId();
2847 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2848 return -1;
2849 }
2850
2851 String enabledStr = getNextArg();
2852 if (enabledStr == null) {
2853 return -1;
2854 }
2855
2856 try {
2857 boolean result =
2858 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2859 if (VDBG) {
2860 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2861 + enabledStr + ", result=" + result);
2862 }
2863 getOutPrintWriter().println(result);
2864 } catch (NumberFormatException | RemoteException e) {
2865 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2866 + enabledStr + ", error" + e.getMessage());
2867 getErrPrintWriter().println("Exception: " + e.getMessage());
2868 return -1;
2869 }
2870 return 0;
2871 }
2872
2873 private int handleSrcGetFeatureValidationCommand() {
2874 int subId = getSubId("src get-feature-validation");
2875 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2876 return -1;
2877 }
2878
2879 Boolean result = false;
2880 try {
2881 result = mInterface.getImsFeatureValidationOverride(subId);
2882 } catch (RemoteException e) {
2883 return -1;
2884 }
2885 if (VDBG) {
2886 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2887 }
2888 getOutPrintWriter().println(result);
2889 return 0;
2890 }
2891
2892
Hall Liuaa4211e2021-01-20 15:43:39 -08002893 private void onHelpCallComposer() {
2894 PrintWriter pw = getOutPrintWriter();
2895 pw.println("Call composer commands");
2896 pw.println(" callcomposer test-mode enable|disable|query");
2897 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2898 pw.println(" upload/download from carrier servers is disabled, and operations are");
2899 pw.println(" performed using emulated local files instead.");
2900 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2901 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2902 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002903 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2904 pw.println(" Enables or disables the user setting for call composer, as set by");
2905 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002906 }
2907
2908 private int handleCallComposerCommand() {
2909 String arg = getNextArg();
2910 if (arg == null) {
2911 onHelpCallComposer();
2912 return 0;
2913 }
2914
2915 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2916 "MODIFY_PHONE_STATE required for call composer shell cmds");
2917 switch (arg) {
2918 case CALL_COMPOSER_TEST_MODE: {
2919 String enabledStr = getNextArg();
2920 if (ENABLE.equals(enabledStr)) {
2921 CallComposerPictureManager.sTestMode = true;
2922 } else if (DISABLE.equals(enabledStr)) {
2923 CallComposerPictureManager.sTestMode = false;
2924 } else if (QUERY.equals(enabledStr)) {
2925 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2926 } else {
2927 onHelpCallComposer();
2928 return 1;
2929 }
2930 break;
2931 }
2932 case CALL_COMPOSER_SIMULATE_CALL: {
2933 int subscriptionId = Integer.valueOf(getNextArg());
2934 String uuidString = getNextArg();
2935 UUID uuid = UUID.fromString(uuidString);
2936 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2937 Binder.withCleanCallingIdentity(() -> {
2938 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2939 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2940 });
2941 try {
2942 Uri uri = storageUriFuture.get();
2943 getOutPrintWriter().println(String.valueOf(uri));
2944 } catch (Exception e) {
2945 throw new RuntimeException(e);
2946 }
2947 break;
2948 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002949 case CALL_COMPOSER_USER_SETTING: {
2950 try {
2951 int subscriptionId = Integer.valueOf(getNextArg());
2952 String enabledStr = getNextArg();
2953 if (ENABLE.equals(enabledStr)) {
2954 mInterface.setCallComposerStatus(subscriptionId,
2955 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2956 } else if (DISABLE.equals(enabledStr)) {
2957 mInterface.setCallComposerStatus(subscriptionId,
2958 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2959 } else if (QUERY.equals(enabledStr)) {
2960 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2961 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2962 } else {
2963 onHelpCallComposer();
2964 return 1;
2965 }
2966 } catch (RemoteException e) {
2967 e.printStackTrace(getOutPrintWriter());
2968 return 1;
2969 }
2970 break;
2971 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002972 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002973 return 0;
2974 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002975
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002976 private int handleHasCarrierPrivilegesCommand() {
2977 String packageName = getNextArgRequired();
2978
2979 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002980 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002981 try {
2982 hasCarrierPrivileges =
2983 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2984 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2985 } catch (RemoteException e) {
2986 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2987 getErrPrintWriter().println("Exception: " + e.getMessage());
2988 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002989 } finally {
2990 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002991 }
2992
2993 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002994 return 0;
2995 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002996
2997 private int handleAllowedNetworkTypesCommand(String command) {
2998 if (!checkShellUid()) {
2999 return -1;
3000 }
3001
3002 PrintWriter errPw = getErrPrintWriter();
3003 String tag = command + ": ";
3004 String opt;
3005 int subId = -1;
3006 Log.v(LOG_TAG, command + " start");
3007
3008 while ((opt = getNextOption()) != null) {
3009 if (opt.equals("-s")) {
3010 try {
3011 subId = slotStringToSubId(tag, getNextArgRequired());
3012 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3013 errPw.println(tag + "No valid subscription found.");
3014 return -1;
3015 }
3016 } catch (IllegalArgumentException e) {
3017 // Missing slot id
3018 errPw.println(tag + "SLOT_ID expected after -s.");
3019 return -1;
3020 }
3021 } else {
3022 errPw.println(tag + "Unknown option " + opt);
3023 return -1;
3024 }
3025 }
3026
3027 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3028 return handleGetAllowedNetworkTypesCommand(subId);
3029 }
3030 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3031 return handleSetAllowedNetworkTypesCommand(subId);
3032 }
3033 return -1;
3034 }
3035
3036 private int handleGetAllowedNetworkTypesCommand(int subId) {
3037 PrintWriter errPw = getErrPrintWriter();
3038
3039 long result = -1;
3040 try {
3041 if (mInterface != null) {
3042 result = mInterface.getAllowedNetworkTypesForReason(subId,
3043 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3044 } else {
3045 throw new IllegalStateException("telephony service is null.");
3046 }
3047 } catch (RemoteException e) {
3048 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3049 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3050 return -1;
3051 }
3052
3053 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3054 return 0;
3055 }
3056
3057 private int handleSetAllowedNetworkTypesCommand(int subId) {
3058 PrintWriter errPw = getErrPrintWriter();
3059
3060 String bitmaskString = getNextArg();
3061 if (TextUtils.isEmpty(bitmaskString)) {
3062 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3063 return -1;
3064 }
3065 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3066 if (allowedNetworkTypes < 0) {
3067 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3068 return -1;
3069 }
3070 boolean result = false;
3071 try {
3072 if (mInterface != null) {
3073 result = mInterface.setAllowedNetworkTypesForReason(subId,
3074 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3075 } else {
3076 throw new IllegalStateException("telephony service is null.");
3077 }
3078 } catch (RemoteException e) {
3079 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3080 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3081 return -1;
3082 }
3083
3084 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3085 if (result) {
3086 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3087 }
3088 getOutPrintWriter().println(resultMessage);
3089 return 0;
3090 }
3091
3092 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3093 if (TextUtils.isEmpty(bitmaskString)) {
3094 return -1;
3095 }
3096 if (VDBG) {
3097 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3098 + ", length: " + bitmaskString.length());
3099 }
3100 try {
3101 return Long.parseLong(bitmaskString, 2);
3102 } catch (NumberFormatException e) {
3103 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3104 return -1;
3105 }
3106 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003107
jimsun3b9ccac2021-10-26 15:01:23 +08003108 private int handleRadioSetModemServiceCommand() {
3109 PrintWriter errPw = getErrPrintWriter();
3110 String serviceName = null;
3111
3112 String opt;
3113 while ((opt = getNextOption()) != null) {
3114 switch (opt) {
3115 case "-s": {
3116 serviceName = getNextArgRequired();
3117 break;
3118 }
3119 }
3120 }
3121
3122 try {
3123 boolean result = mInterface.setModemService(serviceName);
3124 if (VDBG) {
3125 Log.v(LOG_TAG,
3126 "RadioSetModemService " + serviceName + ", result = " + result);
3127 }
3128 getOutPrintWriter().println(result);
3129 } catch (RemoteException e) {
3130 Log.w(LOG_TAG,
3131 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3132 errPw.println("Exception: " + e.getMessage());
3133 return -1;
3134 }
3135 return 0;
3136 }
3137
3138 private int handleRadioGetModemServiceCommand() {
3139 PrintWriter errPw = getErrPrintWriter();
3140 String result;
3141
3142 try {
3143 result = mInterface.getModemService();
3144 getOutPrintWriter().println(result);
3145 } catch (RemoteException e) {
3146 errPw.println("Exception: " + e.getMessage());
3147 return -1;
3148 }
3149 if (VDBG) {
3150 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3151 }
3152 return 0;
3153 }
3154
3155 private int handleRadioCommand() {
3156 String arg = getNextArg();
3157 if (arg == null) {
3158 onHelpRadio();
3159 return 0;
3160 }
3161
3162 switch (arg) {
3163 case RADIO_SET_MODEM_SERVICE:
3164 return handleRadioSetModemServiceCommand();
3165
3166 case RADIO_GET_MODEM_SERVICE:
3167 return handleRadioGetModemServiceCommand();
3168 }
3169
3170 return -1;
3171 }
arunvoddud7401012022-12-15 16:08:12 +00003172
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003173 private int handleSetSatelliteServicePackageNameCommand() {
3174 PrintWriter errPw = getErrPrintWriter();
3175 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003176 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003177
3178 String opt;
3179 while ((opt = getNextOption()) != null) {
3180 switch (opt) {
3181 case "-s": {
3182 serviceName = getNextArgRequired();
3183 break;
3184 }
Hakjun Choic3393242024-06-26 18:02:08 +00003185
3186 case "-p": {
3187 provisioned = getNextArgRequired();
3188 break;
3189 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003190 }
3191 }
3192 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003193 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003194
3195 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003196 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003197 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003198 Log.v(LOG_TAG,
3199 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3200 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003201 }
3202 getOutPrintWriter().println(result);
3203 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003204 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3205 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003206 errPw.println("Exception: " + e.getMessage());
3207 return -1;
3208 }
Hakjun Choic3393242024-06-26 18:02:08 +00003209
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003210 return 0;
3211 }
3212
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003213 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3214 PrintWriter errPw = getErrPrintWriter();
3215 String serviceName = null;
3216
3217 String opt;
3218 while ((opt = getNextOption()) != null) {
3219 switch (opt) {
3220 case "-s": {
3221 serviceName = getNextArgRequired();
3222 break;
3223 }
3224 }
3225 }
3226 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3227 + serviceName);
3228
3229 try {
3230 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3231 if (VDBG) {
3232 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3233 + ", result = " + result);
3234 }
3235 getOutPrintWriter().println(result);
3236 } catch (RemoteException e) {
3237 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3238 + ", error = " + e.getMessage());
3239 errPw.println("Exception: " + e.getMessage());
3240 return -1;
3241 }
3242 return 0;
3243 }
3244
Thomas Nguyen87dce732023-04-20 18:27:16 -07003245 private int handleSetSatellitePointingUiClassNameCommand() {
3246 PrintWriter errPw = getErrPrintWriter();
3247 String packageName = null;
3248 String className = null;
3249
3250 String opt;
3251 while ((opt = getNextOption()) != null) {
3252 switch (opt) {
3253 case "-p": {
3254 packageName = getNextArgRequired();
3255 break;
3256 }
3257 case "-c": {
3258 className = getNextArgRequired();
3259 break;
3260 }
3261 }
3262 }
3263 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3264 + packageName + ", className=" + className);
3265
3266 try {
3267 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3268 if (VDBG) {
3269 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3270 }
3271 getOutPrintWriter().println(result);
3272 } catch (RemoteException e) {
3273 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3274 + ", error = " + e.getMessage());
3275 errPw.println("Exception: " + e.getMessage());
3276 return -1;
3277 }
3278 return 0;
3279 }
3280
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003281 private int handleSetEmergencyCallToSatelliteHandoverType() {
3282 PrintWriter errPw = getErrPrintWriter();
3283 int handoverType = -1;
3284 int delaySeconds = 0;
3285
3286 String opt;
3287 while ((opt = getNextOption()) != null) {
3288 switch (opt) {
3289 case "-t": {
3290 try {
3291 handoverType = Integer.parseInt(getNextArgRequired());
3292 } catch (NumberFormatException e) {
3293 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3294 + " for handoverType");
3295 return -1;
3296 }
3297 break;
3298 }
3299 case "-d": {
3300 try {
3301 delaySeconds = Integer.parseInt(getNextArgRequired());
3302 } catch (NumberFormatException e) {
3303 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3304 + " for delaySeconds");
3305 return -1;
3306 }
3307 break;
3308 }
3309 }
3310 }
3311 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3312 + handoverType + ", delaySeconds=" + delaySeconds);
3313
3314 try {
3315 boolean result =
3316 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3317 if (VDBG) {
3318 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3319 }
3320 getOutPrintWriter().println(result);
3321 } catch (RemoteException e) {
3322 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3323 + ", error = " + e.getMessage());
3324 errPw.println("Exception: " + e.getMessage());
3325 return -1;
3326 }
3327 return 0;
3328 }
3329
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003330 private int handleSetSatelliteListeningTimeoutDuration() {
3331 PrintWriter errPw = getErrPrintWriter();
3332 long timeoutMillis = 0;
3333
3334 String opt;
3335 while ((opt = getNextOption()) != null) {
3336 switch (opt) {
3337 case "-t": {
3338 timeoutMillis = Long.parseLong(getNextArgRequired());
3339 break;
3340 }
3341 }
3342 }
3343 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3344 + timeoutMillis);
3345
3346 try {
3347 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3348 if (VDBG) {
3349 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3350 + ", result = " + result);
3351 }
3352 getOutPrintWriter().println(result);
3353 } catch (RemoteException e) {
3354 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3355 + ", error = " + e.getMessage());
3356 errPw.println("Exception: " + e.getMessage());
3357 return -1;
3358 }
3359 return 0;
3360 }
3361
joonhunshinf46f0d62024-09-27 14:06:26 +00003362 private int handleSetSatelliteIgnoreCellularServiceState() {
3363 PrintWriter errPw = getErrPrintWriter();
3364 boolean enabled = false;
3365
3366 String opt;
3367 while ((opt = getNextOption()) != null) {
3368 switch (opt) {
3369 case "-d": {
3370 enabled = Boolean.parseBoolean(getNextArgRequired());
3371 break;
3372 }
3373 }
3374 }
3375 Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
3376
3377 try {
3378 boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
3379 if (VDBG) {
3380 Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
3381 + ", result = " + result);
3382 }
3383 getOutPrintWriter().println(result);
3384 } catch (RemoteException e) {
3385 Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
3386 + ", error = " + e.getMessage());
3387 errPw.println("Exception: " + e.getMessage());
3388 return -1;
3389 }
3390 return 0;
3391 }
3392
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003393 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003394 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003395 boolean reset = false;
3396 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003397 long timeoutMillis = 0;
3398
3399 String opt;
3400 while ((opt = getNextOption()) != null) {
3401 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003402 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003403 timeoutMillis = Long.parseLong(getNextArgRequired());
3404 break;
3405 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003406 case "-r": {
3407 reset = true;
3408 break;
3409 }
3410 case "-t": {
3411 timeoutType = Integer.parseInt(getNextArgRequired());
3412 break;
3413 }
Hakjun Choiae365972023-04-25 11:00:31 +00003414 }
3415 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003416 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3417 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003418
3419 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003420 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3421 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003422 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003423 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003424 + ", result = " + result);
3425 }
3426 getOutPrintWriter().println(result);
3427 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003428 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3429 + ", error = " + e.getMessage());
3430 errPw.println("Exception: " + e.getMessage());
3431 return -1;
3432 }
3433 return 0;
3434 }
3435
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003436 private int handleSetDatagramControllerBooleanConfig() {
3437 PrintWriter errPw = getErrPrintWriter();
3438 boolean reset = false;
3439 int booleanType = 0;
3440 boolean enable = false;
3441
3442 String opt;
3443 while ((opt = getNextOption()) != null) {
3444 switch (opt) {
3445 case "-d": {
3446 enable = Boolean.parseBoolean(getNextArgRequired());
3447 break;
3448 }
3449 case "-r": {
3450 reset = true;
3451 break;
3452 }
3453 case "-t": {
3454 booleanType = Integer.parseInt(getNextArgRequired());
3455 break;
3456 }
3457 }
3458 }
3459 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3460 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3461
3462 try {
3463 boolean result = mInterface.setDatagramControllerBooleanConfig(
3464 reset, booleanType, enable);
3465 if (VDBG) {
3466 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3467 }
3468 getOutPrintWriter().println(result);
3469 } catch (RemoteException e) {
3470 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3471 errPw.println("Exception: " + e.getMessage());
3472 return -1;
3473 }
3474 return 0;
3475 }
3476
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003477 private int handleSetSatelliteControllerTimeoutDuration() {
3478 PrintWriter errPw = getErrPrintWriter();
3479 boolean reset = false;
3480 int timeoutType = 0;
3481 long timeoutMillis = 0;
3482
3483 String opt;
3484 while ((opt = getNextOption()) != null) {
3485 switch (opt) {
3486 case "-d": {
3487 timeoutMillis = Long.parseLong(getNextArgRequired());
3488 break;
3489 }
3490 case "-r": {
3491 reset = true;
3492 break;
3493 }
3494 case "-t": {
3495 timeoutType = Integer.parseInt(getNextArgRequired());
3496 break;
3497 }
3498 }
3499 }
3500 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3501 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3502
3503 try {
3504 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3505 reset, timeoutType, timeoutMillis);
3506 if (VDBG) {
3507 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3508 + ", result = " + result);
3509 }
3510 getOutPrintWriter().println(result);
3511 } catch (RemoteException e) {
3512 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003513 + ", error = " + e.getMessage());
3514 errPw.println("Exception: " + e.getMessage());
3515 return -1;
3516 }
3517 return 0;
3518 }
3519
Hakjun Choibc6ce992023-11-07 16:04:33 +00003520 private int handleSetShouldSendDatagramToModemInDemoMode() {
3521 PrintWriter errPw = getErrPrintWriter();
3522 String opt;
3523 boolean shouldSendToDemoMode;
3524
3525 if ((opt = getNextArg()) == null) {
3526 errPw.println(
3527 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3528 + " Invalid Argument");
3529 return -1;
3530 } else {
3531 switch (opt) {
3532 case "true": {
3533 shouldSendToDemoMode = true;
3534 break;
3535 }
3536 case "false": {
3537 shouldSendToDemoMode = false;
3538 break;
3539 }
3540 default:
3541 errPw.println(
3542 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3543 + " Invalid Argument");
3544 return -1;
3545 }
3546 }
3547
3548 Log.d(LOG_TAG,
3549 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3550
3551 try {
3552 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3553 shouldSendToDemoMode);
3554 if (VDBG) {
3555 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3556 + result);
3557 }
3558 getOutPrintWriter().println(false);
3559 } catch (RemoteException e) {
3560 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3561 + "), error = " + e.getMessage());
3562 errPw.println("Exception: " + e.getMessage());
3563 return -1;
3564 }
3565 return 0;
3566 }
3567
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003568 private int handleSetSatelliteAccessControlOverlayConfigs() {
3569 PrintWriter errPw = getErrPrintWriter();
3570 boolean reset = false;
3571 boolean isAllowed = false;
3572 String s2CellFile = null;
3573 long locationFreshDurationNanos = 0;
3574 List<String> satelliteCountryCodes = null;
3575
3576 String opt;
3577 while ((opt = getNextOption()) != null) {
3578 switch (opt) {
3579 case "-r": {
3580 reset = true;
3581 break;
3582 }
3583 case "-a": {
3584 isAllowed = true;
3585 break;
3586 }
3587 case "-f": {
3588 s2CellFile = getNextArgRequired();
3589 break;
3590 }
3591 case "-d": {
3592 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3593 break;
3594 }
3595 case "-c": {
3596 String countryCodeStr = getNextArgRequired();
3597 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3598 break;
3599 }
3600 }
3601 }
3602 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3603 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3604 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3605 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3606
3607 try {
3608 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3609 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3610 if (VDBG) {
3611 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3612 }
3613 getOutPrintWriter().println(result);
3614 } catch (RemoteException e) {
3615 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3616 errPw.println("Exception: " + e.getMessage());
3617 return -1;
3618 }
3619 return 0;
3620 }
3621
3622 private int handleSetCountryCodes() {
3623 PrintWriter errPw = getErrPrintWriter();
3624 List<String> currentNetworkCountryCodes = new ArrayList<>();
3625 String locationCountryCode = null;
3626 long locationCountryCodeTimestampNanos = 0;
3627 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3628 boolean reset = false;
3629
3630 String opt;
3631 while ((opt = getNextOption()) != null) {
3632 switch (opt) {
3633 case "-r": {
3634 reset = true;
3635 break;
3636 }
3637 case "-n": {
3638 String countryCodeStr = getNextArgRequired();
3639 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3640 break;
3641 }
3642 case "-c": {
3643 String cachedNetworkCountryCodeStr = getNextArgRequired();
3644 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3645 break;
3646 }
3647 case "-l": {
3648 locationCountryCode = getNextArgRequired();
3649 break;
3650 }
3651 case "-t": {
3652 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3653 break;
3654 }
3655 }
3656 }
3657 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3658 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3659 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3660 + currentNetworkCountryCodes);
3661
3662 try {
3663 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3664 cachedNetworkCountryCodes, locationCountryCode,
3665 locationCountryCodeTimestampNanos);
3666 if (VDBG) {
3667 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3668 }
3669 getOutPrintWriter().println(result);
3670 } catch (RemoteException e) {
3671 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3672 errPw.println("Exception: " + e.getMessage());
3673 return -1;
3674 }
3675 return 0;
3676 }
3677
Thomas Nguyen3d602742024-01-19 11:29:35 -08003678 private int handleSetOemEnabledSatelliteProvisionStatus() {
3679 PrintWriter errPw = getErrPrintWriter();
3680 boolean isProvisioned = false;
3681 boolean reset = true;
3682
3683 String opt;
3684 while ((opt = getNextOption()) != null) {
3685 switch (opt) {
3686 case "-p": {
3687 try {
3688 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3689 reset = false;
3690 } catch (Exception e) {
3691 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3692 + "after -p indicating provision status");
3693 return -1;
3694 }
3695 }
3696 }
3697 }
3698 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3699 + ", isProvisioned=" + isProvisioned);
3700
3701 try {
3702 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3703 if (VDBG) {
3704 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3705 }
3706 getOutPrintWriter().println(result);
3707 } catch (RemoteException e) {
3708 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3709 errPw.println("Exception: " + e.getMessage());
3710 return -1;
3711 }
3712 return 0;
3713 }
3714
Hakjun Choi4a832d12024-05-28 22:23:55 +00003715 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3716 PrintWriter errPw = getErrPrintWriter();
3717 String opt;
3718 String state;
3719
3720 if ((opt = getNextArg()) == null) {
3721 errPw.println(
3722 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3723 + "-location-cache :"
3724 + " Invalid Argument");
3725 return -1;
3726 } else {
3727 switch (opt) {
3728 case "-a": {
3729 state = "cache_allowed";
3730 break;
3731 }
youngtaecha32bde212024-09-17 22:58:11 +00003732 case "-na": {
3733 state = "cache_not_allowed";
3734 break;
3735 }
Hakjun Choi4a832d12024-05-28 22:23:55 +00003736 case "-n": {
3737 state = "cache_clear_and_not_allowed";
3738 break;
3739 }
3740 case "-c": {
3741 state = "clear_cache_only";
3742 break;
3743 }
3744 default:
3745 errPw.println(
3746 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3747 + "-location-cache :"
3748 + " Invalid Argument");
3749 return -1;
3750 }
3751 }
3752
3753 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3754 + state + ")");
3755
3756 try {
3757 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3758 state);
3759 if (VDBG) {
3760 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3761 + "returns: "
3762 + result);
3763 }
3764 getOutPrintWriter().println(result);
3765 } catch (RemoteException e) {
3766 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3767 + state + "), error = " + e.getMessage());
3768 errPw.println("Exception: " + e.getMessage());
3769 return -1;
3770 }
3771 return 0;
3772 }
3773
Hyosund6aaf062024-08-23 23:02:10 +00003774 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3775 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3776 PrintWriter errPw = getErrPrintWriter();
3777 String opt;
3778 String name;
3779
3780 if ((opt = getNextArg()) == null) {
3781 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3782 return -1;
3783 } else {
3784 switch (opt) {
3785 case "-p": {
3786 name = opt + "/" + "android.telephony.cts";
3787 break;
3788 }
3789 case "-c": {
3790 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3791 break;
3792 }
3793 case "-r": {
3794 name = "reset";
3795 break;
3796 }
3797 default:
3798 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3799 return -1;
3800 }
3801 }
3802
3803 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3804 + name + ")");
3805
3806 try {
3807 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3808 if (VDBG) {
3809 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3810 + "returns: " + result);
3811 }
3812 getOutPrintWriter().println(result);
3813 } catch (RemoteException e) {
3814 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3815 + name + "), error = " + e.getMessage());
3816 errPw.println("Exception: " + e.getMessage());
3817 return -1;
3818 }
3819 return 0;
3820 }
3821
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003822 /**
3823 * Sample inputStr = "US,UK,CA;2,1,3"
3824 * Sample output: {[US,2], [UK,1], [CA,3]}
3825 */
3826 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3827 Map<String, Long> result = new HashMap<>();
3828 if (!TextUtils.isEmpty(inputStr)) {
3829 String[] stringLongArr = inputStr.split(";");
3830 if (stringLongArr.length != 2) {
3831 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3832 return result;
3833 }
3834
3835 String[] stringArr = stringLongArr[0].split(",");
3836 String[] longArr = stringLongArr[1].split(",");
3837 if (stringArr.length != longArr.length) {
3838 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3839 return result;
3840 }
3841
3842 for (int i = 0; i < stringArr.length; i++) {
3843 try {
3844 result.put(stringArr[i], Long.parseLong(longArr[i]));
3845 } catch (Exception ex) {
3846 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3847 + ", ex=" + ex);
3848 return result;
3849 }
3850 }
3851 }
3852 return result;
3853 }
3854
arunvoddud7401012022-12-15 16:08:12 +00003855 private int handleCarrierRestrictionStatusCommand() {
3856 try {
3857 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3858 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3859 mInterface.getModemService()))) {
3860 Log.v(LOG_TAG,
3861 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3862 + " checkShellUid fails");
3863 return -1;
3864 }
3865 } catch (RemoteException ex) {
3866 ex.printStackTrace();
3867 }
3868 String callerInfo = getNextOption();
3869 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3870 if (TextUtils.isEmpty(callerInfo)) {
3871 // reset the Json content after testing
3872 allowListInfo.updateJsonForTest(null);
3873 return 0;
3874 }
3875 if (callerInfo.startsWith("--")) {
3876 callerInfo = callerInfo.replace("--", "");
3877 }
3878 String params[] = callerInfo.split(",");
3879 StringBuffer jsonStrBuffer = new StringBuffer();
3880 String tokens;
3881 for (int index = 0; index < params.length; index++) {
3882 tokens = convertToJsonString(index, params[index]);
3883 if (TextUtils.isEmpty(tokens)) {
3884 // received wrong format from CTS
3885 if (VDBG) {
3886 Log.v(LOG_TAG,
3887 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3888 }
3889 return -1;
3890 }
3891 jsonStrBuffer.append(tokens);
3892 }
3893 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3894 return result;
3895 }
3896
Benedict Wong66477622023-02-03 23:30:57 +00003897 // set-carrier-service-package-override
3898 private int setCarrierServicePackageOverride() {
3899 PrintWriter errPw = getErrPrintWriter();
3900 int subId = SubscriptionManager.getDefaultSubscriptionId();
3901
3902 String opt;
3903 while ((opt = getNextOption()) != null) {
3904 switch (opt) {
3905 case "-s":
3906 try {
3907 subId = Integer.parseInt(getNextArgRequired());
3908 } catch (NumberFormatException e) {
3909 errPw.println(
3910 "set-carrier-service-package-override requires an integer as a"
3911 + " subscription ID.");
3912 return -1;
3913 }
3914 break;
3915 }
3916 }
3917
3918 String packageName = getNextArg();
3919 if (packageName == null) {
3920 errPw.println("set-carrier-service-package-override requires a override package name.");
3921 return -1;
3922 }
3923
3924 try {
3925 mInterface.setCarrierServicePackageOverride(
3926 subId, packageName, mContext.getOpPackageName());
3927
3928 if (VDBG) {
3929 Log.v(
3930 LOG_TAG,
3931 "set-carrier-service-package-override -s " + subId + " " + packageName);
3932 }
3933 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3934 Log.w(
3935 LOG_TAG,
3936 "set-carrier-service-package-override -s "
3937 + subId
3938 + " "
3939 + packageName
3940 + ", error"
3941 + e.getMessage());
3942 errPw.println("Exception: " + e.getMessage());
3943 return -1;
3944 }
3945 return 0;
3946 }
3947
3948 // clear-carrier-service-package-override
3949 private int clearCarrierServicePackageOverride() {
3950 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003951 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003952
3953 String opt;
3954 while ((opt = getNextOption()) != null) {
3955 switch (opt) {
3956 case "-s":
3957 try {
3958 subId = Integer.parseInt(getNextArgRequired());
3959 } catch (NumberFormatException e) {
3960 errPw.println(
3961 "clear-carrier-service-package-override requires an integer as a"
3962 + " subscription ID.");
3963 return -1;
3964 }
3965 break;
3966 }
3967 }
3968
3969 try {
3970 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3971
3972 if (VDBG) {
3973 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3974 }
3975 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3976 Log.w(
3977 LOG_TAG,
3978 "clear-carrier-service-package-override -s "
3979 + subId
3980 + ", error"
3981 + e.getMessage());
3982 errPw.println("Exception: " + e.getMessage());
3983 return -1;
3984 }
3985 return 0;
3986 }
arunvoddud7401012022-12-15 16:08:12 +00003987
Hunsuk Choi13078be2023-09-13 10:55:21 +00003988 private int handleDomainSelectionCommand() {
3989 String arg = getNextArg();
3990 if (arg == null) {
3991 onHelpDomainSelection();
3992 return 0;
3993 }
3994
3995 switch (arg) {
3996 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
3997 return handleDomainSelectionSetServiceOverrideCommand();
3998 }
3999 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4000 return handleDomainSelectionClearServiceOverrideCommand();
4001 }
4002 }
4003
4004 return -1;
4005 }
4006
4007 // domainselection set-dss-override
4008 private int handleDomainSelectionSetServiceOverrideCommand() {
4009 PrintWriter errPw = getErrPrintWriter();
4010
4011 String componentName = getNextArg();
4012
4013 try {
4014 boolean result = mInterface.setDomainSelectionServiceOverride(
4015 ComponentName.unflattenFromString(componentName));
4016 if (VDBG) {
4017 Log.v(LOG_TAG, "domainselection set-dss-override "
4018 + componentName + ", result=" + result);
4019 }
4020 getOutPrintWriter().println(result);
4021 } catch (Exception e) {
4022 Log.w(LOG_TAG, "domainselection set-dss-override "
4023 + componentName + ", error=" + e.getMessage());
4024 errPw.println("Exception: " + e.getMessage());
4025 return -1;
4026 }
4027 return 0;
4028 }
4029
4030 // domainselection clear-dss-override
4031 private int handleDomainSelectionClearServiceOverrideCommand() {
4032 PrintWriter errPw = getErrPrintWriter();
4033
4034 try {
4035 boolean result = mInterface.clearDomainSelectionServiceOverride();
4036 if (VDBG) {
4037 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4038 }
4039 getOutPrintWriter().println(result);
4040 } catch (RemoteException e) {
4041 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4042 errPw.println("Exception: " + e.getMessage());
4043 return -1;
4044 }
4045 return 0;
4046 }
4047
arunvoddud7401012022-12-15 16:08:12 +00004048 /**
4049 * Building the string that can be used to build the JsonObject which supports to stub the data
4050 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004051 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004052 */
4053 private String convertToJsonString(int index, String param) {
4054
4055 String token[] = param.split(":");
4056 String jSonString;
4057 switch (index) {
4058 case 0:
4059 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4060 break;
4061 case 1:
4062 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004063 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004064 break;
4065 case 2:
4066 jSonString =
4067 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4068 break;
4069 default:
4070 jSonString = null;
4071 }
4072 return jSonString;
4073 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004074}