blob: 5ea13047b5bb976f2baaf2a2458cfc6b428dd1f1 [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
arunvoddue3a6dbc2024-09-27 16:27:08 +0000215 private static final String SET_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT =
216 "set-satellite-access-restriction-checking-result";
217
Hunsuk Choi13078be2023-09-13 10:55:21 +0000218 private static final String DOMAIN_SELECTION_SUBCOMMAND = "domainselection";
219 private static final String DOMAIN_SELECTION_SET_SERVICE_OVERRIDE = "set-dss-override";
220 private static final String DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE = "clear-dss-override";
221
Grant Menke567d48f2022-08-18 20:19:10 +0000222 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
223 + "'*', '#' or '+') needs to be specified after -a in the command ";
224
225 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
226 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
227 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
228
SongFerngWang98dd5992021-05-13 17:50:00 +0800229 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
230 "get-allowed-network-types-for-users";
231 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
232 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000233 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000234 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700235 // Take advantage of existing methods that already contain permissions checks when possible.
236 private final ITelephony mInterface;
237
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100238 private SubscriptionManager mSubscriptionManager;
239 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700240 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700241 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100242
243 private enum CcType {
244 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000245 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100246 }
247
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100248 private class CcOptionParseResult {
249 public int mSubId;
250 public boolean mPersistent;
251 }
252
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100253 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
254 // keys by looking at the end of the string which usually tells the type.
255 // For instance: "xxxx_string", "xxxx_string_array", etc.
256 // The carrier config keys in this map does not follow this convention. It is therefore not
257 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700258 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
259 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
260 CcType.STRING),
261 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
266 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
267 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
268 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
269 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
270 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
271 CcType.STRING),
272 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
273 CcType.STRING_ARRAY),
274 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
275 CcType.STRING_ARRAY),
276 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
277 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
279 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
280 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
281 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
282 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
283 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100284
Brad Ebinger14d467f2021-02-12 06:18:28 +0000285 /**
286 * Map from a shorthand string to the feature tags required in registration required in order
287 * for the RCS feature to be considered "capable".
288 */
289 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
290 static {
291 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
292 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
293 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
294 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
295 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
296 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
297 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
298 FeatureTags.FEATURE_TAG_VIDEO)));
299 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
300 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
301 map.put("call_comp",
302 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
303 map.put("call_comp_mmtel",
304 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
305 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
306 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
307 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
308 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
309 // version
310 map.put("chatbot", new ArraySet<>(Arrays.asList(
311 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
312 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
313 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
314 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000315 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000316 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
317 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
318 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
319 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
320 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000321 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000322 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
323 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
324 }
325
326
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100327 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700328 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100329 mCarrierConfigManager =
330 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
331 mSubscriptionManager = (SubscriptionManager)
332 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700333 mTelephonyRegistryManager = (TelephonyRegistryManager)
334 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700335 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700336 }
337
338 @Override
339 public int onCommand(String cmd) {
340 if (cmd == null) {
341 return handleDefaultCommands(null);
342 }
343
344 switch (cmd) {
345 case IMS_SUBCOMMAND: {
346 return handleImsCommand();
347 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800348 case RCS_UCE_COMMAND:
349 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800350 case NUMBER_VERIFICATION_SUBCOMMAND:
351 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800352 case EMERGENCY_CALLBACK_MODE:
353 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800354 case EMERGENCY_NUMBER_TEST_MODE:
355 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100356 case CARRIER_CONFIG_SUBCOMMAND: {
357 return handleCcCommand();
358 }
Shuo Qianf5125122019-12-16 17:03:07 -0800359 case DATA_TEST_MODE:
360 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700361 case END_BLOCK_SUPPRESSION:
362 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700363 case GBA_SUBCOMMAND:
364 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800365 case D2D_SUBCOMMAND:
366 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700367 case BARRING_SUBCOMMAND:
368 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000369 case SINGLE_REGISTATION_CONFIG:
370 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000371 case RESTART_MODEM:
372 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800373 case CALL_COMPOSER_SUBCOMMAND:
374 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000375 case UNATTENDED_REBOOT:
376 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800377 case HAS_CARRIER_PRIVILEGES_COMMAND:
378 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800379 case THERMAL_MITIGATION_COMMAND:
380 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700381 case DISABLE_PHYSICAL_SUBSCRIPTION:
382 return handleEnablePhysicalSubscription(false);
383 case ENABLE_PHYSICAL_SUBSCRIPTION:
384 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800385 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
386 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
387 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000388 case GET_IMEI:
389 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000390 case GET_SIM_SLOTS_MAPPING:
391 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800392 case RADIO_SUBCOMMAND:
393 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000394 case CARRIER_RESTRICTION_STATUS_TEST:
395 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000396 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
397 return setCarrierServicePackageOverride();
398 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
399 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000400 case DOMAIN_SELECTION_SUBCOMMAND:
401 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700402 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
403 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700404 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
405 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700406 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
407 return handleSetSatelliteListeningTimeoutDuration();
joonhunshinf46f0d62024-09-27 14:06:26 +0000408 case SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE:
409 return handleSetSatelliteIgnoreCellularServiceState();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700410 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
411 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800412 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
413 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000414 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
415 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800416 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
417 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700418 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
419 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000420 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
421 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800422 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
423 return handleSetSatelliteAccessControlOverlayConfigs();
424 case SET_COUNTRY_CODES:
425 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800426 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
427 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000428 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
429 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000430 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
431 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
arunvoddue3a6dbc2024-09-27 16:27:08 +0000432 case SET_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT:
433 return handleOverrideCarrierRoamingNtnEligibilityChanged();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700434 default: {
435 return handleDefaultCommands(cmd);
436 }
437 }
438 }
439
440 @Override
441 public void onHelp() {
442 PrintWriter pw = getOutPrintWriter();
443 pw.println("Telephony Commands:");
444 pw.println(" help");
445 pw.println(" Print this help text.");
446 pw.println(" ims");
447 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800448 pw.println(" uce");
449 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800450 pw.println(" emergency-number-test-mode");
451 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700452 pw.println(" end-block-suppression");
453 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800454 pw.println(" data");
455 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100456 pw.println(" cc");
457 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700458 pw.println(" gba");
459 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000460 pw.println(" src");
461 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000462 pw.println(" restart-modem");
463 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000464 pw.println(" unattended-reboot");
465 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800466 pw.println(" has-carrier-privileges [package]");
467 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800468 pw.println(" get-allowed-network-types-for-users");
469 pw.println(" Get the Allowed Network Types.");
470 pw.println(" set-allowed-network-types-for-users");
471 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800472 pw.println(" radio");
473 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700474 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800475 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800476 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700477 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800478 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100479 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700480 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000481 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800482 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700483 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800484 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800485 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000486 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700487 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000488 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800489 }
490
491 private void onHelpD2D() {
492 PrintWriter pw = getOutPrintWriter();
493 pw.println("D2D Comms Commands:");
494 pw.println(" d2d send TYPE VALUE");
495 pw.println(" Sends a D2D message of specified type and value.");
496 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
497 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
498 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
499 MESSAGE_CALL_AUDIO_CODEC));
500 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
501 + Communicator.messageToString(
502 MESSAGE_DEVICE_BATTERY_STATE));
503 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
504 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800505 pw.println(" d2d transport TYPE");
506 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
507 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700508 pw.println(" d2d set-device-support true/default");
509 pw.println(" true - forces device support to be enabled for D2D.");
510 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
511 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700512 }
513
Nazanin014f41e2021-05-06 17:26:31 -0700514 private void onHelpBarring() {
515 PrintWriter pw = getOutPrintWriter();
516 pw.println("Barring Commands:");
517 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
518 + " -t CONDITIONAL_BARRING_TIME_SECS");
519 pw.println(" Notifies of a barring info change for the specified slot id.");
520 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
521 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
522 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
523 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
524 }
525
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700526 private void onHelpIms() {
527 PrintWriter pw = getOutPrintWriter();
528 pw.println("IMS Commands:");
Brad Ebinger555ddec2024-11-04 13:46:31 -0800529 pw.println(" ims set-ims-service [-s SLOT_ID] [-u USER_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700530 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
531 pw.println(" ImsService. Options are:");
532 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
533 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger555ddec2024-11-04 13:46:31 -0800534 pw.println(" -u: the user ID that the ImsService should be bound on. If no option");
535 pw.println(" is specified, the SYSTEM user ID will be preferred followed by the");
536 pw.println(" current user ID if they are different");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700537 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
538 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800539 pw.println(" -f: Set the feature that this override if for, if no option is");
540 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700541 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
542 pw.println(" Gets the package name of the currently defined ImsService.");
543 pw.println(" Options are:");
544 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
545 pw.println(" is specified, it will choose the default voice SIM slot.");
546 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000547 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800548 pw.println(" -f: The feature type that the query will be requested for. If none is");
549 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800550 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
551 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
552 pw.println(" configuration overrides. Options are:");
553 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
554 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700555 pw.println(" ims enable [-s SLOT_ID]");
556 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
557 pw.println(" if none is specified.");
558 pw.println(" ims disable [-s SLOT_ID]");
559 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
560 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700561 pw.println(" ims conference-event-package [enable/disable]");
562 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700563 }
564
James.cf Linbcdf8b32021-01-14 16:44:13 +0800565 private void onHelpUce() {
566 PrintWriter pw = getOutPrintWriter();
567 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800568 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
569 pw.println(" Get the EAB contacts from the EAB database.");
570 pw.println(" Options are:");
571 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
572 pw.println(" Expected output format :");
573 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800574 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
575 pw.println(" Remove the EAB contacts from the EAB database.");
576 pw.println(" Options are:");
577 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
578 pw.println(" is specified, it will choose the default voice SIM slot.");
579 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800580 pw.println(" uce get-device-enabled");
581 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
582 pw.println(" uce set-device-enabled true|false");
583 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
584 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000585 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
586 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
587 pw.println(" Options are:");
588 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
589 pw.println(" is specified, it will choose the default voice SIM slot.");
590 pw.println(" add [CAPABILITY]: add a new capability");
591 pw.println(" remove [CAPABILITY]: remove a capability");
592 pw.println(" clear: clear all capability overrides");
593 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
594 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
595 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
596 pw.println(" chatbot_sa, chatbot_role] as well as full length");
597 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
598 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
599 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
600 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800601 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
602 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800603 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
604 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800605 }
606
Hall Liud892bec2018-11-30 14:51:45 -0800607 private void onHelpNumberVerification() {
608 PrintWriter pw = getOutPrintWriter();
609 pw.println("Number verification commands");
610 pw.println(" numverify override-package PACKAGE_NAME;");
611 pw.println(" Set the authorized package for number verification.");
612 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800613 pw.println(" numverify fake-call NUMBER;");
614 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
615 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800616 }
617
Jack Nudelman644b91a2021-03-12 14:09:48 -0800618 private void onHelpThermalMitigation() {
619 PrintWriter pw = getOutPrintWriter();
620 pw.println("Thermal mitigation commands");
621 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
622 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
623 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
624 pw.println(" Remove the package from one of the authorized packages for thermal "
625 + "mitigation.");
626 }
627
Jordan Liu0ccee222021-04-27 11:55:13 -0700628 private void onHelpDisableOrEnablePhysicalSubscription() {
629 PrintWriter pw = getOutPrintWriter();
630 pw.println("Disable or enable a physical subscription");
631 pw.println(" disable-physical-subscription SUB_ID");
632 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
633 pw.println(" enable-physical-subscription SUB_ID");
634 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
635 }
636
Shuo Qianf5125122019-12-16 17:03:07 -0800637 private void onHelpDataTestMode() {
638 PrintWriter pw = getOutPrintWriter();
639 pw.println("Mobile Data Test Mode Commands:");
640 pw.println(" data enable: enable mobile data connectivity");
641 pw.println(" data disable: disable mobile data connectivity");
642 }
643
sqian9d4df8b2019-01-15 18:32:07 -0800644 private void onHelpEmergencyNumber() {
645 PrintWriter pw = getOutPrintWriter();
646 pw.println("Emergency Number Test Mode Commands:");
647 pw.println(" emergency-number-test-mode ");
648 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
649 + " the test mode");
650 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700651 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800652 pw.println(" -c: clear the emergency number list in the test mode.");
653 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700654 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800655 pw.println(" -p: get the full emergency number list in the test mode.");
656 }
657
Shuo Qian489d9282020-07-09 11:30:03 -0700658 private void onHelpEndBlockSupperssion() {
659 PrintWriter pw = getOutPrintWriter();
660 pw.println("End Block Suppression command:");
661 pw.println(" end-block-suppression: disable suppressing blocking by contact");
662 pw.println(" with emergency services.");
663 }
664
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100665 private void onHelpCc() {
666 PrintWriter pw = getOutPrintWriter();
667 pw.println("Carrier Config Commands:");
668 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
669 pw.println(" Print carrier config values.");
670 pw.println(" Options are:");
671 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
672 pw.println(" is specified, it will choose the default voice SIM slot.");
673 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
674 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100675 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100676 pw.println(" Set carrier config KEY to NEW_VALUE.");
677 pw.println(" Options are:");
678 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
679 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100680 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100681 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
682 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
683 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
684 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000685 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
686 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
687 pw.println(" provided through standard input and follow CarrierConfig XML format.");
688 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
689 pw.println(" Options are:");
690 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
691 pw.println(" is specified, it will choose the default voice SIM slot.");
692 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100693 pw.println(" cc clear-values [-s SLOT_ID]");
694 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000695 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100696 pw.println(" Options are:");
697 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
698 pw.println(" is specified, it will choose the default voice SIM slot.");
699 }
700
Hui Wang641e81c2020-10-12 12:14:23 -0700701 private void onHelpGba() {
702 PrintWriter pw = getOutPrintWriter();
703 pw.println("Gba Commands:");
704 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
705 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
706 pw.println(" Options are:");
707 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
708 pw.println(" is specified, it will choose the default voice SIM slot.");
709 pw.println(" gba get-service [-s SLOT_ID]");
710 pw.println(" Gets the package name of the currently defined GbaService.");
711 pw.println(" Options are:");
712 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
713 pw.println(" is specified, it will choose the default voice SIM slot.");
714 pw.println(" gba set-release [-s SLOT_ID] n");
715 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
716 pw.println(" Do not release/unbind if n is -1.");
717 pw.println(" Options are:");
718 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
719 pw.println(" is specified, it will choose the default voice SIM slot.");
720 pw.println(" gba get-release [-s SLOT_ID]");
721 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
722 pw.println(" Options are:");
723 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
724 pw.println(" is specified, it will choose the default voice SIM slot.");
725 }
726
Hui Wang761a6682020-10-31 05:12:53 +0000727 private void onHelpSrc() {
728 PrintWriter pw = getOutPrintWriter();
729 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800730 pw.println(" src set-test-enabled true|false");
731 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
732 pw.println(" The value could be true, false, or null(undefined).");
733 pw.println(" src get-test-enabled");
734 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000735 pw.println(" src set-device-enabled true|false|null");
736 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
737 pw.println(" The value could be true, false, or null(undefined).");
738 pw.println(" src get-device-enabled");
739 pw.println(" Gets the device config for RCS VoLTE single registration.");
740 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
741 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
742 pw.println(" The value could be true, false, or null(undefined).");
743 pw.println(" Options are:");
744 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
745 pw.println(" is specified, it will choose the default voice SIM slot.");
746 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
747 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
748 pw.println(" Options are:");
749 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
750 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800751 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
752 pw.println(" Sets ims feature validation result.");
753 pw.println(" The value could be true, false, or null(undefined).");
754 pw.println(" Options are:");
755 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
756 pw.println(" is specified, it will choose the default voice SIM slot.");
757 pw.println(" src get-feature-validation [-s SLOT_ID]");
758 pw.println(" Gets ims feature validation override value.");
759 pw.println(" Options are:");
760 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
761 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000762 }
763
SongFerngWang98dd5992021-05-13 17:50:00 +0800764 private void onHelpAllowedNetworkTypes() {
765 PrintWriter pw = getOutPrintWriter();
766 pw.println("Allowed Network Types Commands:");
767 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
768 pw.println(" Print allowed network types value.");
769 pw.println(" Options are:");
770 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
771 pw.println(" option is specified, it will choose the default voice SIM slot.");
772 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
773 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
774 pw.println(" Options are:");
775 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
776 pw.println(" option is specified, it will choose the default voice SIM slot.");
777 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
778 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
779 pw.println(" at TelephonyManager.java");
780 pw.println(" For example:");
781 pw.println(" NR only : 10000000000000000000");
782 pw.println(" NR|LTE : 11000001000000000000");
783 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
784 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
785 pw.println(" LTE only : 01000001000000000000");
786 }
787
jimsun3b9ccac2021-10-26 15:01:23 +0800788 private void onHelpRadio() {
789 PrintWriter pw = getOutPrintWriter();
790 pw.println("Radio Commands:");
791 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
792 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
793 pw.println(" to be the bound. Options are:");
794 pw.println(" -s: the service name that the modem service should be bound for.");
795 pw.println(" If no option is specified, it will bind to the default.");
796 pw.println(" radio get-modem-service");
797 pw.println(" Gets the service name of the currently defined modem service.");
798 pw.println(" If it is binding to default, 'default' returns.");
799 pw.println(" If it doesn't bind to any modem service for some reasons,");
800 pw.println(" the result would be 'unknown'.");
801 }
802
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700803 private void onHelpSatellite() {
804 PrintWriter pw = getOutPrintWriter();
805 pw.println("Satellite Commands:");
806 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
807 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700808 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700809 pw.println(" -s: the satellite service package name that Telephony will bind to.");
810 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700811 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
812 pw.println(" Sets the package name of satellite gateway service defined in");
813 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
814 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
815 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700816 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
817 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
818 pw.println(" mode. Options are:");
819 pw.println(" -t: the timeout duration in milliseconds.");
820 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700821 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
822 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
823 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
824 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
825 pw.println(" launch. If no option is specified, it will launch the default.");
826 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
827 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700828 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
829 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
830 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
831 pw.println(" Options are:");
832 pw.println(" -t: the emergency call to satellite handover type.");
833 pw.println(" If no option is specified, override is disabled.");
834 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
835 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800836 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
837 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
838 pw.println(" configs of satellite access controller.");
839 pw.println(" Options are:");
840 pw.println(" -r: clear the overriding. Absent means enable overriding.");
841 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
842 pw.println(" -f: the satellite s2 file.");
843 pw.println(" -d: the location fresh duration nanos.");
844 pw.println(" -c: the list of satellite country codes separated by comma.");
845 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
846 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
847 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
848 pw.println(" Override the cached location country code and its update timestamp. ");
849 pw.println(" Options are:");
850 pw.println(" -r: clear the overriding. Absent means enable overriding.");
851 pw.println(" -n: the current network country code ISOs.");
852 pw.println(" -c: the cached network country code ISOs.");
853 pw.println(" -l: the location country code ISO.");
854 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800855 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
856 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
857 pw.println(" -p: the overriding satellite provision status. If no option is ");
858 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700859 }
860
Ling Ma4fbab492022-01-25 22:36:16 +0000861 private void onHelpImei() {
862 PrintWriter pw = getOutPrintWriter();
863 pw.println("IMEI Commands:");
864 pw.println(" get-imei [-s SLOT_ID]");
865 pw.println(" Gets the device IMEI. Options are:");
866 pw.println(" -s: the slot ID to get the IMEI. If no option");
867 pw.println(" is specified, it will choose the default voice SIM slot.");
868 }
869
Hunsuk Choi13078be2023-09-13 10:55:21 +0000870 private void onHelpDomainSelection() {
871 PrintWriter pw = getOutPrintWriter();
872 pw.println("Domain Selection Commands:");
873 pw.println(" domainselection set-dss-override COMPONENT_NAME");
874 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
875 pw.println(" domainselection clear-dss-override");
876 pw.println(" Clears DomainSelectionService override.");
877 }
878
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700879 private int handleImsCommand() {
880 String arg = getNextArg();
881 if (arg == null) {
882 onHelpIms();
883 return 0;
884 }
885
886 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800887 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700888 return handleImsSetServiceCommand();
889 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800890 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700891 return handleImsGetServiceCommand();
892 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800893 case IMS_CLEAR_SERVICE_OVERRIDE: {
894 return handleImsClearCarrierServiceCommand();
895 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800896 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700897 return handleEnableIms();
898 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800899 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700900 return handleDisableIms();
901 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700902 case IMS_CEP: {
903 return handleCepChange();
904 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700905 }
906
907 return -1;
908 }
909
Shuo Qianf5125122019-12-16 17:03:07 -0800910 private int handleDataTestModeCommand() {
911 PrintWriter errPw = getErrPrintWriter();
912 String arg = getNextArgRequired();
913 if (arg == null) {
914 onHelpDataTestMode();
915 return 0;
916 }
917 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800918 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800919 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700920 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800921 } catch (RemoteException ex) {
922 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
923 errPw.println("Exception: " + ex.getMessage());
924 return -1;
925 }
926 break;
927 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800928 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800929 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700930 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800931 } catch (RemoteException ex) {
932 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
933 errPw.println("Exception: " + ex.getMessage());
934 return -1;
935 }
936 break;
937 }
938 default:
939 onHelpDataTestMode();
940 break;
941 }
942 return 0;
943 }
944
Shuo Qianccbaf742021-02-22 18:32:21 -0800945 private int handleEmergencyCallbackModeCommand() {
946 PrintWriter errPw = getErrPrintWriter();
947 try {
948 mInterface.startEmergencyCallbackMode();
949 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
950 } catch (RemoteException ex) {
951 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
952 errPw.println("Exception: " + ex.getMessage());
953 return -1;
954 }
955 return 0;
956 }
957
Grant Menke567d48f2022-08-18 20:19:10 +0000958 private void removeEmergencyNumberTestMode(String emergencyNumber) {
959 PrintWriter errPw = getErrPrintWriter();
960 for (int routingType : ROUTING_TYPES) {
961 try {
962 mInterface.updateEmergencyNumberListTestMode(
963 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
964 new EmergencyNumber(emergencyNumber, "", "",
965 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
966 new ArrayList<String>(),
967 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
968 routingType));
969 } catch (RemoteException ex) {
970 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
971 errPw.println("Exception: " + ex.getMessage());
972 }
973 }
974 }
975
sqian9d4df8b2019-01-15 18:32:07 -0800976 private int handleEmergencyNumberTestModeCommand() {
977 PrintWriter errPw = getErrPrintWriter();
978 String opt = getNextOption();
979 if (opt == null) {
980 onHelpEmergencyNumber();
981 return 0;
982 }
sqian9d4df8b2019-01-15 18:32:07 -0800983 switch (opt) {
984 case "-a": {
985 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000986 if (emergencyNumberCmd == null){
987 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800988 return -1;
989 }
Grant Menke567d48f2022-08-18 20:19:10 +0000990 String[] params = emergencyNumberCmd.split(":");
991 String emergencyNumber;
992 if (params[0] == null ||
993 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
994 errPw.println(INVALID_ENTRY_ERROR);
995 return -1;
996 } else {
997 emergencyNumber = params[0];
998 }
999 removeEmergencyNumberTestMode(emergencyNumber);
1000 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
1001 if (params.length > 1) {
1002 switch (params[1].toLowerCase(Locale.ROOT)) {
1003 case "emergency":
1004 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1005 break;
1006 case "normal":
1007 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1008 break;
1009 case "unknown":
1010 break;
1011 default:
1012 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1013 + "emergency call routing. Please enter either \"normal\", "
1014 + "\"unknown\", or \"emergency\" for call routing. "
1015 + "(-a 1234:normal)");
1016 return -1;
1017 }
1018 }
sqian9d4df8b2019-01-15 18:32:07 -08001019 try {
1020 mInterface.updateEmergencyNumberListTestMode(
1021 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001022 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001023 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1024 new ArrayList<String>(),
1025 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001026 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001027 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001028 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001029 + ", error " + ex.getMessage());
1030 errPw.println("Exception: " + ex.getMessage());
1031 return -1;
1032 }
1033 break;
1034 }
1035 case "-c": {
1036 try {
1037 mInterface.updateEmergencyNumberListTestMode(
1038 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1039 } catch (RemoteException ex) {
1040 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1041 errPw.println("Exception: " + ex.getMessage());
1042 return -1;
1043 }
1044 break;
1045 }
1046 case "-r": {
1047 String emergencyNumberCmd = getNextArgRequired();
1048 if (emergencyNumberCmd == null
1049 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001050 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001051 + " to be specified after -r in the command ");
1052 return -1;
1053 }
Grant Menke567d48f2022-08-18 20:19:10 +00001054 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001055 break;
1056 }
1057 case "-p": {
1058 try {
1059 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1060 } catch (RemoteException ex) {
1061 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1062 errPw.println("Exception: " + ex.getMessage());
1063 return -1;
1064 }
1065 break;
1066 }
1067 default:
1068 onHelpEmergencyNumber();
1069 break;
1070 }
1071 return 0;
1072 }
1073
Hall Liud892bec2018-11-30 14:51:45 -08001074 private int handleNumberVerificationCommand() {
1075 String arg = getNextArg();
1076 if (arg == null) {
1077 onHelpNumberVerification();
1078 return 0;
1079 }
1080
Hall Liuca5af3a2018-12-04 16:58:23 -08001081 if (!checkShellUid()) {
1082 return -1;
1083 }
1084
Hall Liud892bec2018-11-30 14:51:45 -08001085 switch (arg) {
1086 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001087 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1088 return 0;
1089 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001090 case NUMBER_VERIFICATION_FAKE_CALL: {
1091 boolean val = NumberVerificationManager.getInstance()
1092 .checkIncomingCall(getNextArg());
1093 getOutPrintWriter().println(val ? "1" : "0");
1094 return 0;
1095 }
Hall Liud892bec2018-11-30 14:51:45 -08001096 }
1097
1098 return -1;
1099 }
1100
Jordan Liu0ccee222021-04-27 11:55:13 -07001101 private boolean subIsEsim(int subId) {
1102 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1103 if (info != null) {
1104 return info.isEmbedded();
1105 }
1106 return false;
1107 }
1108
1109 private int handleEnablePhysicalSubscription(boolean enable) {
1110 PrintWriter errPw = getErrPrintWriter();
1111 int subId = 0;
1112 try {
1113 subId = Integer.parseInt(getNextArgRequired());
1114 } catch (NumberFormatException e) {
1115 errPw.println((enable ? "enable" : "disable")
1116 + "-physical-subscription requires an integer as a subId.");
1117 return -1;
1118 }
1119 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1120 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001121 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1122 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001123 errPw.println("cc: Permission denied.");
1124 return -1;
1125 }
1126 // Verify that the subId represents a physical sub
1127 if (subIsEsim(subId)) {
1128 errPw.println("SubId " + subId + " is not for a physical subscription");
1129 return -1;
1130 }
1131 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1132 + " physical subscription with subId=" + subId);
1133 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1134 return 0;
1135 }
1136
Jack Nudelman644b91a2021-03-12 14:09:48 -08001137 private int handleThermalMitigationCommand() {
1138 String arg = getNextArg();
1139 String packageName = getNextArg();
1140 if (arg == null || packageName == null) {
1141 onHelpThermalMitigation();
1142 return 0;
1143 }
1144
1145 if (!checkShellUid()) {
1146 return -1;
1147 }
1148
1149 switch (arg) {
1150 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1151 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1152 return 0;
1153 }
1154 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1155 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1156 mContext);
1157 return 0;
1158 }
1159 default:
1160 onHelpThermalMitigation();
1161 }
1162
1163 return -1;
1164
1165 }
1166
Tyler Gunn92479152021-01-20 16:30:10 -08001167 private int handleD2dCommand() {
1168 String arg = getNextArg();
1169 if (arg == null) {
1170 onHelpD2D();
1171 return 0;
1172 }
1173
1174 switch (arg) {
1175 case D2D_SEND: {
1176 return handleD2dSendCommand();
1177 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001178 case D2D_TRANSPORT: {
1179 return handleD2dTransportCommand();
1180 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001181 case D2D_SET_DEVICE_SUPPORT: {
1182 return handleD2dDeviceSupportedCommand();
1183 }
Tyler Gunn92479152021-01-20 16:30:10 -08001184 }
1185
1186 return -1;
1187 }
1188
1189 private int handleD2dSendCommand() {
1190 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001191 int messageType = -1;
1192 int messageValue = -1;
1193
Tyler Gunn92479152021-01-20 16:30:10 -08001194 String arg = getNextArg();
1195 if (arg == null) {
1196 onHelpD2D();
1197 return 0;
1198 }
1199 try {
1200 messageType = Integer.parseInt(arg);
1201 } catch (NumberFormatException e) {
1202 errPw.println("message type must be a valid integer");
1203 return -1;
1204 }
1205
1206 arg = getNextArg();
1207 if (arg == null) {
1208 onHelpD2D();
1209 return 0;
1210 }
1211 try {
1212 messageValue = Integer.parseInt(arg);
1213 } catch (NumberFormatException e) {
1214 errPw.println("message value must be a valid integer");
1215 return -1;
1216 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001217
Tyler Gunn92479152021-01-20 16:30:10 -08001218 try {
1219 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1220 } catch (RemoteException e) {
1221 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1222 errPw.println("Exception: " + e.getMessage());
1223 return -1;
1224 }
1225
1226 return 0;
1227 }
1228
Tyler Gunnbabbda02021-02-10 11:05:02 -08001229 private int handleD2dTransportCommand() {
1230 PrintWriter errPw = getErrPrintWriter();
1231
1232 String arg = getNextArg();
1233 if (arg == null) {
1234 onHelpD2D();
1235 return 0;
1236 }
1237
1238 try {
1239 mInterface.setActiveDeviceToDeviceTransport(arg);
1240 } catch (RemoteException e) {
1241 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1242 errPw.println("Exception: " + e.getMessage());
1243 return -1;
1244 }
1245 return 0;
1246 }
Nazanin014f41e2021-05-06 17:26:31 -07001247 private int handleBarringCommand() {
1248 String arg = getNextArg();
1249 if (arg == null) {
1250 onHelpBarring();
1251 return 0;
1252 }
1253
1254 switch (arg) {
1255 case BARRING_SEND_INFO: {
1256 return handleBarringSendCommand();
1257 }
1258 }
1259 return -1;
1260 }
1261
1262 private int handleBarringSendCommand() {
1263 PrintWriter errPw = getErrPrintWriter();
1264 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001265 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001266 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1267 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1268 boolean isConditionallyBarred = false;
1269 int conditionalBarringTimeSeconds = 0;
1270
1271 String opt;
1272 while ((opt = getNextOption()) != null) {
1273 switch (opt) {
1274 case "-s": {
1275 try {
1276 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001277 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001278 } catch (NumberFormatException e) {
1279 errPw.println("barring send requires an integer as a SLOT_ID.");
1280 return -1;
1281 }
1282 break;
1283 }
1284 case "-b": {
1285 try {
1286 barringType = Integer.parseInt(getNextArgRequired());
1287 if (barringType < -1 || barringType > 2) {
1288 throw new NumberFormatException();
1289 }
1290
1291 } catch (NumberFormatException e) {
1292 errPw.println("barring send requires an integer in range [-1,2] as "
1293 + "a BARRING_TYPE.");
1294 return -1;
1295 }
1296 break;
1297 }
1298 case "-c": {
1299 try {
1300 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1301 } catch (Exception e) {
1302 errPw.println("barring send requires a boolean after -c indicating"
1303 + " conditional barring");
1304 return -1;
1305 }
1306 break;
1307 }
1308 case "-t": {
1309 try {
1310 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1311 } catch (NumberFormatException e) {
1312 errPw.println("barring send requires an integer for time of barring"
1313 + " in seconds after -t for conditional barring");
1314 return -1;
1315 }
1316 break;
1317 }
1318 }
1319 }
1320 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1321 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1322 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1323 barringServiceInfos.append(0, bsi);
1324 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1325 try {
1326 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1327 } catch (Exception e) {
1328 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1329 errPw.println("Exception: " + e.getMessage());
1330 return -1;
1331 }
1332 return 0;
1333 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001334
Tyler Gunnd4575212021-05-03 14:46:49 -07001335 private int handleD2dDeviceSupportedCommand() {
1336 PrintWriter errPw = getErrPrintWriter();
1337
1338 String arg = getNextArg();
1339 if (arg == null) {
1340 onHelpD2D();
1341 return 0;
1342 }
1343
Jack Yua533d632022-09-30 13:53:46 -07001344 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001345 try {
1346 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1347 } catch (RemoteException e) {
1348 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1349 errPw.println("Exception: " + e.getMessage());
1350 return -1;
1351 }
1352 return 0;
1353 }
1354
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001355 // ims set-ims-service
1356 private int handleImsSetServiceCommand() {
1357 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001358 int slotId = getDefaultSlot();
Brad Ebinger555ddec2024-11-04 13:46:31 -08001359 int userId = UserHandle.USER_NULL; // By default, set no userId constraint
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001360 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001361 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001362
1363 String opt;
1364 while ((opt = getNextOption()) != null) {
1365 switch (opt) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001366 case "-u": {
1367 try {
1368 userId = Integer.parseInt(getNextArgRequired());
1369 } catch (NumberFormatException e) {
1370 errPw.println("ims set-ims-service requires an integer as a USER_ID");
1371 return -1;
1372 }
1373 break;
1374 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001375 case "-s": {
1376 try {
1377 slotId = Integer.parseInt(getNextArgRequired());
1378 } catch (NumberFormatException e) {
1379 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1380 return -1;
1381 }
1382 break;
1383 }
1384 case "-c": {
1385 isCarrierService = true;
1386 break;
1387 }
1388 case "-d": {
1389 isCarrierService = false;
1390 break;
1391 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001392 case "-f": {
1393 String featureString = getNextArgRequired();
1394 String[] features = featureString.split(",");
1395 for (int i = 0; i < features.length; i++) {
1396 try {
1397 Integer result = Integer.parseInt(features[i]);
1398 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1399 || result >= ImsFeature.FEATURE_MAX) {
1400 errPw.println("ims set-ims-service -f " + result
1401 + " is an invalid feature.");
1402 return -1;
1403 }
1404 featuresList.add(result);
1405 } catch (NumberFormatException e) {
1406 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1407 + " as an integer.");
1408 return -1;
1409 }
1410 }
1411 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001412 }
1413 }
1414 // Mandatory param, either -c or -d
1415 if (isCarrierService == null) {
1416 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1417 return -1;
1418 }
1419
1420 String packageName = getNextArg();
1421
1422 try {
1423 if (packageName == null) {
1424 packageName = "";
1425 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001426 int[] featureArray = new int[featuresList.size()];
1427 for (int i = 0; i < featuresList.size(); i++) {
1428 featureArray[i] = featuresList.get(i);
1429 }
Brad Ebinger555ddec2024-11-04 13:46:31 -08001430 boolean result = mInterface.setBoundImsServiceOverride(slotId, userId, isCarrierService,
Brad Ebinger24c29992019-12-05 13:03:21 -08001431 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001432 if (VDBG) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001433 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001434 + (isCarrierService ? "-c " : "-d ")
1435 + "-f " + featuresList + " "
1436 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001437 }
1438 getOutPrintWriter().println(result);
1439 } catch (RemoteException e) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001440 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001441 + (isCarrierService ? "-c " : "-d ")
1442 + "-f " + featuresList + " "
1443 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001444 errPw.println("Exception: " + e.getMessage());
1445 return -1;
1446 }
1447 return 0;
1448 }
1449
Brad Ebinger999d3302020-11-25 14:31:39 -08001450 // ims clear-ims-service-override
1451 private int handleImsClearCarrierServiceCommand() {
1452 PrintWriter errPw = getErrPrintWriter();
1453 int slotId = getDefaultSlot();
1454
1455 String opt;
1456 while ((opt = getNextOption()) != null) {
1457 switch (opt) {
1458 case "-s": {
1459 try {
1460 slotId = Integer.parseInt(getNextArgRequired());
1461 } catch (NumberFormatException e) {
1462 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1463 return -1;
1464 }
1465 break;
1466 }
1467 }
1468 }
1469
1470 try {
1471 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1472 if (VDBG) {
1473 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1474 + ", result=" + result);
1475 }
1476 getOutPrintWriter().println(result);
1477 } catch (RemoteException e) {
1478 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1479 + ", error" + e.getMessage());
1480 errPw.println("Exception: " + e.getMessage());
1481 return -1;
1482 }
1483 return 0;
1484 }
1485
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001486 // ims get-ims-service
1487 private int handleImsGetServiceCommand() {
1488 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001489 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001490 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001491 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001492
1493 String opt;
1494 while ((opt = getNextOption()) != null) {
1495 switch (opt) {
1496 case "-s": {
1497 try {
1498 slotId = Integer.parseInt(getNextArgRequired());
1499 } catch (NumberFormatException e) {
1500 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1501 return -1;
1502 }
1503 break;
1504 }
1505 case "-c": {
1506 isCarrierService = true;
1507 break;
1508 }
1509 case "-d": {
1510 isCarrierService = false;
1511 break;
1512 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001513 case "-f": {
1514 try {
1515 featureType = Integer.parseInt(getNextArg());
1516 } catch (NumberFormatException e) {
1517 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1518 return -1;
1519 }
1520 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1521 || featureType >= ImsFeature.FEATURE_MAX) {
1522 errPw.println("ims get-ims-service -f invalid feature.");
1523 return -1;
1524 }
1525 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001526 }
1527 }
1528 // Mandatory param, either -c or -d
1529 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001530 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001531 return -1;
1532 }
1533
1534 String result;
1535 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001536 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001537 } catch (RemoteException e) {
1538 return -1;
1539 }
1540 if (VDBG) {
1541 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001542 + (isCarrierService ? "-c " : "-d ")
1543 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1544 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001545 }
1546 getOutPrintWriter().println(result);
1547 return 0;
1548 }
1549
1550 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001551 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001552 String opt;
1553 while ((opt = getNextOption()) != null) {
1554 switch (opt) {
1555 case "-s": {
1556 try {
1557 slotId = Integer.parseInt(getNextArgRequired());
1558 } catch (NumberFormatException e) {
1559 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1560 return -1;
1561 }
1562 break;
1563 }
1564 }
1565 }
1566 try {
1567 mInterface.enableIms(slotId);
1568 } catch (RemoteException e) {
1569 return -1;
1570 }
1571 if (VDBG) {
1572 Log.v(LOG_TAG, "ims enable -s " + slotId);
1573 }
1574 return 0;
1575 }
1576
1577 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001578 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001579 String opt;
1580 while ((opt = getNextOption()) != null) {
1581 switch (opt) {
1582 case "-s": {
1583 try {
1584 slotId = Integer.parseInt(getNextArgRequired());
1585 } catch (NumberFormatException e) {
1586 getErrPrintWriter().println(
1587 "ims disable requires an integer as a SLOT_ID.");
1588 return -1;
1589 }
1590 break;
1591 }
1592 }
1593 }
1594 try {
1595 mInterface.disableIms(slotId);
1596 } catch (RemoteException e) {
1597 return -1;
1598 }
1599 if (VDBG) {
1600 Log.v(LOG_TAG, "ims disable -s " + slotId);
1601 }
1602 return 0;
1603 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001604
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001605 private int handleCepChange() {
1606 Log.i(LOG_TAG, "handleCepChange");
1607 String opt = getNextArg();
1608 if (opt == null) {
1609 return -1;
1610 }
1611 boolean isCepEnabled = opt.equals("enable");
1612
1613 try {
1614 mInterface.setCepEnabled(isCepEnabled);
1615 } catch (RemoteException e) {
1616 return -1;
1617 }
1618 return 0;
1619 }
1620
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001621 private int getDefaultSlot() {
1622 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1623 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1624 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1625 // If there is no default, default to slot 0.
1626 slotId = DEFAULT_PHONE_ID;
1627 }
1628 return slotId;
1629 }
sqian2fff4a32018-11-05 14:18:37 -08001630
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001631 // Parse options related to Carrier Config Commands.
1632 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001633 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 CcOptionParseResult result = new CcOptionParseResult();
1635 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1636 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001637
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001638 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001639 while ((opt = getNextOption()) != null) {
1640 switch (opt) {
1641 case "-s": {
1642 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001643 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1644 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1645 errPw.println(tag + "No valid subscription found.");
1646 return null;
1647 }
1648
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001649 } catch (IllegalArgumentException e) {
1650 // Missing slot id
1651 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001652 return null;
1653 }
1654 break;
1655 }
1656 case "-p": {
1657 if (allowOptionPersistent) {
1658 result.mPersistent = true;
1659 } else {
1660 errPw.println(tag + "Unexpected option " + opt);
1661 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001662 }
1663 break;
1664 }
1665 default: {
1666 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001667 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001668 }
1669 }
1670 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001671 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001672 }
1673
1674 private int slotStringToSubId(String tag, String slotString) {
1675 int slotId = -1;
1676 try {
1677 slotId = Integer.parseInt(slotString);
1678 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001679 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1680 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1681 }
1682
1683 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001684 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1685 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1686 }
1687
Qiong Liuf25799b2020-09-10 10:13:46 +08001688 Phone phone = PhoneFactory.getPhone(slotId);
1689 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001690 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1691 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1692 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001693 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001694 }
1695
Hall Liud892bec2018-11-30 14:51:45 -08001696 private boolean checkShellUid() {
Jack Yu26735292024-09-25 14:33:49 -07001697 return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
Hall Liud892bec2018-11-30 14:51:45 -08001698 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001699
1700 private int handleCcCommand() {
1701 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1702 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001703 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1704 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001705 getErrPrintWriter().println("cc: Permission denied.");
1706 return -1;
1707 }
1708
1709 String arg = getNextArg();
1710 if (arg == null) {
1711 onHelpCc();
1712 return 0;
1713 }
1714
1715 switch (arg) {
1716 case CC_GET_VALUE: {
1717 return handleCcGetValue();
1718 }
1719 case CC_SET_VALUE: {
1720 return handleCcSetValue();
1721 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001722 case CC_SET_VALUES_FROM_XML: {
1723 return handleCcSetValuesFromXml();
1724 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001725 case CC_CLEAR_VALUES: {
1726 return handleCcClearValues();
1727 }
1728 default: {
1729 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1730 }
1731 }
1732 return -1;
1733 }
1734
1735 // cc get-value
1736 private int handleCcGetValue() {
1737 PrintWriter errPw = getErrPrintWriter();
1738 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1739 String key = null;
1740
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001741 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001742 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001743 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001744 return -1;
1745 }
1746
1747 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001748 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001749 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001750 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001751 return -1;
1752 }
1753
1754 // Get the key.
1755 key = getNextArg();
1756 if (key != null) {
1757 // A key was provided. Verify if it is a valid key
1758 if (!bundle.containsKey(key)) {
1759 errPw.println(tag + key + " is not a valid key.");
1760 return -1;
1761 }
1762
1763 // Print the carrier config value for key.
1764 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1765 } else {
1766 // No key provided. Show all values.
1767 // Iterate over a sorted list of all carrier config keys and print them.
1768 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1769 for (String k : sortedSet) {
1770 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1771 }
1772 }
1773 return 0;
1774 }
1775
1776 // cc set-value
1777 private int handleCcSetValue() {
1778 PrintWriter errPw = getErrPrintWriter();
1779 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1780
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001781 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001782 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001783 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001784 return -1;
1785 }
1786
1787 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001788 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001789 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001790 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001791 return -1;
1792 }
1793
1794 // Get the key.
1795 String key = getNextArg();
1796 if (key == null || key.equals("")) {
1797 errPw.println(tag + "KEY is missing");
1798 return -1;
1799 }
1800
1801 // Verify if the key is valid
1802 if (!originalValues.containsKey(key)) {
1803 errPw.println(tag + key + " is not a valid key.");
1804 return -1;
1805 }
1806
1807 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1808 ArrayList<String> valueList = new ArrayList<String>();
1809 while (peekNextArg() != null) {
1810 valueList.add(getNextArg());
1811 }
1812
1813 // Find the type of the carrier config value
1814 CcType type = getType(tag, key, originalValues);
1815 if (type == CcType.UNKNOWN) {
1816 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1817 return -1;
1818 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001819 if (type == CcType.PERSISTABLE_BUNDLE) {
1820 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1821 + "Use set-values-from-xml instead.");
1822 return -1;
1823 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001824
1825 // Create an override bundle containing the key and value that should be overriden.
1826 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1827 if (overrideBundle == null) {
1828 return -1;
1829 }
1830
1831 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001832 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001833
1834 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001835 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001836 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001837 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001838 return -1;
1839 }
1840
1841 // Print the original and new value.
1842 String originalValueString = ccValueToString(key, type, originalValues);
1843 String newValueString = ccValueToString(key, type, newValues);
1844 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1845 getOutPrintWriter().println("New value: \n" + newValueString);
1846
1847 return 0;
1848 }
1849
Allen Xuee00f0e2022-03-14 21:04:49 +00001850 // cc set-values-from-xml
1851 private int handleCcSetValuesFromXml() {
1852 PrintWriter errPw = getErrPrintWriter();
1853 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1854
1855 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001856 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001857 if (options == null) {
1858 return -1;
1859 }
1860
1861 // Get bundle containing all current carrier configuration values.
1862 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1863 if (originalValues == null) {
1864 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1865 return -1;
1866 }
1867
1868 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1869 if (overrideBundle == null) {
1870 return -1;
1871 }
1872
1873 // Verify all values are valid types
1874 for (String key : overrideBundle.keySet()) {
1875 CcType type = getType(tag, key, originalValues);
1876 if (type == CcType.UNKNOWN) {
1877 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1878 return -1;
1879 }
1880 }
1881
1882 // Override the value
1883 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1884
1885 // Find bundle containing all new carrier configuration values after the override.
1886 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1887 if (newValues == null) {
1888 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1889 return -1;
1890 }
1891
1892 // Print the original and new values
1893 overrideBundle.keySet().forEach(key -> {
1894 CcType type = getType(tag, key, originalValues);
1895 String originalValueString = ccValueToString(key, type, originalValues);
1896 String newValueString = ccValueToString(key, type, newValues);
1897 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1898 getOutPrintWriter().println("New value: \n" + newValueString);
1899 });
1900
1901 return 0;
1902 }
1903
1904 private PersistableBundle readPersistableBundleFromXml(String tag) {
1905 PersistableBundle subIdBundles;
1906 try {
1907 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1908 } catch (IOException | RuntimeException e) {
1909 PrintWriter errPw = getErrPrintWriter();
1910 errPw.println(tag + e);
1911 return null;
1912 }
1913
1914 return subIdBundles;
1915 }
1916
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001917 // cc clear-values
1918 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001919 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1920
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001921 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001922 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001923 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001924 return -1;
1925 }
1926
1927 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001928 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001929 getOutPrintWriter()
1930 .println("All previously set carrier config override values has been cleared");
1931 return 0;
1932 }
1933
1934 private CcType getType(String tag, String key, PersistableBundle bundle) {
1935 // Find the type by checking the type of the current value stored in the bundle.
1936 Object value = bundle.get(key);
1937
1938 if (CC_TYPE_MAP.containsKey(key)) {
1939 return CC_TYPE_MAP.get(key);
1940 } else if (value != null) {
1941 if (value instanceof Boolean) {
1942 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001943 }
1944 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001945 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 }
1947 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001948 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001949 }
1950 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001951 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001952 }
1953 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001954 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 }
1956 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001957 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001958 }
1959 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001960 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001961 }
1962 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001963 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001964 }
1965 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001966 return CcType.STRING_ARRAY;
1967 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001968 if (value instanceof PersistableBundle) {
1969 return CcType.PERSISTABLE_BUNDLE;
1970 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001971 } else {
1972 // Current value was null and can therefore not be used in order to find the type.
1973 // Check the name of the key to infer the type. This check is not needed for primitive
1974 // data types (boolean, double, int and long), since they can not be null.
1975 if (key.endsWith("double_array")) {
1976 return CcType.DOUBLE_ARRAY;
1977 }
1978 if (key.endsWith("int_array")) {
1979 return CcType.INT_ARRAY;
1980 }
1981 if (key.endsWith("long_array")) {
1982 return CcType.LONG_ARRAY;
1983 }
1984 if (key.endsWith("string")) {
1985 return CcType.STRING;
1986 }
1987 if (key.endsWith("string_array") || key.endsWith("strings")) {
1988 return CcType.STRING_ARRAY;
1989 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001990 if (key.endsWith("bundle")) {
1991 return CcType.PERSISTABLE_BUNDLE;
1992 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001993 }
1994
1995 // Not possible to infer the type by looking at the current value or the key.
1996 PrintWriter errPw = getErrPrintWriter();
1997 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1998 return CcType.UNKNOWN;
1999 }
2000
2001 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
2002 String result;
2003 StringBuilder valueString = new StringBuilder();
2004 String typeString = type.toString();
2005 Object value = bundle.get(key);
2006
2007 if (value == null) {
2008 valueString.append("null");
2009 } else {
2010 switch (type) {
2011 case DOUBLE_ARRAY: {
2012 // Format the string representation of the int array as value1 value2......
2013 double[] valueArray = (double[]) value;
2014 for (int i = 0; i < valueArray.length; i++) {
2015 if (i != 0) {
2016 valueString.append(" ");
2017 }
2018 valueString.append(valueArray[i]);
2019 }
2020 break;
2021 }
2022 case INT_ARRAY: {
2023 // Format the string representation of the int array as value1 value2......
2024 int[] valueArray = (int[]) value;
2025 for (int i = 0; i < valueArray.length; i++) {
2026 if (i != 0) {
2027 valueString.append(" ");
2028 }
2029 valueString.append(valueArray[i]);
2030 }
2031 break;
2032 }
2033 case LONG_ARRAY: {
2034 // Format the string representation of the int array as value1 value2......
2035 long[] valueArray = (long[]) value;
2036 for (int i = 0; i < valueArray.length; i++) {
2037 if (i != 0) {
2038 valueString.append(" ");
2039 }
2040 valueString.append(valueArray[i]);
2041 }
2042 break;
2043 }
2044 case STRING: {
2045 valueString.append("\"" + value.toString() + "\"");
2046 break;
2047 }
2048 case STRING_ARRAY: {
2049 // Format the string representation of the string array as "value1" "value2"....
2050 String[] valueArray = (String[]) value;
2051 for (int i = 0; i < valueArray.length; i++) {
2052 if (i != 0) {
2053 valueString.append(" ");
2054 }
2055 if (valueArray[i] != null) {
2056 valueString.append("\"" + valueArray[i] + "\"");
2057 } else {
2058 valueString.append("null");
2059 }
2060 }
2061 break;
2062 }
2063 default: {
2064 valueString.append(value.toString());
2065 }
2066 }
2067 }
2068 return String.format("%-70s %-15s %s", key, typeString, valueString);
2069 }
2070
2071 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2072 ArrayList<String> valueList) {
2073 PrintWriter errPw = getErrPrintWriter();
2074 PersistableBundle bundle = new PersistableBundle();
2075
2076 // First verify that a valid number of values has been provided for the type.
2077 switch (type) {
2078 case BOOLEAN:
2079 case DOUBLE:
2080 case INT:
2081 case LONG: {
2082 if (valueList.size() != 1) {
2083 errPw.println(tag + "Expected 1 value for type " + type
2084 + ". Found: " + valueList.size());
2085 return null;
2086 }
2087 break;
2088 }
2089 case STRING: {
2090 if (valueList.size() > 1) {
2091 errPw.println(tag + "Expected 0 or 1 values for type " + type
2092 + ". Found: " + valueList.size());
2093 return null;
2094 }
2095 break;
2096 }
2097 }
2098
2099 // Parse the value according to type and add it to the Bundle.
2100 switch (type) {
2101 case BOOLEAN: {
2102 if ("true".equalsIgnoreCase(valueList.get(0))) {
2103 bundle.putBoolean(key, true);
2104 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2105 bundle.putBoolean(key, false);
2106 } else {
2107 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2108 return null;
2109 }
2110 break;
2111 }
2112 case DOUBLE: {
2113 try {
2114 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2115 } catch (NumberFormatException nfe) {
2116 // Not a valid double
2117 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2118 return null;
2119 }
2120 break;
2121 }
2122 case DOUBLE_ARRAY: {
2123 double[] valueDoubleArray = null;
2124 if (valueList.size() > 0) {
2125 valueDoubleArray = new double[valueList.size()];
2126 for (int i = 0; i < valueList.size(); i++) {
2127 try {
2128 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2129 } catch (NumberFormatException nfe) {
2130 // Not a valid double
2131 errPw.println(
2132 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2133 return null;
2134 }
2135 }
2136 }
2137 bundle.putDoubleArray(key, valueDoubleArray);
2138 break;
2139 }
2140 case INT: {
2141 try {
2142 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2143 } catch (NumberFormatException nfe) {
2144 // Not a valid integer
2145 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2146 return null;
2147 }
2148 break;
2149 }
2150 case INT_ARRAY: {
2151 int[] valueIntArray = null;
2152 if (valueList.size() > 0) {
2153 valueIntArray = new int[valueList.size()];
2154 for (int i = 0; i < valueList.size(); i++) {
2155 try {
2156 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2157 } catch (NumberFormatException nfe) {
2158 // Not a valid integer
2159 errPw.println(tag
2160 + "Unable to parse " + valueList.get(i) + " as an integer.");
2161 return null;
2162 }
2163 }
2164 }
2165 bundle.putIntArray(key, valueIntArray);
2166 break;
2167 }
2168 case LONG: {
2169 try {
2170 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2171 } catch (NumberFormatException nfe) {
2172 // Not a valid long
2173 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2174 return null;
2175 }
2176 break;
2177 }
2178 case LONG_ARRAY: {
2179 long[] valueLongArray = null;
2180 if (valueList.size() > 0) {
2181 valueLongArray = new long[valueList.size()];
2182 for (int i = 0; i < valueList.size(); i++) {
2183 try {
2184 valueLongArray[i] = Long.parseLong(valueList.get(i));
2185 } catch (NumberFormatException nfe) {
2186 // Not a valid long
2187 errPw.println(
2188 tag + "Unable to parse " + valueList.get(i) + " as a long");
2189 return null;
2190 }
2191 }
2192 }
2193 bundle.putLongArray(key, valueLongArray);
2194 break;
2195 }
2196 case STRING: {
2197 String value = null;
2198 if (valueList.size() > 0) {
2199 value = valueList.get(0);
2200 }
2201 bundle.putString(key, value);
2202 break;
2203 }
2204 case STRING_ARRAY: {
2205 String[] valueStringArray = null;
2206 if (valueList.size() > 0) {
2207 valueStringArray = new String[valueList.size()];
2208 valueList.toArray(valueStringArray);
2209 }
2210 bundle.putStringArray(key, valueStringArray);
2211 break;
2212 }
2213 }
2214 return bundle;
2215 }
Shuo Qian489d9282020-07-09 11:30:03 -07002216
2217 private int handleEndBlockSuppressionCommand() {
2218 if (!checkShellUid()) {
2219 return -1;
2220 }
2221
2222 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2223 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2224 }
2225 return 0;
2226 }
Hui Wang641e81c2020-10-12 12:14:23 -07002227
Michele Berionne54af4632020-12-28 20:23:16 +00002228 private int handleRestartModemCommand() {
2229 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2230 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002231 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2232 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002233 getErrPrintWriter().println("RestartModem: Permission denied.");
2234 return -1;
2235 }
2236
2237 boolean result = TelephonyManager.getDefault().rebootRadio();
2238 getOutPrintWriter().println(result);
2239
2240 return result ? 0 : -1;
2241 }
2242
Ling Ma4fbab492022-01-25 22:36:16 +00002243 private int handleGetImei() {
2244 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2245 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002246 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2247 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002248 getErrPrintWriter().println("Device IMEI: Permission denied.");
2249 return -1;
2250 }
2251
2252 final long identity = Binder.clearCallingIdentity();
2253
2254 String imei = null;
2255 String arg = getNextArg();
2256 if (arg != null) {
2257 try {
2258 int specifiedSlotIndex = Integer.parseInt(arg);
2259 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2260 } catch (NumberFormatException exception) {
2261 PrintWriter errPw = getErrPrintWriter();
2262 errPw.println("-s requires an integer as slot index.");
2263 return -1;
2264 }
2265
2266 } else {
2267 imei = TelephonyManager.from(mContext).getImei();
2268 }
2269 getOutPrintWriter().println("Device IMEI: " + imei);
2270
2271 Binder.restoreCallingIdentity(identity);
2272 return 0;
2273 }
2274
Michele Berionne5e411512020-11-13 02:36:59 +00002275 private int handleUnattendedReboot() {
2276 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2277 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002278 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2279 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002280 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2281 return -1;
2282 }
2283
2284 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2285 getOutPrintWriter().println("result: " + result);
2286
2287 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2288 }
2289
Aman Gupta07124872022-02-09 08:02:14 +00002290 private int handleGetSimSlotsMapping() {
2291 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2292 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002293 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2294 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002295 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2296 return -1;
2297 }
2298 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2299 String result = telephonyManager.getSimSlotMapping().toString();
2300 getOutPrintWriter().println("simSlotsMapping: " + result);
2301
2302 return 0;
2303 }
2304
Hui Wang641e81c2020-10-12 12:14:23 -07002305 private int handleGbaCommand() {
2306 String arg = getNextArg();
2307 if (arg == null) {
2308 onHelpGba();
2309 return 0;
2310 }
2311
2312 switch (arg) {
2313 case GBA_SET_SERVICE: {
2314 return handleGbaSetServiceCommand();
2315 }
2316 case GBA_GET_SERVICE: {
2317 return handleGbaGetServiceCommand();
2318 }
2319 case GBA_SET_RELEASE_TIME: {
2320 return handleGbaSetReleaseCommand();
2321 }
2322 case GBA_GET_RELEASE_TIME: {
2323 return handleGbaGetReleaseCommand();
2324 }
2325 }
2326
2327 return -1;
2328 }
2329
2330 private int getSubId(String cmd) {
2331 int slotId = getDefaultSlot();
2332 String opt = getNextOption();
2333 if (opt != null && opt.equals("-s")) {
2334 try {
2335 slotId = Integer.parseInt(getNextArgRequired());
2336 } catch (NumberFormatException e) {
2337 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2338 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2339 }
2340 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002341 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002342 }
2343
2344 private int handleGbaSetServiceCommand() {
2345 int subId = getSubId("gba set-service");
2346 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2347 return -1;
2348 }
2349
2350 String packageName = getNextArg();
2351 try {
2352 if (packageName == null) {
2353 packageName = "";
2354 }
2355 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2356 if (VDBG) {
2357 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2358 + packageName + ", result=" + result);
2359 }
2360 getOutPrintWriter().println(result);
2361 } catch (RemoteException e) {
2362 Log.w(LOG_TAG, "gba set-service " + subId + " "
2363 + packageName + ", error" + e.getMessage());
2364 getErrPrintWriter().println("Exception: " + e.getMessage());
2365 return -1;
2366 }
2367 return 0;
2368 }
2369
2370 private int handleGbaGetServiceCommand() {
2371 String result;
2372
2373 int subId = getSubId("gba get-service");
2374 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2375 return -1;
2376 }
2377
2378 try {
2379 result = mInterface.getBoundGbaService(subId);
2380 } catch (RemoteException e) {
2381 return -1;
2382 }
2383 if (VDBG) {
2384 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2385 }
2386 getOutPrintWriter().println(result);
2387 return 0;
2388 }
2389
2390 private int handleGbaSetReleaseCommand() {
2391 //the release time value could be -1
2392 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2393 : SubscriptionManager.getDefaultSubscriptionId();
2394 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2395 return -1;
2396 }
2397
2398 String intervalStr = getNextArg();
2399 if (intervalStr == null) {
2400 return -1;
2401 }
2402
2403 try {
2404 int interval = Integer.parseInt(intervalStr);
2405 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2406 if (VDBG) {
2407 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2408 + intervalStr + ", result=" + result);
2409 }
2410 getOutPrintWriter().println(result);
2411 } catch (NumberFormatException | RemoteException e) {
2412 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2413 + intervalStr + ", error" + e.getMessage());
2414 getErrPrintWriter().println("Exception: " + e.getMessage());
2415 return -1;
2416 }
2417 return 0;
2418 }
2419
2420 private int handleGbaGetReleaseCommand() {
2421 int subId = getSubId("gba get-release");
2422 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2423 return -1;
2424 }
2425
2426 int result = 0;
2427 try {
2428 result = mInterface.getGbaReleaseTime(subId);
2429 } catch (RemoteException e) {
2430 return -1;
2431 }
2432 if (VDBG) {
2433 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2434 }
2435 getOutPrintWriter().println(result);
2436 return 0;
2437 }
Hui Wang761a6682020-10-31 05:12:53 +00002438
2439 private int handleSingleRegistrationConfigCommand() {
2440 String arg = getNextArg();
2441 if (arg == null) {
2442 onHelpSrc();
2443 return 0;
2444 }
2445
2446 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002447 case SRC_SET_TEST_ENABLED: {
2448 return handleSrcSetTestEnabledCommand();
2449 }
2450 case SRC_GET_TEST_ENABLED: {
2451 return handleSrcGetTestEnabledCommand();
2452 }
Hui Wang761a6682020-10-31 05:12:53 +00002453 case SRC_SET_DEVICE_ENABLED: {
2454 return handleSrcSetDeviceEnabledCommand();
2455 }
2456 case SRC_GET_DEVICE_ENABLED: {
2457 return handleSrcGetDeviceEnabledCommand();
2458 }
2459 case SRC_SET_CARRIER_ENABLED: {
2460 return handleSrcSetCarrierEnabledCommand();
2461 }
2462 case SRC_GET_CARRIER_ENABLED: {
2463 return handleSrcGetCarrierEnabledCommand();
2464 }
Hui Wangb647abe2021-02-26 09:33:38 -08002465 case SRC_SET_FEATURE_ENABLED: {
2466 return handleSrcSetFeatureValidationCommand();
2467 }
2468 case SRC_GET_FEATURE_ENABLED: {
2469 return handleSrcGetFeatureValidationCommand();
2470 }
Hui Wang761a6682020-10-31 05:12:53 +00002471 }
2472
2473 return -1;
2474 }
2475
James.cf Linbcdf8b32021-01-14 16:44:13 +08002476 private int handleRcsUceCommand() {
2477 String arg = getNextArg();
2478 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002479 onHelpUce();
2480 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002481 }
2482
2483 switch (arg) {
2484 case UCE_REMOVE_EAB_CONTACT:
2485 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002486 case UCE_GET_EAB_CONTACT:
2487 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002488 case UCE_GET_EAB_CAPABILITY:
2489 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002490 case UCE_GET_DEVICE_ENABLED:
2491 return handleUceGetDeviceEnabledCommand();
2492 case UCE_SET_DEVICE_ENABLED:
2493 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002494 case UCE_OVERRIDE_PUBLISH_CAPS:
2495 return handleUceOverridePublishCaps();
2496 case UCE_GET_LAST_PIDF_XML:
2497 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002498 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2499 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002500 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2501 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002502 }
2503 return -1;
2504 }
2505
2506 private int handleRemovingEabContactCommand() {
2507 int subId = getSubId("uce remove-eab-contact");
2508 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2509 return -1;
2510 }
2511
2512 String phoneNumber = getNextArgRequired();
2513 if (TextUtils.isEmpty(phoneNumber)) {
2514 return -1;
2515 }
2516 int result = 0;
2517 try {
2518 result = mInterface.removeContactFromEab(subId, phoneNumber);
2519 } catch (RemoteException e) {
2520 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2521 getErrPrintWriter().println("Exception: " + e.getMessage());
2522 return -1;
2523 }
2524
2525 if (VDBG) {
2526 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2527 }
calvinpan293ea1b2021-02-04 17:52:13 +08002528 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002529 }
2530
calvinpane4a8a1d2021-01-25 13:51:18 +08002531 private int handleGettingEabContactCommand() {
2532 String phoneNumber = getNextArgRequired();
2533 if (TextUtils.isEmpty(phoneNumber)) {
2534 return -1;
2535 }
2536 String result = "";
2537 try {
2538 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002539 } catch (RemoteException e) {
2540 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2541 getErrPrintWriter().println("Exception: " + e.getMessage());
2542 return -1;
2543 }
2544
2545 if (VDBG) {
2546 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2547 }
calvinpan293ea1b2021-02-04 17:52:13 +08002548 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002549 return 0;
2550 }
2551
Calvin Pana1434322021-07-01 19:27:01 +08002552 private int handleGettingEabCapabilityCommand() {
2553 String phoneNumber = getNextArgRequired();
2554 if (TextUtils.isEmpty(phoneNumber)) {
2555 return -1;
2556 }
2557 String result = "";
2558 try {
2559 result = mInterface.getCapabilityFromEab(phoneNumber);
2560 } catch (RemoteException e) {
2561 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2562 getErrPrintWriter().println("Exception: " + e.getMessage());
2563 return -1;
2564 }
2565
2566 if (VDBG) {
2567 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2568 }
2569 getOutPrintWriter().println(result);
2570 return 0;
2571 }
2572
James.cf Lin4b784aa2021-01-31 03:25:15 +08002573 private int handleUceGetDeviceEnabledCommand() {
2574 boolean result = false;
2575 try {
2576 result = mInterface.getDeviceUceEnabled();
2577 } catch (RemoteException e) {
2578 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2579 return -1;
2580 }
2581 if (VDBG) {
2582 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2583 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002584 getOutPrintWriter().println(result);
2585 return 0;
2586 }
2587
James.cf Lin4b784aa2021-01-31 03:25:15 +08002588 private int handleUceSetDeviceEnabledCommand() {
2589 String enabledStr = getNextArg();
2590 if (TextUtils.isEmpty(enabledStr)) {
2591 return -1;
2592 }
2593
2594 try {
2595 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2596 mInterface.setDeviceUceEnabled(isEnabled);
2597 if (VDBG) {
2598 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2599 }
2600 } catch (NumberFormatException | RemoteException e) {
2601 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2602 getErrPrintWriter().println("Exception: " + e.getMessage());
2603 return -1;
2604 }
2605 return 0;
2606 }
2607
James.cf Line8713a42021-04-29 16:04:26 +08002608 private int handleUceRemoveRequestDisallowedStatus() {
2609 int subId = getSubId("uce remove-request-disallowed-status");
2610 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2611 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2612 return -1;
2613 }
2614 boolean result;
2615 try {
2616 result = mInterface.removeUceRequestDisallowedStatus(subId);
2617 } catch (RemoteException e) {
2618 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2619 return -1;
2620 }
2621 if (VDBG) {
2622 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2623 }
2624 getOutPrintWriter().println(result);
2625 return 0;
2626 }
2627
James.cf Lin0fc71b02021-05-25 01:37:38 +08002628 private int handleUceSetCapRequestTimeout() {
2629 int subId = getSubId("uce set-capabilities-request-timeout");
2630 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2631 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2632 return -1;
2633 }
2634 long timeoutAfterMs = Long.valueOf(getNextArg());
2635 boolean result;
2636 try {
2637 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2638 } catch (RemoteException e) {
2639 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2640 return -1;
2641 }
2642 if (VDBG) {
2643 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2644 }
2645 getOutPrintWriter().println(result);
2646 return 0;
2647 }
2648
Hui Wangbaaee6a2021-02-19 20:45:36 -08002649 private int handleSrcSetTestEnabledCommand() {
2650 String enabledStr = getNextArg();
2651 if (enabledStr == null) {
2652 return -1;
2653 }
2654
2655 try {
2656 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2657 if (VDBG) {
2658 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2659 }
2660 getOutPrintWriter().println("Done");
2661 } catch (NumberFormatException | RemoteException e) {
2662 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2663 getErrPrintWriter().println("Exception: " + e.getMessage());
2664 return -1;
2665 }
2666 return 0;
2667 }
2668
2669 private int handleSrcGetTestEnabledCommand() {
2670 boolean result = false;
2671 try {
2672 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2673 } catch (RemoteException e) {
2674 return -1;
2675 }
2676 if (VDBG) {
2677 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2678 }
2679 getOutPrintWriter().println(result);
2680 return 0;
2681 }
2682
Brad Ebinger14d467f2021-02-12 06:18:28 +00002683 private int handleUceOverridePublishCaps() {
2684 int subId = getSubId("uce override-published-caps");
2685 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2686 return -1;
2687 }
2688 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2689 String operation = getNextArgRequired();
2690 String caps = getNextArg();
2691 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2692 && !"list".equals(operation)) {
2693 getErrPrintWriter().println("Invalid operation: " + operation);
2694 return -1;
2695 }
2696
2697 // add/remove requires capabilities to be specified.
2698 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2699 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2700 + "specified");
2701 return -1;
2702 }
2703
2704 ArraySet<String> capSet = new ArraySet<>();
2705 if (!TextUtils.isEmpty(caps)) {
2706 String[] capArray = caps.split(":");
2707 for (String cap : capArray) {
2708 // Allow unknown tags to be passed in as well.
2709 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2710 }
2711 }
2712
2713 RcsContactUceCapability result = null;
2714 try {
2715 switch (operation) {
2716 case "add":
2717 result = mInterface.addUceRegistrationOverrideShell(subId,
2718 new ArrayList<>(capSet));
2719 break;
2720 case "remove":
2721 result = mInterface.removeUceRegistrationOverrideShell(subId,
2722 new ArrayList<>(capSet));
2723 break;
2724 case "clear":
2725 result = mInterface.clearUceRegistrationOverrideShell(subId);
2726 break;
2727 case "list":
2728 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2729 break;
2730 }
2731 } catch (RemoteException e) {
2732 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2733 getErrPrintWriter().println("Exception: " + e.getMessage());
2734 return -1;
2735 } catch (ServiceSpecificException sse) {
2736 // Reconstruct ImsException
2737 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2738 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2739 getErrPrintWriter().println("Exception: " + imsException);
2740 return -1;
2741 }
2742 if (result == null) {
2743 getErrPrintWriter().println("Service not available");
2744 return -1;
2745 }
2746 getOutPrintWriter().println(result);
2747 return 0;
2748 }
2749
2750 private int handleUceGetPidfXml() {
2751 int subId = getSubId("uce get-last-publish-pidf");
2752 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2753 return -1;
2754 }
2755
2756 String result;
2757 try {
2758 result = mInterface.getLastUcePidfXmlShell(subId);
2759 } catch (RemoteException e) {
2760 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2761 getErrPrintWriter().println("Exception: " + e.getMessage());
2762 return -1;
2763 } catch (ServiceSpecificException sse) {
2764 // Reconstruct ImsException
2765 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2766 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2767 getErrPrintWriter().println("Exception: " + imsException);
2768 return -1;
2769 }
2770 if (result == null) {
2771 getErrPrintWriter().println("Service not available");
2772 return -1;
2773 }
2774 getOutPrintWriter().println(result);
2775 return 0;
2776 }
2777
Hui Wang761a6682020-10-31 05:12:53 +00002778 private int handleSrcSetDeviceEnabledCommand() {
2779 String enabledStr = getNextArg();
2780 if (enabledStr == null) {
2781 return -1;
2782 }
2783
2784 try {
2785 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2786 if (VDBG) {
2787 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2788 }
2789 getOutPrintWriter().println("Done");
2790 } catch (NumberFormatException | RemoteException e) {
2791 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2792 getErrPrintWriter().println("Exception: " + e.getMessage());
2793 return -1;
2794 }
2795 return 0;
2796 }
2797
2798 private int handleSrcGetDeviceEnabledCommand() {
2799 boolean result = false;
2800 try {
2801 result = mInterface.getDeviceSingleRegistrationEnabled();
2802 } catch (RemoteException e) {
2803 return -1;
2804 }
2805 if (VDBG) {
2806 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2807 }
2808 getOutPrintWriter().println(result);
2809 return 0;
2810 }
2811
2812 private int handleSrcSetCarrierEnabledCommand() {
2813 //the release time value could be -1
2814 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2815 : SubscriptionManager.getDefaultSubscriptionId();
2816 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2817 return -1;
2818 }
2819
2820 String enabledStr = getNextArg();
2821 if (enabledStr == null) {
2822 return -1;
2823 }
2824
2825 try {
2826 boolean result =
2827 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2828 if (VDBG) {
2829 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2830 + enabledStr + ", result=" + result);
2831 }
2832 getOutPrintWriter().println(result);
2833 } catch (NumberFormatException | RemoteException e) {
2834 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2835 + enabledStr + ", error" + e.getMessage());
2836 getErrPrintWriter().println("Exception: " + e.getMessage());
2837 return -1;
2838 }
2839 return 0;
2840 }
2841
2842 private int handleSrcGetCarrierEnabledCommand() {
2843 int subId = getSubId("src get-carrier-enabled");
2844 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2845 return -1;
2846 }
2847
2848 boolean result = false;
2849 try {
2850 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2851 } catch (RemoteException e) {
2852 return -1;
2853 }
2854 if (VDBG) {
2855 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2856 }
2857 getOutPrintWriter().println(result);
2858 return 0;
2859 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002860
Hui Wangb647abe2021-02-26 09:33:38 -08002861 private int handleSrcSetFeatureValidationCommand() {
2862 //the release time value could be -1
2863 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2864 : SubscriptionManager.getDefaultSubscriptionId();
2865 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2866 return -1;
2867 }
2868
2869 String enabledStr = getNextArg();
2870 if (enabledStr == null) {
2871 return -1;
2872 }
2873
2874 try {
2875 boolean result =
2876 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2877 if (VDBG) {
2878 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2879 + enabledStr + ", result=" + result);
2880 }
2881 getOutPrintWriter().println(result);
2882 } catch (NumberFormatException | RemoteException e) {
2883 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2884 + enabledStr + ", error" + e.getMessage());
2885 getErrPrintWriter().println("Exception: " + e.getMessage());
2886 return -1;
2887 }
2888 return 0;
2889 }
2890
2891 private int handleSrcGetFeatureValidationCommand() {
2892 int subId = getSubId("src get-feature-validation");
2893 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2894 return -1;
2895 }
2896
2897 Boolean result = false;
2898 try {
2899 result = mInterface.getImsFeatureValidationOverride(subId);
2900 } catch (RemoteException e) {
2901 return -1;
2902 }
2903 if (VDBG) {
2904 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2905 }
2906 getOutPrintWriter().println(result);
2907 return 0;
2908 }
2909
2910
Hall Liuaa4211e2021-01-20 15:43:39 -08002911 private void onHelpCallComposer() {
2912 PrintWriter pw = getOutPrintWriter();
2913 pw.println("Call composer commands");
2914 pw.println(" callcomposer test-mode enable|disable|query");
2915 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2916 pw.println(" upload/download from carrier servers is disabled, and operations are");
2917 pw.println(" performed using emulated local files instead.");
2918 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2919 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2920 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002921 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2922 pw.println(" Enables or disables the user setting for call composer, as set by");
2923 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002924 }
2925
2926 private int handleCallComposerCommand() {
2927 String arg = getNextArg();
2928 if (arg == null) {
2929 onHelpCallComposer();
2930 return 0;
2931 }
2932
2933 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2934 "MODIFY_PHONE_STATE required for call composer shell cmds");
2935 switch (arg) {
2936 case CALL_COMPOSER_TEST_MODE: {
2937 String enabledStr = getNextArg();
2938 if (ENABLE.equals(enabledStr)) {
2939 CallComposerPictureManager.sTestMode = true;
2940 } else if (DISABLE.equals(enabledStr)) {
2941 CallComposerPictureManager.sTestMode = false;
2942 } else if (QUERY.equals(enabledStr)) {
2943 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2944 } else {
2945 onHelpCallComposer();
2946 return 1;
2947 }
2948 break;
2949 }
2950 case CALL_COMPOSER_SIMULATE_CALL: {
2951 int subscriptionId = Integer.valueOf(getNextArg());
2952 String uuidString = getNextArg();
2953 UUID uuid = UUID.fromString(uuidString);
2954 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2955 Binder.withCleanCallingIdentity(() -> {
2956 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2957 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2958 });
2959 try {
2960 Uri uri = storageUriFuture.get();
2961 getOutPrintWriter().println(String.valueOf(uri));
2962 } catch (Exception e) {
2963 throw new RuntimeException(e);
2964 }
2965 break;
2966 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002967 case CALL_COMPOSER_USER_SETTING: {
2968 try {
2969 int subscriptionId = Integer.valueOf(getNextArg());
2970 String enabledStr = getNextArg();
2971 if (ENABLE.equals(enabledStr)) {
2972 mInterface.setCallComposerStatus(subscriptionId,
2973 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2974 } else if (DISABLE.equals(enabledStr)) {
2975 mInterface.setCallComposerStatus(subscriptionId,
2976 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2977 } else if (QUERY.equals(enabledStr)) {
2978 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2979 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2980 } else {
2981 onHelpCallComposer();
2982 return 1;
2983 }
2984 } catch (RemoteException e) {
2985 e.printStackTrace(getOutPrintWriter());
2986 return 1;
2987 }
2988 break;
2989 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002990 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002991 return 0;
2992 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002993
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002994 private int handleHasCarrierPrivilegesCommand() {
2995 String packageName = getNextArgRequired();
2996
2997 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002998 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002999 try {
3000 hasCarrierPrivileges =
3001 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3002 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3003 } catch (RemoteException e) {
3004 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3005 getErrPrintWriter().println("Exception: " + e.getMessage());
3006 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003007 } finally {
3008 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003009 }
3010
3011 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003012 return 0;
3013 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003014
3015 private int handleAllowedNetworkTypesCommand(String command) {
3016 if (!checkShellUid()) {
3017 return -1;
3018 }
3019
3020 PrintWriter errPw = getErrPrintWriter();
3021 String tag = command + ": ";
3022 String opt;
3023 int subId = -1;
3024 Log.v(LOG_TAG, command + " start");
3025
3026 while ((opt = getNextOption()) != null) {
3027 if (opt.equals("-s")) {
3028 try {
3029 subId = slotStringToSubId(tag, getNextArgRequired());
3030 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3031 errPw.println(tag + "No valid subscription found.");
3032 return -1;
3033 }
3034 } catch (IllegalArgumentException e) {
3035 // Missing slot id
3036 errPw.println(tag + "SLOT_ID expected after -s.");
3037 return -1;
3038 }
3039 } else {
3040 errPw.println(tag + "Unknown option " + opt);
3041 return -1;
3042 }
3043 }
3044
3045 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3046 return handleGetAllowedNetworkTypesCommand(subId);
3047 }
3048 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3049 return handleSetAllowedNetworkTypesCommand(subId);
3050 }
3051 return -1;
3052 }
3053
3054 private int handleGetAllowedNetworkTypesCommand(int subId) {
3055 PrintWriter errPw = getErrPrintWriter();
3056
3057 long result = -1;
3058 try {
3059 if (mInterface != null) {
3060 result = mInterface.getAllowedNetworkTypesForReason(subId,
3061 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3062 } else {
3063 throw new IllegalStateException("telephony service is null.");
3064 }
3065 } catch (RemoteException e) {
3066 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3067 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3068 return -1;
3069 }
3070
3071 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3072 return 0;
3073 }
3074
3075 private int handleSetAllowedNetworkTypesCommand(int subId) {
3076 PrintWriter errPw = getErrPrintWriter();
3077
3078 String bitmaskString = getNextArg();
3079 if (TextUtils.isEmpty(bitmaskString)) {
3080 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3081 return -1;
3082 }
3083 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3084 if (allowedNetworkTypes < 0) {
3085 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3086 return -1;
3087 }
3088 boolean result = false;
3089 try {
3090 if (mInterface != null) {
3091 result = mInterface.setAllowedNetworkTypesForReason(subId,
3092 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3093 } else {
3094 throw new IllegalStateException("telephony service is null.");
3095 }
3096 } catch (RemoteException e) {
3097 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3098 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3099 return -1;
3100 }
3101
3102 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3103 if (result) {
3104 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3105 }
3106 getOutPrintWriter().println(resultMessage);
3107 return 0;
3108 }
3109
3110 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3111 if (TextUtils.isEmpty(bitmaskString)) {
3112 return -1;
3113 }
3114 if (VDBG) {
3115 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3116 + ", length: " + bitmaskString.length());
3117 }
3118 try {
3119 return Long.parseLong(bitmaskString, 2);
3120 } catch (NumberFormatException e) {
3121 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3122 return -1;
3123 }
3124 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003125
jimsun3b9ccac2021-10-26 15:01:23 +08003126 private int handleRadioSetModemServiceCommand() {
3127 PrintWriter errPw = getErrPrintWriter();
3128 String serviceName = null;
3129
3130 String opt;
3131 while ((opt = getNextOption()) != null) {
3132 switch (opt) {
3133 case "-s": {
3134 serviceName = getNextArgRequired();
3135 break;
3136 }
3137 }
3138 }
3139
3140 try {
3141 boolean result = mInterface.setModemService(serviceName);
3142 if (VDBG) {
3143 Log.v(LOG_TAG,
3144 "RadioSetModemService " + serviceName + ", result = " + result);
3145 }
3146 getOutPrintWriter().println(result);
3147 } catch (RemoteException e) {
3148 Log.w(LOG_TAG,
3149 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3150 errPw.println("Exception: " + e.getMessage());
3151 return -1;
3152 }
3153 return 0;
3154 }
3155
3156 private int handleRadioGetModemServiceCommand() {
3157 PrintWriter errPw = getErrPrintWriter();
3158 String result;
3159
3160 try {
3161 result = mInterface.getModemService();
3162 getOutPrintWriter().println(result);
3163 } catch (RemoteException e) {
3164 errPw.println("Exception: " + e.getMessage());
3165 return -1;
3166 }
3167 if (VDBG) {
3168 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3169 }
3170 return 0;
3171 }
3172
3173 private int handleRadioCommand() {
3174 String arg = getNextArg();
3175 if (arg == null) {
3176 onHelpRadio();
3177 return 0;
3178 }
3179
3180 switch (arg) {
3181 case RADIO_SET_MODEM_SERVICE:
3182 return handleRadioSetModemServiceCommand();
3183
3184 case RADIO_GET_MODEM_SERVICE:
3185 return handleRadioGetModemServiceCommand();
3186 }
3187
3188 return -1;
3189 }
arunvoddud7401012022-12-15 16:08:12 +00003190
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003191 private int handleSetSatelliteServicePackageNameCommand() {
3192 PrintWriter errPw = getErrPrintWriter();
3193 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003194 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003195
3196 String opt;
3197 while ((opt = getNextOption()) != null) {
3198 switch (opt) {
3199 case "-s": {
3200 serviceName = getNextArgRequired();
3201 break;
3202 }
Hakjun Choic3393242024-06-26 18:02:08 +00003203
3204 case "-p": {
3205 provisioned = getNextArgRequired();
3206 break;
3207 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003208 }
3209 }
3210 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003211 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003212
3213 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003214 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003215 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003216 Log.v(LOG_TAG,
3217 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3218 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003219 }
3220 getOutPrintWriter().println(result);
3221 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003222 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3223 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003224 errPw.println("Exception: " + e.getMessage());
3225 return -1;
3226 }
Hakjun Choic3393242024-06-26 18:02:08 +00003227
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003228 return 0;
3229 }
3230
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003231 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3232 PrintWriter errPw = getErrPrintWriter();
3233 String serviceName = null;
3234
3235 String opt;
3236 while ((opt = getNextOption()) != null) {
3237 switch (opt) {
3238 case "-s": {
3239 serviceName = getNextArgRequired();
3240 break;
3241 }
3242 }
3243 }
3244 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3245 + serviceName);
3246
3247 try {
3248 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3249 if (VDBG) {
3250 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3251 + ", result = " + result);
3252 }
3253 getOutPrintWriter().println(result);
3254 } catch (RemoteException e) {
3255 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3256 + ", error = " + e.getMessage());
3257 errPw.println("Exception: " + e.getMessage());
3258 return -1;
3259 }
3260 return 0;
3261 }
3262
Thomas Nguyen87dce732023-04-20 18:27:16 -07003263 private int handleSetSatellitePointingUiClassNameCommand() {
3264 PrintWriter errPw = getErrPrintWriter();
3265 String packageName = null;
3266 String className = null;
3267
3268 String opt;
3269 while ((opt = getNextOption()) != null) {
3270 switch (opt) {
3271 case "-p": {
3272 packageName = getNextArgRequired();
3273 break;
3274 }
3275 case "-c": {
3276 className = getNextArgRequired();
3277 break;
3278 }
3279 }
3280 }
3281 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3282 + packageName + ", className=" + className);
3283
3284 try {
3285 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3286 if (VDBG) {
3287 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3288 }
3289 getOutPrintWriter().println(result);
3290 } catch (RemoteException e) {
3291 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3292 + ", error = " + e.getMessage());
3293 errPw.println("Exception: " + e.getMessage());
3294 return -1;
3295 }
3296 return 0;
3297 }
3298
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003299 private int handleSetEmergencyCallToSatelliteHandoverType() {
3300 PrintWriter errPw = getErrPrintWriter();
3301 int handoverType = -1;
3302 int delaySeconds = 0;
3303
3304 String opt;
3305 while ((opt = getNextOption()) != null) {
3306 switch (opt) {
3307 case "-t": {
3308 try {
3309 handoverType = Integer.parseInt(getNextArgRequired());
3310 } catch (NumberFormatException e) {
3311 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3312 + " for handoverType");
3313 return -1;
3314 }
3315 break;
3316 }
3317 case "-d": {
3318 try {
3319 delaySeconds = Integer.parseInt(getNextArgRequired());
3320 } catch (NumberFormatException e) {
3321 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3322 + " for delaySeconds");
3323 return -1;
3324 }
3325 break;
3326 }
3327 }
3328 }
3329 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3330 + handoverType + ", delaySeconds=" + delaySeconds);
3331
3332 try {
3333 boolean result =
3334 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3335 if (VDBG) {
3336 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3337 }
3338 getOutPrintWriter().println(result);
3339 } catch (RemoteException e) {
3340 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3341 + ", error = " + e.getMessage());
3342 errPw.println("Exception: " + e.getMessage());
3343 return -1;
3344 }
3345 return 0;
3346 }
3347
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003348 private int handleSetSatelliteListeningTimeoutDuration() {
3349 PrintWriter errPw = getErrPrintWriter();
3350 long timeoutMillis = 0;
3351
3352 String opt;
3353 while ((opt = getNextOption()) != null) {
3354 switch (opt) {
3355 case "-t": {
3356 timeoutMillis = Long.parseLong(getNextArgRequired());
3357 break;
3358 }
3359 }
3360 }
3361 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3362 + timeoutMillis);
3363
3364 try {
3365 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3366 if (VDBG) {
3367 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3368 + ", result = " + result);
3369 }
3370 getOutPrintWriter().println(result);
3371 } catch (RemoteException e) {
3372 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3373 + ", error = " + e.getMessage());
3374 errPw.println("Exception: " + e.getMessage());
3375 return -1;
3376 }
3377 return 0;
3378 }
3379
joonhunshinf46f0d62024-09-27 14:06:26 +00003380 private int handleSetSatelliteIgnoreCellularServiceState() {
3381 PrintWriter errPw = getErrPrintWriter();
3382 boolean enabled = false;
3383
3384 String opt;
3385 while ((opt = getNextOption()) != null) {
3386 switch (opt) {
3387 case "-d": {
3388 enabled = Boolean.parseBoolean(getNextArgRequired());
3389 break;
3390 }
3391 }
3392 }
3393 Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
3394
3395 try {
3396 boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
3397 if (VDBG) {
3398 Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
3399 + ", result = " + result);
3400 }
3401 getOutPrintWriter().println(result);
3402 } catch (RemoteException e) {
3403 Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
3404 + ", error = " + e.getMessage());
3405 errPw.println("Exception: " + e.getMessage());
3406 return -1;
3407 }
3408 return 0;
3409 }
3410
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003411 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003412 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003413 boolean reset = false;
3414 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003415 long timeoutMillis = 0;
3416
3417 String opt;
3418 while ((opt = getNextOption()) != null) {
3419 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003420 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003421 timeoutMillis = Long.parseLong(getNextArgRequired());
3422 break;
3423 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003424 case "-r": {
3425 reset = true;
3426 break;
3427 }
3428 case "-t": {
3429 timeoutType = Integer.parseInt(getNextArgRequired());
3430 break;
3431 }
Hakjun Choiae365972023-04-25 11:00:31 +00003432 }
3433 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003434 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3435 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003436
3437 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003438 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3439 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003440 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003441 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003442 + ", result = " + result);
3443 }
3444 getOutPrintWriter().println(result);
3445 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003446 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3447 + ", error = " + e.getMessage());
3448 errPw.println("Exception: " + e.getMessage());
3449 return -1;
3450 }
3451 return 0;
3452 }
3453
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003454 private int handleSetDatagramControllerBooleanConfig() {
3455 PrintWriter errPw = getErrPrintWriter();
3456 boolean reset = false;
3457 int booleanType = 0;
3458 boolean enable = false;
3459
3460 String opt;
3461 while ((opt = getNextOption()) != null) {
3462 switch (opt) {
3463 case "-d": {
3464 enable = Boolean.parseBoolean(getNextArgRequired());
3465 break;
3466 }
3467 case "-r": {
3468 reset = true;
3469 break;
3470 }
3471 case "-t": {
3472 booleanType = Integer.parseInt(getNextArgRequired());
3473 break;
3474 }
3475 }
3476 }
3477 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3478 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3479
3480 try {
3481 boolean result = mInterface.setDatagramControllerBooleanConfig(
3482 reset, booleanType, enable);
3483 if (VDBG) {
3484 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3485 }
3486 getOutPrintWriter().println(result);
3487 } catch (RemoteException e) {
3488 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3489 errPw.println("Exception: " + e.getMessage());
3490 return -1;
3491 }
3492 return 0;
3493 }
3494
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003495 private int handleSetSatelliteControllerTimeoutDuration() {
3496 PrintWriter errPw = getErrPrintWriter();
3497 boolean reset = false;
3498 int timeoutType = 0;
3499 long timeoutMillis = 0;
3500
3501 String opt;
3502 while ((opt = getNextOption()) != null) {
3503 switch (opt) {
3504 case "-d": {
3505 timeoutMillis = Long.parseLong(getNextArgRequired());
3506 break;
3507 }
3508 case "-r": {
3509 reset = true;
3510 break;
3511 }
3512 case "-t": {
3513 timeoutType = Integer.parseInt(getNextArgRequired());
3514 break;
3515 }
3516 }
3517 }
3518 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3519 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3520
3521 try {
3522 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3523 reset, timeoutType, timeoutMillis);
3524 if (VDBG) {
3525 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3526 + ", result = " + result);
3527 }
3528 getOutPrintWriter().println(result);
3529 } catch (RemoteException e) {
3530 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003531 + ", error = " + e.getMessage());
3532 errPw.println("Exception: " + e.getMessage());
3533 return -1;
3534 }
3535 return 0;
3536 }
3537
Hakjun Choibc6ce992023-11-07 16:04:33 +00003538 private int handleSetShouldSendDatagramToModemInDemoMode() {
3539 PrintWriter errPw = getErrPrintWriter();
3540 String opt;
3541 boolean shouldSendToDemoMode;
3542
3543 if ((opt = getNextArg()) == null) {
3544 errPw.println(
3545 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3546 + " Invalid Argument");
3547 return -1;
3548 } else {
3549 switch (opt) {
3550 case "true": {
3551 shouldSendToDemoMode = true;
3552 break;
3553 }
3554 case "false": {
3555 shouldSendToDemoMode = false;
3556 break;
3557 }
3558 default:
3559 errPw.println(
3560 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3561 + " Invalid Argument");
3562 return -1;
3563 }
3564 }
3565
3566 Log.d(LOG_TAG,
3567 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3568
3569 try {
3570 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3571 shouldSendToDemoMode);
3572 if (VDBG) {
3573 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3574 + result);
3575 }
3576 getOutPrintWriter().println(false);
3577 } catch (RemoteException e) {
3578 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3579 + "), error = " + e.getMessage());
3580 errPw.println("Exception: " + e.getMessage());
3581 return -1;
3582 }
3583 return 0;
3584 }
3585
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003586 private int handleSetSatelliteAccessControlOverlayConfigs() {
3587 PrintWriter errPw = getErrPrintWriter();
3588 boolean reset = false;
3589 boolean isAllowed = false;
3590 String s2CellFile = null;
3591 long locationFreshDurationNanos = 0;
3592 List<String> satelliteCountryCodes = null;
3593
3594 String opt;
3595 while ((opt = getNextOption()) != null) {
3596 switch (opt) {
3597 case "-r": {
3598 reset = true;
3599 break;
3600 }
3601 case "-a": {
3602 isAllowed = true;
3603 break;
3604 }
3605 case "-f": {
3606 s2CellFile = getNextArgRequired();
3607 break;
3608 }
3609 case "-d": {
3610 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3611 break;
3612 }
3613 case "-c": {
3614 String countryCodeStr = getNextArgRequired();
3615 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3616 break;
3617 }
3618 }
3619 }
3620 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3621 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3622 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3623 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3624
3625 try {
3626 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3627 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3628 if (VDBG) {
3629 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3630 }
3631 getOutPrintWriter().println(result);
3632 } catch (RemoteException e) {
3633 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3634 errPw.println("Exception: " + e.getMessage());
3635 return -1;
3636 }
3637 return 0;
3638 }
3639
3640 private int handleSetCountryCodes() {
3641 PrintWriter errPw = getErrPrintWriter();
3642 List<String> currentNetworkCountryCodes = new ArrayList<>();
3643 String locationCountryCode = null;
3644 long locationCountryCodeTimestampNanos = 0;
3645 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3646 boolean reset = false;
3647
3648 String opt;
3649 while ((opt = getNextOption()) != null) {
3650 switch (opt) {
3651 case "-r": {
3652 reset = true;
3653 break;
3654 }
3655 case "-n": {
3656 String countryCodeStr = getNextArgRequired();
3657 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3658 break;
3659 }
3660 case "-c": {
3661 String cachedNetworkCountryCodeStr = getNextArgRequired();
3662 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3663 break;
3664 }
3665 case "-l": {
3666 locationCountryCode = getNextArgRequired();
3667 break;
3668 }
3669 case "-t": {
3670 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3671 break;
3672 }
3673 }
3674 }
3675 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3676 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3677 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3678 + currentNetworkCountryCodes);
3679
3680 try {
3681 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3682 cachedNetworkCountryCodes, locationCountryCode,
3683 locationCountryCodeTimestampNanos);
3684 if (VDBG) {
3685 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3686 }
3687 getOutPrintWriter().println(result);
3688 } catch (RemoteException e) {
3689 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3690 errPw.println("Exception: " + e.getMessage());
3691 return -1;
3692 }
3693 return 0;
3694 }
3695
Thomas Nguyen3d602742024-01-19 11:29:35 -08003696 private int handleSetOemEnabledSatelliteProvisionStatus() {
3697 PrintWriter errPw = getErrPrintWriter();
3698 boolean isProvisioned = false;
3699 boolean reset = true;
3700
3701 String opt;
3702 while ((opt = getNextOption()) != null) {
3703 switch (opt) {
3704 case "-p": {
3705 try {
3706 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3707 reset = false;
3708 } catch (Exception e) {
3709 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3710 + "after -p indicating provision status");
3711 return -1;
3712 }
3713 }
3714 }
3715 }
3716 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3717 + ", isProvisioned=" + isProvisioned);
3718
3719 try {
3720 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3721 if (VDBG) {
3722 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3723 }
3724 getOutPrintWriter().println(result);
3725 } catch (RemoteException e) {
3726 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3727 errPw.println("Exception: " + e.getMessage());
3728 return -1;
3729 }
3730 return 0;
3731 }
3732
Hakjun Choi4a832d12024-05-28 22:23:55 +00003733 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3734 PrintWriter errPw = getErrPrintWriter();
3735 String opt;
3736 String state;
Hakjun Choi4a832d12024-05-28 22:23:55 +00003737 if ((opt = getNextArg()) == null) {
3738 errPw.println(
3739 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3740 + "-location-cache :"
3741 + " Invalid Argument");
3742 return -1;
3743 } else {
3744 switch (opt) {
3745 case "-a": {
3746 state = "cache_allowed";
3747 break;
3748 }
youngtaecha32bde212024-09-17 22:58:11 +00003749 case "-na": {
3750 state = "cache_not_allowed";
3751 break;
3752 }
Hakjun Choi4a832d12024-05-28 22:23:55 +00003753 case "-n": {
3754 state = "cache_clear_and_not_allowed";
3755 break;
3756 }
3757 case "-c": {
3758 state = "clear_cache_only";
3759 break;
3760 }
3761 default:
3762 errPw.println(
3763 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3764 + "-location-cache :"
3765 + " Invalid Argument");
3766 return -1;
3767 }
3768 }
3769
3770 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3771 + state + ")");
3772
3773 try {
3774 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3775 state);
3776 if (VDBG) {
3777 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3778 + "returns: "
3779 + result);
3780 }
3781 getOutPrintWriter().println(result);
3782 } catch (RemoteException e) {
3783 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3784 + state + "), error = " + e.getMessage());
3785 errPw.println("Exception: " + e.getMessage());
3786 return -1;
3787 }
3788 return 0;
3789 }
3790
Hyosund6aaf062024-08-23 23:02:10 +00003791 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3792 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3793 PrintWriter errPw = getErrPrintWriter();
3794 String opt;
3795 String name;
3796
3797 if ((opt = getNextArg()) == null) {
3798 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3799 return -1;
3800 } else {
3801 switch (opt) {
3802 case "-p": {
3803 name = opt + "/" + "android.telephony.cts";
3804 break;
3805 }
3806 case "-c": {
3807 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3808 break;
3809 }
3810 case "-r": {
3811 name = "reset";
3812 break;
3813 }
3814 default:
3815 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3816 return -1;
3817 }
3818 }
3819
3820 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3821 + name + ")");
3822
3823 try {
3824 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3825 if (VDBG) {
3826 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3827 + "returns: " + result);
3828 }
3829 getOutPrintWriter().println(result);
3830 } catch (RemoteException e) {
3831 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3832 + name + "), error = " + e.getMessage());
3833 errPw.println("Exception: " + e.getMessage());
3834 return -1;
3835 }
3836 return 0;
3837 }
3838
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003839 /**
3840 * Sample inputStr = "US,UK,CA;2,1,3"
3841 * Sample output: {[US,2], [UK,1], [CA,3]}
3842 */
3843 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3844 Map<String, Long> result = new HashMap<>();
3845 if (!TextUtils.isEmpty(inputStr)) {
3846 String[] stringLongArr = inputStr.split(";");
3847 if (stringLongArr.length != 2) {
3848 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3849 return result;
3850 }
3851
3852 String[] stringArr = stringLongArr[0].split(",");
3853 String[] longArr = stringLongArr[1].split(",");
3854 if (stringArr.length != longArr.length) {
3855 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3856 return result;
3857 }
3858
3859 for (int i = 0; i < stringArr.length; i++) {
3860 try {
3861 result.put(stringArr[i], Long.parseLong(longArr[i]));
3862 } catch (Exception ex) {
3863 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3864 + ", ex=" + ex);
3865 return result;
3866 }
3867 }
3868 }
3869 return result;
3870 }
3871
arunvoddud7401012022-12-15 16:08:12 +00003872 private int handleCarrierRestrictionStatusCommand() {
3873 try {
3874 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3875 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3876 mInterface.getModemService()))) {
3877 Log.v(LOG_TAG,
3878 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3879 + " checkShellUid fails");
3880 return -1;
3881 }
3882 } catch (RemoteException ex) {
3883 ex.printStackTrace();
3884 }
3885 String callerInfo = getNextOption();
3886 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3887 if (TextUtils.isEmpty(callerInfo)) {
3888 // reset the Json content after testing
3889 allowListInfo.updateJsonForTest(null);
3890 return 0;
3891 }
3892 if (callerInfo.startsWith("--")) {
3893 callerInfo = callerInfo.replace("--", "");
3894 }
3895 String params[] = callerInfo.split(",");
3896 StringBuffer jsonStrBuffer = new StringBuffer();
3897 String tokens;
3898 for (int index = 0; index < params.length; index++) {
3899 tokens = convertToJsonString(index, params[index]);
3900 if (TextUtils.isEmpty(tokens)) {
3901 // received wrong format from CTS
3902 if (VDBG) {
3903 Log.v(LOG_TAG,
3904 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3905 }
3906 return -1;
3907 }
3908 jsonStrBuffer.append(tokens);
3909 }
3910 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3911 return result;
3912 }
3913
Benedict Wong66477622023-02-03 23:30:57 +00003914 // set-carrier-service-package-override
3915 private int setCarrierServicePackageOverride() {
3916 PrintWriter errPw = getErrPrintWriter();
3917 int subId = SubscriptionManager.getDefaultSubscriptionId();
3918
3919 String opt;
3920 while ((opt = getNextOption()) != null) {
3921 switch (opt) {
3922 case "-s":
3923 try {
3924 subId = Integer.parseInt(getNextArgRequired());
3925 } catch (NumberFormatException e) {
3926 errPw.println(
3927 "set-carrier-service-package-override requires an integer as a"
3928 + " subscription ID.");
3929 return -1;
3930 }
3931 break;
3932 }
3933 }
3934
3935 String packageName = getNextArg();
3936 if (packageName == null) {
3937 errPw.println("set-carrier-service-package-override requires a override package name.");
3938 return -1;
3939 }
3940
3941 try {
3942 mInterface.setCarrierServicePackageOverride(
3943 subId, packageName, mContext.getOpPackageName());
3944
3945 if (VDBG) {
3946 Log.v(
3947 LOG_TAG,
3948 "set-carrier-service-package-override -s " + subId + " " + packageName);
3949 }
3950 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3951 Log.w(
3952 LOG_TAG,
3953 "set-carrier-service-package-override -s "
3954 + subId
3955 + " "
3956 + packageName
3957 + ", error"
3958 + e.getMessage());
3959 errPw.println("Exception: " + e.getMessage());
3960 return -1;
3961 }
3962 return 0;
3963 }
3964
3965 // clear-carrier-service-package-override
3966 private int clearCarrierServicePackageOverride() {
3967 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003968 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003969
3970 String opt;
3971 while ((opt = getNextOption()) != null) {
3972 switch (opt) {
3973 case "-s":
3974 try {
3975 subId = Integer.parseInt(getNextArgRequired());
3976 } catch (NumberFormatException e) {
3977 errPw.println(
3978 "clear-carrier-service-package-override requires an integer as a"
3979 + " subscription ID.");
3980 return -1;
3981 }
3982 break;
3983 }
3984 }
3985
3986 try {
3987 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3988
3989 if (VDBG) {
3990 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3991 }
3992 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3993 Log.w(
3994 LOG_TAG,
3995 "clear-carrier-service-package-override -s "
3996 + subId
3997 + ", error"
3998 + e.getMessage());
3999 errPw.println("Exception: " + e.getMessage());
4000 return -1;
4001 }
4002 return 0;
4003 }
arunvoddud7401012022-12-15 16:08:12 +00004004
Hunsuk Choi13078be2023-09-13 10:55:21 +00004005 private int handleDomainSelectionCommand() {
4006 String arg = getNextArg();
4007 if (arg == null) {
4008 onHelpDomainSelection();
4009 return 0;
4010 }
4011
4012 switch (arg) {
4013 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
4014 return handleDomainSelectionSetServiceOverrideCommand();
4015 }
4016 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4017 return handleDomainSelectionClearServiceOverrideCommand();
4018 }
4019 }
4020
4021 return -1;
4022 }
4023
4024 // domainselection set-dss-override
4025 private int handleDomainSelectionSetServiceOverrideCommand() {
4026 PrintWriter errPw = getErrPrintWriter();
4027
4028 String componentName = getNextArg();
4029
4030 try {
4031 boolean result = mInterface.setDomainSelectionServiceOverride(
4032 ComponentName.unflattenFromString(componentName));
4033 if (VDBG) {
4034 Log.v(LOG_TAG, "domainselection set-dss-override "
4035 + componentName + ", result=" + result);
4036 }
4037 getOutPrintWriter().println(result);
4038 } catch (Exception e) {
4039 Log.w(LOG_TAG, "domainselection set-dss-override "
4040 + componentName + ", error=" + e.getMessage());
4041 errPw.println("Exception: " + e.getMessage());
4042 return -1;
4043 }
4044 return 0;
4045 }
4046
4047 // domainselection clear-dss-override
4048 private int handleDomainSelectionClearServiceOverrideCommand() {
4049 PrintWriter errPw = getErrPrintWriter();
4050
4051 try {
4052 boolean result = mInterface.clearDomainSelectionServiceOverride();
4053 if (VDBG) {
4054 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4055 }
4056 getOutPrintWriter().println(result);
4057 } catch (RemoteException e) {
4058 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4059 errPw.println("Exception: " + e.getMessage());
4060 return -1;
4061 }
4062 return 0;
4063 }
4064
arunvoddud7401012022-12-15 16:08:12 +00004065 /**
4066 * Building the string that can be used to build the JsonObject which supports to stub the data
4067 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004068 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004069 */
4070 private String convertToJsonString(int index, String param) {
4071
4072 String token[] = param.split(":");
4073 String jSonString;
4074 switch (index) {
4075 case 0:
4076 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4077 break;
4078 case 1:
4079 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004080 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004081 break;
4082 case 2:
4083 jSonString =
4084 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4085 break;
4086 default:
4087 jSonString = null;
4088 }
4089 return jSonString;
4090 }
arunvoddue3a6dbc2024-09-27 16:27:08 +00004091
4092 /**
4093 * This method override the check for carrier roaming Ntn eligibility.
4094 * <ul>
4095 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result true` will set
4096 * override eligibility to true.</li>
4097 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result false` will
4098 * override eligibility to false.</li>
4099 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result` will reset the
4100 * override data set through adb command.</li>
4101 * </ul>
4102 *
4103 * @return {@code true} is command executed successfully otherwise {@code false}.
4104 */
4105 private int handleOverrideCarrierRoamingNtnEligibilityChanged() {
4106 PrintWriter errPw = getErrPrintWriter();
4107 String opt;
4108 boolean state = false;
4109 boolean isRestRequired = false;
4110 try {
4111 if ((opt = getNextArg()) == null) {
4112 isRestRequired = true;
4113 } else {
4114 if ("true".equalsIgnoreCase(opt)) {
4115 state = true;
4116 }
4117 }
4118 boolean result = mInterface.overrideCarrierRoamingNtnEligibilityChanged(state,
4119 isRestRequired);
4120 if (VDBG) {
4121 Log.v(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult "
4122 + "returns: "
4123 + result);
4124 }
4125 getOutPrintWriter().println(result);
4126 } catch (RemoteException e) {
4127 Log.w(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult("
4128 + state + "), error = " + e.getMessage());
4129 errPw.println("Exception: " + e.getMessage());
4130 return -1;
4131 }
4132 Log.d(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult(" + state + ")");
4133 return 0;
4134 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004135}