blob: 840f961270ea2a8e3a889beb06c2f26018f9386b [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 Ebinger24c29992019-12-05 13:03:21 -0800529 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700530 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
531 pw.println(" ImsService. Options are:");
532 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
533 pw.println(" is specified, it will choose the default voice SIM slot.");
534 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
535 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800536 pw.println(" -f: Set the feature that this override if for, if no option is");
537 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700538 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
539 pw.println(" Gets the package name of the currently defined ImsService.");
540 pw.println(" Options are:");
541 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
543 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000544 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800545 pw.println(" -f: The feature type that the query will be requested for. If none is");
546 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800547 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
548 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
549 pw.println(" configuration overrides. Options are:");
550 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
551 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700552 pw.println(" ims enable [-s SLOT_ID]");
553 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
554 pw.println(" if none is specified.");
555 pw.println(" ims disable [-s SLOT_ID]");
556 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
557 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700558 pw.println(" ims conference-event-package [enable/disable]");
559 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700560 }
561
James.cf Linbcdf8b32021-01-14 16:44:13 +0800562 private void onHelpUce() {
563 PrintWriter pw = getOutPrintWriter();
564 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800565 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
566 pw.println(" Get the EAB contacts from the EAB database.");
567 pw.println(" Options are:");
568 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
569 pw.println(" Expected output format :");
570 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800571 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
572 pw.println(" Remove the EAB contacts from the EAB database.");
573 pw.println(" Options are:");
574 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
575 pw.println(" is specified, it will choose the default voice SIM slot.");
576 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800577 pw.println(" uce get-device-enabled");
578 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
579 pw.println(" uce set-device-enabled true|false");
580 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
581 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000582 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
583 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
584 pw.println(" Options are:");
585 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
586 pw.println(" is specified, it will choose the default voice SIM slot.");
587 pw.println(" add [CAPABILITY]: add a new capability");
588 pw.println(" remove [CAPABILITY]: remove a capability");
589 pw.println(" clear: clear all capability overrides");
590 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
591 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
592 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
593 pw.println(" chatbot_sa, chatbot_role] as well as full length");
594 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
595 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
596 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
597 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800598 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
599 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800600 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
601 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800602 }
603
Hall Liud892bec2018-11-30 14:51:45 -0800604 private void onHelpNumberVerification() {
605 PrintWriter pw = getOutPrintWriter();
606 pw.println("Number verification commands");
607 pw.println(" numverify override-package PACKAGE_NAME;");
608 pw.println(" Set the authorized package for number verification.");
609 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800610 pw.println(" numverify fake-call NUMBER;");
611 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
612 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800613 }
614
Jack Nudelman644b91a2021-03-12 14:09:48 -0800615 private void onHelpThermalMitigation() {
616 PrintWriter pw = getOutPrintWriter();
617 pw.println("Thermal mitigation commands");
618 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
619 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
620 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
621 pw.println(" Remove the package from one of the authorized packages for thermal "
622 + "mitigation.");
623 }
624
Jordan Liu0ccee222021-04-27 11:55:13 -0700625 private void onHelpDisableOrEnablePhysicalSubscription() {
626 PrintWriter pw = getOutPrintWriter();
627 pw.println("Disable or enable a physical subscription");
628 pw.println(" disable-physical-subscription SUB_ID");
629 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
630 pw.println(" enable-physical-subscription SUB_ID");
631 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
632 }
633
Shuo Qianf5125122019-12-16 17:03:07 -0800634 private void onHelpDataTestMode() {
635 PrintWriter pw = getOutPrintWriter();
636 pw.println("Mobile Data Test Mode Commands:");
637 pw.println(" data enable: enable mobile data connectivity");
638 pw.println(" data disable: disable mobile data connectivity");
639 }
640
sqian9d4df8b2019-01-15 18:32:07 -0800641 private void onHelpEmergencyNumber() {
642 PrintWriter pw = getOutPrintWriter();
643 pw.println("Emergency Number Test Mode Commands:");
644 pw.println(" emergency-number-test-mode ");
645 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
646 + " the test mode");
647 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700648 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800649 pw.println(" -c: clear the emergency number list in the test mode.");
650 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700651 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800652 pw.println(" -p: get the full emergency number list in the test mode.");
653 }
654
Shuo Qian489d9282020-07-09 11:30:03 -0700655 private void onHelpEndBlockSupperssion() {
656 PrintWriter pw = getOutPrintWriter();
657 pw.println("End Block Suppression command:");
658 pw.println(" end-block-suppression: disable suppressing blocking by contact");
659 pw.println(" with emergency services.");
660 }
661
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100662 private void onHelpCc() {
663 PrintWriter pw = getOutPrintWriter();
664 pw.println("Carrier Config Commands:");
665 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
666 pw.println(" Print carrier config values.");
667 pw.println(" Options are:");
668 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
669 pw.println(" is specified, it will choose the default voice SIM slot.");
670 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
671 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100672 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100673 pw.println(" Set carrier config KEY to NEW_VALUE.");
674 pw.println(" Options are:");
675 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
676 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100677 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100678 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
679 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
680 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
681 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000682 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
683 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
684 pw.println(" provided through standard input and follow CarrierConfig XML format.");
685 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
686 pw.println(" Options are:");
687 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
688 pw.println(" is specified, it will choose the default voice SIM slot.");
689 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100690 pw.println(" cc clear-values [-s SLOT_ID]");
691 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000692 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100693 pw.println(" Options are:");
694 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
695 pw.println(" is specified, it will choose the default voice SIM slot.");
696 }
697
Hui Wang641e81c2020-10-12 12:14:23 -0700698 private void onHelpGba() {
699 PrintWriter pw = getOutPrintWriter();
700 pw.println("Gba Commands:");
701 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
702 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
703 pw.println(" Options are:");
704 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
705 pw.println(" is specified, it will choose the default voice SIM slot.");
706 pw.println(" gba get-service [-s SLOT_ID]");
707 pw.println(" Gets the package name of the currently defined GbaService.");
708 pw.println(" Options are:");
709 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
710 pw.println(" is specified, it will choose the default voice SIM slot.");
711 pw.println(" gba set-release [-s SLOT_ID] n");
712 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
713 pw.println(" Do not release/unbind if n is -1.");
714 pw.println(" Options are:");
715 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
716 pw.println(" is specified, it will choose the default voice SIM slot.");
717 pw.println(" gba get-release [-s SLOT_ID]");
718 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
719 pw.println(" Options are:");
720 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
721 pw.println(" is specified, it will choose the default voice SIM slot.");
722 }
723
Hui Wang761a6682020-10-31 05:12:53 +0000724 private void onHelpSrc() {
725 PrintWriter pw = getOutPrintWriter();
726 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800727 pw.println(" src set-test-enabled true|false");
728 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
729 pw.println(" The value could be true, false, or null(undefined).");
730 pw.println(" src get-test-enabled");
731 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000732 pw.println(" src set-device-enabled true|false|null");
733 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
734 pw.println(" The value could be true, false, or null(undefined).");
735 pw.println(" src get-device-enabled");
736 pw.println(" Gets the device config for RCS VoLTE single registration.");
737 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
738 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
739 pw.println(" The value could be true, false, or null(undefined).");
740 pw.println(" Options are:");
741 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
742 pw.println(" is specified, it will choose the default voice SIM slot.");
743 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
744 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
745 pw.println(" Options are:");
746 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
747 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800748 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
749 pw.println(" Sets ims feature validation result.");
750 pw.println(" The value could be true, false, or null(undefined).");
751 pw.println(" Options are:");
752 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
753 pw.println(" is specified, it will choose the default voice SIM slot.");
754 pw.println(" src get-feature-validation [-s SLOT_ID]");
755 pw.println(" Gets ims feature validation override value.");
756 pw.println(" Options are:");
757 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
758 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000759 }
760
SongFerngWang98dd5992021-05-13 17:50:00 +0800761 private void onHelpAllowedNetworkTypes() {
762 PrintWriter pw = getOutPrintWriter();
763 pw.println("Allowed Network Types Commands:");
764 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
765 pw.println(" Print allowed network types value.");
766 pw.println(" Options are:");
767 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
768 pw.println(" option is specified, it will choose the default voice SIM slot.");
769 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
770 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
771 pw.println(" Options are:");
772 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
773 pw.println(" option is specified, it will choose the default voice SIM slot.");
774 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
775 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
776 pw.println(" at TelephonyManager.java");
777 pw.println(" For example:");
778 pw.println(" NR only : 10000000000000000000");
779 pw.println(" NR|LTE : 11000001000000000000");
780 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
781 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
782 pw.println(" LTE only : 01000001000000000000");
783 }
784
jimsun3b9ccac2021-10-26 15:01:23 +0800785 private void onHelpRadio() {
786 PrintWriter pw = getOutPrintWriter();
787 pw.println("Radio Commands:");
788 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
789 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
790 pw.println(" to be the bound. Options are:");
791 pw.println(" -s: the service name that the modem service should be bound for.");
792 pw.println(" If no option is specified, it will bind to the default.");
793 pw.println(" radio get-modem-service");
794 pw.println(" Gets the service name of the currently defined modem service.");
795 pw.println(" If it is binding to default, 'default' returns.");
796 pw.println(" If it doesn't bind to any modem service for some reasons,");
797 pw.println(" the result would be 'unknown'.");
798 }
799
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700800 private void onHelpSatellite() {
801 PrintWriter pw = getOutPrintWriter();
802 pw.println("Satellite Commands:");
803 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
804 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700805 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700806 pw.println(" -s: the satellite service package name that Telephony will bind to.");
807 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700808 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
809 pw.println(" Sets the package name of satellite gateway service defined in");
810 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
811 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
812 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700813 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
814 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
815 pw.println(" mode. Options are:");
816 pw.println(" -t: the timeout duration in milliseconds.");
817 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700818 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
819 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
820 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
821 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
822 pw.println(" launch. If no option is specified, it will launch the default.");
823 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
824 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700825 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
826 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
827 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
828 pw.println(" Options are:");
829 pw.println(" -t: the emergency call to satellite handover type.");
830 pw.println(" If no option is specified, override is disabled.");
831 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
832 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800833 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
834 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
835 pw.println(" configs of satellite access controller.");
836 pw.println(" Options are:");
837 pw.println(" -r: clear the overriding. Absent means enable overriding.");
838 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
839 pw.println(" -f: the satellite s2 file.");
840 pw.println(" -d: the location fresh duration nanos.");
841 pw.println(" -c: the list of satellite country codes separated by comma.");
842 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
843 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
844 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
845 pw.println(" Override the cached location country code and its update timestamp. ");
846 pw.println(" Options are:");
847 pw.println(" -r: clear the overriding. Absent means enable overriding.");
848 pw.println(" -n: the current network country code ISOs.");
849 pw.println(" -c: the cached network country code ISOs.");
850 pw.println(" -l: the location country code ISO.");
851 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800852 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
853 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
854 pw.println(" -p: the overriding satellite provision status. If no option is ");
855 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700856 }
857
Ling Ma4fbab492022-01-25 22:36:16 +0000858 private void onHelpImei() {
859 PrintWriter pw = getOutPrintWriter();
860 pw.println("IMEI Commands:");
861 pw.println(" get-imei [-s SLOT_ID]");
862 pw.println(" Gets the device IMEI. Options are:");
863 pw.println(" -s: the slot ID to get the IMEI. If no option");
864 pw.println(" is specified, it will choose the default voice SIM slot.");
865 }
866
Hunsuk Choi13078be2023-09-13 10:55:21 +0000867 private void onHelpDomainSelection() {
868 PrintWriter pw = getOutPrintWriter();
869 pw.println("Domain Selection Commands:");
870 pw.println(" domainselection set-dss-override COMPONENT_NAME");
871 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
872 pw.println(" domainselection clear-dss-override");
873 pw.println(" Clears DomainSelectionService override.");
874 }
875
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700876 private int handleImsCommand() {
877 String arg = getNextArg();
878 if (arg == null) {
879 onHelpIms();
880 return 0;
881 }
882
883 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800884 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700885 return handleImsSetServiceCommand();
886 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800887 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700888 return handleImsGetServiceCommand();
889 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800890 case IMS_CLEAR_SERVICE_OVERRIDE: {
891 return handleImsClearCarrierServiceCommand();
892 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800893 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700894 return handleEnableIms();
895 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800896 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700897 return handleDisableIms();
898 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700899 case IMS_CEP: {
900 return handleCepChange();
901 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700902 }
903
904 return -1;
905 }
906
Shuo Qianf5125122019-12-16 17:03:07 -0800907 private int handleDataTestModeCommand() {
908 PrintWriter errPw = getErrPrintWriter();
909 String arg = getNextArgRequired();
910 if (arg == null) {
911 onHelpDataTestMode();
912 return 0;
913 }
914 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800915 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800916 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700917 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800918 } catch (RemoteException ex) {
919 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
920 errPw.println("Exception: " + ex.getMessage());
921 return -1;
922 }
923 break;
924 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800925 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800926 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700927 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800928 } catch (RemoteException ex) {
929 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
930 errPw.println("Exception: " + ex.getMessage());
931 return -1;
932 }
933 break;
934 }
935 default:
936 onHelpDataTestMode();
937 break;
938 }
939 return 0;
940 }
941
Shuo Qianccbaf742021-02-22 18:32:21 -0800942 private int handleEmergencyCallbackModeCommand() {
943 PrintWriter errPw = getErrPrintWriter();
944 try {
945 mInterface.startEmergencyCallbackMode();
946 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
947 } catch (RemoteException ex) {
948 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
949 errPw.println("Exception: " + ex.getMessage());
950 return -1;
951 }
952 return 0;
953 }
954
Grant Menke567d48f2022-08-18 20:19:10 +0000955 private void removeEmergencyNumberTestMode(String emergencyNumber) {
956 PrintWriter errPw = getErrPrintWriter();
957 for (int routingType : ROUTING_TYPES) {
958 try {
959 mInterface.updateEmergencyNumberListTestMode(
960 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
961 new EmergencyNumber(emergencyNumber, "", "",
962 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
963 new ArrayList<String>(),
964 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
965 routingType));
966 } catch (RemoteException ex) {
967 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
968 errPw.println("Exception: " + ex.getMessage());
969 }
970 }
971 }
972
sqian9d4df8b2019-01-15 18:32:07 -0800973 private int handleEmergencyNumberTestModeCommand() {
974 PrintWriter errPw = getErrPrintWriter();
975 String opt = getNextOption();
976 if (opt == null) {
977 onHelpEmergencyNumber();
978 return 0;
979 }
sqian9d4df8b2019-01-15 18:32:07 -0800980 switch (opt) {
981 case "-a": {
982 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000983 if (emergencyNumberCmd == null){
984 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800985 return -1;
986 }
Grant Menke567d48f2022-08-18 20:19:10 +0000987 String[] params = emergencyNumberCmd.split(":");
988 String emergencyNumber;
989 if (params[0] == null ||
990 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
991 errPw.println(INVALID_ENTRY_ERROR);
992 return -1;
993 } else {
994 emergencyNumber = params[0];
995 }
996 removeEmergencyNumberTestMode(emergencyNumber);
997 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
998 if (params.length > 1) {
999 switch (params[1].toLowerCase(Locale.ROOT)) {
1000 case "emergency":
1001 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1002 break;
1003 case "normal":
1004 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1005 break;
1006 case "unknown":
1007 break;
1008 default:
1009 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1010 + "emergency call routing. Please enter either \"normal\", "
1011 + "\"unknown\", or \"emergency\" for call routing. "
1012 + "(-a 1234:normal)");
1013 return -1;
1014 }
1015 }
sqian9d4df8b2019-01-15 18:32:07 -08001016 try {
1017 mInterface.updateEmergencyNumberListTestMode(
1018 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001019 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001020 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1021 new ArrayList<String>(),
1022 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001023 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001024 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001025 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001026 + ", error " + ex.getMessage());
1027 errPw.println("Exception: " + ex.getMessage());
1028 return -1;
1029 }
1030 break;
1031 }
1032 case "-c": {
1033 try {
1034 mInterface.updateEmergencyNumberListTestMode(
1035 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1036 } catch (RemoteException ex) {
1037 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1038 errPw.println("Exception: " + ex.getMessage());
1039 return -1;
1040 }
1041 break;
1042 }
1043 case "-r": {
1044 String emergencyNumberCmd = getNextArgRequired();
1045 if (emergencyNumberCmd == null
1046 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001047 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001048 + " to be specified after -r in the command ");
1049 return -1;
1050 }
Grant Menke567d48f2022-08-18 20:19:10 +00001051 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001052 break;
1053 }
1054 case "-p": {
1055 try {
1056 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1057 } catch (RemoteException ex) {
1058 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1059 errPw.println("Exception: " + ex.getMessage());
1060 return -1;
1061 }
1062 break;
1063 }
1064 default:
1065 onHelpEmergencyNumber();
1066 break;
1067 }
1068 return 0;
1069 }
1070
Hall Liud892bec2018-11-30 14:51:45 -08001071 private int handleNumberVerificationCommand() {
1072 String arg = getNextArg();
1073 if (arg == null) {
1074 onHelpNumberVerification();
1075 return 0;
1076 }
1077
Hall Liuca5af3a2018-12-04 16:58:23 -08001078 if (!checkShellUid()) {
1079 return -1;
1080 }
1081
Hall Liud892bec2018-11-30 14:51:45 -08001082 switch (arg) {
1083 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001084 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1085 return 0;
1086 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001087 case NUMBER_VERIFICATION_FAKE_CALL: {
1088 boolean val = NumberVerificationManager.getInstance()
1089 .checkIncomingCall(getNextArg());
1090 getOutPrintWriter().println(val ? "1" : "0");
1091 return 0;
1092 }
Hall Liud892bec2018-11-30 14:51:45 -08001093 }
1094
1095 return -1;
1096 }
1097
Jordan Liu0ccee222021-04-27 11:55:13 -07001098 private boolean subIsEsim(int subId) {
1099 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1100 if (info != null) {
1101 return info.isEmbedded();
1102 }
1103 return false;
1104 }
1105
1106 private int handleEnablePhysicalSubscription(boolean enable) {
1107 PrintWriter errPw = getErrPrintWriter();
1108 int subId = 0;
1109 try {
1110 subId = Integer.parseInt(getNextArgRequired());
1111 } catch (NumberFormatException e) {
1112 errPw.println((enable ? "enable" : "disable")
1113 + "-physical-subscription requires an integer as a subId.");
1114 return -1;
1115 }
1116 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1117 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001118 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1119 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001120 errPw.println("cc: Permission denied.");
1121 return -1;
1122 }
1123 // Verify that the subId represents a physical sub
1124 if (subIsEsim(subId)) {
1125 errPw.println("SubId " + subId + " is not for a physical subscription");
1126 return -1;
1127 }
1128 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1129 + " physical subscription with subId=" + subId);
1130 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1131 return 0;
1132 }
1133
Jack Nudelman644b91a2021-03-12 14:09:48 -08001134 private int handleThermalMitigationCommand() {
1135 String arg = getNextArg();
1136 String packageName = getNextArg();
1137 if (arg == null || packageName == null) {
1138 onHelpThermalMitigation();
1139 return 0;
1140 }
1141
1142 if (!checkShellUid()) {
1143 return -1;
1144 }
1145
1146 switch (arg) {
1147 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1148 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1149 return 0;
1150 }
1151 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1152 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1153 mContext);
1154 return 0;
1155 }
1156 default:
1157 onHelpThermalMitigation();
1158 }
1159
1160 return -1;
1161
1162 }
1163
Tyler Gunn92479152021-01-20 16:30:10 -08001164 private int handleD2dCommand() {
1165 String arg = getNextArg();
1166 if (arg == null) {
1167 onHelpD2D();
1168 return 0;
1169 }
1170
1171 switch (arg) {
1172 case D2D_SEND: {
1173 return handleD2dSendCommand();
1174 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001175 case D2D_TRANSPORT: {
1176 return handleD2dTransportCommand();
1177 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001178 case D2D_SET_DEVICE_SUPPORT: {
1179 return handleD2dDeviceSupportedCommand();
1180 }
Tyler Gunn92479152021-01-20 16:30:10 -08001181 }
1182
1183 return -1;
1184 }
1185
1186 private int handleD2dSendCommand() {
1187 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001188 int messageType = -1;
1189 int messageValue = -1;
1190
Tyler Gunn92479152021-01-20 16:30:10 -08001191 String arg = getNextArg();
1192 if (arg == null) {
1193 onHelpD2D();
1194 return 0;
1195 }
1196 try {
1197 messageType = Integer.parseInt(arg);
1198 } catch (NumberFormatException e) {
1199 errPw.println("message type must be a valid integer");
1200 return -1;
1201 }
1202
1203 arg = getNextArg();
1204 if (arg == null) {
1205 onHelpD2D();
1206 return 0;
1207 }
1208 try {
1209 messageValue = Integer.parseInt(arg);
1210 } catch (NumberFormatException e) {
1211 errPw.println("message value must be a valid integer");
1212 return -1;
1213 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001214
Tyler Gunn92479152021-01-20 16:30:10 -08001215 try {
1216 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1217 } catch (RemoteException e) {
1218 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1219 errPw.println("Exception: " + e.getMessage());
1220 return -1;
1221 }
1222
1223 return 0;
1224 }
1225
Tyler Gunnbabbda02021-02-10 11:05:02 -08001226 private int handleD2dTransportCommand() {
1227 PrintWriter errPw = getErrPrintWriter();
1228
1229 String arg = getNextArg();
1230 if (arg == null) {
1231 onHelpD2D();
1232 return 0;
1233 }
1234
1235 try {
1236 mInterface.setActiveDeviceToDeviceTransport(arg);
1237 } catch (RemoteException e) {
1238 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1239 errPw.println("Exception: " + e.getMessage());
1240 return -1;
1241 }
1242 return 0;
1243 }
Nazanin014f41e2021-05-06 17:26:31 -07001244 private int handleBarringCommand() {
1245 String arg = getNextArg();
1246 if (arg == null) {
1247 onHelpBarring();
1248 return 0;
1249 }
1250
1251 switch (arg) {
1252 case BARRING_SEND_INFO: {
1253 return handleBarringSendCommand();
1254 }
1255 }
1256 return -1;
1257 }
1258
1259 private int handleBarringSendCommand() {
1260 PrintWriter errPw = getErrPrintWriter();
1261 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001262 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001263 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1264 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1265 boolean isConditionallyBarred = false;
1266 int conditionalBarringTimeSeconds = 0;
1267
1268 String opt;
1269 while ((opt = getNextOption()) != null) {
1270 switch (opt) {
1271 case "-s": {
1272 try {
1273 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001274 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001275 } catch (NumberFormatException e) {
1276 errPw.println("barring send requires an integer as a SLOT_ID.");
1277 return -1;
1278 }
1279 break;
1280 }
1281 case "-b": {
1282 try {
1283 barringType = Integer.parseInt(getNextArgRequired());
1284 if (barringType < -1 || barringType > 2) {
1285 throw new NumberFormatException();
1286 }
1287
1288 } catch (NumberFormatException e) {
1289 errPw.println("barring send requires an integer in range [-1,2] as "
1290 + "a BARRING_TYPE.");
1291 return -1;
1292 }
1293 break;
1294 }
1295 case "-c": {
1296 try {
1297 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1298 } catch (Exception e) {
1299 errPw.println("barring send requires a boolean after -c indicating"
1300 + " conditional barring");
1301 return -1;
1302 }
1303 break;
1304 }
1305 case "-t": {
1306 try {
1307 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1308 } catch (NumberFormatException e) {
1309 errPw.println("barring send requires an integer for time of barring"
1310 + " in seconds after -t for conditional barring");
1311 return -1;
1312 }
1313 break;
1314 }
1315 }
1316 }
1317 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1318 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1319 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1320 barringServiceInfos.append(0, bsi);
1321 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1322 try {
1323 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1324 } catch (Exception e) {
1325 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1326 errPw.println("Exception: " + e.getMessage());
1327 return -1;
1328 }
1329 return 0;
1330 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001331
Tyler Gunnd4575212021-05-03 14:46:49 -07001332 private int handleD2dDeviceSupportedCommand() {
1333 PrintWriter errPw = getErrPrintWriter();
1334
1335 String arg = getNextArg();
1336 if (arg == null) {
1337 onHelpD2D();
1338 return 0;
1339 }
1340
Jack Yua533d632022-09-30 13:53:46 -07001341 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001342 try {
1343 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1344 } catch (RemoteException e) {
1345 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1346 errPw.println("Exception: " + e.getMessage());
1347 return -1;
1348 }
1349 return 0;
1350 }
1351
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001352 // ims set-ims-service
1353 private int handleImsSetServiceCommand() {
1354 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001355 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001356 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001357 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001358
1359 String opt;
1360 while ((opt = getNextOption()) != null) {
1361 switch (opt) {
1362 case "-s": {
1363 try {
1364 slotId = Integer.parseInt(getNextArgRequired());
1365 } catch (NumberFormatException e) {
1366 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1367 return -1;
1368 }
1369 break;
1370 }
1371 case "-c": {
1372 isCarrierService = true;
1373 break;
1374 }
1375 case "-d": {
1376 isCarrierService = false;
1377 break;
1378 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001379 case "-f": {
1380 String featureString = getNextArgRequired();
1381 String[] features = featureString.split(",");
1382 for (int i = 0; i < features.length; i++) {
1383 try {
1384 Integer result = Integer.parseInt(features[i]);
1385 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1386 || result >= ImsFeature.FEATURE_MAX) {
1387 errPw.println("ims set-ims-service -f " + result
1388 + " is an invalid feature.");
1389 return -1;
1390 }
1391 featuresList.add(result);
1392 } catch (NumberFormatException e) {
1393 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1394 + " as an integer.");
1395 return -1;
1396 }
1397 }
1398 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001399 }
1400 }
1401 // Mandatory param, either -c or -d
1402 if (isCarrierService == null) {
1403 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1404 return -1;
1405 }
1406
1407 String packageName = getNextArg();
1408
1409 try {
1410 if (packageName == null) {
1411 packageName = "";
1412 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001413 int[] featureArray = new int[featuresList.size()];
1414 for (int i = 0; i < featuresList.size(); i++) {
1415 featureArray[i] = featuresList.get(i);
1416 }
1417 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1418 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001419 if (VDBG) {
1420 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001421 + (isCarrierService ? "-c " : "-d ")
1422 + "-f " + featuresList + " "
1423 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001424 }
1425 getOutPrintWriter().println(result);
1426 } catch (RemoteException e) {
1427 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001428 + (isCarrierService ? "-c " : "-d ")
1429 + "-f " + featuresList + " "
1430 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001431 errPw.println("Exception: " + e.getMessage());
1432 return -1;
1433 }
1434 return 0;
1435 }
1436
Brad Ebinger999d3302020-11-25 14:31:39 -08001437 // ims clear-ims-service-override
1438 private int handleImsClearCarrierServiceCommand() {
1439 PrintWriter errPw = getErrPrintWriter();
1440 int slotId = getDefaultSlot();
1441
1442 String opt;
1443 while ((opt = getNextOption()) != null) {
1444 switch (opt) {
1445 case "-s": {
1446 try {
1447 slotId = Integer.parseInt(getNextArgRequired());
1448 } catch (NumberFormatException e) {
1449 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1450 return -1;
1451 }
1452 break;
1453 }
1454 }
1455 }
1456
1457 try {
1458 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1459 if (VDBG) {
1460 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1461 + ", result=" + result);
1462 }
1463 getOutPrintWriter().println(result);
1464 } catch (RemoteException e) {
1465 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1466 + ", error" + e.getMessage());
1467 errPw.println("Exception: " + e.getMessage());
1468 return -1;
1469 }
1470 return 0;
1471 }
1472
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001473 // ims get-ims-service
1474 private int handleImsGetServiceCommand() {
1475 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001476 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001477 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001478 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001479
1480 String opt;
1481 while ((opt = getNextOption()) != null) {
1482 switch (opt) {
1483 case "-s": {
1484 try {
1485 slotId = Integer.parseInt(getNextArgRequired());
1486 } catch (NumberFormatException e) {
1487 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1488 return -1;
1489 }
1490 break;
1491 }
1492 case "-c": {
1493 isCarrierService = true;
1494 break;
1495 }
1496 case "-d": {
1497 isCarrierService = false;
1498 break;
1499 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001500 case "-f": {
1501 try {
1502 featureType = Integer.parseInt(getNextArg());
1503 } catch (NumberFormatException e) {
1504 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1505 return -1;
1506 }
1507 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1508 || featureType >= ImsFeature.FEATURE_MAX) {
1509 errPw.println("ims get-ims-service -f invalid feature.");
1510 return -1;
1511 }
1512 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001513 }
1514 }
1515 // Mandatory param, either -c or -d
1516 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001517 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001518 return -1;
1519 }
1520
1521 String result;
1522 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001523 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001524 } catch (RemoteException e) {
1525 return -1;
1526 }
1527 if (VDBG) {
1528 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001529 + (isCarrierService ? "-c " : "-d ")
1530 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1531 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001532 }
1533 getOutPrintWriter().println(result);
1534 return 0;
1535 }
1536
1537 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001538 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001539 String opt;
1540 while ((opt = getNextOption()) != null) {
1541 switch (opt) {
1542 case "-s": {
1543 try {
1544 slotId = Integer.parseInt(getNextArgRequired());
1545 } catch (NumberFormatException e) {
1546 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1547 return -1;
1548 }
1549 break;
1550 }
1551 }
1552 }
1553 try {
1554 mInterface.enableIms(slotId);
1555 } catch (RemoteException e) {
1556 return -1;
1557 }
1558 if (VDBG) {
1559 Log.v(LOG_TAG, "ims enable -s " + slotId);
1560 }
1561 return 0;
1562 }
1563
1564 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001565 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001566 String opt;
1567 while ((opt = getNextOption()) != null) {
1568 switch (opt) {
1569 case "-s": {
1570 try {
1571 slotId = Integer.parseInt(getNextArgRequired());
1572 } catch (NumberFormatException e) {
1573 getErrPrintWriter().println(
1574 "ims disable requires an integer as a SLOT_ID.");
1575 return -1;
1576 }
1577 break;
1578 }
1579 }
1580 }
1581 try {
1582 mInterface.disableIms(slotId);
1583 } catch (RemoteException e) {
1584 return -1;
1585 }
1586 if (VDBG) {
1587 Log.v(LOG_TAG, "ims disable -s " + slotId);
1588 }
1589 return 0;
1590 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001591
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001592 private int handleCepChange() {
1593 Log.i(LOG_TAG, "handleCepChange");
1594 String opt = getNextArg();
1595 if (opt == null) {
1596 return -1;
1597 }
1598 boolean isCepEnabled = opt.equals("enable");
1599
1600 try {
1601 mInterface.setCepEnabled(isCepEnabled);
1602 } catch (RemoteException e) {
1603 return -1;
1604 }
1605 return 0;
1606 }
1607
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001608 private int getDefaultSlot() {
1609 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1610 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1611 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1612 // If there is no default, default to slot 0.
1613 slotId = DEFAULT_PHONE_ID;
1614 }
1615 return slotId;
1616 }
sqian2fff4a32018-11-05 14:18:37 -08001617
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001618 // Parse options related to Carrier Config Commands.
1619 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001620 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001621 CcOptionParseResult result = new CcOptionParseResult();
1622 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1623 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001624
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001625 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001626 while ((opt = getNextOption()) != null) {
1627 switch (opt) {
1628 case "-s": {
1629 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1631 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1632 errPw.println(tag + "No valid subscription found.");
1633 return null;
1634 }
1635
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001636 } catch (IllegalArgumentException e) {
1637 // Missing slot id
1638 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001639 return null;
1640 }
1641 break;
1642 }
1643 case "-p": {
1644 if (allowOptionPersistent) {
1645 result.mPersistent = true;
1646 } else {
1647 errPw.println(tag + "Unexpected option " + opt);
1648 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001649 }
1650 break;
1651 }
1652 default: {
1653 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001654 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001655 }
1656 }
1657 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001658 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001659 }
1660
1661 private int slotStringToSubId(String tag, String slotString) {
1662 int slotId = -1;
1663 try {
1664 slotId = Integer.parseInt(slotString);
1665 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001666 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1667 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1668 }
1669
1670 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001671 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1672 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1673 }
1674
Qiong Liuf25799b2020-09-10 10:13:46 +08001675 Phone phone = PhoneFactory.getPhone(slotId);
1676 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001677 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1678 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1679 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001680 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001681 }
1682
Hall Liud892bec2018-11-30 14:51:45 -08001683 private boolean checkShellUid() {
Jack Yu26735292024-09-25 14:33:49 -07001684 return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
Hall Liud892bec2018-11-30 14:51:45 -08001685 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001686
1687 private int handleCcCommand() {
1688 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1689 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001690 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1691 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001692 getErrPrintWriter().println("cc: Permission denied.");
1693 return -1;
1694 }
1695
1696 String arg = getNextArg();
1697 if (arg == null) {
1698 onHelpCc();
1699 return 0;
1700 }
1701
1702 switch (arg) {
1703 case CC_GET_VALUE: {
1704 return handleCcGetValue();
1705 }
1706 case CC_SET_VALUE: {
1707 return handleCcSetValue();
1708 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001709 case CC_SET_VALUES_FROM_XML: {
1710 return handleCcSetValuesFromXml();
1711 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001712 case CC_CLEAR_VALUES: {
1713 return handleCcClearValues();
1714 }
1715 default: {
1716 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1717 }
1718 }
1719 return -1;
1720 }
1721
1722 // cc get-value
1723 private int handleCcGetValue() {
1724 PrintWriter errPw = getErrPrintWriter();
1725 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1726 String key = null;
1727
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001728 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001729 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001730 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001731 return -1;
1732 }
1733
1734 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001735 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001736 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001737 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001738 return -1;
1739 }
1740
1741 // Get the key.
1742 key = getNextArg();
1743 if (key != null) {
1744 // A key was provided. Verify if it is a valid key
1745 if (!bundle.containsKey(key)) {
1746 errPw.println(tag + key + " is not a valid key.");
1747 return -1;
1748 }
1749
1750 // Print the carrier config value for key.
1751 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1752 } else {
1753 // No key provided. Show all values.
1754 // Iterate over a sorted list of all carrier config keys and print them.
1755 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1756 for (String k : sortedSet) {
1757 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1758 }
1759 }
1760 return 0;
1761 }
1762
1763 // cc set-value
1764 private int handleCcSetValue() {
1765 PrintWriter errPw = getErrPrintWriter();
1766 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1767
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001768 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001769 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001770 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001771 return -1;
1772 }
1773
1774 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001775 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001776 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001777 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001778 return -1;
1779 }
1780
1781 // Get the key.
1782 String key = getNextArg();
1783 if (key == null || key.equals("")) {
1784 errPw.println(tag + "KEY is missing");
1785 return -1;
1786 }
1787
1788 // Verify if the key is valid
1789 if (!originalValues.containsKey(key)) {
1790 errPw.println(tag + key + " is not a valid key.");
1791 return -1;
1792 }
1793
1794 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1795 ArrayList<String> valueList = new ArrayList<String>();
1796 while (peekNextArg() != null) {
1797 valueList.add(getNextArg());
1798 }
1799
1800 // Find the type of the carrier config value
1801 CcType type = getType(tag, key, originalValues);
1802 if (type == CcType.UNKNOWN) {
1803 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1804 return -1;
1805 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001806 if (type == CcType.PERSISTABLE_BUNDLE) {
1807 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1808 + "Use set-values-from-xml instead.");
1809 return -1;
1810 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001811
1812 // Create an override bundle containing the key and value that should be overriden.
1813 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1814 if (overrideBundle == null) {
1815 return -1;
1816 }
1817
1818 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001819 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001820
1821 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001822 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001823 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001824 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001825 return -1;
1826 }
1827
1828 // Print the original and new value.
1829 String originalValueString = ccValueToString(key, type, originalValues);
1830 String newValueString = ccValueToString(key, type, newValues);
1831 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1832 getOutPrintWriter().println("New value: \n" + newValueString);
1833
1834 return 0;
1835 }
1836
Allen Xuee00f0e2022-03-14 21:04:49 +00001837 // cc set-values-from-xml
1838 private int handleCcSetValuesFromXml() {
1839 PrintWriter errPw = getErrPrintWriter();
1840 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1841
1842 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001843 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001844 if (options == null) {
1845 return -1;
1846 }
1847
1848 // Get bundle containing all current carrier configuration values.
1849 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1850 if (originalValues == null) {
1851 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1852 return -1;
1853 }
1854
1855 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1856 if (overrideBundle == null) {
1857 return -1;
1858 }
1859
1860 // Verify all values are valid types
1861 for (String key : overrideBundle.keySet()) {
1862 CcType type = getType(tag, key, originalValues);
1863 if (type == CcType.UNKNOWN) {
1864 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1865 return -1;
1866 }
1867 }
1868
1869 // Override the value
1870 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1871
1872 // Find bundle containing all new carrier configuration values after the override.
1873 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1874 if (newValues == null) {
1875 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1876 return -1;
1877 }
1878
1879 // Print the original and new values
1880 overrideBundle.keySet().forEach(key -> {
1881 CcType type = getType(tag, key, originalValues);
1882 String originalValueString = ccValueToString(key, type, originalValues);
1883 String newValueString = ccValueToString(key, type, newValues);
1884 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1885 getOutPrintWriter().println("New value: \n" + newValueString);
1886 });
1887
1888 return 0;
1889 }
1890
1891 private PersistableBundle readPersistableBundleFromXml(String tag) {
1892 PersistableBundle subIdBundles;
1893 try {
1894 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1895 } catch (IOException | RuntimeException e) {
1896 PrintWriter errPw = getErrPrintWriter();
1897 errPw.println(tag + e);
1898 return null;
1899 }
1900
1901 return subIdBundles;
1902 }
1903
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001904 // cc clear-values
1905 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001906 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1907
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001908 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001909 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001910 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001911 return -1;
1912 }
1913
1914 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001915 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001916 getOutPrintWriter()
1917 .println("All previously set carrier config override values has been cleared");
1918 return 0;
1919 }
1920
1921 private CcType getType(String tag, String key, PersistableBundle bundle) {
1922 // Find the type by checking the type of the current value stored in the bundle.
1923 Object value = bundle.get(key);
1924
1925 if (CC_TYPE_MAP.containsKey(key)) {
1926 return CC_TYPE_MAP.get(key);
1927 } else if (value != null) {
1928 if (value instanceof Boolean) {
1929 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001930 }
1931 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001932 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001933 }
1934 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001935 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001936 }
1937 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001938 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001939 }
1940 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001941 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001942 }
1943 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001944 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001945 }
1946 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001947 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001948 }
1949 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001950 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001951 }
1952 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001953 return CcType.STRING_ARRAY;
1954 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 if (value instanceof PersistableBundle) {
1956 return CcType.PERSISTABLE_BUNDLE;
1957 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001958 } else {
1959 // Current value was null and can therefore not be used in order to find the type.
1960 // Check the name of the key to infer the type. This check is not needed for primitive
1961 // data types (boolean, double, int and long), since they can not be null.
1962 if (key.endsWith("double_array")) {
1963 return CcType.DOUBLE_ARRAY;
1964 }
1965 if (key.endsWith("int_array")) {
1966 return CcType.INT_ARRAY;
1967 }
1968 if (key.endsWith("long_array")) {
1969 return CcType.LONG_ARRAY;
1970 }
1971 if (key.endsWith("string")) {
1972 return CcType.STRING;
1973 }
1974 if (key.endsWith("string_array") || key.endsWith("strings")) {
1975 return CcType.STRING_ARRAY;
1976 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001977 if (key.endsWith("bundle")) {
1978 return CcType.PERSISTABLE_BUNDLE;
1979 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001980 }
1981
1982 // Not possible to infer the type by looking at the current value or the key.
1983 PrintWriter errPw = getErrPrintWriter();
1984 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1985 return CcType.UNKNOWN;
1986 }
1987
1988 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1989 String result;
1990 StringBuilder valueString = new StringBuilder();
1991 String typeString = type.toString();
1992 Object value = bundle.get(key);
1993
1994 if (value == null) {
1995 valueString.append("null");
1996 } else {
1997 switch (type) {
1998 case DOUBLE_ARRAY: {
1999 // Format the string representation of the int array as value1 value2......
2000 double[] valueArray = (double[]) value;
2001 for (int i = 0; i < valueArray.length; i++) {
2002 if (i != 0) {
2003 valueString.append(" ");
2004 }
2005 valueString.append(valueArray[i]);
2006 }
2007 break;
2008 }
2009 case INT_ARRAY: {
2010 // Format the string representation of the int array as value1 value2......
2011 int[] valueArray = (int[]) value;
2012 for (int i = 0; i < valueArray.length; i++) {
2013 if (i != 0) {
2014 valueString.append(" ");
2015 }
2016 valueString.append(valueArray[i]);
2017 }
2018 break;
2019 }
2020 case LONG_ARRAY: {
2021 // Format the string representation of the int array as value1 value2......
2022 long[] valueArray = (long[]) value;
2023 for (int i = 0; i < valueArray.length; i++) {
2024 if (i != 0) {
2025 valueString.append(" ");
2026 }
2027 valueString.append(valueArray[i]);
2028 }
2029 break;
2030 }
2031 case STRING: {
2032 valueString.append("\"" + value.toString() + "\"");
2033 break;
2034 }
2035 case STRING_ARRAY: {
2036 // Format the string representation of the string array as "value1" "value2"....
2037 String[] valueArray = (String[]) value;
2038 for (int i = 0; i < valueArray.length; i++) {
2039 if (i != 0) {
2040 valueString.append(" ");
2041 }
2042 if (valueArray[i] != null) {
2043 valueString.append("\"" + valueArray[i] + "\"");
2044 } else {
2045 valueString.append("null");
2046 }
2047 }
2048 break;
2049 }
2050 default: {
2051 valueString.append(value.toString());
2052 }
2053 }
2054 }
2055 return String.format("%-70s %-15s %s", key, typeString, valueString);
2056 }
2057
2058 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2059 ArrayList<String> valueList) {
2060 PrintWriter errPw = getErrPrintWriter();
2061 PersistableBundle bundle = new PersistableBundle();
2062
2063 // First verify that a valid number of values has been provided for the type.
2064 switch (type) {
2065 case BOOLEAN:
2066 case DOUBLE:
2067 case INT:
2068 case LONG: {
2069 if (valueList.size() != 1) {
2070 errPw.println(tag + "Expected 1 value for type " + type
2071 + ". Found: " + valueList.size());
2072 return null;
2073 }
2074 break;
2075 }
2076 case STRING: {
2077 if (valueList.size() > 1) {
2078 errPw.println(tag + "Expected 0 or 1 values for type " + type
2079 + ". Found: " + valueList.size());
2080 return null;
2081 }
2082 break;
2083 }
2084 }
2085
2086 // Parse the value according to type and add it to the Bundle.
2087 switch (type) {
2088 case BOOLEAN: {
2089 if ("true".equalsIgnoreCase(valueList.get(0))) {
2090 bundle.putBoolean(key, true);
2091 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2092 bundle.putBoolean(key, false);
2093 } else {
2094 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2095 return null;
2096 }
2097 break;
2098 }
2099 case DOUBLE: {
2100 try {
2101 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2102 } catch (NumberFormatException nfe) {
2103 // Not a valid double
2104 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2105 return null;
2106 }
2107 break;
2108 }
2109 case DOUBLE_ARRAY: {
2110 double[] valueDoubleArray = null;
2111 if (valueList.size() > 0) {
2112 valueDoubleArray = new double[valueList.size()];
2113 for (int i = 0; i < valueList.size(); i++) {
2114 try {
2115 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2116 } catch (NumberFormatException nfe) {
2117 // Not a valid double
2118 errPw.println(
2119 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2120 return null;
2121 }
2122 }
2123 }
2124 bundle.putDoubleArray(key, valueDoubleArray);
2125 break;
2126 }
2127 case INT: {
2128 try {
2129 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2130 } catch (NumberFormatException nfe) {
2131 // Not a valid integer
2132 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2133 return null;
2134 }
2135 break;
2136 }
2137 case INT_ARRAY: {
2138 int[] valueIntArray = null;
2139 if (valueList.size() > 0) {
2140 valueIntArray = new int[valueList.size()];
2141 for (int i = 0; i < valueList.size(); i++) {
2142 try {
2143 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2144 } catch (NumberFormatException nfe) {
2145 // Not a valid integer
2146 errPw.println(tag
2147 + "Unable to parse " + valueList.get(i) + " as an integer.");
2148 return null;
2149 }
2150 }
2151 }
2152 bundle.putIntArray(key, valueIntArray);
2153 break;
2154 }
2155 case LONG: {
2156 try {
2157 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2158 } catch (NumberFormatException nfe) {
2159 // Not a valid long
2160 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2161 return null;
2162 }
2163 break;
2164 }
2165 case LONG_ARRAY: {
2166 long[] valueLongArray = null;
2167 if (valueList.size() > 0) {
2168 valueLongArray = new long[valueList.size()];
2169 for (int i = 0; i < valueList.size(); i++) {
2170 try {
2171 valueLongArray[i] = Long.parseLong(valueList.get(i));
2172 } catch (NumberFormatException nfe) {
2173 // Not a valid long
2174 errPw.println(
2175 tag + "Unable to parse " + valueList.get(i) + " as a long");
2176 return null;
2177 }
2178 }
2179 }
2180 bundle.putLongArray(key, valueLongArray);
2181 break;
2182 }
2183 case STRING: {
2184 String value = null;
2185 if (valueList.size() > 0) {
2186 value = valueList.get(0);
2187 }
2188 bundle.putString(key, value);
2189 break;
2190 }
2191 case STRING_ARRAY: {
2192 String[] valueStringArray = null;
2193 if (valueList.size() > 0) {
2194 valueStringArray = new String[valueList.size()];
2195 valueList.toArray(valueStringArray);
2196 }
2197 bundle.putStringArray(key, valueStringArray);
2198 break;
2199 }
2200 }
2201 return bundle;
2202 }
Shuo Qian489d9282020-07-09 11:30:03 -07002203
2204 private int handleEndBlockSuppressionCommand() {
2205 if (!checkShellUid()) {
2206 return -1;
2207 }
2208
2209 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2210 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2211 }
2212 return 0;
2213 }
Hui Wang641e81c2020-10-12 12:14:23 -07002214
Michele Berionne54af4632020-12-28 20:23:16 +00002215 private int handleRestartModemCommand() {
2216 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2217 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002218 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2219 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002220 getErrPrintWriter().println("RestartModem: Permission denied.");
2221 return -1;
2222 }
2223
2224 boolean result = TelephonyManager.getDefault().rebootRadio();
2225 getOutPrintWriter().println(result);
2226
2227 return result ? 0 : -1;
2228 }
2229
Ling Ma4fbab492022-01-25 22:36:16 +00002230 private int handleGetImei() {
2231 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2232 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002233 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2234 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002235 getErrPrintWriter().println("Device IMEI: Permission denied.");
2236 return -1;
2237 }
2238
2239 final long identity = Binder.clearCallingIdentity();
2240
2241 String imei = null;
2242 String arg = getNextArg();
2243 if (arg != null) {
2244 try {
2245 int specifiedSlotIndex = Integer.parseInt(arg);
2246 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2247 } catch (NumberFormatException exception) {
2248 PrintWriter errPw = getErrPrintWriter();
2249 errPw.println("-s requires an integer as slot index.");
2250 return -1;
2251 }
2252
2253 } else {
2254 imei = TelephonyManager.from(mContext).getImei();
2255 }
2256 getOutPrintWriter().println("Device IMEI: " + imei);
2257
2258 Binder.restoreCallingIdentity(identity);
2259 return 0;
2260 }
2261
Michele Berionne5e411512020-11-13 02:36:59 +00002262 private int handleUnattendedReboot() {
2263 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2264 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002265 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2266 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002267 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2268 return -1;
2269 }
2270
2271 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2272 getOutPrintWriter().println("result: " + result);
2273
2274 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2275 }
2276
Aman Gupta07124872022-02-09 08:02:14 +00002277 private int handleGetSimSlotsMapping() {
2278 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2279 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002280 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2281 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002282 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2283 return -1;
2284 }
2285 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2286 String result = telephonyManager.getSimSlotMapping().toString();
2287 getOutPrintWriter().println("simSlotsMapping: " + result);
2288
2289 return 0;
2290 }
2291
Hui Wang641e81c2020-10-12 12:14:23 -07002292 private int handleGbaCommand() {
2293 String arg = getNextArg();
2294 if (arg == null) {
2295 onHelpGba();
2296 return 0;
2297 }
2298
2299 switch (arg) {
2300 case GBA_SET_SERVICE: {
2301 return handleGbaSetServiceCommand();
2302 }
2303 case GBA_GET_SERVICE: {
2304 return handleGbaGetServiceCommand();
2305 }
2306 case GBA_SET_RELEASE_TIME: {
2307 return handleGbaSetReleaseCommand();
2308 }
2309 case GBA_GET_RELEASE_TIME: {
2310 return handleGbaGetReleaseCommand();
2311 }
2312 }
2313
2314 return -1;
2315 }
2316
2317 private int getSubId(String cmd) {
2318 int slotId = getDefaultSlot();
2319 String opt = getNextOption();
2320 if (opt != null && opt.equals("-s")) {
2321 try {
2322 slotId = Integer.parseInt(getNextArgRequired());
2323 } catch (NumberFormatException e) {
2324 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2325 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2326 }
2327 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002328 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002329 }
2330
2331 private int handleGbaSetServiceCommand() {
2332 int subId = getSubId("gba set-service");
2333 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2334 return -1;
2335 }
2336
2337 String packageName = getNextArg();
2338 try {
2339 if (packageName == null) {
2340 packageName = "";
2341 }
2342 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2343 if (VDBG) {
2344 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2345 + packageName + ", result=" + result);
2346 }
2347 getOutPrintWriter().println(result);
2348 } catch (RemoteException e) {
2349 Log.w(LOG_TAG, "gba set-service " + subId + " "
2350 + packageName + ", error" + e.getMessage());
2351 getErrPrintWriter().println("Exception: " + e.getMessage());
2352 return -1;
2353 }
2354 return 0;
2355 }
2356
2357 private int handleGbaGetServiceCommand() {
2358 String result;
2359
2360 int subId = getSubId("gba get-service");
2361 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2362 return -1;
2363 }
2364
2365 try {
2366 result = mInterface.getBoundGbaService(subId);
2367 } catch (RemoteException e) {
2368 return -1;
2369 }
2370 if (VDBG) {
2371 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2372 }
2373 getOutPrintWriter().println(result);
2374 return 0;
2375 }
2376
2377 private int handleGbaSetReleaseCommand() {
2378 //the release time value could be -1
2379 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2380 : SubscriptionManager.getDefaultSubscriptionId();
2381 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2382 return -1;
2383 }
2384
2385 String intervalStr = getNextArg();
2386 if (intervalStr == null) {
2387 return -1;
2388 }
2389
2390 try {
2391 int interval = Integer.parseInt(intervalStr);
2392 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2393 if (VDBG) {
2394 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2395 + intervalStr + ", result=" + result);
2396 }
2397 getOutPrintWriter().println(result);
2398 } catch (NumberFormatException | RemoteException e) {
2399 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2400 + intervalStr + ", error" + e.getMessage());
2401 getErrPrintWriter().println("Exception: " + e.getMessage());
2402 return -1;
2403 }
2404 return 0;
2405 }
2406
2407 private int handleGbaGetReleaseCommand() {
2408 int subId = getSubId("gba get-release");
2409 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2410 return -1;
2411 }
2412
2413 int result = 0;
2414 try {
2415 result = mInterface.getGbaReleaseTime(subId);
2416 } catch (RemoteException e) {
2417 return -1;
2418 }
2419 if (VDBG) {
2420 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2421 }
2422 getOutPrintWriter().println(result);
2423 return 0;
2424 }
Hui Wang761a6682020-10-31 05:12:53 +00002425
2426 private int handleSingleRegistrationConfigCommand() {
2427 String arg = getNextArg();
2428 if (arg == null) {
2429 onHelpSrc();
2430 return 0;
2431 }
2432
2433 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002434 case SRC_SET_TEST_ENABLED: {
2435 return handleSrcSetTestEnabledCommand();
2436 }
2437 case SRC_GET_TEST_ENABLED: {
2438 return handleSrcGetTestEnabledCommand();
2439 }
Hui Wang761a6682020-10-31 05:12:53 +00002440 case SRC_SET_DEVICE_ENABLED: {
2441 return handleSrcSetDeviceEnabledCommand();
2442 }
2443 case SRC_GET_DEVICE_ENABLED: {
2444 return handleSrcGetDeviceEnabledCommand();
2445 }
2446 case SRC_SET_CARRIER_ENABLED: {
2447 return handleSrcSetCarrierEnabledCommand();
2448 }
2449 case SRC_GET_CARRIER_ENABLED: {
2450 return handleSrcGetCarrierEnabledCommand();
2451 }
Hui Wangb647abe2021-02-26 09:33:38 -08002452 case SRC_SET_FEATURE_ENABLED: {
2453 return handleSrcSetFeatureValidationCommand();
2454 }
2455 case SRC_GET_FEATURE_ENABLED: {
2456 return handleSrcGetFeatureValidationCommand();
2457 }
Hui Wang761a6682020-10-31 05:12:53 +00002458 }
2459
2460 return -1;
2461 }
2462
James.cf Linbcdf8b32021-01-14 16:44:13 +08002463 private int handleRcsUceCommand() {
2464 String arg = getNextArg();
2465 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002466 onHelpUce();
2467 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002468 }
2469
2470 switch (arg) {
2471 case UCE_REMOVE_EAB_CONTACT:
2472 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002473 case UCE_GET_EAB_CONTACT:
2474 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002475 case UCE_GET_EAB_CAPABILITY:
2476 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002477 case UCE_GET_DEVICE_ENABLED:
2478 return handleUceGetDeviceEnabledCommand();
2479 case UCE_SET_DEVICE_ENABLED:
2480 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002481 case UCE_OVERRIDE_PUBLISH_CAPS:
2482 return handleUceOverridePublishCaps();
2483 case UCE_GET_LAST_PIDF_XML:
2484 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002485 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2486 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002487 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2488 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002489 }
2490 return -1;
2491 }
2492
2493 private int handleRemovingEabContactCommand() {
2494 int subId = getSubId("uce remove-eab-contact");
2495 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2496 return -1;
2497 }
2498
2499 String phoneNumber = getNextArgRequired();
2500 if (TextUtils.isEmpty(phoneNumber)) {
2501 return -1;
2502 }
2503 int result = 0;
2504 try {
2505 result = mInterface.removeContactFromEab(subId, phoneNumber);
2506 } catch (RemoteException e) {
2507 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2508 getErrPrintWriter().println("Exception: " + e.getMessage());
2509 return -1;
2510 }
2511
2512 if (VDBG) {
2513 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2514 }
calvinpan293ea1b2021-02-04 17:52:13 +08002515 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002516 }
2517
calvinpane4a8a1d2021-01-25 13:51:18 +08002518 private int handleGettingEabContactCommand() {
2519 String phoneNumber = getNextArgRequired();
2520 if (TextUtils.isEmpty(phoneNumber)) {
2521 return -1;
2522 }
2523 String result = "";
2524 try {
2525 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002526 } catch (RemoteException e) {
2527 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2528 getErrPrintWriter().println("Exception: " + e.getMessage());
2529 return -1;
2530 }
2531
2532 if (VDBG) {
2533 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2534 }
calvinpan293ea1b2021-02-04 17:52:13 +08002535 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002536 return 0;
2537 }
2538
Calvin Pana1434322021-07-01 19:27:01 +08002539 private int handleGettingEabCapabilityCommand() {
2540 String phoneNumber = getNextArgRequired();
2541 if (TextUtils.isEmpty(phoneNumber)) {
2542 return -1;
2543 }
2544 String result = "";
2545 try {
2546 result = mInterface.getCapabilityFromEab(phoneNumber);
2547 } catch (RemoteException e) {
2548 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2549 getErrPrintWriter().println("Exception: " + e.getMessage());
2550 return -1;
2551 }
2552
2553 if (VDBG) {
2554 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2555 }
2556 getOutPrintWriter().println(result);
2557 return 0;
2558 }
2559
James.cf Lin4b784aa2021-01-31 03:25:15 +08002560 private int handleUceGetDeviceEnabledCommand() {
2561 boolean result = false;
2562 try {
2563 result = mInterface.getDeviceUceEnabled();
2564 } catch (RemoteException e) {
2565 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2566 return -1;
2567 }
2568 if (VDBG) {
2569 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2570 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002571 getOutPrintWriter().println(result);
2572 return 0;
2573 }
2574
James.cf Lin4b784aa2021-01-31 03:25:15 +08002575 private int handleUceSetDeviceEnabledCommand() {
2576 String enabledStr = getNextArg();
2577 if (TextUtils.isEmpty(enabledStr)) {
2578 return -1;
2579 }
2580
2581 try {
2582 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2583 mInterface.setDeviceUceEnabled(isEnabled);
2584 if (VDBG) {
2585 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2586 }
2587 } catch (NumberFormatException | RemoteException e) {
2588 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2589 getErrPrintWriter().println("Exception: " + e.getMessage());
2590 return -1;
2591 }
2592 return 0;
2593 }
2594
James.cf Line8713a42021-04-29 16:04:26 +08002595 private int handleUceRemoveRequestDisallowedStatus() {
2596 int subId = getSubId("uce remove-request-disallowed-status");
2597 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2598 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2599 return -1;
2600 }
2601 boolean result;
2602 try {
2603 result = mInterface.removeUceRequestDisallowedStatus(subId);
2604 } catch (RemoteException e) {
2605 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2606 return -1;
2607 }
2608 if (VDBG) {
2609 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2610 }
2611 getOutPrintWriter().println(result);
2612 return 0;
2613 }
2614
James.cf Lin0fc71b02021-05-25 01:37:38 +08002615 private int handleUceSetCapRequestTimeout() {
2616 int subId = getSubId("uce set-capabilities-request-timeout");
2617 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2618 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2619 return -1;
2620 }
2621 long timeoutAfterMs = Long.valueOf(getNextArg());
2622 boolean result;
2623 try {
2624 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2625 } catch (RemoteException e) {
2626 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2627 return -1;
2628 }
2629 if (VDBG) {
2630 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2631 }
2632 getOutPrintWriter().println(result);
2633 return 0;
2634 }
2635
Hui Wangbaaee6a2021-02-19 20:45:36 -08002636 private int handleSrcSetTestEnabledCommand() {
2637 String enabledStr = getNextArg();
2638 if (enabledStr == null) {
2639 return -1;
2640 }
2641
2642 try {
2643 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2644 if (VDBG) {
2645 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2646 }
2647 getOutPrintWriter().println("Done");
2648 } catch (NumberFormatException | RemoteException e) {
2649 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2650 getErrPrintWriter().println("Exception: " + e.getMessage());
2651 return -1;
2652 }
2653 return 0;
2654 }
2655
2656 private int handleSrcGetTestEnabledCommand() {
2657 boolean result = false;
2658 try {
2659 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2660 } catch (RemoteException e) {
2661 return -1;
2662 }
2663 if (VDBG) {
2664 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2665 }
2666 getOutPrintWriter().println(result);
2667 return 0;
2668 }
2669
Brad Ebinger14d467f2021-02-12 06:18:28 +00002670 private int handleUceOverridePublishCaps() {
2671 int subId = getSubId("uce override-published-caps");
2672 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2673 return -1;
2674 }
2675 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2676 String operation = getNextArgRequired();
2677 String caps = getNextArg();
2678 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2679 && !"list".equals(operation)) {
2680 getErrPrintWriter().println("Invalid operation: " + operation);
2681 return -1;
2682 }
2683
2684 // add/remove requires capabilities to be specified.
2685 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2686 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2687 + "specified");
2688 return -1;
2689 }
2690
2691 ArraySet<String> capSet = new ArraySet<>();
2692 if (!TextUtils.isEmpty(caps)) {
2693 String[] capArray = caps.split(":");
2694 for (String cap : capArray) {
2695 // Allow unknown tags to be passed in as well.
2696 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2697 }
2698 }
2699
2700 RcsContactUceCapability result = null;
2701 try {
2702 switch (operation) {
2703 case "add":
2704 result = mInterface.addUceRegistrationOverrideShell(subId,
2705 new ArrayList<>(capSet));
2706 break;
2707 case "remove":
2708 result = mInterface.removeUceRegistrationOverrideShell(subId,
2709 new ArrayList<>(capSet));
2710 break;
2711 case "clear":
2712 result = mInterface.clearUceRegistrationOverrideShell(subId);
2713 break;
2714 case "list":
2715 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2716 break;
2717 }
2718 } catch (RemoteException e) {
2719 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2720 getErrPrintWriter().println("Exception: " + e.getMessage());
2721 return -1;
2722 } catch (ServiceSpecificException sse) {
2723 // Reconstruct ImsException
2724 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2725 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2726 getErrPrintWriter().println("Exception: " + imsException);
2727 return -1;
2728 }
2729 if (result == null) {
2730 getErrPrintWriter().println("Service not available");
2731 return -1;
2732 }
2733 getOutPrintWriter().println(result);
2734 return 0;
2735 }
2736
2737 private int handleUceGetPidfXml() {
2738 int subId = getSubId("uce get-last-publish-pidf");
2739 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2740 return -1;
2741 }
2742
2743 String result;
2744 try {
2745 result = mInterface.getLastUcePidfXmlShell(subId);
2746 } catch (RemoteException e) {
2747 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2748 getErrPrintWriter().println("Exception: " + e.getMessage());
2749 return -1;
2750 } catch (ServiceSpecificException sse) {
2751 // Reconstruct ImsException
2752 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2753 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2754 getErrPrintWriter().println("Exception: " + imsException);
2755 return -1;
2756 }
2757 if (result == null) {
2758 getErrPrintWriter().println("Service not available");
2759 return -1;
2760 }
2761 getOutPrintWriter().println(result);
2762 return 0;
2763 }
2764
Hui Wang761a6682020-10-31 05:12:53 +00002765 private int handleSrcSetDeviceEnabledCommand() {
2766 String enabledStr = getNextArg();
2767 if (enabledStr == null) {
2768 return -1;
2769 }
2770
2771 try {
2772 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2773 if (VDBG) {
2774 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2775 }
2776 getOutPrintWriter().println("Done");
2777 } catch (NumberFormatException | RemoteException e) {
2778 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2779 getErrPrintWriter().println("Exception: " + e.getMessage());
2780 return -1;
2781 }
2782 return 0;
2783 }
2784
2785 private int handleSrcGetDeviceEnabledCommand() {
2786 boolean result = false;
2787 try {
2788 result = mInterface.getDeviceSingleRegistrationEnabled();
2789 } catch (RemoteException e) {
2790 return -1;
2791 }
2792 if (VDBG) {
2793 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2794 }
2795 getOutPrintWriter().println(result);
2796 return 0;
2797 }
2798
2799 private int handleSrcSetCarrierEnabledCommand() {
2800 //the release time value could be -1
2801 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2802 : SubscriptionManager.getDefaultSubscriptionId();
2803 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2804 return -1;
2805 }
2806
2807 String enabledStr = getNextArg();
2808 if (enabledStr == null) {
2809 return -1;
2810 }
2811
2812 try {
2813 boolean result =
2814 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2815 if (VDBG) {
2816 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2817 + enabledStr + ", result=" + result);
2818 }
2819 getOutPrintWriter().println(result);
2820 } catch (NumberFormatException | RemoteException e) {
2821 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2822 + enabledStr + ", error" + e.getMessage());
2823 getErrPrintWriter().println("Exception: " + e.getMessage());
2824 return -1;
2825 }
2826 return 0;
2827 }
2828
2829 private int handleSrcGetCarrierEnabledCommand() {
2830 int subId = getSubId("src get-carrier-enabled");
2831 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2832 return -1;
2833 }
2834
2835 boolean result = false;
2836 try {
2837 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2838 } catch (RemoteException e) {
2839 return -1;
2840 }
2841 if (VDBG) {
2842 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2843 }
2844 getOutPrintWriter().println(result);
2845 return 0;
2846 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002847
Hui Wangb647abe2021-02-26 09:33:38 -08002848 private int handleSrcSetFeatureValidationCommand() {
2849 //the release time value could be -1
2850 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2851 : SubscriptionManager.getDefaultSubscriptionId();
2852 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2853 return -1;
2854 }
2855
2856 String enabledStr = getNextArg();
2857 if (enabledStr == null) {
2858 return -1;
2859 }
2860
2861 try {
2862 boolean result =
2863 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2864 if (VDBG) {
2865 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2866 + enabledStr + ", result=" + result);
2867 }
2868 getOutPrintWriter().println(result);
2869 } catch (NumberFormatException | RemoteException e) {
2870 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2871 + enabledStr + ", error" + e.getMessage());
2872 getErrPrintWriter().println("Exception: " + e.getMessage());
2873 return -1;
2874 }
2875 return 0;
2876 }
2877
2878 private int handleSrcGetFeatureValidationCommand() {
2879 int subId = getSubId("src get-feature-validation");
2880 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2881 return -1;
2882 }
2883
2884 Boolean result = false;
2885 try {
2886 result = mInterface.getImsFeatureValidationOverride(subId);
2887 } catch (RemoteException e) {
2888 return -1;
2889 }
2890 if (VDBG) {
2891 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2892 }
2893 getOutPrintWriter().println(result);
2894 return 0;
2895 }
2896
2897
Hall Liuaa4211e2021-01-20 15:43:39 -08002898 private void onHelpCallComposer() {
2899 PrintWriter pw = getOutPrintWriter();
2900 pw.println("Call composer commands");
2901 pw.println(" callcomposer test-mode enable|disable|query");
2902 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2903 pw.println(" upload/download from carrier servers is disabled, and operations are");
2904 pw.println(" performed using emulated local files instead.");
2905 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2906 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2907 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002908 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2909 pw.println(" Enables or disables the user setting for call composer, as set by");
2910 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002911 }
2912
2913 private int handleCallComposerCommand() {
2914 String arg = getNextArg();
2915 if (arg == null) {
2916 onHelpCallComposer();
2917 return 0;
2918 }
2919
2920 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2921 "MODIFY_PHONE_STATE required for call composer shell cmds");
2922 switch (arg) {
2923 case CALL_COMPOSER_TEST_MODE: {
2924 String enabledStr = getNextArg();
2925 if (ENABLE.equals(enabledStr)) {
2926 CallComposerPictureManager.sTestMode = true;
2927 } else if (DISABLE.equals(enabledStr)) {
2928 CallComposerPictureManager.sTestMode = false;
2929 } else if (QUERY.equals(enabledStr)) {
2930 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2931 } else {
2932 onHelpCallComposer();
2933 return 1;
2934 }
2935 break;
2936 }
2937 case CALL_COMPOSER_SIMULATE_CALL: {
2938 int subscriptionId = Integer.valueOf(getNextArg());
2939 String uuidString = getNextArg();
2940 UUID uuid = UUID.fromString(uuidString);
2941 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2942 Binder.withCleanCallingIdentity(() -> {
2943 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2944 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2945 });
2946 try {
2947 Uri uri = storageUriFuture.get();
2948 getOutPrintWriter().println(String.valueOf(uri));
2949 } catch (Exception e) {
2950 throw new RuntimeException(e);
2951 }
2952 break;
2953 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002954 case CALL_COMPOSER_USER_SETTING: {
2955 try {
2956 int subscriptionId = Integer.valueOf(getNextArg());
2957 String enabledStr = getNextArg();
2958 if (ENABLE.equals(enabledStr)) {
2959 mInterface.setCallComposerStatus(subscriptionId,
2960 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2961 } else if (DISABLE.equals(enabledStr)) {
2962 mInterface.setCallComposerStatus(subscriptionId,
2963 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2964 } else if (QUERY.equals(enabledStr)) {
2965 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2966 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2967 } else {
2968 onHelpCallComposer();
2969 return 1;
2970 }
2971 } catch (RemoteException e) {
2972 e.printStackTrace(getOutPrintWriter());
2973 return 1;
2974 }
2975 break;
2976 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002977 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002978 return 0;
2979 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002980
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002981 private int handleHasCarrierPrivilegesCommand() {
2982 String packageName = getNextArgRequired();
2983
2984 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002985 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002986 try {
2987 hasCarrierPrivileges =
2988 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2989 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2990 } catch (RemoteException e) {
2991 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2992 getErrPrintWriter().println("Exception: " + e.getMessage());
2993 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002994 } finally {
2995 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002996 }
2997
2998 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002999 return 0;
3000 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003001
3002 private int handleAllowedNetworkTypesCommand(String command) {
3003 if (!checkShellUid()) {
3004 return -1;
3005 }
3006
3007 PrintWriter errPw = getErrPrintWriter();
3008 String tag = command + ": ";
3009 String opt;
3010 int subId = -1;
3011 Log.v(LOG_TAG, command + " start");
3012
3013 while ((opt = getNextOption()) != null) {
3014 if (opt.equals("-s")) {
3015 try {
3016 subId = slotStringToSubId(tag, getNextArgRequired());
3017 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3018 errPw.println(tag + "No valid subscription found.");
3019 return -1;
3020 }
3021 } catch (IllegalArgumentException e) {
3022 // Missing slot id
3023 errPw.println(tag + "SLOT_ID expected after -s.");
3024 return -1;
3025 }
3026 } else {
3027 errPw.println(tag + "Unknown option " + opt);
3028 return -1;
3029 }
3030 }
3031
3032 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3033 return handleGetAllowedNetworkTypesCommand(subId);
3034 }
3035 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3036 return handleSetAllowedNetworkTypesCommand(subId);
3037 }
3038 return -1;
3039 }
3040
3041 private int handleGetAllowedNetworkTypesCommand(int subId) {
3042 PrintWriter errPw = getErrPrintWriter();
3043
3044 long result = -1;
3045 try {
3046 if (mInterface != null) {
3047 result = mInterface.getAllowedNetworkTypesForReason(subId,
3048 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3049 } else {
3050 throw new IllegalStateException("telephony service is null.");
3051 }
3052 } catch (RemoteException e) {
3053 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3054 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3055 return -1;
3056 }
3057
3058 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3059 return 0;
3060 }
3061
3062 private int handleSetAllowedNetworkTypesCommand(int subId) {
3063 PrintWriter errPw = getErrPrintWriter();
3064
3065 String bitmaskString = getNextArg();
3066 if (TextUtils.isEmpty(bitmaskString)) {
3067 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3068 return -1;
3069 }
3070 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3071 if (allowedNetworkTypes < 0) {
3072 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3073 return -1;
3074 }
3075 boolean result = false;
3076 try {
3077 if (mInterface != null) {
3078 result = mInterface.setAllowedNetworkTypesForReason(subId,
3079 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3080 } else {
3081 throw new IllegalStateException("telephony service is null.");
3082 }
3083 } catch (RemoteException e) {
3084 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3085 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3086 return -1;
3087 }
3088
3089 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3090 if (result) {
3091 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3092 }
3093 getOutPrintWriter().println(resultMessage);
3094 return 0;
3095 }
3096
3097 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3098 if (TextUtils.isEmpty(bitmaskString)) {
3099 return -1;
3100 }
3101 if (VDBG) {
3102 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3103 + ", length: " + bitmaskString.length());
3104 }
3105 try {
3106 return Long.parseLong(bitmaskString, 2);
3107 } catch (NumberFormatException e) {
3108 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3109 return -1;
3110 }
3111 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003112
jimsun3b9ccac2021-10-26 15:01:23 +08003113 private int handleRadioSetModemServiceCommand() {
3114 PrintWriter errPw = getErrPrintWriter();
3115 String serviceName = null;
3116
3117 String opt;
3118 while ((opt = getNextOption()) != null) {
3119 switch (opt) {
3120 case "-s": {
3121 serviceName = getNextArgRequired();
3122 break;
3123 }
3124 }
3125 }
3126
3127 try {
3128 boolean result = mInterface.setModemService(serviceName);
3129 if (VDBG) {
3130 Log.v(LOG_TAG,
3131 "RadioSetModemService " + serviceName + ", result = " + result);
3132 }
3133 getOutPrintWriter().println(result);
3134 } catch (RemoteException e) {
3135 Log.w(LOG_TAG,
3136 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3137 errPw.println("Exception: " + e.getMessage());
3138 return -1;
3139 }
3140 return 0;
3141 }
3142
3143 private int handleRadioGetModemServiceCommand() {
3144 PrintWriter errPw = getErrPrintWriter();
3145 String result;
3146
3147 try {
3148 result = mInterface.getModemService();
3149 getOutPrintWriter().println(result);
3150 } catch (RemoteException e) {
3151 errPw.println("Exception: " + e.getMessage());
3152 return -1;
3153 }
3154 if (VDBG) {
3155 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3156 }
3157 return 0;
3158 }
3159
3160 private int handleRadioCommand() {
3161 String arg = getNextArg();
3162 if (arg == null) {
3163 onHelpRadio();
3164 return 0;
3165 }
3166
3167 switch (arg) {
3168 case RADIO_SET_MODEM_SERVICE:
3169 return handleRadioSetModemServiceCommand();
3170
3171 case RADIO_GET_MODEM_SERVICE:
3172 return handleRadioGetModemServiceCommand();
3173 }
3174
3175 return -1;
3176 }
arunvoddud7401012022-12-15 16:08:12 +00003177
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003178 private int handleSetSatelliteServicePackageNameCommand() {
3179 PrintWriter errPw = getErrPrintWriter();
3180 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003181 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003182
3183 String opt;
3184 while ((opt = getNextOption()) != null) {
3185 switch (opt) {
3186 case "-s": {
3187 serviceName = getNextArgRequired();
3188 break;
3189 }
Hakjun Choic3393242024-06-26 18:02:08 +00003190
3191 case "-p": {
3192 provisioned = getNextArgRequired();
3193 break;
3194 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003195 }
3196 }
3197 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003198 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003199
3200 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003201 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003202 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003203 Log.v(LOG_TAG,
3204 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3205 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003206 }
3207 getOutPrintWriter().println(result);
3208 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003209 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3210 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003211 errPw.println("Exception: " + e.getMessage());
3212 return -1;
3213 }
Hakjun Choic3393242024-06-26 18:02:08 +00003214
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003215 return 0;
3216 }
3217
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003218 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3219 PrintWriter errPw = getErrPrintWriter();
3220 String serviceName = null;
3221
3222 String opt;
3223 while ((opt = getNextOption()) != null) {
3224 switch (opt) {
3225 case "-s": {
3226 serviceName = getNextArgRequired();
3227 break;
3228 }
3229 }
3230 }
3231 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3232 + serviceName);
3233
3234 try {
3235 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3236 if (VDBG) {
3237 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3238 + ", result = " + result);
3239 }
3240 getOutPrintWriter().println(result);
3241 } catch (RemoteException e) {
3242 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3243 + ", error = " + e.getMessage());
3244 errPw.println("Exception: " + e.getMessage());
3245 return -1;
3246 }
3247 return 0;
3248 }
3249
Thomas Nguyen87dce732023-04-20 18:27:16 -07003250 private int handleSetSatellitePointingUiClassNameCommand() {
3251 PrintWriter errPw = getErrPrintWriter();
3252 String packageName = null;
3253 String className = null;
3254
3255 String opt;
3256 while ((opt = getNextOption()) != null) {
3257 switch (opt) {
3258 case "-p": {
3259 packageName = getNextArgRequired();
3260 break;
3261 }
3262 case "-c": {
3263 className = getNextArgRequired();
3264 break;
3265 }
3266 }
3267 }
3268 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3269 + packageName + ", className=" + className);
3270
3271 try {
3272 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3273 if (VDBG) {
3274 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3275 }
3276 getOutPrintWriter().println(result);
3277 } catch (RemoteException e) {
3278 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3279 + ", error = " + e.getMessage());
3280 errPw.println("Exception: " + e.getMessage());
3281 return -1;
3282 }
3283 return 0;
3284 }
3285
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003286 private int handleSetEmergencyCallToSatelliteHandoverType() {
3287 PrintWriter errPw = getErrPrintWriter();
3288 int handoverType = -1;
3289 int delaySeconds = 0;
3290
3291 String opt;
3292 while ((opt = getNextOption()) != null) {
3293 switch (opt) {
3294 case "-t": {
3295 try {
3296 handoverType = Integer.parseInt(getNextArgRequired());
3297 } catch (NumberFormatException e) {
3298 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3299 + " for handoverType");
3300 return -1;
3301 }
3302 break;
3303 }
3304 case "-d": {
3305 try {
3306 delaySeconds = Integer.parseInt(getNextArgRequired());
3307 } catch (NumberFormatException e) {
3308 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3309 + " for delaySeconds");
3310 return -1;
3311 }
3312 break;
3313 }
3314 }
3315 }
3316 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3317 + handoverType + ", delaySeconds=" + delaySeconds);
3318
3319 try {
3320 boolean result =
3321 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3322 if (VDBG) {
3323 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3324 }
3325 getOutPrintWriter().println(result);
3326 } catch (RemoteException e) {
3327 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3328 + ", error = " + e.getMessage());
3329 errPw.println("Exception: " + e.getMessage());
3330 return -1;
3331 }
3332 return 0;
3333 }
3334
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003335 private int handleSetSatelliteListeningTimeoutDuration() {
3336 PrintWriter errPw = getErrPrintWriter();
3337 long timeoutMillis = 0;
3338
3339 String opt;
3340 while ((opt = getNextOption()) != null) {
3341 switch (opt) {
3342 case "-t": {
3343 timeoutMillis = Long.parseLong(getNextArgRequired());
3344 break;
3345 }
3346 }
3347 }
3348 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3349 + timeoutMillis);
3350
3351 try {
3352 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3353 if (VDBG) {
3354 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3355 + ", result = " + result);
3356 }
3357 getOutPrintWriter().println(result);
3358 } catch (RemoteException e) {
3359 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3360 + ", error = " + e.getMessage());
3361 errPw.println("Exception: " + e.getMessage());
3362 return -1;
3363 }
3364 return 0;
3365 }
3366
joonhunshinf46f0d62024-09-27 14:06:26 +00003367 private int handleSetSatelliteIgnoreCellularServiceState() {
3368 PrintWriter errPw = getErrPrintWriter();
3369 boolean enabled = false;
3370
3371 String opt;
3372 while ((opt = getNextOption()) != null) {
3373 switch (opt) {
3374 case "-d": {
3375 enabled = Boolean.parseBoolean(getNextArgRequired());
3376 break;
3377 }
3378 }
3379 }
3380 Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
3381
3382 try {
3383 boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
3384 if (VDBG) {
3385 Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
3386 + ", result = " + result);
3387 }
3388 getOutPrintWriter().println(result);
3389 } catch (RemoteException e) {
3390 Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
3391 + ", error = " + e.getMessage());
3392 errPw.println("Exception: " + e.getMessage());
3393 return -1;
3394 }
3395 return 0;
3396 }
3397
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003398 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003399 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003400 boolean reset = false;
3401 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003402 long timeoutMillis = 0;
3403
3404 String opt;
3405 while ((opt = getNextOption()) != null) {
3406 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003407 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003408 timeoutMillis = Long.parseLong(getNextArgRequired());
3409 break;
3410 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003411 case "-r": {
3412 reset = true;
3413 break;
3414 }
3415 case "-t": {
3416 timeoutType = Integer.parseInt(getNextArgRequired());
3417 break;
3418 }
Hakjun Choiae365972023-04-25 11:00:31 +00003419 }
3420 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003421 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3422 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003423
3424 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003425 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3426 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003427 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003428 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003429 + ", result = " + result);
3430 }
3431 getOutPrintWriter().println(result);
3432 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003433 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3434 + ", error = " + e.getMessage());
3435 errPw.println("Exception: " + e.getMessage());
3436 return -1;
3437 }
3438 return 0;
3439 }
3440
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003441 private int handleSetDatagramControllerBooleanConfig() {
3442 PrintWriter errPw = getErrPrintWriter();
3443 boolean reset = false;
3444 int booleanType = 0;
3445 boolean enable = false;
3446
3447 String opt;
3448 while ((opt = getNextOption()) != null) {
3449 switch (opt) {
3450 case "-d": {
3451 enable = Boolean.parseBoolean(getNextArgRequired());
3452 break;
3453 }
3454 case "-r": {
3455 reset = true;
3456 break;
3457 }
3458 case "-t": {
3459 booleanType = Integer.parseInt(getNextArgRequired());
3460 break;
3461 }
3462 }
3463 }
3464 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3465 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3466
3467 try {
3468 boolean result = mInterface.setDatagramControllerBooleanConfig(
3469 reset, booleanType, enable);
3470 if (VDBG) {
3471 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3472 }
3473 getOutPrintWriter().println(result);
3474 } catch (RemoteException e) {
3475 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3476 errPw.println("Exception: " + e.getMessage());
3477 return -1;
3478 }
3479 return 0;
3480 }
3481
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003482 private int handleSetSatelliteControllerTimeoutDuration() {
3483 PrintWriter errPw = getErrPrintWriter();
3484 boolean reset = false;
3485 int timeoutType = 0;
3486 long timeoutMillis = 0;
3487
3488 String opt;
3489 while ((opt = getNextOption()) != null) {
3490 switch (opt) {
3491 case "-d": {
3492 timeoutMillis = Long.parseLong(getNextArgRequired());
3493 break;
3494 }
3495 case "-r": {
3496 reset = true;
3497 break;
3498 }
3499 case "-t": {
3500 timeoutType = Integer.parseInt(getNextArgRequired());
3501 break;
3502 }
3503 }
3504 }
3505 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3506 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3507
3508 try {
3509 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3510 reset, timeoutType, timeoutMillis);
3511 if (VDBG) {
3512 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3513 + ", result = " + result);
3514 }
3515 getOutPrintWriter().println(result);
3516 } catch (RemoteException e) {
3517 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003518 + ", error = " + e.getMessage());
3519 errPw.println("Exception: " + e.getMessage());
3520 return -1;
3521 }
3522 return 0;
3523 }
3524
Hakjun Choibc6ce992023-11-07 16:04:33 +00003525 private int handleSetShouldSendDatagramToModemInDemoMode() {
3526 PrintWriter errPw = getErrPrintWriter();
3527 String opt;
3528 boolean shouldSendToDemoMode;
3529
3530 if ((opt = getNextArg()) == null) {
3531 errPw.println(
3532 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3533 + " Invalid Argument");
3534 return -1;
3535 } else {
3536 switch (opt) {
3537 case "true": {
3538 shouldSendToDemoMode = true;
3539 break;
3540 }
3541 case "false": {
3542 shouldSendToDemoMode = false;
3543 break;
3544 }
3545 default:
3546 errPw.println(
3547 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3548 + " Invalid Argument");
3549 return -1;
3550 }
3551 }
3552
3553 Log.d(LOG_TAG,
3554 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3555
3556 try {
3557 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3558 shouldSendToDemoMode);
3559 if (VDBG) {
3560 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3561 + result);
3562 }
3563 getOutPrintWriter().println(false);
3564 } catch (RemoteException e) {
3565 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3566 + "), error = " + e.getMessage());
3567 errPw.println("Exception: " + e.getMessage());
3568 return -1;
3569 }
3570 return 0;
3571 }
3572
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003573 private int handleSetSatelliteAccessControlOverlayConfigs() {
3574 PrintWriter errPw = getErrPrintWriter();
3575 boolean reset = false;
3576 boolean isAllowed = false;
3577 String s2CellFile = null;
3578 long locationFreshDurationNanos = 0;
3579 List<String> satelliteCountryCodes = null;
3580
3581 String opt;
3582 while ((opt = getNextOption()) != null) {
3583 switch (opt) {
3584 case "-r": {
3585 reset = true;
3586 break;
3587 }
3588 case "-a": {
3589 isAllowed = true;
3590 break;
3591 }
3592 case "-f": {
3593 s2CellFile = getNextArgRequired();
3594 break;
3595 }
3596 case "-d": {
3597 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3598 break;
3599 }
3600 case "-c": {
3601 String countryCodeStr = getNextArgRequired();
3602 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3603 break;
3604 }
3605 }
3606 }
3607 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3608 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3609 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
3610 + ", satelliteCountryCodes=" + satelliteCountryCodes);
3611
3612 try {
3613 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
3614 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes);
3615 if (VDBG) {
3616 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3617 }
3618 getOutPrintWriter().println(result);
3619 } catch (RemoteException e) {
3620 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3621 errPw.println("Exception: " + e.getMessage());
3622 return -1;
3623 }
3624 return 0;
3625 }
3626
3627 private int handleSetCountryCodes() {
3628 PrintWriter errPw = getErrPrintWriter();
3629 List<String> currentNetworkCountryCodes = new ArrayList<>();
3630 String locationCountryCode = null;
3631 long locationCountryCodeTimestampNanos = 0;
3632 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3633 boolean reset = false;
3634
3635 String opt;
3636 while ((opt = getNextOption()) != null) {
3637 switch (opt) {
3638 case "-r": {
3639 reset = true;
3640 break;
3641 }
3642 case "-n": {
3643 String countryCodeStr = getNextArgRequired();
3644 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3645 break;
3646 }
3647 case "-c": {
3648 String cachedNetworkCountryCodeStr = getNextArgRequired();
3649 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3650 break;
3651 }
3652 case "-l": {
3653 locationCountryCode = getNextArgRequired();
3654 break;
3655 }
3656 case "-t": {
3657 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3658 break;
3659 }
3660 }
3661 }
3662 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3663 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3664 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3665 + currentNetworkCountryCodes);
3666
3667 try {
3668 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3669 cachedNetworkCountryCodes, locationCountryCode,
3670 locationCountryCodeTimestampNanos);
3671 if (VDBG) {
3672 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3673 }
3674 getOutPrintWriter().println(result);
3675 } catch (RemoteException e) {
3676 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3677 errPw.println("Exception: " + e.getMessage());
3678 return -1;
3679 }
3680 return 0;
3681 }
3682
Thomas Nguyen3d602742024-01-19 11:29:35 -08003683 private int handleSetOemEnabledSatelliteProvisionStatus() {
3684 PrintWriter errPw = getErrPrintWriter();
3685 boolean isProvisioned = false;
3686 boolean reset = true;
3687
3688 String opt;
3689 while ((opt = getNextOption()) != null) {
3690 switch (opt) {
3691 case "-p": {
3692 try {
3693 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3694 reset = false;
3695 } catch (Exception e) {
3696 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3697 + "after -p indicating provision status");
3698 return -1;
3699 }
3700 }
3701 }
3702 }
3703 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3704 + ", isProvisioned=" + isProvisioned);
3705
3706 try {
3707 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3708 if (VDBG) {
3709 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3710 }
3711 getOutPrintWriter().println(result);
3712 } catch (RemoteException e) {
3713 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3714 errPw.println("Exception: " + e.getMessage());
3715 return -1;
3716 }
3717 return 0;
3718 }
3719
Hakjun Choi4a832d12024-05-28 22:23:55 +00003720 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3721 PrintWriter errPw = getErrPrintWriter();
3722 String opt;
3723 String state;
Hakjun Choi4a832d12024-05-28 22:23:55 +00003724 if ((opt = getNextArg()) == null) {
3725 errPw.println(
3726 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3727 + "-location-cache :"
3728 + " Invalid Argument");
3729 return -1;
3730 } else {
3731 switch (opt) {
3732 case "-a": {
3733 state = "cache_allowed";
3734 break;
3735 }
youngtaecha32bde212024-09-17 22:58:11 +00003736 case "-na": {
3737 state = "cache_not_allowed";
3738 break;
3739 }
Hakjun Choi4a832d12024-05-28 22:23:55 +00003740 case "-n": {
3741 state = "cache_clear_and_not_allowed";
3742 break;
3743 }
3744 case "-c": {
3745 state = "clear_cache_only";
3746 break;
3747 }
3748 default:
3749 errPw.println(
3750 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3751 + "-location-cache :"
3752 + " Invalid Argument");
3753 return -1;
3754 }
3755 }
3756
3757 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3758 + state + ")");
3759
3760 try {
3761 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3762 state);
3763 if (VDBG) {
3764 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3765 + "returns: "
3766 + result);
3767 }
3768 getOutPrintWriter().println(result);
3769 } catch (RemoteException e) {
3770 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3771 + state + "), error = " + e.getMessage());
3772 errPw.println("Exception: " + e.getMessage());
3773 return -1;
3774 }
3775 return 0;
3776 }
3777
Hyosund6aaf062024-08-23 23:02:10 +00003778 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3779 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3780 PrintWriter errPw = getErrPrintWriter();
3781 String opt;
3782 String name;
3783
3784 if ((opt = getNextArg()) == null) {
3785 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3786 return -1;
3787 } else {
3788 switch (opt) {
3789 case "-p": {
3790 name = opt + "/" + "android.telephony.cts";
3791 break;
3792 }
3793 case "-c": {
3794 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3795 break;
3796 }
3797 case "-r": {
3798 name = "reset";
3799 break;
3800 }
3801 default:
3802 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3803 return -1;
3804 }
3805 }
3806
3807 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3808 + name + ")");
3809
3810 try {
3811 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3812 if (VDBG) {
3813 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3814 + "returns: " + result);
3815 }
3816 getOutPrintWriter().println(result);
3817 } catch (RemoteException e) {
3818 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3819 + name + "), error = " + e.getMessage());
3820 errPw.println("Exception: " + e.getMessage());
3821 return -1;
3822 }
3823 return 0;
3824 }
3825
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003826 /**
3827 * Sample inputStr = "US,UK,CA;2,1,3"
3828 * Sample output: {[US,2], [UK,1], [CA,3]}
3829 */
3830 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3831 Map<String, Long> result = new HashMap<>();
3832 if (!TextUtils.isEmpty(inputStr)) {
3833 String[] stringLongArr = inputStr.split(";");
3834 if (stringLongArr.length != 2) {
3835 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3836 return result;
3837 }
3838
3839 String[] stringArr = stringLongArr[0].split(",");
3840 String[] longArr = stringLongArr[1].split(",");
3841 if (stringArr.length != longArr.length) {
3842 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3843 return result;
3844 }
3845
3846 for (int i = 0; i < stringArr.length; i++) {
3847 try {
3848 result.put(stringArr[i], Long.parseLong(longArr[i]));
3849 } catch (Exception ex) {
3850 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3851 + ", ex=" + ex);
3852 return result;
3853 }
3854 }
3855 }
3856 return result;
3857 }
3858
arunvoddud7401012022-12-15 16:08:12 +00003859 private int handleCarrierRestrictionStatusCommand() {
3860 try {
3861 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3862 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3863 mInterface.getModemService()))) {
3864 Log.v(LOG_TAG,
3865 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3866 + " checkShellUid fails");
3867 return -1;
3868 }
3869 } catch (RemoteException ex) {
3870 ex.printStackTrace();
3871 }
3872 String callerInfo = getNextOption();
3873 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3874 if (TextUtils.isEmpty(callerInfo)) {
3875 // reset the Json content after testing
3876 allowListInfo.updateJsonForTest(null);
3877 return 0;
3878 }
3879 if (callerInfo.startsWith("--")) {
3880 callerInfo = callerInfo.replace("--", "");
3881 }
3882 String params[] = callerInfo.split(",");
3883 StringBuffer jsonStrBuffer = new StringBuffer();
3884 String tokens;
3885 for (int index = 0; index < params.length; index++) {
3886 tokens = convertToJsonString(index, params[index]);
3887 if (TextUtils.isEmpty(tokens)) {
3888 // received wrong format from CTS
3889 if (VDBG) {
3890 Log.v(LOG_TAG,
3891 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3892 }
3893 return -1;
3894 }
3895 jsonStrBuffer.append(tokens);
3896 }
3897 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3898 return result;
3899 }
3900
Benedict Wong66477622023-02-03 23:30:57 +00003901 // set-carrier-service-package-override
3902 private int setCarrierServicePackageOverride() {
3903 PrintWriter errPw = getErrPrintWriter();
3904 int subId = SubscriptionManager.getDefaultSubscriptionId();
3905
3906 String opt;
3907 while ((opt = getNextOption()) != null) {
3908 switch (opt) {
3909 case "-s":
3910 try {
3911 subId = Integer.parseInt(getNextArgRequired());
3912 } catch (NumberFormatException e) {
3913 errPw.println(
3914 "set-carrier-service-package-override requires an integer as a"
3915 + " subscription ID.");
3916 return -1;
3917 }
3918 break;
3919 }
3920 }
3921
3922 String packageName = getNextArg();
3923 if (packageName == null) {
3924 errPw.println("set-carrier-service-package-override requires a override package name.");
3925 return -1;
3926 }
3927
3928 try {
3929 mInterface.setCarrierServicePackageOverride(
3930 subId, packageName, mContext.getOpPackageName());
3931
3932 if (VDBG) {
3933 Log.v(
3934 LOG_TAG,
3935 "set-carrier-service-package-override -s " + subId + " " + packageName);
3936 }
3937 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3938 Log.w(
3939 LOG_TAG,
3940 "set-carrier-service-package-override -s "
3941 + subId
3942 + " "
3943 + packageName
3944 + ", error"
3945 + e.getMessage());
3946 errPw.println("Exception: " + e.getMessage());
3947 return -1;
3948 }
3949 return 0;
3950 }
3951
3952 // clear-carrier-service-package-override
3953 private int clearCarrierServicePackageOverride() {
3954 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003955 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003956
3957 String opt;
3958 while ((opt = getNextOption()) != null) {
3959 switch (opt) {
3960 case "-s":
3961 try {
3962 subId = Integer.parseInt(getNextArgRequired());
3963 } catch (NumberFormatException e) {
3964 errPw.println(
3965 "clear-carrier-service-package-override requires an integer as a"
3966 + " subscription ID.");
3967 return -1;
3968 }
3969 break;
3970 }
3971 }
3972
3973 try {
3974 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3975
3976 if (VDBG) {
3977 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3978 }
3979 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3980 Log.w(
3981 LOG_TAG,
3982 "clear-carrier-service-package-override -s "
3983 + subId
3984 + ", error"
3985 + e.getMessage());
3986 errPw.println("Exception: " + e.getMessage());
3987 return -1;
3988 }
3989 return 0;
3990 }
arunvoddud7401012022-12-15 16:08:12 +00003991
Hunsuk Choi13078be2023-09-13 10:55:21 +00003992 private int handleDomainSelectionCommand() {
3993 String arg = getNextArg();
3994 if (arg == null) {
3995 onHelpDomainSelection();
3996 return 0;
3997 }
3998
3999 switch (arg) {
4000 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
4001 return handleDomainSelectionSetServiceOverrideCommand();
4002 }
4003 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4004 return handleDomainSelectionClearServiceOverrideCommand();
4005 }
4006 }
4007
4008 return -1;
4009 }
4010
4011 // domainselection set-dss-override
4012 private int handleDomainSelectionSetServiceOverrideCommand() {
4013 PrintWriter errPw = getErrPrintWriter();
4014
4015 String componentName = getNextArg();
4016
4017 try {
4018 boolean result = mInterface.setDomainSelectionServiceOverride(
4019 ComponentName.unflattenFromString(componentName));
4020 if (VDBG) {
4021 Log.v(LOG_TAG, "domainselection set-dss-override "
4022 + componentName + ", result=" + result);
4023 }
4024 getOutPrintWriter().println(result);
4025 } catch (Exception e) {
4026 Log.w(LOG_TAG, "domainselection set-dss-override "
4027 + componentName + ", error=" + e.getMessage());
4028 errPw.println("Exception: " + e.getMessage());
4029 return -1;
4030 }
4031 return 0;
4032 }
4033
4034 // domainselection clear-dss-override
4035 private int handleDomainSelectionClearServiceOverrideCommand() {
4036 PrintWriter errPw = getErrPrintWriter();
4037
4038 try {
4039 boolean result = mInterface.clearDomainSelectionServiceOverride();
4040 if (VDBG) {
4041 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4042 }
4043 getOutPrintWriter().println(result);
4044 } catch (RemoteException e) {
4045 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4046 errPw.println("Exception: " + e.getMessage());
4047 return -1;
4048 }
4049 return 0;
4050 }
4051
arunvoddud7401012022-12-15 16:08:12 +00004052 /**
4053 * Building the string that can be used to build the JsonObject which supports to stub the data
4054 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004055 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004056 */
4057 private String convertToJsonString(int index, String param) {
4058
4059 String token[] = param.split(":");
4060 String jSonString;
4061 switch (index) {
4062 case 0:
4063 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4064 break;
4065 case 1:
4066 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004067 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004068 break;
4069 case 2:
4070 jSonString =
4071 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4072 break;
4073 default:
4074 jSonString = null;
4075 }
4076 return jSonString;
4077 }
arunvoddue3a6dbc2024-09-27 16:27:08 +00004078
4079 /**
4080 * This method override the check for carrier roaming Ntn eligibility.
4081 * <ul>
4082 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result true` will set
4083 * override eligibility to true.</li>
4084 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result false` will
4085 * override eligibility to false.</li>
4086 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result` will reset the
4087 * override data set through adb command.</li>
4088 * </ul>
4089 *
4090 * @return {@code true} is command executed successfully otherwise {@code false}.
4091 */
4092 private int handleOverrideCarrierRoamingNtnEligibilityChanged() {
4093 PrintWriter errPw = getErrPrintWriter();
4094 String opt;
4095 boolean state = false;
4096 boolean isRestRequired = false;
4097 try {
4098 if ((opt = getNextArg()) == null) {
4099 isRestRequired = true;
4100 } else {
4101 if ("true".equalsIgnoreCase(opt)) {
4102 state = true;
4103 }
4104 }
4105 boolean result = mInterface.overrideCarrierRoamingNtnEligibilityChanged(state,
4106 isRestRequired);
4107 if (VDBG) {
4108 Log.v(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult "
4109 + "returns: "
4110 + result);
4111 }
4112 getOutPrintWriter().println(result);
4113 } catch (RemoteException e) {
4114 Log.w(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult("
4115 + state + "), error = " + e.getMessage());
4116 errPw.println("Exception: " + e.getMessage());
4117 return -1;
4118 }
4119 Log.d(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult(" + state + ")");
4120 return 0;
4121 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004122}