blob: cd6a369cf5b415cbd3bd2a65fab233d12d4585d3 [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";
TAKAHASHI Uichiroc4b07452022-08-29 16:03:11 +0900235 private static final String COMMAND_DELETE_IMSI_KEY = "delete_imsi_key";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700236 // Take advantage of existing methods that already contain permissions checks when possible.
237 private final ITelephony mInterface;
238
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100239 private SubscriptionManager mSubscriptionManager;
240 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700241 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700242 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100243
244 private enum CcType {
245 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000246 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100247 }
248
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100249 private class CcOptionParseResult {
250 public int mSubId;
251 public boolean mPersistent;
252 }
253
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100254 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
255 // keys by looking at the end of the string which usually tells the type.
256 // For instance: "xxxx_string", "xxxx_string_array", etc.
257 // The carrier config keys in this map does not follow this convention. It is therefore not
258 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700259 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
260 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
261 CcType.STRING),
262 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
263 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
264 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
265 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
266 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
267 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
268 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
269 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
270 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
271 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
272 CcType.STRING),
273 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
274 CcType.STRING_ARRAY),
275 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
276 CcType.STRING_ARRAY),
277 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
278 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
279 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
280 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
281 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
282 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
283 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
284 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100285
Brad Ebinger14d467f2021-02-12 06:18:28 +0000286 /**
287 * Map from a shorthand string to the feature tags required in registration required in order
288 * for the RCS feature to be considered "capable".
289 */
290 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
291 static {
292 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
293 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
294 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
295 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
296 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
297 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
298 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
299 FeatureTags.FEATURE_TAG_VIDEO)));
300 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
301 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
302 map.put("call_comp",
303 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
304 map.put("call_comp_mmtel",
305 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
306 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
307 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
308 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
309 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
310 // version
311 map.put("chatbot", new ArraySet<>(Arrays.asList(
312 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
313 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
314 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
315 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000316 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000317 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
318 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
319 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
320 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
321 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000322 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000323 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
324 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
325 }
326
327
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100328 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700329 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100330 mCarrierConfigManager =
331 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
332 mSubscriptionManager = (SubscriptionManager)
333 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700334 mTelephonyRegistryManager = (TelephonyRegistryManager)
335 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700336 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700337 }
338
339 @Override
340 public int onCommand(String cmd) {
341 if (cmd == null) {
342 return handleDefaultCommands(null);
343 }
344
345 switch (cmd) {
346 case IMS_SUBCOMMAND: {
347 return handleImsCommand();
348 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800349 case RCS_UCE_COMMAND:
350 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800351 case NUMBER_VERIFICATION_SUBCOMMAND:
352 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800353 case EMERGENCY_CALLBACK_MODE:
354 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800355 case EMERGENCY_NUMBER_TEST_MODE:
356 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100357 case CARRIER_CONFIG_SUBCOMMAND: {
358 return handleCcCommand();
359 }
Shuo Qianf5125122019-12-16 17:03:07 -0800360 case DATA_TEST_MODE:
361 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700362 case END_BLOCK_SUPPRESSION:
363 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700364 case GBA_SUBCOMMAND:
365 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800366 case D2D_SUBCOMMAND:
367 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700368 case BARRING_SUBCOMMAND:
369 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000370 case SINGLE_REGISTATION_CONFIG:
371 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000372 case RESTART_MODEM:
373 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800374 case CALL_COMPOSER_SUBCOMMAND:
375 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000376 case UNATTENDED_REBOOT:
377 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800378 case HAS_CARRIER_PRIVILEGES_COMMAND:
379 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800380 case THERMAL_MITIGATION_COMMAND:
381 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700382 case DISABLE_PHYSICAL_SUBSCRIPTION:
383 return handleEnablePhysicalSubscription(false);
384 case ENABLE_PHYSICAL_SUBSCRIPTION:
385 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800386 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
387 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
388 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000389 case GET_IMEI:
390 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000391 case GET_SIM_SLOTS_MAPPING:
392 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800393 case RADIO_SUBCOMMAND:
394 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000395 case CARRIER_RESTRICTION_STATUS_TEST:
396 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000397 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
398 return setCarrierServicePackageOverride();
399 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
400 return clearCarrierServicePackageOverride();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000401 case DOMAIN_SELECTION_SUBCOMMAND:
402 return handleDomainSelectionCommand();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700403 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
404 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700405 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
406 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700407 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
408 return handleSetSatelliteListeningTimeoutDuration();
joonhunshinf46f0d62024-09-27 14:06:26 +0000409 case SET_SATELLITE_IGNORE_CELLULAR_SERVICE_STATE:
410 return handleSetSatelliteIgnoreCellularServiceState();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700411 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
412 return handleSetSatellitePointingUiClassNameCommand();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800413 case SET_DATAGRAM_CONTROLLER_TIMEOUT_DURATION:
414 return handleSetDatagramControllerTimeoutDuration();
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +0000415 case SET_DATAGRAM_CONTROLLER_BOOLEAN_CONFIG:
416 return handleSetDatagramControllerBooleanConfig();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -0800417 case SET_SATELLITE_CONTROLLER_TIMEOUT_DURATION:
418 return handleSetSatelliteControllerTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700419 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
420 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000421 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
422 return handleSetShouldSendDatagramToModemInDemoMode();
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800423 case SET_SATELLITE_ACCESS_CONTROL_OVERLAY_CONFIGS:
424 return handleSetSatelliteAccessControlOverlayConfigs();
425 case SET_COUNTRY_CODES:
426 return handleSetCountryCodes();
Thomas Nguyen3d602742024-01-19 11:29:35 -0800427 case SET_OEM_ENABLED_SATELLITE_PROVISION_STATUS:
428 return handleSetOemEnabledSatelliteProvisionStatus();
Hakjun Choi4a832d12024-05-28 22:23:55 +0000429 case SET_IS_SATELLITE_COMMUNICATION_ALLOWED_FOR_CURRENT_LOCATION_CACHE:
430 return handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache();
Hyosund6aaf062024-08-23 23:02:10 +0000431 case SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT:
432 return handleSetSatelliteSubscriberIdListChangedIntentComponent();
arunvoddue3a6dbc2024-09-27 16:27:08 +0000433 case SET_SATELLITE_ACCESS_RESTRICTION_CHECKING_RESULT:
434 return handleOverrideCarrierRoamingNtnEligibilityChanged();
TAKAHASHI Uichiroc4b07452022-08-29 16:03:11 +0900435 case COMMAND_DELETE_IMSI_KEY:
436 return handleDeleteTestImsiKey();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700437 default: {
438 return handleDefaultCommands(cmd);
439 }
440 }
441 }
442
443 @Override
444 public void onHelp() {
445 PrintWriter pw = getOutPrintWriter();
446 pw.println("Telephony Commands:");
447 pw.println(" help");
448 pw.println(" Print this help text.");
449 pw.println(" ims");
450 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800451 pw.println(" uce");
452 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800453 pw.println(" emergency-number-test-mode");
454 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700455 pw.println(" end-block-suppression");
456 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800457 pw.println(" data");
458 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100459 pw.println(" cc");
460 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700461 pw.println(" gba");
462 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000463 pw.println(" src");
464 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000465 pw.println(" restart-modem");
466 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000467 pw.println(" unattended-reboot");
468 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800469 pw.println(" has-carrier-privileges [package]");
470 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800471 pw.println(" get-allowed-network-types-for-users");
472 pw.println(" Get the Allowed Network Types.");
473 pw.println(" set-allowed-network-types-for-users");
474 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800475 pw.println(" radio");
476 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700477 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800478 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800479 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700480 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800481 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100482 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700483 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000484 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800485 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700486 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800487 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800488 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000489 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700490 onHelpSatellite();
Hunsuk Choi13078be2023-09-13 10:55:21 +0000491 onHelpDomainSelection();
Tyler Gunn92479152021-01-20 16:30:10 -0800492 }
493
494 private void onHelpD2D() {
495 PrintWriter pw = getOutPrintWriter();
496 pw.println("D2D Comms Commands:");
497 pw.println(" d2d send TYPE VALUE");
498 pw.println(" Sends a D2D message of specified type and value.");
499 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
500 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
501 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
502 MESSAGE_CALL_AUDIO_CODEC));
503 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
504 + Communicator.messageToString(
505 MESSAGE_DEVICE_BATTERY_STATE));
506 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
507 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800508 pw.println(" d2d transport TYPE");
509 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
510 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700511 pw.println(" d2d set-device-support true/default");
512 pw.println(" true - forces device support to be enabled for D2D.");
513 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
514 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700515 }
516
Nazanin014f41e2021-05-06 17:26:31 -0700517 private void onHelpBarring() {
518 PrintWriter pw = getOutPrintWriter();
519 pw.println("Barring Commands:");
520 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
521 + " -t CONDITIONAL_BARRING_TIME_SECS");
522 pw.println(" Notifies of a barring info change for the specified slot id.");
523 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
524 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
525 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
526 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
527 }
528
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700529 private void onHelpIms() {
530 PrintWriter pw = getOutPrintWriter();
531 pw.println("IMS Commands:");
Brad Ebinger555ddec2024-11-04 13:46:31 -0800532 pw.println(" ims set-ims-service [-s SLOT_ID] [-u USER_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700533 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
534 pw.println(" ImsService. Options are:");
535 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
536 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger555ddec2024-11-04 13:46:31 -0800537 pw.println(" -u: the user ID that the ImsService should be bound on. If no option");
538 pw.println(" is specified, the SYSTEM user ID will be preferred followed by the");
539 pw.println(" current user ID if they are different");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700540 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
541 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800542 pw.println(" -f: Set the feature that this override if for, if no option is");
543 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700544 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
545 pw.println(" Gets the package name of the currently defined ImsService.");
546 pw.println(" Options are:");
547 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
548 pw.println(" is specified, it will choose the default voice SIM slot.");
549 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000550 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800551 pw.println(" -f: The feature type that the query will be requested for. If none is");
552 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800553 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
554 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
555 pw.println(" configuration overrides. Options are:");
556 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
557 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700558 pw.println(" ims enable [-s SLOT_ID]");
559 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
560 pw.println(" if none is specified.");
561 pw.println(" ims disable [-s SLOT_ID]");
562 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
563 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700564 pw.println(" ims conference-event-package [enable/disable]");
565 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700566 }
567
James.cf Linbcdf8b32021-01-14 16:44:13 +0800568 private void onHelpUce() {
569 PrintWriter pw = getOutPrintWriter();
570 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800571 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
572 pw.println(" Get the EAB contacts from the EAB database.");
573 pw.println(" Options are:");
574 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
575 pw.println(" Expected output format :");
576 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800577 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
578 pw.println(" Remove the EAB contacts from the EAB database.");
579 pw.println(" Options are:");
580 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
581 pw.println(" is specified, it will choose the default voice SIM slot.");
582 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800583 pw.println(" uce get-device-enabled");
584 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
585 pw.println(" uce set-device-enabled true|false");
586 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
587 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000588 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
589 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
590 pw.println(" Options are:");
591 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
592 pw.println(" is specified, it will choose the default voice SIM slot.");
593 pw.println(" add [CAPABILITY]: add a new capability");
594 pw.println(" remove [CAPABILITY]: remove a capability");
595 pw.println(" clear: clear all capability overrides");
596 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
597 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
598 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
599 pw.println(" chatbot_sa, chatbot_role] as well as full length");
600 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
601 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
602 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
603 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800604 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
605 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800606 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
607 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800608 }
609
Hall Liud892bec2018-11-30 14:51:45 -0800610 private void onHelpNumberVerification() {
611 PrintWriter pw = getOutPrintWriter();
612 pw.println("Number verification commands");
613 pw.println(" numverify override-package PACKAGE_NAME;");
614 pw.println(" Set the authorized package for number verification.");
615 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800616 pw.println(" numverify fake-call NUMBER;");
617 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
618 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800619 }
620
Jack Nudelman644b91a2021-03-12 14:09:48 -0800621 private void onHelpThermalMitigation() {
622 PrintWriter pw = getOutPrintWriter();
623 pw.println("Thermal mitigation commands");
624 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
625 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
626 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
627 pw.println(" Remove the package from one of the authorized packages for thermal "
628 + "mitigation.");
629 }
630
Jordan Liu0ccee222021-04-27 11:55:13 -0700631 private void onHelpDisableOrEnablePhysicalSubscription() {
632 PrintWriter pw = getOutPrintWriter();
633 pw.println("Disable or enable a physical subscription");
634 pw.println(" disable-physical-subscription SUB_ID");
635 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
636 pw.println(" enable-physical-subscription SUB_ID");
637 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
638 }
639
Shuo Qianf5125122019-12-16 17:03:07 -0800640 private void onHelpDataTestMode() {
641 PrintWriter pw = getOutPrintWriter();
642 pw.println("Mobile Data Test Mode Commands:");
643 pw.println(" data enable: enable mobile data connectivity");
644 pw.println(" data disable: disable mobile data connectivity");
645 }
646
sqian9d4df8b2019-01-15 18:32:07 -0800647 private void onHelpEmergencyNumber() {
648 PrintWriter pw = getOutPrintWriter();
649 pw.println("Emergency Number Test Mode Commands:");
650 pw.println(" emergency-number-test-mode ");
651 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
652 + " the test mode");
653 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700654 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800655 pw.println(" -c: clear the emergency number list in the test mode.");
656 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700657 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800658 pw.println(" -p: get the full emergency number list in the test mode.");
659 }
660
Shuo Qian489d9282020-07-09 11:30:03 -0700661 private void onHelpEndBlockSupperssion() {
662 PrintWriter pw = getOutPrintWriter();
663 pw.println("End Block Suppression command:");
664 pw.println(" end-block-suppression: disable suppressing blocking by contact");
665 pw.println(" with emergency services.");
666 }
667
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100668 private void onHelpCc() {
669 PrintWriter pw = getOutPrintWriter();
670 pw.println("Carrier Config Commands:");
671 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
672 pw.println(" Print carrier config values.");
673 pw.println(" Options are:");
674 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
675 pw.println(" is specified, it will choose the default voice SIM slot.");
676 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
677 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100678 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100679 pw.println(" Set carrier config KEY to NEW_VALUE.");
680 pw.println(" Options are:");
681 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
682 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100683 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100684 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
685 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
686 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
687 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000688 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
689 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
690 pw.println(" provided through standard input and follow CarrierConfig XML format.");
691 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
692 pw.println(" Options are:");
693 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
694 pw.println(" is specified, it will choose the default voice SIM slot.");
695 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100696 pw.println(" cc clear-values [-s SLOT_ID]");
697 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000698 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100699 pw.println(" Options are:");
700 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
701 pw.println(" is specified, it will choose the default voice SIM slot.");
702 }
703
Hui Wang641e81c2020-10-12 12:14:23 -0700704 private void onHelpGba() {
705 PrintWriter pw = getOutPrintWriter();
706 pw.println("Gba Commands:");
707 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
708 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
709 pw.println(" Options are:");
710 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
711 pw.println(" is specified, it will choose the default voice SIM slot.");
712 pw.println(" gba get-service [-s SLOT_ID]");
713 pw.println(" Gets the package name of the currently defined GbaService.");
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 set-release [-s SLOT_ID] n");
718 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
719 pw.println(" Do not release/unbind if n is -1.");
720 pw.println(" Options are:");
721 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
722 pw.println(" is specified, it will choose the default voice SIM slot.");
723 pw.println(" gba get-release [-s SLOT_ID]");
724 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
725 pw.println(" Options are:");
726 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
727 pw.println(" is specified, it will choose the default voice SIM slot.");
728 }
729
Hui Wang761a6682020-10-31 05:12:53 +0000730 private void onHelpSrc() {
731 PrintWriter pw = getOutPrintWriter();
732 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800733 pw.println(" src set-test-enabled true|false");
734 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
735 pw.println(" The value could be true, false, or null(undefined).");
736 pw.println(" src get-test-enabled");
737 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000738 pw.println(" src set-device-enabled true|false|null");
739 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
740 pw.println(" The value could be true, false, or null(undefined).");
741 pw.println(" src get-device-enabled");
742 pw.println(" Gets the device config for RCS VoLTE single registration.");
743 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
744 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
745 pw.println(" The value could be true, false, or null(undefined).");
746 pw.println(" Options are:");
747 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
748 pw.println(" is specified, it will choose the default voice SIM slot.");
749 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
750 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
751 pw.println(" Options are:");
752 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
753 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800754 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
755 pw.println(" Sets ims feature validation result.");
756 pw.println(" The value could be true, false, or null(undefined).");
757 pw.println(" Options are:");
758 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
759 pw.println(" is specified, it will choose the default voice SIM slot.");
760 pw.println(" src get-feature-validation [-s SLOT_ID]");
761 pw.println(" Gets ims feature validation override value.");
762 pw.println(" Options are:");
763 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
764 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000765 }
766
SongFerngWang98dd5992021-05-13 17:50:00 +0800767 private void onHelpAllowedNetworkTypes() {
768 PrintWriter pw = getOutPrintWriter();
769 pw.println("Allowed Network Types Commands:");
770 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
771 pw.println(" Print allowed network types value.");
772 pw.println(" Options are:");
773 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
774 pw.println(" option is specified, it will choose the default voice SIM slot.");
775 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
776 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
777 pw.println(" Options are:");
778 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
779 pw.println(" option is specified, it will choose the default voice SIM slot.");
780 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
781 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
782 pw.println(" at TelephonyManager.java");
783 pw.println(" For example:");
784 pw.println(" NR only : 10000000000000000000");
785 pw.println(" NR|LTE : 11000001000000000000");
786 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
787 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
788 pw.println(" LTE only : 01000001000000000000");
789 }
790
jimsun3b9ccac2021-10-26 15:01:23 +0800791 private void onHelpRadio() {
792 PrintWriter pw = getOutPrintWriter();
793 pw.println("Radio Commands:");
794 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
795 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
796 pw.println(" to be the bound. Options are:");
797 pw.println(" -s: the service name that the modem service should be bound for.");
798 pw.println(" If no option is specified, it will bind to the default.");
799 pw.println(" radio get-modem-service");
800 pw.println(" Gets the service name of the currently defined modem service.");
801 pw.println(" If it is binding to default, 'default' returns.");
802 pw.println(" If it doesn't bind to any modem service for some reasons,");
803 pw.println(" the result would be 'unknown'.");
804 }
805
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700806 private void onHelpSatellite() {
807 PrintWriter pw = getOutPrintWriter();
808 pw.println("Satellite Commands:");
809 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
810 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700811 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700812 pw.println(" -s: the satellite service package name that Telephony will bind to.");
813 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700814 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
815 pw.println(" Sets the package name of satellite gateway service defined in");
816 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
817 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
818 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700819 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
820 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
821 pw.println(" mode. Options are:");
822 pw.println(" -t: the timeout duration in milliseconds.");
823 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700824 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
825 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
826 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
827 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
828 pw.println(" launch. If no option is specified, it will launch the default.");
829 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
830 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700831 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
832 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
833 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
834 pw.println(" Options are:");
835 pw.println(" -t: the emergency call to satellite handover type.");
836 pw.println(" If no option is specified, override is disabled.");
837 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
838 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -0800839 pw.println(" set-satellite-access-control-overlay-configs [-r -a -f SATELLITE_S2_FILE ");
840 pw.println(" -d LOCATION_FRESH_DURATION_NANOS -c COUNTRY_CODES] Override the overlay");
841 pw.println(" configs of satellite access controller.");
842 pw.println(" Options are:");
843 pw.println(" -r: clear the overriding. Absent means enable overriding.");
844 pw.println(" -a: the country codes is an allowed list. Absent means disallowed.");
845 pw.println(" -f: the satellite s2 file.");
846 pw.println(" -d: the location fresh duration nanos.");
847 pw.println(" -c: the list of satellite country codes separated by comma.");
848 pw.println(" set-country-codes [-r -n CURRENT_NETWORK_COUNTRY_CODES -c");
849 pw.println(" CACHED_NETWORK_COUNTRY_CODES -l LOCATION_COUNTRY_CODE -t");
850 pw.println(" LOCATION_COUNTRY_CODE_TIMESTAMP] ");
851 pw.println(" Override the cached location country code and its update timestamp. ");
852 pw.println(" Options are:");
853 pw.println(" -r: clear the overriding. Absent means enable overriding.");
854 pw.println(" -n: the current network country code ISOs.");
855 pw.println(" -c: the cached network country code ISOs.");
856 pw.println(" -l: the location country code ISO.");
857 pw.println(" -t: the update timestamp nanos of the location country code.");
Thomas Nguyen3d602742024-01-19 11:29:35 -0800858 pw.println(" set-oem-enabled-satellite-provision-status [-p true/false]");
859 pw.println(" Sets the OEM-enabled satellite provision status. Options are:");
860 pw.println(" -p: the overriding satellite provision status. If no option is ");
861 pw.println(" specified, reset the overridden provision status.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700862 }
863
Ling Ma4fbab492022-01-25 22:36:16 +0000864 private void onHelpImei() {
865 PrintWriter pw = getOutPrintWriter();
866 pw.println("IMEI Commands:");
867 pw.println(" get-imei [-s SLOT_ID]");
868 pw.println(" Gets the device IMEI. Options are:");
869 pw.println(" -s: the slot ID to get the IMEI. If no option");
870 pw.println(" is specified, it will choose the default voice SIM slot.");
871 }
872
Hunsuk Choi13078be2023-09-13 10:55:21 +0000873 private void onHelpDomainSelection() {
874 PrintWriter pw = getOutPrintWriter();
875 pw.println("Domain Selection Commands:");
876 pw.println(" domainselection set-dss-override COMPONENT_NAME");
877 pw.println(" Sets the service defined in COMPONENT_NAME to be bound");
878 pw.println(" domainselection clear-dss-override");
879 pw.println(" Clears DomainSelectionService override.");
880 }
881
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700882 private int handleImsCommand() {
883 String arg = getNextArg();
884 if (arg == null) {
885 onHelpIms();
886 return 0;
887 }
888
889 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800890 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700891 return handleImsSetServiceCommand();
892 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800893 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700894 return handleImsGetServiceCommand();
895 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800896 case IMS_CLEAR_SERVICE_OVERRIDE: {
897 return handleImsClearCarrierServiceCommand();
898 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800899 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700900 return handleEnableIms();
901 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800902 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700903 return handleDisableIms();
904 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700905 case IMS_CEP: {
906 return handleCepChange();
907 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700908 }
909
910 return -1;
911 }
912
Shuo Qianf5125122019-12-16 17:03:07 -0800913 private int handleDataTestModeCommand() {
914 PrintWriter errPw = getErrPrintWriter();
915 String arg = getNextArgRequired();
916 if (arg == null) {
917 onHelpDataTestMode();
918 return 0;
919 }
920 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800921 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800922 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700923 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800924 } catch (RemoteException ex) {
925 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
926 errPw.println("Exception: " + ex.getMessage());
927 return -1;
928 }
929 break;
930 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800931 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800932 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700933 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800934 } catch (RemoteException ex) {
935 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
936 errPw.println("Exception: " + ex.getMessage());
937 return -1;
938 }
939 break;
940 }
941 default:
942 onHelpDataTestMode();
943 break;
944 }
945 return 0;
946 }
947
Shuo Qianccbaf742021-02-22 18:32:21 -0800948 private int handleEmergencyCallbackModeCommand() {
949 PrintWriter errPw = getErrPrintWriter();
950 try {
951 mInterface.startEmergencyCallbackMode();
952 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
953 } catch (RemoteException ex) {
954 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
955 errPw.println("Exception: " + ex.getMessage());
956 return -1;
957 }
958 return 0;
959 }
960
Grant Menke567d48f2022-08-18 20:19:10 +0000961 private void removeEmergencyNumberTestMode(String emergencyNumber) {
962 PrintWriter errPw = getErrPrintWriter();
963 for (int routingType : ROUTING_TYPES) {
964 try {
965 mInterface.updateEmergencyNumberListTestMode(
966 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
967 new EmergencyNumber(emergencyNumber, "", "",
968 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
969 new ArrayList<String>(),
970 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
971 routingType));
972 } catch (RemoteException ex) {
973 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
974 errPw.println("Exception: " + ex.getMessage());
975 }
976 }
977 }
978
sqian9d4df8b2019-01-15 18:32:07 -0800979 private int handleEmergencyNumberTestModeCommand() {
980 PrintWriter errPw = getErrPrintWriter();
981 String opt = getNextOption();
982 if (opt == null) {
983 onHelpEmergencyNumber();
984 return 0;
985 }
sqian9d4df8b2019-01-15 18:32:07 -0800986 switch (opt) {
987 case "-a": {
988 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000989 if (emergencyNumberCmd == null){
990 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800991 return -1;
992 }
Grant Menke567d48f2022-08-18 20:19:10 +0000993 String[] params = emergencyNumberCmd.split(":");
994 String emergencyNumber;
995 if (params[0] == null ||
996 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
997 errPw.println(INVALID_ENTRY_ERROR);
998 return -1;
999 } else {
1000 emergencyNumber = params[0];
1001 }
1002 removeEmergencyNumberTestMode(emergencyNumber);
1003 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
1004 if (params.length > 1) {
1005 switch (params[1].toLowerCase(Locale.ROOT)) {
1006 case "emergency":
1007 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
1008 break;
1009 case "normal":
1010 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
1011 break;
1012 case "unknown":
1013 break;
1014 default:
1015 errPw.println("\"" + params[1] + "\" is not a valid specification for "
1016 + "emergency call routing. Please enter either \"normal\", "
1017 + "\"unknown\", or \"emergency\" for call routing. "
1018 + "(-a 1234:normal)");
1019 return -1;
1020 }
1021 }
sqian9d4df8b2019-01-15 18:32:07 -08001022 try {
1023 mInterface.updateEmergencyNumberListTestMode(
1024 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +00001025 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -08001026 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
1027 new ArrayList<String>(),
1028 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +00001029 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -08001030 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +00001031 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -08001032 + ", error " + ex.getMessage());
1033 errPw.println("Exception: " + ex.getMessage());
1034 return -1;
1035 }
1036 break;
1037 }
1038 case "-c": {
1039 try {
1040 mInterface.updateEmergencyNumberListTestMode(
1041 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
1042 } catch (RemoteException ex) {
1043 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
1044 errPw.println("Exception: " + ex.getMessage());
1045 return -1;
1046 }
1047 break;
1048 }
1049 case "-r": {
1050 String emergencyNumberCmd = getNextArgRequired();
1051 if (emergencyNumberCmd == null
1052 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -07001053 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -08001054 + " to be specified after -r in the command ");
1055 return -1;
1056 }
Grant Menke567d48f2022-08-18 20:19:10 +00001057 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -08001058 break;
1059 }
1060 case "-p": {
1061 try {
1062 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
1063 } catch (RemoteException ex) {
1064 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
1065 errPw.println("Exception: " + ex.getMessage());
1066 return -1;
1067 }
1068 break;
1069 }
1070 default:
1071 onHelpEmergencyNumber();
1072 break;
1073 }
1074 return 0;
1075 }
1076
Hall Liud892bec2018-11-30 14:51:45 -08001077 private int handleNumberVerificationCommand() {
1078 String arg = getNextArg();
1079 if (arg == null) {
1080 onHelpNumberVerification();
1081 return 0;
1082 }
1083
Hall Liuca5af3a2018-12-04 16:58:23 -08001084 if (!checkShellUid()) {
1085 return -1;
1086 }
1087
Hall Liud892bec2018-11-30 14:51:45 -08001088 switch (arg) {
1089 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001090 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1091 return 0;
1092 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001093 case NUMBER_VERIFICATION_FAKE_CALL: {
1094 boolean val = NumberVerificationManager.getInstance()
1095 .checkIncomingCall(getNextArg());
1096 getOutPrintWriter().println(val ? "1" : "0");
1097 return 0;
1098 }
Hall Liud892bec2018-11-30 14:51:45 -08001099 }
1100
1101 return -1;
1102 }
1103
Jordan Liu0ccee222021-04-27 11:55:13 -07001104 private boolean subIsEsim(int subId) {
1105 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1106 if (info != null) {
1107 return info.isEmbedded();
1108 }
1109 return false;
1110 }
1111
1112 private int handleEnablePhysicalSubscription(boolean enable) {
1113 PrintWriter errPw = getErrPrintWriter();
1114 int subId = 0;
1115 try {
1116 subId = Integer.parseInt(getNextArgRequired());
1117 } catch (NumberFormatException e) {
1118 errPw.println((enable ? "enable" : "disable")
1119 + "-physical-subscription requires an integer as a subId.");
1120 return -1;
1121 }
1122 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1123 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001124 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1125 || TelephonyUtils.IS_USER) {
Jordan Liu0ccee222021-04-27 11:55:13 -07001126 errPw.println("cc: Permission denied.");
1127 return -1;
1128 }
1129 // Verify that the subId represents a physical sub
1130 if (subIsEsim(subId)) {
1131 errPw.println("SubId " + subId + " is not for a physical subscription");
1132 return -1;
1133 }
1134 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1135 + " physical subscription with subId=" + subId);
1136 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1137 return 0;
1138 }
1139
Jack Nudelman644b91a2021-03-12 14:09:48 -08001140 private int handleThermalMitigationCommand() {
1141 String arg = getNextArg();
1142 String packageName = getNextArg();
1143 if (arg == null || packageName == null) {
1144 onHelpThermalMitigation();
1145 return 0;
1146 }
1147
1148 if (!checkShellUid()) {
1149 return -1;
1150 }
1151
1152 switch (arg) {
1153 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1154 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1155 return 0;
1156 }
1157 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1158 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1159 mContext);
1160 return 0;
1161 }
1162 default:
1163 onHelpThermalMitigation();
1164 }
1165
1166 return -1;
1167
1168 }
1169
Tyler Gunn92479152021-01-20 16:30:10 -08001170 private int handleD2dCommand() {
1171 String arg = getNextArg();
1172 if (arg == null) {
1173 onHelpD2D();
1174 return 0;
1175 }
1176
1177 switch (arg) {
1178 case D2D_SEND: {
1179 return handleD2dSendCommand();
1180 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001181 case D2D_TRANSPORT: {
1182 return handleD2dTransportCommand();
1183 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001184 case D2D_SET_DEVICE_SUPPORT: {
1185 return handleD2dDeviceSupportedCommand();
1186 }
Tyler Gunn92479152021-01-20 16:30:10 -08001187 }
1188
1189 return -1;
1190 }
1191
1192 private int handleD2dSendCommand() {
1193 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001194 int messageType = -1;
1195 int messageValue = -1;
1196
Tyler Gunn92479152021-01-20 16:30:10 -08001197 String arg = getNextArg();
1198 if (arg == null) {
1199 onHelpD2D();
1200 return 0;
1201 }
1202 try {
1203 messageType = Integer.parseInt(arg);
1204 } catch (NumberFormatException e) {
1205 errPw.println("message type must be a valid integer");
1206 return -1;
1207 }
1208
1209 arg = getNextArg();
1210 if (arg == null) {
1211 onHelpD2D();
1212 return 0;
1213 }
1214 try {
1215 messageValue = Integer.parseInt(arg);
1216 } catch (NumberFormatException e) {
1217 errPw.println("message value must be a valid integer");
1218 return -1;
1219 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001220
Tyler Gunn92479152021-01-20 16:30:10 -08001221 try {
1222 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1223 } catch (RemoteException e) {
1224 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1225 errPw.println("Exception: " + e.getMessage());
1226 return -1;
1227 }
1228
1229 return 0;
1230 }
1231
Tyler Gunnbabbda02021-02-10 11:05:02 -08001232 private int handleD2dTransportCommand() {
1233 PrintWriter errPw = getErrPrintWriter();
1234
1235 String arg = getNextArg();
1236 if (arg == null) {
1237 onHelpD2D();
1238 return 0;
1239 }
1240
1241 try {
1242 mInterface.setActiveDeviceToDeviceTransport(arg);
1243 } catch (RemoteException e) {
1244 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1245 errPw.println("Exception: " + e.getMessage());
1246 return -1;
1247 }
1248 return 0;
1249 }
Nazanin014f41e2021-05-06 17:26:31 -07001250 private int handleBarringCommand() {
1251 String arg = getNextArg();
1252 if (arg == null) {
1253 onHelpBarring();
1254 return 0;
1255 }
1256
1257 switch (arg) {
1258 case BARRING_SEND_INFO: {
1259 return handleBarringSendCommand();
1260 }
1261 }
1262 return -1;
1263 }
1264
1265 private int handleBarringSendCommand() {
1266 PrintWriter errPw = getErrPrintWriter();
1267 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001268 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001269 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1270 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1271 boolean isConditionallyBarred = false;
1272 int conditionalBarringTimeSeconds = 0;
1273
1274 String opt;
1275 while ((opt = getNextOption()) != null) {
1276 switch (opt) {
1277 case "-s": {
1278 try {
1279 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001280 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001281 } catch (NumberFormatException e) {
1282 errPw.println("barring send requires an integer as a SLOT_ID.");
1283 return -1;
1284 }
1285 break;
1286 }
1287 case "-b": {
1288 try {
1289 barringType = Integer.parseInt(getNextArgRequired());
1290 if (barringType < -1 || barringType > 2) {
1291 throw new NumberFormatException();
1292 }
1293
1294 } catch (NumberFormatException e) {
1295 errPw.println("barring send requires an integer in range [-1,2] as "
1296 + "a BARRING_TYPE.");
1297 return -1;
1298 }
1299 break;
1300 }
1301 case "-c": {
1302 try {
1303 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1304 } catch (Exception e) {
1305 errPw.println("barring send requires a boolean after -c indicating"
1306 + " conditional barring");
1307 return -1;
1308 }
1309 break;
1310 }
1311 case "-t": {
1312 try {
1313 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1314 } catch (NumberFormatException e) {
1315 errPw.println("barring send requires an integer for time of barring"
1316 + " in seconds after -t for conditional barring");
1317 return -1;
1318 }
1319 break;
1320 }
1321 }
1322 }
1323 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1324 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1325 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1326 barringServiceInfos.append(0, bsi);
1327 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1328 try {
1329 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1330 } catch (Exception e) {
1331 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1332 errPw.println("Exception: " + e.getMessage());
1333 return -1;
1334 }
1335 return 0;
1336 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001337
Tyler Gunnd4575212021-05-03 14:46:49 -07001338 private int handleD2dDeviceSupportedCommand() {
1339 PrintWriter errPw = getErrPrintWriter();
1340
1341 String arg = getNextArg();
1342 if (arg == null) {
1343 onHelpD2D();
1344 return 0;
1345 }
1346
Jack Yua533d632022-09-30 13:53:46 -07001347 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001348 try {
1349 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1350 } catch (RemoteException e) {
1351 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1352 errPw.println("Exception: " + e.getMessage());
1353 return -1;
1354 }
1355 return 0;
1356 }
1357
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001358 // ims set-ims-service
1359 private int handleImsSetServiceCommand() {
1360 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001361 int slotId = getDefaultSlot();
Brad Ebinger555ddec2024-11-04 13:46:31 -08001362 int userId = UserHandle.USER_NULL; // By default, set no userId constraint
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001363 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001364 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001365
1366 String opt;
1367 while ((opt = getNextOption()) != null) {
1368 switch (opt) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001369 case "-u": {
1370 try {
1371 userId = Integer.parseInt(getNextArgRequired());
1372 } catch (NumberFormatException e) {
1373 errPw.println("ims set-ims-service requires an integer as a USER_ID");
1374 return -1;
1375 }
1376 break;
1377 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001378 case "-s": {
1379 try {
1380 slotId = Integer.parseInt(getNextArgRequired());
1381 } catch (NumberFormatException e) {
1382 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1383 return -1;
1384 }
1385 break;
1386 }
1387 case "-c": {
1388 isCarrierService = true;
1389 break;
1390 }
1391 case "-d": {
1392 isCarrierService = false;
1393 break;
1394 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001395 case "-f": {
1396 String featureString = getNextArgRequired();
1397 String[] features = featureString.split(",");
1398 for (int i = 0; i < features.length; i++) {
1399 try {
1400 Integer result = Integer.parseInt(features[i]);
1401 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1402 || result >= ImsFeature.FEATURE_MAX) {
1403 errPw.println("ims set-ims-service -f " + result
1404 + " is an invalid feature.");
1405 return -1;
1406 }
1407 featuresList.add(result);
1408 } catch (NumberFormatException e) {
1409 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1410 + " as an integer.");
1411 return -1;
1412 }
1413 }
1414 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001415 }
1416 }
1417 // Mandatory param, either -c or -d
1418 if (isCarrierService == null) {
1419 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1420 return -1;
1421 }
1422
1423 String packageName = getNextArg();
1424
1425 try {
1426 if (packageName == null) {
1427 packageName = "";
1428 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001429 int[] featureArray = new int[featuresList.size()];
1430 for (int i = 0; i < featuresList.size(); i++) {
1431 featureArray[i] = featuresList.get(i);
1432 }
Brad Ebinger555ddec2024-11-04 13:46:31 -08001433 boolean result = mInterface.setBoundImsServiceOverride(slotId, userId, isCarrierService,
Brad Ebinger24c29992019-12-05 13:03:21 -08001434 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001435 if (VDBG) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001436 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001437 + (isCarrierService ? "-c " : "-d ")
1438 + "-f " + featuresList + " "
1439 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001440 }
1441 getOutPrintWriter().println(result);
1442 } catch (RemoteException e) {
Brad Ebinger555ddec2024-11-04 13:46:31 -08001443 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " -u " + userId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001444 + (isCarrierService ? "-c " : "-d ")
1445 + "-f " + featuresList + " "
1446 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001447 errPw.println("Exception: " + e.getMessage());
1448 return -1;
1449 }
1450 return 0;
1451 }
1452
Brad Ebinger999d3302020-11-25 14:31:39 -08001453 // ims clear-ims-service-override
1454 private int handleImsClearCarrierServiceCommand() {
1455 PrintWriter errPw = getErrPrintWriter();
1456 int slotId = getDefaultSlot();
1457
1458 String opt;
1459 while ((opt = getNextOption()) != null) {
1460 switch (opt) {
1461 case "-s": {
1462 try {
1463 slotId = Integer.parseInt(getNextArgRequired());
1464 } catch (NumberFormatException e) {
1465 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1466 return -1;
1467 }
1468 break;
1469 }
1470 }
1471 }
1472
1473 try {
1474 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1475 if (VDBG) {
1476 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1477 + ", result=" + result);
1478 }
1479 getOutPrintWriter().println(result);
1480 } catch (RemoteException e) {
1481 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1482 + ", error" + e.getMessage());
1483 errPw.println("Exception: " + e.getMessage());
1484 return -1;
1485 }
1486 return 0;
1487 }
1488
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001489 // ims get-ims-service
1490 private int handleImsGetServiceCommand() {
1491 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001492 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001493 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001494 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001495
1496 String opt;
1497 while ((opt = getNextOption()) != null) {
1498 switch (opt) {
1499 case "-s": {
1500 try {
1501 slotId = Integer.parseInt(getNextArgRequired());
1502 } catch (NumberFormatException e) {
1503 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1504 return -1;
1505 }
1506 break;
1507 }
1508 case "-c": {
1509 isCarrierService = true;
1510 break;
1511 }
1512 case "-d": {
1513 isCarrierService = false;
1514 break;
1515 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001516 case "-f": {
1517 try {
1518 featureType = Integer.parseInt(getNextArg());
1519 } catch (NumberFormatException e) {
1520 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1521 return -1;
1522 }
1523 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1524 || featureType >= ImsFeature.FEATURE_MAX) {
1525 errPw.println("ims get-ims-service -f invalid feature.");
1526 return -1;
1527 }
1528 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001529 }
1530 }
1531 // Mandatory param, either -c or -d
1532 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001533 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001534 return -1;
1535 }
1536
1537 String result;
1538 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001539 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001540 } catch (RemoteException e) {
1541 return -1;
1542 }
1543 if (VDBG) {
1544 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001545 + (isCarrierService ? "-c " : "-d ")
1546 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1547 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001548 }
1549 getOutPrintWriter().println(result);
1550 return 0;
1551 }
1552
1553 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001554 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001555 String opt;
1556 while ((opt = getNextOption()) != null) {
1557 switch (opt) {
1558 case "-s": {
1559 try {
1560 slotId = Integer.parseInt(getNextArgRequired());
1561 } catch (NumberFormatException e) {
1562 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1563 return -1;
1564 }
1565 break;
1566 }
1567 }
1568 }
1569 try {
1570 mInterface.enableIms(slotId);
1571 } catch (RemoteException e) {
1572 return -1;
1573 }
1574 if (VDBG) {
1575 Log.v(LOG_TAG, "ims enable -s " + slotId);
1576 }
1577 return 0;
1578 }
1579
1580 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001581 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001582 String opt;
1583 while ((opt = getNextOption()) != null) {
1584 switch (opt) {
1585 case "-s": {
1586 try {
1587 slotId = Integer.parseInt(getNextArgRequired());
1588 } catch (NumberFormatException e) {
1589 getErrPrintWriter().println(
1590 "ims disable requires an integer as a SLOT_ID.");
1591 return -1;
1592 }
1593 break;
1594 }
1595 }
1596 }
1597 try {
1598 mInterface.disableIms(slotId);
1599 } catch (RemoteException e) {
1600 return -1;
1601 }
1602 if (VDBG) {
1603 Log.v(LOG_TAG, "ims disable -s " + slotId);
1604 }
1605 return 0;
1606 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001607
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001608 private int handleCepChange() {
1609 Log.i(LOG_TAG, "handleCepChange");
1610 String opt = getNextArg();
1611 if (opt == null) {
1612 return -1;
1613 }
1614 boolean isCepEnabled = opt.equals("enable");
1615
1616 try {
1617 mInterface.setCepEnabled(isCepEnabled);
1618 } catch (RemoteException e) {
1619 return -1;
1620 }
1621 return 0;
1622 }
1623
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001624 private int getDefaultSlot() {
1625 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1626 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1627 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1628 // If there is no default, default to slot 0.
1629 slotId = DEFAULT_PHONE_ID;
1630 }
1631 return slotId;
1632 }
sqian2fff4a32018-11-05 14:18:37 -08001633
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 // Parse options related to Carrier Config Commands.
1635 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001636 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001637 CcOptionParseResult result = new CcOptionParseResult();
1638 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1639 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001640
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001641 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001642 while ((opt = getNextOption()) != null) {
1643 switch (opt) {
1644 case "-s": {
1645 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001646 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1647 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1648 errPw.println(tag + "No valid subscription found.");
1649 return null;
1650 }
1651
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001652 } catch (IllegalArgumentException e) {
1653 // Missing slot id
1654 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001655 return null;
1656 }
1657 break;
1658 }
1659 case "-p": {
1660 if (allowOptionPersistent) {
1661 result.mPersistent = true;
1662 } else {
1663 errPw.println(tag + "Unexpected option " + opt);
1664 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001665 }
1666 break;
1667 }
1668 default: {
1669 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001670 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001671 }
1672 }
1673 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001674 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001675 }
1676
1677 private int slotStringToSubId(String tag, String slotString) {
1678 int slotId = -1;
1679 try {
1680 slotId = Integer.parseInt(slotString);
1681 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001682 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1683 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1684 }
1685
1686 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001687 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1688 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1689 }
1690
Qiong Liuf25799b2020-09-10 10:13:46 +08001691 Phone phone = PhoneFactory.getPhone(slotId);
1692 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001693 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1694 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1695 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001696 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001697 }
1698
Hall Liud892bec2018-11-30 14:51:45 -08001699 private boolean checkShellUid() {
Jack Yu26735292024-09-25 14:33:49 -07001700 return TelephonyPermissions.isRootOrShell(Binder.getCallingUid());
Hall Liud892bec2018-11-30 14:51:45 -08001701 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001702
1703 private int handleCcCommand() {
1704 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1705 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07001706 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
1707 || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001708 getErrPrintWriter().println("cc: Permission denied.");
1709 return -1;
1710 }
1711
1712 String arg = getNextArg();
1713 if (arg == null) {
1714 onHelpCc();
1715 return 0;
1716 }
1717
1718 switch (arg) {
1719 case CC_GET_VALUE: {
1720 return handleCcGetValue();
1721 }
1722 case CC_SET_VALUE: {
1723 return handleCcSetValue();
1724 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001725 case CC_SET_VALUES_FROM_XML: {
1726 return handleCcSetValuesFromXml();
1727 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001728 case CC_CLEAR_VALUES: {
1729 return handleCcClearValues();
1730 }
1731 default: {
1732 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1733 }
1734 }
1735 return -1;
1736 }
1737
1738 // cc get-value
1739 private int handleCcGetValue() {
1740 PrintWriter errPw = getErrPrintWriter();
1741 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1742 String key = null;
1743
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001744 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001745 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001746 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001747 return -1;
1748 }
1749
1750 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001751 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001752 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001753 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001754 return -1;
1755 }
1756
1757 // Get the key.
1758 key = getNextArg();
1759 if (key != null) {
1760 // A key was provided. Verify if it is a valid key
1761 if (!bundle.containsKey(key)) {
1762 errPw.println(tag + key + " is not a valid key.");
1763 return -1;
1764 }
1765
1766 // Print the carrier config value for key.
1767 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1768 } else {
1769 // No key provided. Show all values.
1770 // Iterate over a sorted list of all carrier config keys and print them.
1771 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1772 for (String k : sortedSet) {
1773 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1774 }
1775 }
1776 return 0;
1777 }
1778
1779 // cc set-value
1780 private int handleCcSetValue() {
1781 PrintWriter errPw = getErrPrintWriter();
1782 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1783
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001784 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001785 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001786 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001787 return -1;
1788 }
1789
1790 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001791 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001792 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001793 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001794 return -1;
1795 }
1796
1797 // Get the key.
1798 String key = getNextArg();
1799 if (key == null || key.equals("")) {
1800 errPw.println(tag + "KEY is missing");
1801 return -1;
1802 }
1803
1804 // Verify if the key is valid
1805 if (!originalValues.containsKey(key)) {
1806 errPw.println(tag + key + " is not a valid key.");
1807 return -1;
1808 }
1809
1810 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1811 ArrayList<String> valueList = new ArrayList<String>();
1812 while (peekNextArg() != null) {
1813 valueList.add(getNextArg());
1814 }
1815
1816 // Find the type of the carrier config value
1817 CcType type = getType(tag, key, originalValues);
1818 if (type == CcType.UNKNOWN) {
1819 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1820 return -1;
1821 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001822 if (type == CcType.PERSISTABLE_BUNDLE) {
1823 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1824 + "Use set-values-from-xml instead.");
1825 return -1;
1826 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001827
1828 // Create an override bundle containing the key and value that should be overriden.
1829 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1830 if (overrideBundle == null) {
1831 return -1;
1832 }
1833
1834 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001835 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001836
1837 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001838 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001839 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001840 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001841 return -1;
1842 }
1843
1844 // Print the original and new value.
1845 String originalValueString = ccValueToString(key, type, originalValues);
1846 String newValueString = ccValueToString(key, type, newValues);
1847 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1848 getOutPrintWriter().println("New value: \n" + newValueString);
1849
1850 return 0;
1851 }
1852
Allen Xuee00f0e2022-03-14 21:04:49 +00001853 // cc set-values-from-xml
1854 private int handleCcSetValuesFromXml() {
1855 PrintWriter errPw = getErrPrintWriter();
1856 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1857
1858 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001859 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001860 if (options == null) {
1861 return -1;
1862 }
1863
1864 // Get bundle containing all current carrier configuration values.
1865 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1866 if (originalValues == null) {
1867 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1868 return -1;
1869 }
1870
1871 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1872 if (overrideBundle == null) {
1873 return -1;
1874 }
1875
1876 // Verify all values are valid types
1877 for (String key : overrideBundle.keySet()) {
1878 CcType type = getType(tag, key, originalValues);
1879 if (type == CcType.UNKNOWN) {
1880 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1881 return -1;
1882 }
1883 }
1884
1885 // Override the value
1886 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1887
1888 // Find bundle containing all new carrier configuration values after the override.
1889 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1890 if (newValues == null) {
1891 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1892 return -1;
1893 }
1894
1895 // Print the original and new values
1896 overrideBundle.keySet().forEach(key -> {
1897 CcType type = getType(tag, key, originalValues);
1898 String originalValueString = ccValueToString(key, type, originalValues);
1899 String newValueString = ccValueToString(key, type, newValues);
1900 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1901 getOutPrintWriter().println("New value: \n" + newValueString);
1902 });
1903
1904 return 0;
1905 }
1906
1907 private PersistableBundle readPersistableBundleFromXml(String tag) {
1908 PersistableBundle subIdBundles;
1909 try {
1910 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1911 } catch (IOException | RuntimeException e) {
1912 PrintWriter errPw = getErrPrintWriter();
1913 errPw.println(tag + e);
1914 return null;
1915 }
1916
1917 return subIdBundles;
1918 }
1919
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001920 // cc clear-values
1921 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001922 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1923
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001924 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001925 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001926 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001927 return -1;
1928 }
1929
1930 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001931 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001932 getOutPrintWriter()
1933 .println("All previously set carrier config override values has been cleared");
1934 return 0;
1935 }
1936
1937 private CcType getType(String tag, String key, PersistableBundle bundle) {
1938 // Find the type by checking the type of the current value stored in the bundle.
1939 Object value = bundle.get(key);
1940
1941 if (CC_TYPE_MAP.containsKey(key)) {
1942 return CC_TYPE_MAP.get(key);
1943 } else if (value != null) {
1944 if (value instanceof Boolean) {
1945 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001946 }
1947 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001948 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001949 }
1950 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001951 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001952 }
1953 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001954 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001955 }
1956 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001957 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001958 }
1959 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001960 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001961 }
1962 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001963 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001964 }
1965 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001966 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001967 }
1968 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001969 return CcType.STRING_ARRAY;
1970 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001971 if (value instanceof PersistableBundle) {
1972 return CcType.PERSISTABLE_BUNDLE;
1973 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001974 } else {
1975 // Current value was null and can therefore not be used in order to find the type.
1976 // Check the name of the key to infer the type. This check is not needed for primitive
1977 // data types (boolean, double, int and long), since they can not be null.
1978 if (key.endsWith("double_array")) {
1979 return CcType.DOUBLE_ARRAY;
1980 }
1981 if (key.endsWith("int_array")) {
1982 return CcType.INT_ARRAY;
1983 }
1984 if (key.endsWith("long_array")) {
1985 return CcType.LONG_ARRAY;
1986 }
1987 if (key.endsWith("string")) {
1988 return CcType.STRING;
1989 }
1990 if (key.endsWith("string_array") || key.endsWith("strings")) {
1991 return CcType.STRING_ARRAY;
1992 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001993 if (key.endsWith("bundle")) {
1994 return CcType.PERSISTABLE_BUNDLE;
1995 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001996 }
1997
1998 // Not possible to infer the type by looking at the current value or the key.
1999 PrintWriter errPw = getErrPrintWriter();
2000 errPw.println(tag + "ERROR: " + key + " has unknown type.");
2001 return CcType.UNKNOWN;
2002 }
2003
2004 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
2005 String result;
2006 StringBuilder valueString = new StringBuilder();
2007 String typeString = type.toString();
2008 Object value = bundle.get(key);
2009
2010 if (value == null) {
2011 valueString.append("null");
2012 } else {
2013 switch (type) {
2014 case DOUBLE_ARRAY: {
2015 // Format the string representation of the int array as value1 value2......
2016 double[] valueArray = (double[]) value;
2017 for (int i = 0; i < valueArray.length; i++) {
2018 if (i != 0) {
2019 valueString.append(" ");
2020 }
2021 valueString.append(valueArray[i]);
2022 }
2023 break;
2024 }
2025 case INT_ARRAY: {
2026 // Format the string representation of the int array as value1 value2......
2027 int[] valueArray = (int[]) value;
2028 for (int i = 0; i < valueArray.length; i++) {
2029 if (i != 0) {
2030 valueString.append(" ");
2031 }
2032 valueString.append(valueArray[i]);
2033 }
2034 break;
2035 }
2036 case LONG_ARRAY: {
2037 // Format the string representation of the int array as value1 value2......
2038 long[] valueArray = (long[]) value;
2039 for (int i = 0; i < valueArray.length; i++) {
2040 if (i != 0) {
2041 valueString.append(" ");
2042 }
2043 valueString.append(valueArray[i]);
2044 }
2045 break;
2046 }
2047 case STRING: {
2048 valueString.append("\"" + value.toString() + "\"");
2049 break;
2050 }
2051 case STRING_ARRAY: {
2052 // Format the string representation of the string array as "value1" "value2"....
2053 String[] valueArray = (String[]) value;
2054 for (int i = 0; i < valueArray.length; i++) {
2055 if (i != 0) {
2056 valueString.append(" ");
2057 }
2058 if (valueArray[i] != null) {
2059 valueString.append("\"" + valueArray[i] + "\"");
2060 } else {
2061 valueString.append("null");
2062 }
2063 }
2064 break;
2065 }
2066 default: {
2067 valueString.append(value.toString());
2068 }
2069 }
2070 }
2071 return String.format("%-70s %-15s %s", key, typeString, valueString);
2072 }
2073
2074 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
2075 ArrayList<String> valueList) {
2076 PrintWriter errPw = getErrPrintWriter();
2077 PersistableBundle bundle = new PersistableBundle();
2078
2079 // First verify that a valid number of values has been provided for the type.
2080 switch (type) {
2081 case BOOLEAN:
2082 case DOUBLE:
2083 case INT:
2084 case LONG: {
2085 if (valueList.size() != 1) {
2086 errPw.println(tag + "Expected 1 value for type " + type
2087 + ". Found: " + valueList.size());
2088 return null;
2089 }
2090 break;
2091 }
2092 case STRING: {
2093 if (valueList.size() > 1) {
2094 errPw.println(tag + "Expected 0 or 1 values for type " + type
2095 + ". Found: " + valueList.size());
2096 return null;
2097 }
2098 break;
2099 }
2100 }
2101
2102 // Parse the value according to type and add it to the Bundle.
2103 switch (type) {
2104 case BOOLEAN: {
2105 if ("true".equalsIgnoreCase(valueList.get(0))) {
2106 bundle.putBoolean(key, true);
2107 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2108 bundle.putBoolean(key, false);
2109 } else {
2110 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2111 return null;
2112 }
2113 break;
2114 }
2115 case DOUBLE: {
2116 try {
2117 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2118 } catch (NumberFormatException nfe) {
2119 // Not a valid double
2120 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2121 return null;
2122 }
2123 break;
2124 }
2125 case DOUBLE_ARRAY: {
2126 double[] valueDoubleArray = null;
2127 if (valueList.size() > 0) {
2128 valueDoubleArray = new double[valueList.size()];
2129 for (int i = 0; i < valueList.size(); i++) {
2130 try {
2131 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2132 } catch (NumberFormatException nfe) {
2133 // Not a valid double
2134 errPw.println(
2135 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2136 return null;
2137 }
2138 }
2139 }
2140 bundle.putDoubleArray(key, valueDoubleArray);
2141 break;
2142 }
2143 case INT: {
2144 try {
2145 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2146 } catch (NumberFormatException nfe) {
2147 // Not a valid integer
2148 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2149 return null;
2150 }
2151 break;
2152 }
2153 case INT_ARRAY: {
2154 int[] valueIntArray = null;
2155 if (valueList.size() > 0) {
2156 valueIntArray = new int[valueList.size()];
2157 for (int i = 0; i < valueList.size(); i++) {
2158 try {
2159 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2160 } catch (NumberFormatException nfe) {
2161 // Not a valid integer
2162 errPw.println(tag
2163 + "Unable to parse " + valueList.get(i) + " as an integer.");
2164 return null;
2165 }
2166 }
2167 }
2168 bundle.putIntArray(key, valueIntArray);
2169 break;
2170 }
2171 case LONG: {
2172 try {
2173 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2174 } catch (NumberFormatException nfe) {
2175 // Not a valid long
2176 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2177 return null;
2178 }
2179 break;
2180 }
2181 case LONG_ARRAY: {
2182 long[] valueLongArray = null;
2183 if (valueList.size() > 0) {
2184 valueLongArray = new long[valueList.size()];
2185 for (int i = 0; i < valueList.size(); i++) {
2186 try {
2187 valueLongArray[i] = Long.parseLong(valueList.get(i));
2188 } catch (NumberFormatException nfe) {
2189 // Not a valid long
2190 errPw.println(
2191 tag + "Unable to parse " + valueList.get(i) + " as a long");
2192 return null;
2193 }
2194 }
2195 }
2196 bundle.putLongArray(key, valueLongArray);
2197 break;
2198 }
2199 case STRING: {
2200 String value = null;
2201 if (valueList.size() > 0) {
2202 value = valueList.get(0);
2203 }
2204 bundle.putString(key, value);
2205 break;
2206 }
2207 case STRING_ARRAY: {
2208 String[] valueStringArray = null;
2209 if (valueList.size() > 0) {
2210 valueStringArray = new String[valueList.size()];
2211 valueList.toArray(valueStringArray);
2212 }
2213 bundle.putStringArray(key, valueStringArray);
2214 break;
2215 }
2216 }
2217 return bundle;
2218 }
Shuo Qian489d9282020-07-09 11:30:03 -07002219
2220 private int handleEndBlockSuppressionCommand() {
2221 if (!checkShellUid()) {
2222 return -1;
2223 }
2224
2225 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2226 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2227 }
2228 return 0;
2229 }
Hui Wang641e81c2020-10-12 12:14:23 -07002230
Michele Berionne54af4632020-12-28 20:23:16 +00002231 private int handleRestartModemCommand() {
2232 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2233 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002234 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2235 || TelephonyUtils.IS_USER) {
Michele Berionne54af4632020-12-28 20:23:16 +00002236 getErrPrintWriter().println("RestartModem: Permission denied.");
2237 return -1;
2238 }
2239
2240 boolean result = TelephonyManager.getDefault().rebootRadio();
2241 getOutPrintWriter().println(result);
2242
2243 return result ? 0 : -1;
2244 }
2245
Ling Ma4fbab492022-01-25 22:36:16 +00002246 private int handleGetImei() {
2247 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2248 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002249 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2250 || TelephonyUtils.IS_USER) {
Ling Ma4fbab492022-01-25 22:36:16 +00002251 getErrPrintWriter().println("Device IMEI: Permission denied.");
2252 return -1;
2253 }
2254
2255 final long identity = Binder.clearCallingIdentity();
2256
2257 String imei = null;
2258 String arg = getNextArg();
2259 if (arg != null) {
2260 try {
2261 int specifiedSlotIndex = Integer.parseInt(arg);
2262 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2263 } catch (NumberFormatException exception) {
2264 PrintWriter errPw = getErrPrintWriter();
2265 errPw.println("-s requires an integer as slot index.");
2266 return -1;
2267 }
2268
2269 } else {
2270 imei = TelephonyManager.from(mContext).getImei();
2271 }
2272 getOutPrintWriter().println("Device IMEI: " + imei);
2273
2274 Binder.restoreCallingIdentity(identity);
2275 return 0;
2276 }
2277
Michele Berionne5e411512020-11-13 02:36:59 +00002278 private int handleUnattendedReboot() {
2279 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2280 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002281 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2282 || TelephonyUtils.IS_USER) {
Michele Berionne5e411512020-11-13 02:36:59 +00002283 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2284 return -1;
2285 }
2286
2287 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2288 getOutPrintWriter().println("result: " + result);
2289
2290 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2291 }
2292
Aman Gupta07124872022-02-09 08:02:14 +00002293 private int handleGetSimSlotsMapping() {
2294 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2295 // non user build.
Jack Yu86374492024-09-16 13:05:44 -07002296 if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.ROOT_UID)
2297 || TelephonyUtils.IS_USER) {
Aman Gupta07124872022-02-09 08:02:14 +00002298 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2299 return -1;
2300 }
2301 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2302 String result = telephonyManager.getSimSlotMapping().toString();
2303 getOutPrintWriter().println("simSlotsMapping: " + result);
2304
2305 return 0;
2306 }
2307
Hui Wang641e81c2020-10-12 12:14:23 -07002308 private int handleGbaCommand() {
2309 String arg = getNextArg();
2310 if (arg == null) {
2311 onHelpGba();
2312 return 0;
2313 }
2314
2315 switch (arg) {
2316 case GBA_SET_SERVICE: {
2317 return handleGbaSetServiceCommand();
2318 }
2319 case GBA_GET_SERVICE: {
2320 return handleGbaGetServiceCommand();
2321 }
2322 case GBA_SET_RELEASE_TIME: {
2323 return handleGbaSetReleaseCommand();
2324 }
2325 case GBA_GET_RELEASE_TIME: {
2326 return handleGbaGetReleaseCommand();
2327 }
2328 }
2329
2330 return -1;
2331 }
2332
2333 private int getSubId(String cmd) {
2334 int slotId = getDefaultSlot();
2335 String opt = getNextOption();
2336 if (opt != null && opt.equals("-s")) {
2337 try {
2338 slotId = Integer.parseInt(getNextArgRequired());
2339 } catch (NumberFormatException e) {
2340 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2341 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2342 }
2343 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002344 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002345 }
2346
2347 private int handleGbaSetServiceCommand() {
2348 int subId = getSubId("gba set-service");
2349 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2350 return -1;
2351 }
2352
2353 String packageName = getNextArg();
2354 try {
2355 if (packageName == null) {
2356 packageName = "";
2357 }
2358 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2359 if (VDBG) {
2360 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2361 + packageName + ", result=" + result);
2362 }
2363 getOutPrintWriter().println(result);
2364 } catch (RemoteException e) {
2365 Log.w(LOG_TAG, "gba set-service " + subId + " "
2366 + packageName + ", error" + e.getMessage());
2367 getErrPrintWriter().println("Exception: " + e.getMessage());
2368 return -1;
2369 }
2370 return 0;
2371 }
2372
2373 private int handleGbaGetServiceCommand() {
2374 String result;
2375
2376 int subId = getSubId("gba get-service");
2377 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2378 return -1;
2379 }
2380
2381 try {
2382 result = mInterface.getBoundGbaService(subId);
2383 } catch (RemoteException e) {
2384 return -1;
2385 }
2386 if (VDBG) {
2387 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2388 }
2389 getOutPrintWriter().println(result);
2390 return 0;
2391 }
2392
2393 private int handleGbaSetReleaseCommand() {
2394 //the release time value could be -1
2395 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2396 : SubscriptionManager.getDefaultSubscriptionId();
2397 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2398 return -1;
2399 }
2400
2401 String intervalStr = getNextArg();
2402 if (intervalStr == null) {
2403 return -1;
2404 }
2405
2406 try {
2407 int interval = Integer.parseInt(intervalStr);
2408 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2409 if (VDBG) {
2410 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2411 + intervalStr + ", result=" + result);
2412 }
2413 getOutPrintWriter().println(result);
2414 } catch (NumberFormatException | RemoteException e) {
2415 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2416 + intervalStr + ", error" + e.getMessage());
2417 getErrPrintWriter().println("Exception: " + e.getMessage());
2418 return -1;
2419 }
2420 return 0;
2421 }
2422
2423 private int handleGbaGetReleaseCommand() {
2424 int subId = getSubId("gba get-release");
2425 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2426 return -1;
2427 }
2428
2429 int result = 0;
2430 try {
2431 result = mInterface.getGbaReleaseTime(subId);
2432 } catch (RemoteException e) {
2433 return -1;
2434 }
2435 if (VDBG) {
2436 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2437 }
2438 getOutPrintWriter().println(result);
2439 return 0;
2440 }
Hui Wang761a6682020-10-31 05:12:53 +00002441
2442 private int handleSingleRegistrationConfigCommand() {
2443 String arg = getNextArg();
2444 if (arg == null) {
2445 onHelpSrc();
2446 return 0;
2447 }
2448
2449 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002450 case SRC_SET_TEST_ENABLED: {
2451 return handleSrcSetTestEnabledCommand();
2452 }
2453 case SRC_GET_TEST_ENABLED: {
2454 return handleSrcGetTestEnabledCommand();
2455 }
Hui Wang761a6682020-10-31 05:12:53 +00002456 case SRC_SET_DEVICE_ENABLED: {
2457 return handleSrcSetDeviceEnabledCommand();
2458 }
2459 case SRC_GET_DEVICE_ENABLED: {
2460 return handleSrcGetDeviceEnabledCommand();
2461 }
2462 case SRC_SET_CARRIER_ENABLED: {
2463 return handleSrcSetCarrierEnabledCommand();
2464 }
2465 case SRC_GET_CARRIER_ENABLED: {
2466 return handleSrcGetCarrierEnabledCommand();
2467 }
Hui Wangb647abe2021-02-26 09:33:38 -08002468 case SRC_SET_FEATURE_ENABLED: {
2469 return handleSrcSetFeatureValidationCommand();
2470 }
2471 case SRC_GET_FEATURE_ENABLED: {
2472 return handleSrcGetFeatureValidationCommand();
2473 }
Hui Wang761a6682020-10-31 05:12:53 +00002474 }
2475
2476 return -1;
2477 }
2478
James.cf Linbcdf8b32021-01-14 16:44:13 +08002479 private int handleRcsUceCommand() {
2480 String arg = getNextArg();
2481 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002482 onHelpUce();
2483 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002484 }
2485
2486 switch (arg) {
2487 case UCE_REMOVE_EAB_CONTACT:
2488 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002489 case UCE_GET_EAB_CONTACT:
2490 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002491 case UCE_GET_EAB_CAPABILITY:
2492 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002493 case UCE_GET_DEVICE_ENABLED:
2494 return handleUceGetDeviceEnabledCommand();
2495 case UCE_SET_DEVICE_ENABLED:
2496 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002497 case UCE_OVERRIDE_PUBLISH_CAPS:
2498 return handleUceOverridePublishCaps();
2499 case UCE_GET_LAST_PIDF_XML:
2500 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002501 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2502 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002503 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2504 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002505 }
2506 return -1;
2507 }
2508
2509 private int handleRemovingEabContactCommand() {
2510 int subId = getSubId("uce remove-eab-contact");
2511 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2512 return -1;
2513 }
2514
2515 String phoneNumber = getNextArgRequired();
2516 if (TextUtils.isEmpty(phoneNumber)) {
2517 return -1;
2518 }
2519 int result = 0;
2520 try {
2521 result = mInterface.removeContactFromEab(subId, phoneNumber);
2522 } catch (RemoteException e) {
2523 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2524 getErrPrintWriter().println("Exception: " + e.getMessage());
2525 return -1;
2526 }
2527
2528 if (VDBG) {
2529 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2530 }
calvinpan293ea1b2021-02-04 17:52:13 +08002531 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002532 }
2533
calvinpane4a8a1d2021-01-25 13:51:18 +08002534 private int handleGettingEabContactCommand() {
2535 String phoneNumber = getNextArgRequired();
2536 if (TextUtils.isEmpty(phoneNumber)) {
2537 return -1;
2538 }
2539 String result = "";
2540 try {
2541 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002542 } catch (RemoteException e) {
2543 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2544 getErrPrintWriter().println("Exception: " + e.getMessage());
2545 return -1;
2546 }
2547
2548 if (VDBG) {
2549 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2550 }
calvinpan293ea1b2021-02-04 17:52:13 +08002551 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002552 return 0;
2553 }
2554
Calvin Pana1434322021-07-01 19:27:01 +08002555 private int handleGettingEabCapabilityCommand() {
2556 String phoneNumber = getNextArgRequired();
2557 if (TextUtils.isEmpty(phoneNumber)) {
2558 return -1;
2559 }
2560 String result = "";
2561 try {
2562 result = mInterface.getCapabilityFromEab(phoneNumber);
2563 } catch (RemoteException e) {
2564 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2565 getErrPrintWriter().println("Exception: " + e.getMessage());
2566 return -1;
2567 }
2568
2569 if (VDBG) {
2570 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2571 }
2572 getOutPrintWriter().println(result);
2573 return 0;
2574 }
2575
James.cf Lin4b784aa2021-01-31 03:25:15 +08002576 private int handleUceGetDeviceEnabledCommand() {
2577 boolean result = false;
2578 try {
2579 result = mInterface.getDeviceUceEnabled();
2580 } catch (RemoteException e) {
2581 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2582 return -1;
2583 }
2584 if (VDBG) {
2585 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2586 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002587 getOutPrintWriter().println(result);
2588 return 0;
2589 }
2590
James.cf Lin4b784aa2021-01-31 03:25:15 +08002591 private int handleUceSetDeviceEnabledCommand() {
2592 String enabledStr = getNextArg();
2593 if (TextUtils.isEmpty(enabledStr)) {
2594 return -1;
2595 }
2596
2597 try {
2598 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2599 mInterface.setDeviceUceEnabled(isEnabled);
2600 if (VDBG) {
2601 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2602 }
2603 } catch (NumberFormatException | RemoteException e) {
2604 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2605 getErrPrintWriter().println("Exception: " + e.getMessage());
2606 return -1;
2607 }
2608 return 0;
2609 }
2610
James.cf Line8713a42021-04-29 16:04:26 +08002611 private int handleUceRemoveRequestDisallowedStatus() {
2612 int subId = getSubId("uce remove-request-disallowed-status");
2613 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2614 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2615 return -1;
2616 }
2617 boolean result;
2618 try {
2619 result = mInterface.removeUceRequestDisallowedStatus(subId);
2620 } catch (RemoteException e) {
2621 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2622 return -1;
2623 }
2624 if (VDBG) {
2625 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2626 }
2627 getOutPrintWriter().println(result);
2628 return 0;
2629 }
2630
James.cf Lin0fc71b02021-05-25 01:37:38 +08002631 private int handleUceSetCapRequestTimeout() {
2632 int subId = getSubId("uce set-capabilities-request-timeout");
2633 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2634 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2635 return -1;
2636 }
2637 long timeoutAfterMs = Long.valueOf(getNextArg());
2638 boolean result;
2639 try {
2640 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2641 } catch (RemoteException e) {
2642 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2643 return -1;
2644 }
2645 if (VDBG) {
2646 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2647 }
2648 getOutPrintWriter().println(result);
2649 return 0;
2650 }
2651
Hui Wangbaaee6a2021-02-19 20:45:36 -08002652 private int handleSrcSetTestEnabledCommand() {
2653 String enabledStr = getNextArg();
2654 if (enabledStr == null) {
2655 return -1;
2656 }
2657
2658 try {
2659 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2660 if (VDBG) {
2661 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2662 }
2663 getOutPrintWriter().println("Done");
2664 } catch (NumberFormatException | RemoteException e) {
2665 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2666 getErrPrintWriter().println("Exception: " + e.getMessage());
2667 return -1;
2668 }
2669 return 0;
2670 }
2671
2672 private int handleSrcGetTestEnabledCommand() {
2673 boolean result = false;
2674 try {
2675 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2676 } catch (RemoteException e) {
2677 return -1;
2678 }
2679 if (VDBG) {
2680 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2681 }
2682 getOutPrintWriter().println(result);
2683 return 0;
2684 }
2685
Brad Ebinger14d467f2021-02-12 06:18:28 +00002686 private int handleUceOverridePublishCaps() {
2687 int subId = getSubId("uce override-published-caps");
2688 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2689 return -1;
2690 }
2691 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2692 String operation = getNextArgRequired();
2693 String caps = getNextArg();
2694 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2695 && !"list".equals(operation)) {
2696 getErrPrintWriter().println("Invalid operation: " + operation);
2697 return -1;
2698 }
2699
2700 // add/remove requires capabilities to be specified.
2701 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2702 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2703 + "specified");
2704 return -1;
2705 }
2706
2707 ArraySet<String> capSet = new ArraySet<>();
2708 if (!TextUtils.isEmpty(caps)) {
2709 String[] capArray = caps.split(":");
2710 for (String cap : capArray) {
2711 // Allow unknown tags to be passed in as well.
2712 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2713 }
2714 }
2715
2716 RcsContactUceCapability result = null;
2717 try {
2718 switch (operation) {
2719 case "add":
2720 result = mInterface.addUceRegistrationOverrideShell(subId,
2721 new ArrayList<>(capSet));
2722 break;
2723 case "remove":
2724 result = mInterface.removeUceRegistrationOverrideShell(subId,
2725 new ArrayList<>(capSet));
2726 break;
2727 case "clear":
2728 result = mInterface.clearUceRegistrationOverrideShell(subId);
2729 break;
2730 case "list":
2731 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2732 break;
2733 }
2734 } catch (RemoteException e) {
2735 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2736 getErrPrintWriter().println("Exception: " + e.getMessage());
2737 return -1;
2738 } catch (ServiceSpecificException sse) {
2739 // Reconstruct ImsException
2740 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2741 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2742 getErrPrintWriter().println("Exception: " + imsException);
2743 return -1;
2744 }
2745 if (result == null) {
2746 getErrPrintWriter().println("Service not available");
2747 return -1;
2748 }
2749 getOutPrintWriter().println(result);
2750 return 0;
2751 }
2752
2753 private int handleUceGetPidfXml() {
2754 int subId = getSubId("uce get-last-publish-pidf");
2755 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2756 return -1;
2757 }
2758
2759 String result;
2760 try {
2761 result = mInterface.getLastUcePidfXmlShell(subId);
2762 } catch (RemoteException e) {
2763 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2764 getErrPrintWriter().println("Exception: " + e.getMessage());
2765 return -1;
2766 } catch (ServiceSpecificException sse) {
2767 // Reconstruct ImsException
2768 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2769 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2770 getErrPrintWriter().println("Exception: " + imsException);
2771 return -1;
2772 }
2773 if (result == null) {
2774 getErrPrintWriter().println("Service not available");
2775 return -1;
2776 }
2777 getOutPrintWriter().println(result);
2778 return 0;
2779 }
2780
Hui Wang761a6682020-10-31 05:12:53 +00002781 private int handleSrcSetDeviceEnabledCommand() {
2782 String enabledStr = getNextArg();
2783 if (enabledStr == null) {
2784 return -1;
2785 }
2786
2787 try {
2788 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2789 if (VDBG) {
2790 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2791 }
2792 getOutPrintWriter().println("Done");
2793 } catch (NumberFormatException | RemoteException e) {
2794 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2795 getErrPrintWriter().println("Exception: " + e.getMessage());
2796 return -1;
2797 }
2798 return 0;
2799 }
2800
2801 private int handleSrcGetDeviceEnabledCommand() {
2802 boolean result = false;
2803 try {
2804 result = mInterface.getDeviceSingleRegistrationEnabled();
2805 } catch (RemoteException e) {
2806 return -1;
2807 }
2808 if (VDBG) {
2809 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2810 }
2811 getOutPrintWriter().println(result);
2812 return 0;
2813 }
2814
2815 private int handleSrcSetCarrierEnabledCommand() {
2816 //the release time value could be -1
2817 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2818 : SubscriptionManager.getDefaultSubscriptionId();
2819 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2820 return -1;
2821 }
2822
2823 String enabledStr = getNextArg();
2824 if (enabledStr == null) {
2825 return -1;
2826 }
2827
2828 try {
2829 boolean result =
2830 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2831 if (VDBG) {
2832 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2833 + enabledStr + ", result=" + result);
2834 }
2835 getOutPrintWriter().println(result);
2836 } catch (NumberFormatException | RemoteException e) {
2837 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2838 + enabledStr + ", error" + e.getMessage());
2839 getErrPrintWriter().println("Exception: " + e.getMessage());
2840 return -1;
2841 }
2842 return 0;
2843 }
2844
2845 private int handleSrcGetCarrierEnabledCommand() {
2846 int subId = getSubId("src get-carrier-enabled");
2847 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2848 return -1;
2849 }
2850
2851 boolean result = false;
2852 try {
2853 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2854 } catch (RemoteException e) {
2855 return -1;
2856 }
2857 if (VDBG) {
2858 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2859 }
2860 getOutPrintWriter().println(result);
2861 return 0;
2862 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002863
Hui Wangb647abe2021-02-26 09:33:38 -08002864 private int handleSrcSetFeatureValidationCommand() {
2865 //the release time value could be -1
2866 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2867 : SubscriptionManager.getDefaultSubscriptionId();
2868 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2869 return -1;
2870 }
2871
2872 String enabledStr = getNextArg();
2873 if (enabledStr == null) {
2874 return -1;
2875 }
2876
2877 try {
2878 boolean result =
2879 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2880 if (VDBG) {
2881 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2882 + enabledStr + ", result=" + result);
2883 }
2884 getOutPrintWriter().println(result);
2885 } catch (NumberFormatException | RemoteException e) {
2886 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2887 + enabledStr + ", error" + e.getMessage());
2888 getErrPrintWriter().println("Exception: " + e.getMessage());
2889 return -1;
2890 }
2891 return 0;
2892 }
2893
2894 private int handleSrcGetFeatureValidationCommand() {
2895 int subId = getSubId("src get-feature-validation");
2896 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2897 return -1;
2898 }
2899
2900 Boolean result = false;
2901 try {
2902 result = mInterface.getImsFeatureValidationOverride(subId);
2903 } catch (RemoteException e) {
2904 return -1;
2905 }
2906 if (VDBG) {
2907 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2908 }
2909 getOutPrintWriter().println(result);
2910 return 0;
2911 }
2912
2913
Hall Liuaa4211e2021-01-20 15:43:39 -08002914 private void onHelpCallComposer() {
2915 PrintWriter pw = getOutPrintWriter();
2916 pw.println("Call composer commands");
2917 pw.println(" callcomposer test-mode enable|disable|query");
2918 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2919 pw.println(" upload/download from carrier servers is disabled, and operations are");
2920 pw.println(" performed using emulated local files instead.");
2921 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2922 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2923 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002924 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2925 pw.println(" Enables or disables the user setting for call composer, as set by");
2926 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002927 }
2928
2929 private int handleCallComposerCommand() {
2930 String arg = getNextArg();
2931 if (arg == null) {
2932 onHelpCallComposer();
2933 return 0;
2934 }
2935
2936 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2937 "MODIFY_PHONE_STATE required for call composer shell cmds");
2938 switch (arg) {
2939 case CALL_COMPOSER_TEST_MODE: {
2940 String enabledStr = getNextArg();
2941 if (ENABLE.equals(enabledStr)) {
2942 CallComposerPictureManager.sTestMode = true;
2943 } else if (DISABLE.equals(enabledStr)) {
2944 CallComposerPictureManager.sTestMode = false;
2945 } else if (QUERY.equals(enabledStr)) {
2946 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2947 } else {
2948 onHelpCallComposer();
2949 return 1;
2950 }
2951 break;
2952 }
2953 case CALL_COMPOSER_SIMULATE_CALL: {
2954 int subscriptionId = Integer.valueOf(getNextArg());
2955 String uuidString = getNextArg();
2956 UUID uuid = UUID.fromString(uuidString);
2957 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2958 Binder.withCleanCallingIdentity(() -> {
2959 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2960 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2961 });
2962 try {
2963 Uri uri = storageUriFuture.get();
2964 getOutPrintWriter().println(String.valueOf(uri));
2965 } catch (Exception e) {
2966 throw new RuntimeException(e);
2967 }
2968 break;
2969 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002970 case CALL_COMPOSER_USER_SETTING: {
2971 try {
2972 int subscriptionId = Integer.valueOf(getNextArg());
2973 String enabledStr = getNextArg();
2974 if (ENABLE.equals(enabledStr)) {
2975 mInterface.setCallComposerStatus(subscriptionId,
2976 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2977 } else if (DISABLE.equals(enabledStr)) {
2978 mInterface.setCallComposerStatus(subscriptionId,
2979 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2980 } else if (QUERY.equals(enabledStr)) {
2981 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2982 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2983 } else {
2984 onHelpCallComposer();
2985 return 1;
2986 }
2987 } catch (RemoteException e) {
2988 e.printStackTrace(getOutPrintWriter());
2989 return 1;
2990 }
2991 break;
2992 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002993 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002994 return 0;
2995 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002996
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002997 private int handleHasCarrierPrivilegesCommand() {
2998 String packageName = getNextArgRequired();
2999
3000 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07003001 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003002 try {
3003 hasCarrierPrivileges =
3004 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
3005 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
3006 } catch (RemoteException e) {
3007 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
3008 getErrPrintWriter().println("Exception: " + e.getMessage());
3009 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07003010 } finally {
3011 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08003012 }
3013
3014 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08003015 return 0;
3016 }
SongFerngWang98dd5992021-05-13 17:50:00 +08003017
3018 private int handleAllowedNetworkTypesCommand(String command) {
3019 if (!checkShellUid()) {
3020 return -1;
3021 }
3022
3023 PrintWriter errPw = getErrPrintWriter();
3024 String tag = command + ": ";
3025 String opt;
3026 int subId = -1;
3027 Log.v(LOG_TAG, command + " start");
3028
3029 while ((opt = getNextOption()) != null) {
3030 if (opt.equals("-s")) {
3031 try {
3032 subId = slotStringToSubId(tag, getNextArgRequired());
3033 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
3034 errPw.println(tag + "No valid subscription found.");
3035 return -1;
3036 }
3037 } catch (IllegalArgumentException e) {
3038 // Missing slot id
3039 errPw.println(tag + "SLOT_ID expected after -s.");
3040 return -1;
3041 }
3042 } else {
3043 errPw.println(tag + "Unknown option " + opt);
3044 return -1;
3045 }
3046 }
3047
3048 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3049 return handleGetAllowedNetworkTypesCommand(subId);
3050 }
3051 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
3052 return handleSetAllowedNetworkTypesCommand(subId);
3053 }
3054 return -1;
3055 }
3056
3057 private int handleGetAllowedNetworkTypesCommand(int subId) {
3058 PrintWriter errPw = getErrPrintWriter();
3059
3060 long result = -1;
3061 try {
3062 if (mInterface != null) {
3063 result = mInterface.getAllowedNetworkTypesForReason(subId,
3064 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3065 } else {
3066 throw new IllegalStateException("telephony service is null.");
3067 }
3068 } catch (RemoteException e) {
3069 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3070 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3071 return -1;
3072 }
3073
3074 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3075 return 0;
3076 }
3077
3078 private int handleSetAllowedNetworkTypesCommand(int subId) {
3079 PrintWriter errPw = getErrPrintWriter();
3080
3081 String bitmaskString = getNextArg();
3082 if (TextUtils.isEmpty(bitmaskString)) {
3083 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3084 return -1;
3085 }
3086 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3087 if (allowedNetworkTypes < 0) {
3088 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3089 return -1;
3090 }
3091 boolean result = false;
3092 try {
3093 if (mInterface != null) {
3094 result = mInterface.setAllowedNetworkTypesForReason(subId,
3095 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3096 } else {
3097 throw new IllegalStateException("telephony service is null.");
3098 }
3099 } catch (RemoteException e) {
3100 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3101 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3102 return -1;
3103 }
3104
3105 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3106 if (result) {
3107 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3108 }
3109 getOutPrintWriter().println(resultMessage);
3110 return 0;
3111 }
3112
3113 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3114 if (TextUtils.isEmpty(bitmaskString)) {
3115 return -1;
3116 }
3117 if (VDBG) {
3118 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3119 + ", length: " + bitmaskString.length());
3120 }
3121 try {
3122 return Long.parseLong(bitmaskString, 2);
3123 } catch (NumberFormatException e) {
3124 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3125 return -1;
3126 }
3127 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003128
jimsun3b9ccac2021-10-26 15:01:23 +08003129 private int handleRadioSetModemServiceCommand() {
3130 PrintWriter errPw = getErrPrintWriter();
3131 String serviceName = null;
3132
3133 String opt;
3134 while ((opt = getNextOption()) != null) {
3135 switch (opt) {
3136 case "-s": {
3137 serviceName = getNextArgRequired();
3138 break;
3139 }
3140 }
3141 }
3142
3143 try {
3144 boolean result = mInterface.setModemService(serviceName);
3145 if (VDBG) {
3146 Log.v(LOG_TAG,
3147 "RadioSetModemService " + serviceName + ", result = " + result);
3148 }
3149 getOutPrintWriter().println(result);
3150 } catch (RemoteException e) {
3151 Log.w(LOG_TAG,
3152 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3153 errPw.println("Exception: " + e.getMessage());
3154 return -1;
3155 }
3156 return 0;
3157 }
3158
3159 private int handleRadioGetModemServiceCommand() {
3160 PrintWriter errPw = getErrPrintWriter();
3161 String result;
3162
3163 try {
3164 result = mInterface.getModemService();
3165 getOutPrintWriter().println(result);
3166 } catch (RemoteException e) {
3167 errPw.println("Exception: " + e.getMessage());
3168 return -1;
3169 }
3170 if (VDBG) {
3171 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3172 }
3173 return 0;
3174 }
3175
3176 private int handleRadioCommand() {
3177 String arg = getNextArg();
3178 if (arg == null) {
3179 onHelpRadio();
3180 return 0;
3181 }
3182
3183 switch (arg) {
3184 case RADIO_SET_MODEM_SERVICE:
3185 return handleRadioSetModemServiceCommand();
3186
3187 case RADIO_GET_MODEM_SERVICE:
3188 return handleRadioGetModemServiceCommand();
3189 }
3190
3191 return -1;
3192 }
arunvoddud7401012022-12-15 16:08:12 +00003193
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003194 private int handleSetSatelliteServicePackageNameCommand() {
3195 PrintWriter errPw = getErrPrintWriter();
3196 String serviceName = null;
Hakjun Choic3393242024-06-26 18:02:08 +00003197 String provisioned = null;
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003198
3199 String opt;
3200 while ((opt = getNextOption()) != null) {
3201 switch (opt) {
3202 case "-s": {
3203 serviceName = getNextArgRequired();
3204 break;
3205 }
Hakjun Choic3393242024-06-26 18:02:08 +00003206
3207 case "-p": {
3208 provisioned = getNextArgRequired();
3209 break;
3210 }
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003211 }
3212 }
3213 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
Hakjun Choic3393242024-06-26 18:02:08 +00003214 + serviceName + ", provisioned=" + provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003215
3216 try {
Hakjun Choic3393242024-06-26 18:02:08 +00003217 boolean result = mInterface.setSatelliteServicePackageName(serviceName, provisioned);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003218 if (VDBG) {
Hakjun Choic3393242024-06-26 18:02:08 +00003219 Log.v(LOG_TAG,
3220 "SetSatelliteServicePackageName " + serviceName + ", provisioned="
3221 + provisioned + ", result = " + result);
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003222 }
3223 getOutPrintWriter().println(result);
3224 } catch (RemoteException e) {
Hakjun Choic3393242024-06-26 18:02:08 +00003225 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName + ", provisioned="
3226 + provisioned + ", error = " + e.getMessage());
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003227 errPw.println("Exception: " + e.getMessage());
3228 return -1;
3229 }
Hakjun Choic3393242024-06-26 18:02:08 +00003230
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003231 return 0;
3232 }
3233
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003234 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3235 PrintWriter errPw = getErrPrintWriter();
3236 String serviceName = null;
3237
3238 String opt;
3239 while ((opt = getNextOption()) != null) {
3240 switch (opt) {
3241 case "-s": {
3242 serviceName = getNextArgRequired();
3243 break;
3244 }
3245 }
3246 }
3247 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3248 + serviceName);
3249
3250 try {
3251 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3252 if (VDBG) {
3253 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3254 + ", result = " + result);
3255 }
3256 getOutPrintWriter().println(result);
3257 } catch (RemoteException e) {
3258 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3259 + ", error = " + e.getMessage());
3260 errPw.println("Exception: " + e.getMessage());
3261 return -1;
3262 }
3263 return 0;
3264 }
3265
Thomas Nguyen87dce732023-04-20 18:27:16 -07003266 private int handleSetSatellitePointingUiClassNameCommand() {
3267 PrintWriter errPw = getErrPrintWriter();
3268 String packageName = null;
3269 String className = null;
3270
3271 String opt;
3272 while ((opt = getNextOption()) != null) {
3273 switch (opt) {
3274 case "-p": {
3275 packageName = getNextArgRequired();
3276 break;
3277 }
3278 case "-c": {
3279 className = getNextArgRequired();
3280 break;
3281 }
3282 }
3283 }
3284 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3285 + packageName + ", className=" + className);
3286
3287 try {
3288 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3289 if (VDBG) {
3290 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3291 }
3292 getOutPrintWriter().println(result);
3293 } catch (RemoteException e) {
3294 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3295 + ", error = " + e.getMessage());
3296 errPw.println("Exception: " + e.getMessage());
3297 return -1;
3298 }
3299 return 0;
3300 }
3301
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003302 private int handleSetEmergencyCallToSatelliteHandoverType() {
3303 PrintWriter errPw = getErrPrintWriter();
3304 int handoverType = -1;
3305 int delaySeconds = 0;
3306
3307 String opt;
3308 while ((opt = getNextOption()) != null) {
3309 switch (opt) {
3310 case "-t": {
3311 try {
3312 handoverType = Integer.parseInt(getNextArgRequired());
3313 } catch (NumberFormatException e) {
3314 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3315 + " for handoverType");
3316 return -1;
3317 }
3318 break;
3319 }
3320 case "-d": {
3321 try {
3322 delaySeconds = Integer.parseInt(getNextArgRequired());
3323 } catch (NumberFormatException e) {
3324 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3325 + " for delaySeconds");
3326 return -1;
3327 }
3328 break;
3329 }
3330 }
3331 }
3332 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3333 + handoverType + ", delaySeconds=" + delaySeconds);
3334
3335 try {
3336 boolean result =
3337 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3338 if (VDBG) {
3339 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3340 }
3341 getOutPrintWriter().println(result);
3342 } catch (RemoteException e) {
3343 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3344 + ", error = " + e.getMessage());
3345 errPw.println("Exception: " + e.getMessage());
3346 return -1;
3347 }
3348 return 0;
3349 }
3350
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003351 private int handleSetSatelliteListeningTimeoutDuration() {
3352 PrintWriter errPw = getErrPrintWriter();
3353 long timeoutMillis = 0;
3354
3355 String opt;
3356 while ((opt = getNextOption()) != null) {
3357 switch (opt) {
3358 case "-t": {
3359 timeoutMillis = Long.parseLong(getNextArgRequired());
3360 break;
3361 }
3362 }
3363 }
3364 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3365 + timeoutMillis);
3366
3367 try {
3368 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3369 if (VDBG) {
3370 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3371 + ", result = " + result);
3372 }
3373 getOutPrintWriter().println(result);
3374 } catch (RemoteException e) {
3375 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3376 + ", error = " + e.getMessage());
3377 errPw.println("Exception: " + e.getMessage());
3378 return -1;
3379 }
3380 return 0;
3381 }
3382
joonhunshinf46f0d62024-09-27 14:06:26 +00003383 private int handleSetSatelliteIgnoreCellularServiceState() {
3384 PrintWriter errPw = getErrPrintWriter();
3385 boolean enabled = false;
3386
3387 String opt;
3388 while ((opt = getNextOption()) != null) {
3389 switch (opt) {
3390 case "-d": {
3391 enabled = Boolean.parseBoolean(getNextArgRequired());
3392 break;
3393 }
3394 }
3395 }
3396 Log.d(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: enabled =" + enabled);
3397
3398 try {
3399 boolean result = mInterface.setSatelliteIgnoreCellularServiceState(enabled);
3400 if (VDBG) {
3401 Log.v(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState " + enabled
3402 + ", result = " + result);
3403 }
3404 getOutPrintWriter().println(result);
3405 } catch (RemoteException e) {
3406 Log.w(LOG_TAG, "handleSetSatelliteIgnoreCellularServiceState: " + enabled
3407 + ", error = " + e.getMessage());
3408 errPw.println("Exception: " + e.getMessage());
3409 return -1;
3410 }
3411 return 0;
3412 }
3413
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003414 private int handleSetDatagramControllerTimeoutDuration() {
Hakjun Choiae365972023-04-25 11:00:31 +00003415 PrintWriter errPw = getErrPrintWriter();
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003416 boolean reset = false;
3417 int timeoutType = 0;
Hakjun Choiae365972023-04-25 11:00:31 +00003418 long timeoutMillis = 0;
3419
3420 String opt;
3421 while ((opt = getNextOption()) != null) {
3422 switch (opt) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003423 case "-d": {
Hakjun Choiae365972023-04-25 11:00:31 +00003424 timeoutMillis = Long.parseLong(getNextArgRequired());
3425 break;
3426 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003427 case "-r": {
3428 reset = true;
3429 break;
3430 }
3431 case "-t": {
3432 timeoutType = Integer.parseInt(getNextArgRequired());
3433 break;
3434 }
Hakjun Choiae365972023-04-25 11:00:31 +00003435 }
3436 }
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003437 Log.d(LOG_TAG, "setDatagramControllerTimeoutDuration: timeoutMillis="
3438 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
Hakjun Choiae365972023-04-25 11:00:31 +00003439
3440 try {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003441 boolean result = mInterface.setDatagramControllerTimeoutDuration(
3442 reset, timeoutType, timeoutMillis);
Hakjun Choiae365972023-04-25 11:00:31 +00003443 if (VDBG) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003444 Log.v(LOG_TAG, "setDatagramControllerTimeoutDuration " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003445 + ", result = " + result);
3446 }
3447 getOutPrintWriter().println(result);
3448 } catch (RemoteException e) {
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003449 Log.w(LOG_TAG, "setDatagramControllerTimeoutDuration: " + timeoutMillis
3450 + ", error = " + e.getMessage());
3451 errPw.println("Exception: " + e.getMessage());
3452 return -1;
3453 }
3454 return 0;
3455 }
3456
Aishwarya Mallampati3f0ef9b2024-05-17 22:47:04 +00003457 private int handleSetDatagramControllerBooleanConfig() {
3458 PrintWriter errPw = getErrPrintWriter();
3459 boolean reset = false;
3460 int booleanType = 0;
3461 boolean enable = false;
3462
3463 String opt;
3464 while ((opt = getNextOption()) != null) {
3465 switch (opt) {
3466 case "-d": {
3467 enable = Boolean.parseBoolean(getNextArgRequired());
3468 break;
3469 }
3470 case "-r": {
3471 reset = true;
3472 break;
3473 }
3474 case "-t": {
3475 booleanType = Integer.parseInt(getNextArgRequired());
3476 break;
3477 }
3478 }
3479 }
3480 Log.d(LOG_TAG, "setDatagramControllerBooleanConfig: enable="
3481 + enable + ", reset=" + reset + ", booleanType=" + booleanType);
3482
3483 try {
3484 boolean result = mInterface.setDatagramControllerBooleanConfig(
3485 reset, booleanType, enable);
3486 if (VDBG) {
3487 Log.v(LOG_TAG, "setDatagramControllerBooleanConfig result = " + result);
3488 }
3489 getOutPrintWriter().println(result);
3490 } catch (RemoteException e) {
3491 Log.w(LOG_TAG, "setDatagramControllerBooleanConfig: error = " + e.getMessage());
3492 errPw.println("Exception: " + e.getMessage());
3493 return -1;
3494 }
3495 return 0;
3496 }
3497
Thomas Nguyen8b8777f2024-02-05 11:50:23 -08003498 private int handleSetSatelliteControllerTimeoutDuration() {
3499 PrintWriter errPw = getErrPrintWriter();
3500 boolean reset = false;
3501 int timeoutType = 0;
3502 long timeoutMillis = 0;
3503
3504 String opt;
3505 while ((opt = getNextOption()) != null) {
3506 switch (opt) {
3507 case "-d": {
3508 timeoutMillis = Long.parseLong(getNextArgRequired());
3509 break;
3510 }
3511 case "-r": {
3512 reset = true;
3513 break;
3514 }
3515 case "-t": {
3516 timeoutType = Integer.parseInt(getNextArgRequired());
3517 break;
3518 }
3519 }
3520 }
3521 Log.d(LOG_TAG, "setSatelliteControllerTimeoutDuration: timeoutMillis="
3522 + timeoutMillis + ", reset=" + reset + ", timeoutType=" + timeoutType);
3523
3524 try {
3525 boolean result = mInterface.setSatelliteControllerTimeoutDuration(
3526 reset, timeoutType, timeoutMillis);
3527 if (VDBG) {
3528 Log.v(LOG_TAG, "setSatelliteControllerTimeoutDuration " + timeoutMillis
3529 + ", result = " + result);
3530 }
3531 getOutPrintWriter().println(result);
3532 } catch (RemoteException e) {
3533 Log.w(LOG_TAG, "setSatelliteControllerTimeoutDuration: " + timeoutMillis
Hakjun Choiae365972023-04-25 11:00:31 +00003534 + ", error = " + e.getMessage());
3535 errPw.println("Exception: " + e.getMessage());
3536 return -1;
3537 }
3538 return 0;
3539 }
3540
Hakjun Choibc6ce992023-11-07 16:04:33 +00003541 private int handleSetShouldSendDatagramToModemInDemoMode() {
3542 PrintWriter errPw = getErrPrintWriter();
3543 String opt;
3544 boolean shouldSendToDemoMode;
3545
3546 if ((opt = getNextArg()) == null) {
3547 errPw.println(
3548 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3549 + " Invalid Argument");
3550 return -1;
3551 } else {
3552 switch (opt) {
3553 case "true": {
3554 shouldSendToDemoMode = true;
3555 break;
3556 }
3557 case "false": {
3558 shouldSendToDemoMode = false;
3559 break;
3560 }
3561 default:
3562 errPw.println(
3563 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3564 + " Invalid Argument");
3565 return -1;
3566 }
3567 }
3568
3569 Log.d(LOG_TAG,
3570 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3571
3572 try {
3573 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3574 shouldSendToDemoMode);
3575 if (VDBG) {
3576 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3577 + result);
3578 }
3579 getOutPrintWriter().println(false);
3580 } catch (RemoteException e) {
3581 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3582 + "), error = " + e.getMessage());
3583 errPw.println("Exception: " + e.getMessage());
3584 return -1;
3585 }
3586 return 0;
3587 }
3588
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003589 private int handleSetSatelliteAccessControlOverlayConfigs() {
3590 PrintWriter errPw = getErrPrintWriter();
3591 boolean reset = false;
3592 boolean isAllowed = false;
3593 String s2CellFile = null;
3594 long locationFreshDurationNanos = 0;
3595 List<String> satelliteCountryCodes = null;
Hakjun Choi364b6ff2024-11-20 07:38:44 +00003596 String satelliteAccessConfigurationFile = null;
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003597
3598 String opt;
3599 while ((opt = getNextOption()) != null) {
Hakjun Choi364b6ff2024-11-20 07:38:44 +00003600 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: opt=" + opt);
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003601 switch (opt) {
3602 case "-r": {
3603 reset = true;
3604 break;
3605 }
3606 case "-a": {
3607 isAllowed = true;
3608 break;
3609 }
3610 case "-f": {
3611 s2CellFile = getNextArgRequired();
3612 break;
3613 }
3614 case "-d": {
3615 locationFreshDurationNanos = Long.parseLong(getNextArgRequired());
3616 break;
3617 }
3618 case "-c": {
3619 String countryCodeStr = getNextArgRequired();
3620 satelliteCountryCodes = Arrays.asList(countryCodeStr.split(","));
3621 break;
3622 }
Hakjun Choi364b6ff2024-11-20 07:38:44 +00003623 case "-g": {
3624 satelliteAccessConfigurationFile = getNextArgRequired();
3625 break;
3626 }
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003627 }
3628 }
3629 Log.d(LOG_TAG, "handleSetSatelliteAccessControlOverlayConfigs: reset=" + reset
3630 + ", isAllowed=" + isAllowed + ", s2CellFile=" + s2CellFile
3631 + ", locationFreshDurationNanos=" + locationFreshDurationNanos
Hakjun Choi364b6ff2024-11-20 07:38:44 +00003632 + ", satelliteCountryCodes=" + satelliteCountryCodes
3633 + ", satelliteAccessConfigurationFile=" + satelliteAccessConfigurationFile);
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003634
3635 try {
3636 boolean result = mInterface.setSatelliteAccessControlOverlayConfigs(reset, isAllowed,
Hakjun Choi364b6ff2024-11-20 07:38:44 +00003637 s2CellFile, locationFreshDurationNanos, satelliteCountryCodes,
3638 satelliteAccessConfigurationFile);
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003639 if (VDBG) {
3640 Log.v(LOG_TAG, "setSatelliteAccessControlOverlayConfigs result =" + result);
3641 }
3642 getOutPrintWriter().println(result);
3643 } catch (RemoteException e) {
3644 Log.e(LOG_TAG, "setSatelliteAccessControlOverlayConfigs: ex=" + e.getMessage());
3645 errPw.println("Exception: " + e.getMessage());
3646 return -1;
3647 }
3648 return 0;
3649 }
3650
3651 private int handleSetCountryCodes() {
3652 PrintWriter errPw = getErrPrintWriter();
3653 List<String> currentNetworkCountryCodes = new ArrayList<>();
3654 String locationCountryCode = null;
3655 long locationCountryCodeTimestampNanos = 0;
3656 Map<String, Long> cachedNetworkCountryCodes = new HashMap<>();
3657 boolean reset = false;
3658
3659 String opt;
3660 while ((opt = getNextOption()) != null) {
3661 switch (opt) {
3662 case "-r": {
3663 reset = true;
3664 break;
3665 }
3666 case "-n": {
3667 String countryCodeStr = getNextArgRequired();
3668 currentNetworkCountryCodes = Arrays.asList(countryCodeStr.split(","));
3669 break;
3670 }
3671 case "-c": {
3672 String cachedNetworkCountryCodeStr = getNextArgRequired();
3673 cachedNetworkCountryCodes = parseStringLongMap(cachedNetworkCountryCodeStr);
3674 break;
3675 }
3676 case "-l": {
3677 locationCountryCode = getNextArgRequired();
3678 break;
3679 }
3680 case "-t": {
3681 locationCountryCodeTimestampNanos = Long.parseLong(getNextArgRequired());
3682 break;
3683 }
3684 }
3685 }
3686 Log.d(LOG_TAG, "setCountryCodes: locationCountryCode="
3687 + locationCountryCode + ", locationCountryCodeTimestampNanos="
3688 + locationCountryCodeTimestampNanos + ", currentNetworkCountryCodes="
3689 + currentNetworkCountryCodes);
3690
3691 try {
3692 boolean result = mInterface.setCountryCodes(reset, currentNetworkCountryCodes,
3693 cachedNetworkCountryCodes, locationCountryCode,
3694 locationCountryCodeTimestampNanos);
3695 if (VDBG) {
3696 Log.v(LOG_TAG, "setCountryCodes result =" + result);
3697 }
3698 getOutPrintWriter().println(result);
3699 } catch (RemoteException e) {
3700 Log.e(LOG_TAG, "setCountryCodes: ex=" + e.getMessage());
3701 errPw.println("Exception: " + e.getMessage());
3702 return -1;
3703 }
3704 return 0;
3705 }
3706
Thomas Nguyen3d602742024-01-19 11:29:35 -08003707 private int handleSetOemEnabledSatelliteProvisionStatus() {
3708 PrintWriter errPw = getErrPrintWriter();
3709 boolean isProvisioned = false;
3710 boolean reset = true;
3711
3712 String opt;
3713 while ((opt = getNextOption()) != null) {
3714 switch (opt) {
3715 case "-p": {
3716 try {
3717 isProvisioned = Boolean.parseBoolean(getNextArgRequired());
3718 reset = false;
3719 } catch (Exception e) {
3720 errPw.println("setOemEnabledSatelliteProvisionStatus requires a boolean "
3721 + "after -p indicating provision status");
3722 return -1;
3723 }
3724 }
3725 }
3726 }
3727 Log.d(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: reset=" + reset
3728 + ", isProvisioned=" + isProvisioned);
3729
3730 try {
3731 boolean result = mInterface.setOemEnabledSatelliteProvisionStatus(reset, isProvisioned);
3732 if (VDBG) {
3733 Log.v(LOG_TAG, "setOemEnabledSatelliteProvisionStatus result = " + result);
3734 }
3735 getOutPrintWriter().println(result);
3736 } catch (RemoteException e) {
3737 Log.w(LOG_TAG, "setOemEnabledSatelliteProvisionStatus: error = " + e.getMessage());
3738 errPw.println("Exception: " + e.getMessage());
3739 return -1;
3740 }
3741 return 0;
3742 }
3743
Hakjun Choi4a832d12024-05-28 22:23:55 +00003744 private int handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache() {
3745 PrintWriter errPw = getErrPrintWriter();
3746 String opt;
3747 String state;
Hakjun Choi4a832d12024-05-28 22:23:55 +00003748 if ((opt = getNextArg()) == null) {
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 } else {
3755 switch (opt) {
3756 case "-a": {
3757 state = "cache_allowed";
3758 break;
3759 }
youngtaecha32bde212024-09-17 22:58:11 +00003760 case "-na": {
3761 state = "cache_not_allowed";
3762 break;
3763 }
Hakjun Choi4a832d12024-05-28 22:23:55 +00003764 case "-n": {
3765 state = "cache_clear_and_not_allowed";
3766 break;
3767 }
3768 case "-c": {
3769 state = "clear_cache_only";
3770 break;
3771 }
3772 default:
3773 errPw.println(
3774 "adb shell cmd phone set-is-satellite-communication-allowed-for-current"
3775 + "-location-cache :"
3776 + " Invalid Argument");
3777 return -1;
3778 }
3779 }
3780
3781 Log.d(LOG_TAG, "handleSetIsSatelliteCommunicationAllowedForCurrentLocationCache("
3782 + state + ")");
3783
3784 try {
3785 boolean result = mInterface.setIsSatelliteCommunicationAllowedForCurrentLocationCache(
3786 state);
3787 if (VDBG) {
3788 Log.v(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache "
3789 + "returns: "
3790 + result);
3791 }
3792 getOutPrintWriter().println(result);
3793 } catch (RemoteException e) {
3794 Log.w(LOG_TAG, "setIsSatelliteCommunicationAllowedForCurrentLocationCache("
3795 + state + "), error = " + e.getMessage());
3796 errPw.println("Exception: " + e.getMessage());
3797 return -1;
3798 }
3799 return 0;
3800 }
3801
Hyosund6aaf062024-08-23 23:02:10 +00003802 private int handleSetSatelliteSubscriberIdListChangedIntentComponent() {
3803 final String cmd = SET_SATELLITE_SUBSCRIBERID_LIST_CHANGED_INTENT_COMPONENT;
3804 PrintWriter errPw = getErrPrintWriter();
3805 String opt;
3806 String name;
3807
3808 if ((opt = getNextArg()) == null) {
3809 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3810 return -1;
3811 } else {
3812 switch (opt) {
3813 case "-p": {
3814 name = opt + "/" + "android.telephony.cts";
3815 break;
3816 }
3817 case "-c": {
3818 name = opt + "/" + "android.telephony.cts.SatelliteReceiver";
3819 break;
3820 }
3821 case "-r": {
3822 name = "reset";
3823 break;
3824 }
3825 default:
3826 errPw.println("adb shell cmd phone " + cmd + ": Invalid Argument");
3827 return -1;
3828 }
3829 }
3830
3831 Log.d(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3832 + name + ")");
3833
3834 try {
3835 boolean result = mInterface.setSatelliteSubscriberIdListChangedIntentComponent(name);
3836 if (VDBG) {
3837 Log.v(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent "
3838 + "returns: " + result);
3839 }
3840 getOutPrintWriter().println(result);
3841 } catch (RemoteException e) {
3842 Log.w(LOG_TAG, "handleSetSatelliteSubscriberIdListChangedIntentComponent("
3843 + name + "), error = " + e.getMessage());
3844 errPw.println("Exception: " + e.getMessage());
3845 return -1;
3846 }
3847 return 0;
3848 }
3849
Thomas Nguyen4f9c89e2023-12-18 10:51:57 -08003850 /**
3851 * Sample inputStr = "US,UK,CA;2,1,3"
3852 * Sample output: {[US,2], [UK,1], [CA,3]}
3853 */
3854 @NonNull private Map<String, Long> parseStringLongMap(@Nullable String inputStr) {
3855 Map<String, Long> result = new HashMap<>();
3856 if (!TextUtils.isEmpty(inputStr)) {
3857 String[] stringLongArr = inputStr.split(";");
3858 if (stringLongArr.length != 2) {
3859 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3860 return result;
3861 }
3862
3863 String[] stringArr = stringLongArr[0].split(",");
3864 String[] longArr = stringLongArr[1].split(",");
3865 if (stringArr.length != longArr.length) {
3866 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr);
3867 return result;
3868 }
3869
3870 for (int i = 0; i < stringArr.length; i++) {
3871 try {
3872 result.put(stringArr[i], Long.parseLong(longArr[i]));
3873 } catch (Exception ex) {
3874 Log.e(LOG_TAG, "parseStringLongMap: invalid inputStr=" + inputStr
3875 + ", ex=" + ex);
3876 return result;
3877 }
3878 }
3879 }
3880 return result;
3881 }
3882
arunvoddud7401012022-12-15 16:08:12 +00003883 private int handleCarrierRestrictionStatusCommand() {
3884 try {
3885 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3886 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3887 mInterface.getModemService()))) {
3888 Log.v(LOG_TAG,
3889 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3890 + " checkShellUid fails");
3891 return -1;
3892 }
3893 } catch (RemoteException ex) {
3894 ex.printStackTrace();
3895 }
3896 String callerInfo = getNextOption();
3897 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3898 if (TextUtils.isEmpty(callerInfo)) {
3899 // reset the Json content after testing
3900 allowListInfo.updateJsonForTest(null);
3901 return 0;
3902 }
3903 if (callerInfo.startsWith("--")) {
3904 callerInfo = callerInfo.replace("--", "");
3905 }
3906 String params[] = callerInfo.split(",");
3907 StringBuffer jsonStrBuffer = new StringBuffer();
3908 String tokens;
3909 for (int index = 0; index < params.length; index++) {
3910 tokens = convertToJsonString(index, params[index]);
3911 if (TextUtils.isEmpty(tokens)) {
3912 // received wrong format from CTS
3913 if (VDBG) {
3914 Log.v(LOG_TAG,
3915 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3916 }
3917 return -1;
3918 }
3919 jsonStrBuffer.append(tokens);
3920 }
3921 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3922 return result;
3923 }
3924
Benedict Wong66477622023-02-03 23:30:57 +00003925 // set-carrier-service-package-override
3926 private int setCarrierServicePackageOverride() {
3927 PrintWriter errPw = getErrPrintWriter();
3928 int subId = SubscriptionManager.getDefaultSubscriptionId();
3929
3930 String opt;
3931 while ((opt = getNextOption()) != null) {
3932 switch (opt) {
3933 case "-s":
3934 try {
3935 subId = Integer.parseInt(getNextArgRequired());
3936 } catch (NumberFormatException e) {
3937 errPw.println(
3938 "set-carrier-service-package-override requires an integer as a"
3939 + " subscription ID.");
3940 return -1;
3941 }
3942 break;
3943 }
3944 }
3945
3946 String packageName = getNextArg();
3947 if (packageName == null) {
3948 errPw.println("set-carrier-service-package-override requires a override package name.");
3949 return -1;
3950 }
3951
3952 try {
3953 mInterface.setCarrierServicePackageOverride(
3954 subId, packageName, mContext.getOpPackageName());
3955
3956 if (VDBG) {
3957 Log.v(
3958 LOG_TAG,
3959 "set-carrier-service-package-override -s " + subId + " " + packageName);
3960 }
3961 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3962 Log.w(
3963 LOG_TAG,
3964 "set-carrier-service-package-override -s "
3965 + subId
3966 + " "
3967 + packageName
3968 + ", error"
3969 + e.getMessage());
3970 errPw.println("Exception: " + e.getMessage());
3971 return -1;
3972 }
3973 return 0;
3974 }
3975
3976 // clear-carrier-service-package-override
3977 private int clearCarrierServicePackageOverride() {
3978 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003979 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003980
3981 String opt;
3982 while ((opt = getNextOption()) != null) {
3983 switch (opt) {
3984 case "-s":
3985 try {
3986 subId = Integer.parseInt(getNextArgRequired());
3987 } catch (NumberFormatException e) {
3988 errPw.println(
3989 "clear-carrier-service-package-override requires an integer as a"
3990 + " subscription ID.");
3991 return -1;
3992 }
3993 break;
3994 }
3995 }
3996
3997 try {
3998 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3999
4000 if (VDBG) {
4001 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
4002 }
4003 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
4004 Log.w(
4005 LOG_TAG,
4006 "clear-carrier-service-package-override -s "
4007 + subId
4008 + ", error"
4009 + e.getMessage());
4010 errPw.println("Exception: " + e.getMessage());
4011 return -1;
4012 }
4013 return 0;
4014 }
arunvoddud7401012022-12-15 16:08:12 +00004015
Hunsuk Choi13078be2023-09-13 10:55:21 +00004016 private int handleDomainSelectionCommand() {
4017 String arg = getNextArg();
4018 if (arg == null) {
4019 onHelpDomainSelection();
4020 return 0;
4021 }
4022
4023 switch (arg) {
4024 case DOMAIN_SELECTION_SET_SERVICE_OVERRIDE: {
4025 return handleDomainSelectionSetServiceOverrideCommand();
4026 }
4027 case DOMAIN_SELECTION_CLEAR_SERVICE_OVERRIDE: {
4028 return handleDomainSelectionClearServiceOverrideCommand();
4029 }
4030 }
4031
4032 return -1;
4033 }
4034
4035 // domainselection set-dss-override
4036 private int handleDomainSelectionSetServiceOverrideCommand() {
4037 PrintWriter errPw = getErrPrintWriter();
4038
4039 String componentName = getNextArg();
4040
4041 try {
4042 boolean result = mInterface.setDomainSelectionServiceOverride(
4043 ComponentName.unflattenFromString(componentName));
4044 if (VDBG) {
4045 Log.v(LOG_TAG, "domainselection set-dss-override "
4046 + componentName + ", result=" + result);
4047 }
4048 getOutPrintWriter().println(result);
4049 } catch (Exception e) {
4050 Log.w(LOG_TAG, "domainselection set-dss-override "
4051 + componentName + ", error=" + e.getMessage());
4052 errPw.println("Exception: " + e.getMessage());
4053 return -1;
4054 }
4055 return 0;
4056 }
4057
4058 // domainselection clear-dss-override
4059 private int handleDomainSelectionClearServiceOverrideCommand() {
4060 PrintWriter errPw = getErrPrintWriter();
4061
4062 try {
4063 boolean result = mInterface.clearDomainSelectionServiceOverride();
4064 if (VDBG) {
4065 Log.v(LOG_TAG, "domainselection clear-dss-override result=" + result);
4066 }
4067 getOutPrintWriter().println(result);
4068 } catch (RemoteException e) {
4069 Log.w(LOG_TAG, "domainselection clear-dss-override error=" + e.getMessage());
4070 errPw.println("Exception: " + e.getMessage());
4071 return -1;
4072 }
4073 return 0;
4074 }
4075
arunvoddud7401012022-12-15 16:08:12 +00004076 /**
4077 * Building the string that can be used to build the JsonObject which supports to stub the data
4078 * in CarrierAllowListInfo for CTS testing. sample format is like
Steve Statia3dcdec92024-03-28 21:38:45 +00004079 * {"com.android.example":{"carrierIds":[10000],"callerSHA256Ids":["XXXXXXXXXXXXXX"]}}
arunvoddud7401012022-12-15 16:08:12 +00004080 */
4081 private String convertToJsonString(int index, String param) {
4082
4083 String token[] = param.split(":");
4084 String jSonString;
4085 switch (index) {
4086 case 0:
4087 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
4088 break;
4089 case 1:
4090 jSonString =
Steve Statia28b7cb32024-03-11 23:58:50 +00004091 "{" + QUOTES + token[0] + QUOTES + ":" + "[" + token[1] + "],";
arunvoddud7401012022-12-15 16:08:12 +00004092 break;
4093 case 2:
4094 jSonString =
4095 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
4096 break;
4097 default:
4098 jSonString = null;
4099 }
4100 return jSonString;
4101 }
arunvoddue3a6dbc2024-09-27 16:27:08 +00004102
4103 /**
4104 * This method override the check for carrier roaming Ntn eligibility.
4105 * <ul>
4106 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result true` will set
4107 * override eligibility to true.</li>
4108 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result false` will
4109 * override eligibility to false.</li>
4110 * <li> `adb shell cmd phone set-satellite-access-restriction-checking-result` will reset the
4111 * override data set through adb command.</li>
4112 * </ul>
4113 *
4114 * @return {@code true} is command executed successfully otherwise {@code false}.
4115 */
4116 private int handleOverrideCarrierRoamingNtnEligibilityChanged() {
4117 PrintWriter errPw = getErrPrintWriter();
4118 String opt;
4119 boolean state = false;
4120 boolean isRestRequired = false;
4121 try {
4122 if ((opt = getNextArg()) == null) {
4123 isRestRequired = true;
4124 } else {
4125 if ("true".equalsIgnoreCase(opt)) {
4126 state = true;
4127 }
4128 }
4129 boolean result = mInterface.overrideCarrierRoamingNtnEligibilityChanged(state,
4130 isRestRequired);
4131 if (VDBG) {
4132 Log.v(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult "
4133 + "returns: "
4134 + result);
4135 }
4136 getOutPrintWriter().println(result);
4137 } catch (RemoteException e) {
4138 Log.w(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult("
4139 + state + "), error = " + e.getMessage());
4140 errPw.println("Exception: " + e.getMessage());
4141 return -1;
4142 }
4143 Log.d(LOG_TAG, "handleSetSatelliteAccessRestrictionCheckingResult(" + state + ")");
4144 return 0;
4145 }
TAKAHASHI Uichiroc4b07452022-08-29 16:03:11 +09004146
4147 private int handleDeleteTestImsiKey() {
4148 if (!(checkShellUid())) {
4149 Log.v(LOG_TAG,
4150 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
4151 + " checkShellUid fails");
4152 return -1;
4153 }
4154
4155 Phone phone = PhoneFactory.getDefaultPhone();
4156 if (phone == null) {
4157 Log.e(LOG_TAG,
4158 "handleCarrierRestrictionStatusCommand" + "No default Phone available");
4159 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
4160 }
4161 phone.resetCarrierKeysForImsiEncryption(true);
4162 return 1;
4163 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07004164}