blob: 5986a7cfdd7062c1ebc60003718e4a75a83b7446 [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;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010027import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080028import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080031import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070032import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000033import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070034import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070035import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010036import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070037import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070038import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000039import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070040import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080041import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000042import android.telephony.ims.ImsException;
43import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080044import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080045import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import android.util.ArrayMap;
47import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070048import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070049import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050
Brad Ebinger14d467f2021-02-12 06:18:28 +000051import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080053import com.android.internal.telephony.Phone;
54import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080055import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080056import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080057import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080058import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080059import com.android.phone.callcomposer.CallComposerPictureManager;
Shivakumar Neginal9cd61892022-12-19 04:38:52 +000060import com.android.phone.euicc.EuiccUiDispatcherActivity;
arunvoddud7401012022-12-15 16:08:12 +000061import com.android.phone.utils.CarrierAllowListInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070062
Allen Xuee00f0e2022-03-14 21:04:49 +000063import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070064import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080065import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000066import java.util.Arrays;
67import java.util.Collections;
Brad Ebinger24c29992019-12-05 13:03:21 -080068import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000069import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010070import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000071import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010072import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080073import java.util.UUID;
74import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070075
76/**
77 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
78 * permission checks have been done before onCommand was called. Make sure any commands processed
79 * here also contain the appropriate permissions checks.
80 */
81
Hall Liua1548bd2019-12-24 14:14:12 -080082public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070083
84 private static final String LOG_TAG = "TelephonyShellCommand";
85 // Don't commit with this true.
86 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070087 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070088
Hall Liuaa4211e2021-01-20 15:43:39 -080089 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070090 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080091 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080092 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080093 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070094 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000095 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000096 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010097 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080098 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080099 private static final String ENABLE = "enable";
100 private static final String DISABLE = "disable";
101 private static final String QUERY = "query";
arunvoddud7401012022-12-15 16:08:12 +0000102 private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
Benedict Wong66477622023-02-03 23:30:57 +0000103 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
104 "set-carrier-service-package-override";
105 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
106 "clear-carrier-service-package-override";
arunvoddud7401012022-12-15 16:08:12 +0000107 private final String QUOTES = "\"";
Hall Liuaa4211e2021-01-20 15:43:39 -0800108
Hall Liu7135e502021-02-04 16:58:17 -0800109 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800110 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800111 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800112
Brad Ebinger999d3302020-11-25 14:31:39 -0800113 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
114 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
115 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700116 // Used to disable or enable processing of conference event package data from the network.
117 // This is handy for testing scenarios where CEP data does not exist on a network which does
118 // support CEP data.
119 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700120
Hall Liud892bec2018-11-30 14:51:45 -0800121 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800122 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800123
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100124 private static final String CC_GET_VALUE = "get-value";
125 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000126 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100127 private static final String CC_CLEAR_VALUES = "clear-values";
128
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000129 private static final String EUICC_SUBCOMMAND = "euicc";
130 private static final String EUICC_SET_UI_COMPONENT = "set-euicc-uicomponent";
131
Hui Wang641e81c2020-10-12 12:14:23 -0700132 private static final String GBA_SUBCOMMAND = "gba";
133 private static final String GBA_SET_SERVICE = "set-service";
134 private static final String GBA_GET_SERVICE = "get-service";
135 private static final String GBA_SET_RELEASE_TIME = "set-release";
136 private static final String GBA_GET_RELEASE_TIME = "get-release";
137
Hui Wang761a6682020-10-31 05:12:53 +0000138 private static final String SINGLE_REGISTATION_CONFIG = "src";
139 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
140 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
141 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
142 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800143 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
144 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800145 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
146 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000147
Tyler Gunn92479152021-01-20 16:30:10 -0800148 private static final String D2D_SUBCOMMAND = "d2d";
149 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800150 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700151 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800152
Nazanin014f41e2021-05-06 17:26:31 -0700153 private static final String BARRING_SUBCOMMAND = "barring";
154 private static final String BARRING_SEND_INFO = "send";
155
James.cf Linbcdf8b32021-01-14 16:44:13 +0800156 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800157 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800158 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800159 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800160 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
161 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000162 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
163 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800164 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
165 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800166 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
167 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800168
jimsun3b9ccac2021-10-26 15:01:23 +0800169 private static final String RADIO_SUBCOMMAND = "radio";
170 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
171 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
172
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800173 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
174 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
175
Jordan Liu0ccee222021-04-27 11:55:13 -0700176 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
177 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
178
Jack Nudelman644b91a2021-03-12 14:09:48 -0800179 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
180 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
181 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700182 private static final String SET_SATELLITE_SERVICE_PACKAGE_NAME =
183 "set-satellite-service-package-name";
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700184 private static final String SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME =
185 "set-satellite-gateway-service-package-name";
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700186 private static final String SET_SATELLITE_LISTENING_TIMEOUT_DURATION =
187 "set-satellite-listening-timeout-duration";
Thomas Nguyen87dce732023-04-20 18:27:16 -0700188 private static final String SET_SATELLITE_POINTING_UI_CLASS_NAME =
189 "set-satellite-pointing-ui-class-name";
Hakjun Choiae365972023-04-25 11:00:31 +0000190 private static final String SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION =
191 "set-satellite-device-aligned-timeout-duration";
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700192 private static final String SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE =
193 "set-emergency-call-to-satellite-handover-type";
Hakjun Choibc6ce992023-11-07 16:04:33 +0000194 private static final String SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE =
195 "set-should-send-datagram-to-modem-in-demo-mode";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800196
Grant Menke567d48f2022-08-18 20:19:10 +0000197 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
198 + "'*', '#' or '+') needs to be specified after -a in the command ";
199
200 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
201 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
202 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
203
SongFerngWang98dd5992021-05-13 17:50:00 +0800204 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
205 "get-allowed-network-types-for-users";
206 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
207 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000208 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000209 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700210 // Take advantage of existing methods that already contain permissions checks when possible.
211 private final ITelephony mInterface;
212
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100213 private SubscriptionManager mSubscriptionManager;
214 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700215 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700216 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100217
218 private enum CcType {
219 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000220 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100221 }
222
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100223 private class CcOptionParseResult {
224 public int mSubId;
225 public boolean mPersistent;
226 }
227
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100228 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
229 // keys by looking at the end of the string which usually tells the type.
230 // For instance: "xxxx_string", "xxxx_string_array", etc.
231 // The carrier config keys in this map does not follow this convention. It is therefore not
232 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700233 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
234 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
235 CcType.STRING),
236 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
237 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
238 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
239 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
240 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
241 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
242 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
243 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
244 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
245 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
246 CcType.STRING),
247 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
248 CcType.STRING_ARRAY),
249 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
250 CcType.STRING_ARRAY),
251 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
252 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
253 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
254 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
255 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
256 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
257 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
258 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100259
Brad Ebinger14d467f2021-02-12 06:18:28 +0000260 /**
261 * Map from a shorthand string to the feature tags required in registration required in order
262 * for the RCS feature to be considered "capable".
263 */
264 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
265 static {
266 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
267 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
268 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
269 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
270 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
271 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
272 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
273 FeatureTags.FEATURE_TAG_VIDEO)));
274 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
275 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
276 map.put("call_comp",
277 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
278 map.put("call_comp_mmtel",
279 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
280 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
281 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
282 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
283 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
284 // version
285 map.put("chatbot", new ArraySet<>(Arrays.asList(
286 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
287 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
288 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
289 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000290 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000291 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
292 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
293 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
294 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
295 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000296 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000297 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
298 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
299 }
300
301
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100302 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700303 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100304 mCarrierConfigManager =
305 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
306 mSubscriptionManager = (SubscriptionManager)
307 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700308 mTelephonyRegistryManager = (TelephonyRegistryManager)
309 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700310 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700311 }
312
313 @Override
314 public int onCommand(String cmd) {
315 if (cmd == null) {
316 return handleDefaultCommands(null);
317 }
318
319 switch (cmd) {
320 case IMS_SUBCOMMAND: {
321 return handleImsCommand();
322 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800323 case RCS_UCE_COMMAND:
324 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800325 case NUMBER_VERIFICATION_SUBCOMMAND:
326 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800327 case EMERGENCY_CALLBACK_MODE:
328 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800329 case EMERGENCY_NUMBER_TEST_MODE:
330 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100331 case CARRIER_CONFIG_SUBCOMMAND: {
332 return handleCcCommand();
333 }
Shuo Qianf5125122019-12-16 17:03:07 -0800334 case DATA_TEST_MODE:
335 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700336 case END_BLOCK_SUPPRESSION:
337 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000338 case EUICC_SUBCOMMAND:
339 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700340 case GBA_SUBCOMMAND:
341 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800342 case D2D_SUBCOMMAND:
343 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700344 case BARRING_SUBCOMMAND:
345 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000346 case SINGLE_REGISTATION_CONFIG:
347 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000348 case RESTART_MODEM:
349 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800350 case CALL_COMPOSER_SUBCOMMAND:
351 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000352 case UNATTENDED_REBOOT:
353 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800354 case HAS_CARRIER_PRIVILEGES_COMMAND:
355 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800356 case THERMAL_MITIGATION_COMMAND:
357 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700358 case DISABLE_PHYSICAL_SUBSCRIPTION:
359 return handleEnablePhysicalSubscription(false);
360 case ENABLE_PHYSICAL_SUBSCRIPTION:
361 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800362 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
363 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
364 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000365 case GET_IMEI:
366 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000367 case GET_SIM_SLOTS_MAPPING:
368 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800369 case RADIO_SUBCOMMAND:
370 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000371 case CARRIER_RESTRICTION_STATUS_TEST:
372 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000373 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
374 return setCarrierServicePackageOverride();
375 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
376 return clearCarrierServicePackageOverride();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700377 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
378 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700379 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
380 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700381 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
382 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700383 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
384 return handleSetSatellitePointingUiClassNameCommand();
Hakjun Choiae365972023-04-25 11:00:31 +0000385 case SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION:
386 return handleSettSatelliteDeviceAlignedTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700387 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
388 return handleSetEmergencyCallToSatelliteHandoverType();
Hakjun Choibc6ce992023-11-07 16:04:33 +0000389 case SET_SHOULD_SEND_DATAGRAM_TO_MODEM_IN_DEMO_MODE:
390 return handleSetShouldSendDatagramToModemInDemoMode();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700391 default: {
392 return handleDefaultCommands(cmd);
393 }
394 }
395 }
396
397 @Override
398 public void onHelp() {
399 PrintWriter pw = getOutPrintWriter();
400 pw.println("Telephony Commands:");
401 pw.println(" help");
402 pw.println(" Print this help text.");
403 pw.println(" ims");
404 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800405 pw.println(" uce");
406 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800407 pw.println(" emergency-number-test-mode");
408 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700409 pw.println(" end-block-suppression");
410 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800411 pw.println(" data");
412 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100413 pw.println(" cc");
414 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700415 pw.println(" gba");
416 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000417 pw.println(" src");
418 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000419 pw.println(" restart-modem");
420 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000421 pw.println(" unattended-reboot");
422 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800423 pw.println(" has-carrier-privileges [package]");
424 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800425 pw.println(" get-allowed-network-types-for-users");
426 pw.println(" Get the Allowed Network Types.");
427 pw.println(" set-allowed-network-types-for-users");
428 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800429 pw.println(" radio");
430 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700431 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800432 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800433 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700434 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800435 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100436 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700437 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000438 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800439 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700440 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800441 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800442 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000443 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700444 onHelpSatellite();
Tyler Gunn92479152021-01-20 16:30:10 -0800445 }
446
447 private void onHelpD2D() {
448 PrintWriter pw = getOutPrintWriter();
449 pw.println("D2D Comms Commands:");
450 pw.println(" d2d send TYPE VALUE");
451 pw.println(" Sends a D2D message of specified type and value.");
452 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
453 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
454 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
455 MESSAGE_CALL_AUDIO_CODEC));
456 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
457 + Communicator.messageToString(
458 MESSAGE_DEVICE_BATTERY_STATE));
459 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
460 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800461 pw.println(" d2d transport TYPE");
462 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
463 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700464 pw.println(" d2d set-device-support true/default");
465 pw.println(" true - forces device support to be enabled for D2D.");
466 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
467 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700468 }
469
Nazanin014f41e2021-05-06 17:26:31 -0700470 private void onHelpBarring() {
471 PrintWriter pw = getOutPrintWriter();
472 pw.println("Barring Commands:");
473 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
474 + " -t CONDITIONAL_BARRING_TIME_SECS");
475 pw.println(" Notifies of a barring info change for the specified slot id.");
476 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
477 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
478 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
479 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
480 }
481
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700482 private void onHelpIms() {
483 PrintWriter pw = getOutPrintWriter();
484 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800485 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700486 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
487 pw.println(" ImsService. Options are:");
488 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
489 pw.println(" is specified, it will choose the default voice SIM slot.");
490 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
491 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800492 pw.println(" -f: Set the feature that this override if for, if no option is");
493 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700494 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
495 pw.println(" Gets the package name of the currently defined ImsService.");
496 pw.println(" Options are:");
497 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
498 pw.println(" is specified, it will choose the default voice SIM slot.");
499 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000500 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800501 pw.println(" -f: The feature type that the query will be requested for. If none is");
502 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800503 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
504 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
505 pw.println(" configuration overrides. Options are:");
506 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
507 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700508 pw.println(" ims enable [-s SLOT_ID]");
509 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
510 pw.println(" if none is specified.");
511 pw.println(" ims disable [-s SLOT_ID]");
512 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
513 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700514 pw.println(" ims conference-event-package [enable/disable]");
515 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700516 }
517
James.cf Linbcdf8b32021-01-14 16:44:13 +0800518 private void onHelpUce() {
519 PrintWriter pw = getOutPrintWriter();
520 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800521 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
522 pw.println(" Get the EAB contacts from the EAB database.");
523 pw.println(" Options are:");
524 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
525 pw.println(" Expected output format :");
526 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800527 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
528 pw.println(" Remove the EAB contacts from the EAB database.");
529 pw.println(" Options are:");
530 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
531 pw.println(" is specified, it will choose the default voice SIM slot.");
532 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800533 pw.println(" uce get-device-enabled");
534 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
535 pw.println(" uce set-device-enabled true|false");
536 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
537 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000538 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
539 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
540 pw.println(" Options are:");
541 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
543 pw.println(" add [CAPABILITY]: add a new capability");
544 pw.println(" remove [CAPABILITY]: remove a capability");
545 pw.println(" clear: clear all capability overrides");
546 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
547 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
548 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
549 pw.println(" chatbot_sa, chatbot_role] as well as full length");
550 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
551 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
552 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
553 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800554 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
555 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800556 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
557 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800558 }
559
Hall Liud892bec2018-11-30 14:51:45 -0800560 private void onHelpNumberVerification() {
561 PrintWriter pw = getOutPrintWriter();
562 pw.println("Number verification commands");
563 pw.println(" numverify override-package PACKAGE_NAME;");
564 pw.println(" Set the authorized package for number verification.");
565 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800566 pw.println(" numverify fake-call NUMBER;");
567 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
568 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800569 }
570
Jack Nudelman644b91a2021-03-12 14:09:48 -0800571 private void onHelpThermalMitigation() {
572 PrintWriter pw = getOutPrintWriter();
573 pw.println("Thermal mitigation commands");
574 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
575 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
576 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
577 pw.println(" Remove the package from one of the authorized packages for thermal "
578 + "mitigation.");
579 }
580
Jordan Liu0ccee222021-04-27 11:55:13 -0700581 private void onHelpDisableOrEnablePhysicalSubscription() {
582 PrintWriter pw = getOutPrintWriter();
583 pw.println("Disable or enable a physical subscription");
584 pw.println(" disable-physical-subscription SUB_ID");
585 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
586 pw.println(" enable-physical-subscription SUB_ID");
587 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
588 }
589
Shuo Qianf5125122019-12-16 17:03:07 -0800590 private void onHelpDataTestMode() {
591 PrintWriter pw = getOutPrintWriter();
592 pw.println("Mobile Data Test Mode Commands:");
593 pw.println(" data enable: enable mobile data connectivity");
594 pw.println(" data disable: disable mobile data connectivity");
595 }
596
sqian9d4df8b2019-01-15 18:32:07 -0800597 private void onHelpEmergencyNumber() {
598 PrintWriter pw = getOutPrintWriter();
599 pw.println("Emergency Number Test Mode Commands:");
600 pw.println(" emergency-number-test-mode ");
601 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
602 + " the test mode");
603 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700604 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800605 pw.println(" -c: clear the emergency number list in the test mode.");
606 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700607 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800608 pw.println(" -p: get the full emergency number list in the test mode.");
609 }
610
Shuo Qian489d9282020-07-09 11:30:03 -0700611 private void onHelpEndBlockSupperssion() {
612 PrintWriter pw = getOutPrintWriter();
613 pw.println("End Block Suppression command:");
614 pw.println(" end-block-suppression: disable suppressing blocking by contact");
615 pw.println(" with emergency services.");
616 }
617
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100618 private void onHelpCc() {
619 PrintWriter pw = getOutPrintWriter();
620 pw.println("Carrier Config Commands:");
621 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
622 pw.println(" Print carrier config values.");
623 pw.println(" Options are:");
624 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
625 pw.println(" is specified, it will choose the default voice SIM slot.");
626 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
627 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100628 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100629 pw.println(" Set carrier config KEY to NEW_VALUE.");
630 pw.println(" Options are:");
631 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
632 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100633 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100634 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
635 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
636 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
637 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000638 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
639 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
640 pw.println(" provided through standard input and follow CarrierConfig XML format.");
641 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
642 pw.println(" Options are:");
643 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
644 pw.println(" is specified, it will choose the default voice SIM slot.");
645 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100646 pw.println(" cc clear-values [-s SLOT_ID]");
647 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000648 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100649 pw.println(" Options are:");
650 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
651 pw.println(" is specified, it will choose the default voice SIM slot.");
652 }
653
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000654 private void onHelpEuicc() {
655 PrintWriter pw = getOutPrintWriter();
656 pw.println("Euicc Commands:");
657 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
658 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
659 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
660 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
661 }
662
Hui Wang641e81c2020-10-12 12:14:23 -0700663 private void onHelpGba() {
664 PrintWriter pw = getOutPrintWriter();
665 pw.println("Gba Commands:");
666 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
667 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
668 pw.println(" Options are:");
669 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
670 pw.println(" is specified, it will choose the default voice SIM slot.");
671 pw.println(" gba get-service [-s SLOT_ID]");
672 pw.println(" Gets the package name of the currently defined GbaService.");
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(" gba set-release [-s SLOT_ID] n");
677 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
678 pw.println(" Do not release/unbind if n is -1.");
679 pw.println(" Options are:");
680 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
681 pw.println(" is specified, it will choose the default voice SIM slot.");
682 pw.println(" gba get-release [-s SLOT_ID]");
683 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
684 pw.println(" Options are:");
685 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
686 pw.println(" is specified, it will choose the default voice SIM slot.");
687 }
688
Hui Wang761a6682020-10-31 05:12:53 +0000689 private void onHelpSrc() {
690 PrintWriter pw = getOutPrintWriter();
691 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800692 pw.println(" src set-test-enabled true|false");
693 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
694 pw.println(" The value could be true, false, or null(undefined).");
695 pw.println(" src get-test-enabled");
696 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000697 pw.println(" src set-device-enabled true|false|null");
698 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
699 pw.println(" The value could be true, false, or null(undefined).");
700 pw.println(" src get-device-enabled");
701 pw.println(" Gets the device config for RCS VoLTE single registration.");
702 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
703 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
704 pw.println(" The value could be true, false, or null(undefined).");
705 pw.println(" Options are:");
706 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
707 pw.println(" is specified, it will choose the default voice SIM slot.");
708 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
709 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
710 pw.println(" Options are:");
711 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
712 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800713 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
714 pw.println(" Sets ims feature validation result.");
715 pw.println(" The value could be true, false, or null(undefined).");
716 pw.println(" Options are:");
717 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
718 pw.println(" is specified, it will choose the default voice SIM slot.");
719 pw.println(" src get-feature-validation [-s SLOT_ID]");
720 pw.println(" Gets ims feature validation override value.");
721 pw.println(" Options are:");
722 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
723 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000724 }
725
SongFerngWang98dd5992021-05-13 17:50:00 +0800726 private void onHelpAllowedNetworkTypes() {
727 PrintWriter pw = getOutPrintWriter();
728 pw.println("Allowed Network Types Commands:");
729 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
730 pw.println(" Print allowed network types value.");
731 pw.println(" Options are:");
732 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
733 pw.println(" option is specified, it will choose the default voice SIM slot.");
734 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
735 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
736 pw.println(" Options are:");
737 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
738 pw.println(" option is specified, it will choose the default voice SIM slot.");
739 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
740 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
741 pw.println(" at TelephonyManager.java");
742 pw.println(" For example:");
743 pw.println(" NR only : 10000000000000000000");
744 pw.println(" NR|LTE : 11000001000000000000");
745 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
746 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
747 pw.println(" LTE only : 01000001000000000000");
748 }
749
jimsun3b9ccac2021-10-26 15:01:23 +0800750 private void onHelpRadio() {
751 PrintWriter pw = getOutPrintWriter();
752 pw.println("Radio Commands:");
753 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
754 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
755 pw.println(" to be the bound. Options are:");
756 pw.println(" -s: the service name that the modem service should be bound for.");
757 pw.println(" If no option is specified, it will bind to the default.");
758 pw.println(" radio get-modem-service");
759 pw.println(" Gets the service name of the currently defined modem service.");
760 pw.println(" If it is binding to default, 'default' returns.");
761 pw.println(" If it doesn't bind to any modem service for some reasons,");
762 pw.println(" the result would be 'unknown'.");
763 }
764
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700765 private void onHelpSatellite() {
766 PrintWriter pw = getOutPrintWriter();
767 pw.println("Satellite Commands:");
768 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
769 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700770 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700771 pw.println(" -s: the satellite service package name that Telephony will bind to.");
772 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700773 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
774 pw.println(" Sets the package name of satellite gateway service defined in");
775 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
776 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
777 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700778 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
779 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
780 pw.println(" mode. Options are:");
781 pw.println(" -t: the timeout duration in milliseconds.");
782 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700783 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
784 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
785 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
786 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
787 pw.println(" launch. If no option is specified, it will launch the default.");
788 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
789 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700790 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
791 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
792 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
793 pw.println(" Options are:");
794 pw.println(" -t: the emergency call to satellite handover type.");
795 pw.println(" If no option is specified, override is disabled.");
796 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
797 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700798 }
799
Ling Ma4fbab492022-01-25 22:36:16 +0000800 private void onHelpImei() {
801 PrintWriter pw = getOutPrintWriter();
802 pw.println("IMEI Commands:");
803 pw.println(" get-imei [-s SLOT_ID]");
804 pw.println(" Gets the device IMEI. Options are:");
805 pw.println(" -s: the slot ID to get the IMEI. If no option");
806 pw.println(" is specified, it will choose the default voice SIM slot.");
807 }
808
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700809 private int handleImsCommand() {
810 String arg = getNextArg();
811 if (arg == null) {
812 onHelpIms();
813 return 0;
814 }
815
816 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800817 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700818 return handleImsSetServiceCommand();
819 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800820 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700821 return handleImsGetServiceCommand();
822 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800823 case IMS_CLEAR_SERVICE_OVERRIDE: {
824 return handleImsClearCarrierServiceCommand();
825 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800826 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700827 return handleEnableIms();
828 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800829 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700830 return handleDisableIms();
831 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700832 case IMS_CEP: {
833 return handleCepChange();
834 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700835 }
836
837 return -1;
838 }
839
Shuo Qianf5125122019-12-16 17:03:07 -0800840 private int handleDataTestModeCommand() {
841 PrintWriter errPw = getErrPrintWriter();
842 String arg = getNextArgRequired();
843 if (arg == null) {
844 onHelpDataTestMode();
845 return 0;
846 }
847 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800848 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800849 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700850 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800851 } catch (RemoteException ex) {
852 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
853 errPw.println("Exception: " + ex.getMessage());
854 return -1;
855 }
856 break;
857 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800858 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800859 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700860 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800861 } catch (RemoteException ex) {
862 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
863 errPw.println("Exception: " + ex.getMessage());
864 return -1;
865 }
866 break;
867 }
868 default:
869 onHelpDataTestMode();
870 break;
871 }
872 return 0;
873 }
874
Shuo Qianccbaf742021-02-22 18:32:21 -0800875 private int handleEmergencyCallbackModeCommand() {
876 PrintWriter errPw = getErrPrintWriter();
877 try {
878 mInterface.startEmergencyCallbackMode();
879 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
880 } catch (RemoteException ex) {
881 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
882 errPw.println("Exception: " + ex.getMessage());
883 return -1;
884 }
885 return 0;
886 }
887
Grant Menke567d48f2022-08-18 20:19:10 +0000888 private void removeEmergencyNumberTestMode(String emergencyNumber) {
889 PrintWriter errPw = getErrPrintWriter();
890 for (int routingType : ROUTING_TYPES) {
891 try {
892 mInterface.updateEmergencyNumberListTestMode(
893 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
894 new EmergencyNumber(emergencyNumber, "", "",
895 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
896 new ArrayList<String>(),
897 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
898 routingType));
899 } catch (RemoteException ex) {
900 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
901 errPw.println("Exception: " + ex.getMessage());
902 }
903 }
904 }
905
sqian9d4df8b2019-01-15 18:32:07 -0800906 private int handleEmergencyNumberTestModeCommand() {
907 PrintWriter errPw = getErrPrintWriter();
908 String opt = getNextOption();
909 if (opt == null) {
910 onHelpEmergencyNumber();
911 return 0;
912 }
sqian9d4df8b2019-01-15 18:32:07 -0800913 switch (opt) {
914 case "-a": {
915 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000916 if (emergencyNumberCmd == null){
917 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800918 return -1;
919 }
Grant Menke567d48f2022-08-18 20:19:10 +0000920 String[] params = emergencyNumberCmd.split(":");
921 String emergencyNumber;
922 if (params[0] == null ||
923 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
924 errPw.println(INVALID_ENTRY_ERROR);
925 return -1;
926 } else {
927 emergencyNumber = params[0];
928 }
929 removeEmergencyNumberTestMode(emergencyNumber);
930 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
931 if (params.length > 1) {
932 switch (params[1].toLowerCase(Locale.ROOT)) {
933 case "emergency":
934 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
935 break;
936 case "normal":
937 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
938 break;
939 case "unknown":
940 break;
941 default:
942 errPw.println("\"" + params[1] + "\" is not a valid specification for "
943 + "emergency call routing. Please enter either \"normal\", "
944 + "\"unknown\", or \"emergency\" for call routing. "
945 + "(-a 1234:normal)");
946 return -1;
947 }
948 }
sqian9d4df8b2019-01-15 18:32:07 -0800949 try {
950 mInterface.updateEmergencyNumberListTestMode(
951 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +0000952 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -0800953 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
954 new ArrayList<String>(),
955 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +0000956 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -0800957 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +0000958 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -0800959 + ", error " + ex.getMessage());
960 errPw.println("Exception: " + ex.getMessage());
961 return -1;
962 }
963 break;
964 }
965 case "-c": {
966 try {
967 mInterface.updateEmergencyNumberListTestMode(
968 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
969 } catch (RemoteException ex) {
970 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
971 errPw.println("Exception: " + ex.getMessage());
972 return -1;
973 }
974 break;
975 }
976 case "-r": {
977 String emergencyNumberCmd = getNextArgRequired();
978 if (emergencyNumberCmd == null
979 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700980 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800981 + " to be specified after -r in the command ");
982 return -1;
983 }
Grant Menke567d48f2022-08-18 20:19:10 +0000984 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -0800985 break;
986 }
987 case "-p": {
988 try {
989 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
990 } catch (RemoteException ex) {
991 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
992 errPw.println("Exception: " + ex.getMessage());
993 return -1;
994 }
995 break;
996 }
997 default:
998 onHelpEmergencyNumber();
999 break;
1000 }
1001 return 0;
1002 }
1003
Hall Liud892bec2018-11-30 14:51:45 -08001004 private int handleNumberVerificationCommand() {
1005 String arg = getNextArg();
1006 if (arg == null) {
1007 onHelpNumberVerification();
1008 return 0;
1009 }
1010
Hall Liuca5af3a2018-12-04 16:58:23 -08001011 if (!checkShellUid()) {
1012 return -1;
1013 }
1014
Hall Liud892bec2018-11-30 14:51:45 -08001015 switch (arg) {
1016 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001017 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1018 return 0;
1019 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001020 case NUMBER_VERIFICATION_FAKE_CALL: {
1021 boolean val = NumberVerificationManager.getInstance()
1022 .checkIncomingCall(getNextArg());
1023 getOutPrintWriter().println(val ? "1" : "0");
1024 return 0;
1025 }
Hall Liud892bec2018-11-30 14:51:45 -08001026 }
1027
1028 return -1;
1029 }
1030
Jordan Liu0ccee222021-04-27 11:55:13 -07001031 private boolean subIsEsim(int subId) {
1032 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1033 if (info != null) {
1034 return info.isEmbedded();
1035 }
1036 return false;
1037 }
1038
1039 private int handleEnablePhysicalSubscription(boolean enable) {
1040 PrintWriter errPw = getErrPrintWriter();
1041 int subId = 0;
1042 try {
1043 subId = Integer.parseInt(getNextArgRequired());
1044 } catch (NumberFormatException e) {
1045 errPw.println((enable ? "enable" : "disable")
1046 + "-physical-subscription requires an integer as a subId.");
1047 return -1;
1048 }
1049 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1050 // non user build.
1051 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1052 errPw.println("cc: Permission denied.");
1053 return -1;
1054 }
1055 // Verify that the subId represents a physical sub
1056 if (subIsEsim(subId)) {
1057 errPw.println("SubId " + subId + " is not for a physical subscription");
1058 return -1;
1059 }
1060 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1061 + " physical subscription with subId=" + subId);
1062 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1063 return 0;
1064 }
1065
Jack Nudelman644b91a2021-03-12 14:09:48 -08001066 private int handleThermalMitigationCommand() {
1067 String arg = getNextArg();
1068 String packageName = getNextArg();
1069 if (arg == null || packageName == null) {
1070 onHelpThermalMitigation();
1071 return 0;
1072 }
1073
1074 if (!checkShellUid()) {
1075 return -1;
1076 }
1077
1078 switch (arg) {
1079 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1080 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1081 return 0;
1082 }
1083 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1084 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1085 mContext);
1086 return 0;
1087 }
1088 default:
1089 onHelpThermalMitigation();
1090 }
1091
1092 return -1;
1093
1094 }
1095
Tyler Gunn92479152021-01-20 16:30:10 -08001096 private int handleD2dCommand() {
1097 String arg = getNextArg();
1098 if (arg == null) {
1099 onHelpD2D();
1100 return 0;
1101 }
1102
1103 switch (arg) {
1104 case D2D_SEND: {
1105 return handleD2dSendCommand();
1106 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001107 case D2D_TRANSPORT: {
1108 return handleD2dTransportCommand();
1109 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001110 case D2D_SET_DEVICE_SUPPORT: {
1111 return handleD2dDeviceSupportedCommand();
1112 }
Tyler Gunn92479152021-01-20 16:30:10 -08001113 }
1114
1115 return -1;
1116 }
1117
1118 private int handleD2dSendCommand() {
1119 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001120 int messageType = -1;
1121 int messageValue = -1;
1122
Tyler Gunn92479152021-01-20 16:30:10 -08001123 String arg = getNextArg();
1124 if (arg == null) {
1125 onHelpD2D();
1126 return 0;
1127 }
1128 try {
1129 messageType = Integer.parseInt(arg);
1130 } catch (NumberFormatException e) {
1131 errPw.println("message type must be a valid integer");
1132 return -1;
1133 }
1134
1135 arg = getNextArg();
1136 if (arg == null) {
1137 onHelpD2D();
1138 return 0;
1139 }
1140 try {
1141 messageValue = Integer.parseInt(arg);
1142 } catch (NumberFormatException e) {
1143 errPw.println("message value must be a valid integer");
1144 return -1;
1145 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001146
Tyler Gunn92479152021-01-20 16:30:10 -08001147 try {
1148 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1149 } catch (RemoteException e) {
1150 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1151 errPw.println("Exception: " + e.getMessage());
1152 return -1;
1153 }
1154
1155 return 0;
1156 }
1157
Tyler Gunnbabbda02021-02-10 11:05:02 -08001158 private int handleD2dTransportCommand() {
1159 PrintWriter errPw = getErrPrintWriter();
1160
1161 String arg = getNextArg();
1162 if (arg == null) {
1163 onHelpD2D();
1164 return 0;
1165 }
1166
1167 try {
1168 mInterface.setActiveDeviceToDeviceTransport(arg);
1169 } catch (RemoteException e) {
1170 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1171 errPw.println("Exception: " + e.getMessage());
1172 return -1;
1173 }
1174 return 0;
1175 }
Nazanin014f41e2021-05-06 17:26:31 -07001176 private int handleBarringCommand() {
1177 String arg = getNextArg();
1178 if (arg == null) {
1179 onHelpBarring();
1180 return 0;
1181 }
1182
1183 switch (arg) {
1184 case BARRING_SEND_INFO: {
1185 return handleBarringSendCommand();
1186 }
1187 }
1188 return -1;
1189 }
1190
1191 private int handleBarringSendCommand() {
1192 PrintWriter errPw = getErrPrintWriter();
1193 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001194 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001195 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1196 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1197 boolean isConditionallyBarred = false;
1198 int conditionalBarringTimeSeconds = 0;
1199
1200 String opt;
1201 while ((opt = getNextOption()) != null) {
1202 switch (opt) {
1203 case "-s": {
1204 try {
1205 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001206 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001207 } catch (NumberFormatException e) {
1208 errPw.println("barring send requires an integer as a SLOT_ID.");
1209 return -1;
1210 }
1211 break;
1212 }
1213 case "-b": {
1214 try {
1215 barringType = Integer.parseInt(getNextArgRequired());
1216 if (barringType < -1 || barringType > 2) {
1217 throw new NumberFormatException();
1218 }
1219
1220 } catch (NumberFormatException e) {
1221 errPw.println("barring send requires an integer in range [-1,2] as "
1222 + "a BARRING_TYPE.");
1223 return -1;
1224 }
1225 break;
1226 }
1227 case "-c": {
1228 try {
1229 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1230 } catch (Exception e) {
1231 errPw.println("barring send requires a boolean after -c indicating"
1232 + " conditional barring");
1233 return -1;
1234 }
1235 break;
1236 }
1237 case "-t": {
1238 try {
1239 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1240 } catch (NumberFormatException e) {
1241 errPw.println("barring send requires an integer for time of barring"
1242 + " in seconds after -t for conditional barring");
1243 return -1;
1244 }
1245 break;
1246 }
1247 }
1248 }
1249 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1250 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1251 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1252 barringServiceInfos.append(0, bsi);
1253 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1254 try {
1255 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1256 } catch (Exception e) {
1257 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1258 errPw.println("Exception: " + e.getMessage());
1259 return -1;
1260 }
1261 return 0;
1262 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001263
Tyler Gunnd4575212021-05-03 14:46:49 -07001264 private int handleD2dDeviceSupportedCommand() {
1265 PrintWriter errPw = getErrPrintWriter();
1266
1267 String arg = getNextArg();
1268 if (arg == null) {
1269 onHelpD2D();
1270 return 0;
1271 }
1272
Jack Yua533d632022-09-30 13:53:46 -07001273 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001274 try {
1275 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1276 } catch (RemoteException e) {
1277 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1278 errPw.println("Exception: " + e.getMessage());
1279 return -1;
1280 }
1281 return 0;
1282 }
1283
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001284 // ims set-ims-service
1285 private int handleImsSetServiceCommand() {
1286 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001287 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001288 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001289 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001290
1291 String opt;
1292 while ((opt = getNextOption()) != null) {
1293 switch (opt) {
1294 case "-s": {
1295 try {
1296 slotId = Integer.parseInt(getNextArgRequired());
1297 } catch (NumberFormatException e) {
1298 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1299 return -1;
1300 }
1301 break;
1302 }
1303 case "-c": {
1304 isCarrierService = true;
1305 break;
1306 }
1307 case "-d": {
1308 isCarrierService = false;
1309 break;
1310 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001311 case "-f": {
1312 String featureString = getNextArgRequired();
1313 String[] features = featureString.split(",");
1314 for (int i = 0; i < features.length; i++) {
1315 try {
1316 Integer result = Integer.parseInt(features[i]);
1317 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1318 || result >= ImsFeature.FEATURE_MAX) {
1319 errPw.println("ims set-ims-service -f " + result
1320 + " is an invalid feature.");
1321 return -1;
1322 }
1323 featuresList.add(result);
1324 } catch (NumberFormatException e) {
1325 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1326 + " as an integer.");
1327 return -1;
1328 }
1329 }
1330 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001331 }
1332 }
1333 // Mandatory param, either -c or -d
1334 if (isCarrierService == null) {
1335 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1336 return -1;
1337 }
1338
1339 String packageName = getNextArg();
1340
1341 try {
1342 if (packageName == null) {
1343 packageName = "";
1344 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001345 int[] featureArray = new int[featuresList.size()];
1346 for (int i = 0; i < featuresList.size(); i++) {
1347 featureArray[i] = featuresList.get(i);
1348 }
1349 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1350 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001351 if (VDBG) {
1352 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001353 + (isCarrierService ? "-c " : "-d ")
1354 + "-f " + featuresList + " "
1355 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001356 }
1357 getOutPrintWriter().println(result);
1358 } catch (RemoteException e) {
1359 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001360 + (isCarrierService ? "-c " : "-d ")
1361 + "-f " + featuresList + " "
1362 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001363 errPw.println("Exception: " + e.getMessage());
1364 return -1;
1365 }
1366 return 0;
1367 }
1368
Brad Ebinger999d3302020-11-25 14:31:39 -08001369 // ims clear-ims-service-override
1370 private int handleImsClearCarrierServiceCommand() {
1371 PrintWriter errPw = getErrPrintWriter();
1372 int slotId = getDefaultSlot();
1373
1374 String opt;
1375 while ((opt = getNextOption()) != null) {
1376 switch (opt) {
1377 case "-s": {
1378 try {
1379 slotId = Integer.parseInt(getNextArgRequired());
1380 } catch (NumberFormatException e) {
1381 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1382 return -1;
1383 }
1384 break;
1385 }
1386 }
1387 }
1388
1389 try {
1390 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1391 if (VDBG) {
1392 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1393 + ", result=" + result);
1394 }
1395 getOutPrintWriter().println(result);
1396 } catch (RemoteException e) {
1397 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1398 + ", error" + e.getMessage());
1399 errPw.println("Exception: " + e.getMessage());
1400 return -1;
1401 }
1402 return 0;
1403 }
1404
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001405 // ims get-ims-service
1406 private int handleImsGetServiceCommand() {
1407 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001408 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001409 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001410 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001411
1412 String opt;
1413 while ((opt = getNextOption()) != null) {
1414 switch (opt) {
1415 case "-s": {
1416 try {
1417 slotId = Integer.parseInt(getNextArgRequired());
1418 } catch (NumberFormatException e) {
1419 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1420 return -1;
1421 }
1422 break;
1423 }
1424 case "-c": {
1425 isCarrierService = true;
1426 break;
1427 }
1428 case "-d": {
1429 isCarrierService = false;
1430 break;
1431 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001432 case "-f": {
1433 try {
1434 featureType = Integer.parseInt(getNextArg());
1435 } catch (NumberFormatException e) {
1436 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1437 return -1;
1438 }
1439 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1440 || featureType >= ImsFeature.FEATURE_MAX) {
1441 errPw.println("ims get-ims-service -f invalid feature.");
1442 return -1;
1443 }
1444 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001445 }
1446 }
1447 // Mandatory param, either -c or -d
1448 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001449 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001450 return -1;
1451 }
1452
1453 String result;
1454 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001455 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001456 } catch (RemoteException e) {
1457 return -1;
1458 }
1459 if (VDBG) {
1460 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001461 + (isCarrierService ? "-c " : "-d ")
1462 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1463 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001464 }
1465 getOutPrintWriter().println(result);
1466 return 0;
1467 }
1468
1469 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001470 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001471 String opt;
1472 while ((opt = getNextOption()) != null) {
1473 switch (opt) {
1474 case "-s": {
1475 try {
1476 slotId = Integer.parseInt(getNextArgRequired());
1477 } catch (NumberFormatException e) {
1478 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1479 return -1;
1480 }
1481 break;
1482 }
1483 }
1484 }
1485 try {
1486 mInterface.enableIms(slotId);
1487 } catch (RemoteException e) {
1488 return -1;
1489 }
1490 if (VDBG) {
1491 Log.v(LOG_TAG, "ims enable -s " + slotId);
1492 }
1493 return 0;
1494 }
1495
1496 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001497 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001498 String opt;
1499 while ((opt = getNextOption()) != null) {
1500 switch (opt) {
1501 case "-s": {
1502 try {
1503 slotId = Integer.parseInt(getNextArgRequired());
1504 } catch (NumberFormatException e) {
1505 getErrPrintWriter().println(
1506 "ims disable requires an integer as a SLOT_ID.");
1507 return -1;
1508 }
1509 break;
1510 }
1511 }
1512 }
1513 try {
1514 mInterface.disableIms(slotId);
1515 } catch (RemoteException e) {
1516 return -1;
1517 }
1518 if (VDBG) {
1519 Log.v(LOG_TAG, "ims disable -s " + slotId);
1520 }
1521 return 0;
1522 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001523
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001524 private int handleCepChange() {
1525 Log.i(LOG_TAG, "handleCepChange");
1526 String opt = getNextArg();
1527 if (opt == null) {
1528 return -1;
1529 }
1530 boolean isCepEnabled = opt.equals("enable");
1531
1532 try {
1533 mInterface.setCepEnabled(isCepEnabled);
1534 } catch (RemoteException e) {
1535 return -1;
1536 }
1537 return 0;
1538 }
1539
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001540 private int getDefaultSlot() {
1541 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1542 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1543 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1544 // If there is no default, default to slot 0.
1545 slotId = DEFAULT_PHONE_ID;
1546 }
1547 return slotId;
1548 }
sqian2fff4a32018-11-05 14:18:37 -08001549
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001550 // Parse options related to Carrier Config Commands.
1551 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001552 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001553 CcOptionParseResult result = new CcOptionParseResult();
1554 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1555 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001556
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001557 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001558 while ((opt = getNextOption()) != null) {
1559 switch (opt) {
1560 case "-s": {
1561 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001562 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1563 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1564 errPw.println(tag + "No valid subscription found.");
1565 return null;
1566 }
1567
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001568 } catch (IllegalArgumentException e) {
1569 // Missing slot id
1570 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001571 return null;
1572 }
1573 break;
1574 }
1575 case "-p": {
1576 if (allowOptionPersistent) {
1577 result.mPersistent = true;
1578 } else {
1579 errPw.println(tag + "Unexpected option " + opt);
1580 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001581 }
1582 break;
1583 }
1584 default: {
1585 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001586 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001587 }
1588 }
1589 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001590 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001591 }
1592
1593 private int slotStringToSubId(String tag, String slotString) {
1594 int slotId = -1;
1595 try {
1596 slotId = Integer.parseInt(slotString);
1597 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001598 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1599 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1600 }
1601
1602 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001603 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1604 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1605 }
1606
Qiong Liuf25799b2020-09-10 10:13:46 +08001607 Phone phone = PhoneFactory.getPhone(slotId);
1608 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001609 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1610 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1611 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001612 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001613 }
1614
Hall Liud892bec2018-11-30 14:51:45 -08001615 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001616 // adb can run as root or as shell, depending on whether the device is rooted.
1617 return Binder.getCallingUid() == Process.SHELL_UID
1618 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001619 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001620
1621 private int handleCcCommand() {
1622 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1623 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001624 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001625 getErrPrintWriter().println("cc: Permission denied.");
1626 return -1;
1627 }
1628
1629 String arg = getNextArg();
1630 if (arg == null) {
1631 onHelpCc();
1632 return 0;
1633 }
1634
1635 switch (arg) {
1636 case CC_GET_VALUE: {
1637 return handleCcGetValue();
1638 }
1639 case CC_SET_VALUE: {
1640 return handleCcSetValue();
1641 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001642 case CC_SET_VALUES_FROM_XML: {
1643 return handleCcSetValuesFromXml();
1644 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001645 case CC_CLEAR_VALUES: {
1646 return handleCcClearValues();
1647 }
1648 default: {
1649 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1650 }
1651 }
1652 return -1;
1653 }
1654
1655 // cc get-value
1656 private int handleCcGetValue() {
1657 PrintWriter errPw = getErrPrintWriter();
1658 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1659 String key = null;
1660
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001661 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001662 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001663 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001664 return -1;
1665 }
1666
1667 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001668 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001669 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001670 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001671 return -1;
1672 }
1673
1674 // Get the key.
1675 key = getNextArg();
1676 if (key != null) {
1677 // A key was provided. Verify if it is a valid key
1678 if (!bundle.containsKey(key)) {
1679 errPw.println(tag + key + " is not a valid key.");
1680 return -1;
1681 }
1682
1683 // Print the carrier config value for key.
1684 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1685 } else {
1686 // No key provided. Show all values.
1687 // Iterate over a sorted list of all carrier config keys and print them.
1688 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1689 for (String k : sortedSet) {
1690 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1691 }
1692 }
1693 return 0;
1694 }
1695
1696 // cc set-value
1697 private int handleCcSetValue() {
1698 PrintWriter errPw = getErrPrintWriter();
1699 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1700
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001701 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001702 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001703 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001704 return -1;
1705 }
1706
1707 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001708 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001709 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001710 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001711 return -1;
1712 }
1713
1714 // Get the key.
1715 String key = getNextArg();
1716 if (key == null || key.equals("")) {
1717 errPw.println(tag + "KEY is missing");
1718 return -1;
1719 }
1720
1721 // Verify if the key is valid
1722 if (!originalValues.containsKey(key)) {
1723 errPw.println(tag + key + " is not a valid key.");
1724 return -1;
1725 }
1726
1727 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1728 ArrayList<String> valueList = new ArrayList<String>();
1729 while (peekNextArg() != null) {
1730 valueList.add(getNextArg());
1731 }
1732
1733 // Find the type of the carrier config value
1734 CcType type = getType(tag, key, originalValues);
1735 if (type == CcType.UNKNOWN) {
1736 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1737 return -1;
1738 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001739 if (type == CcType.PERSISTABLE_BUNDLE) {
1740 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1741 + "Use set-values-from-xml instead.");
1742 return -1;
1743 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001744
1745 // Create an override bundle containing the key and value that should be overriden.
1746 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1747 if (overrideBundle == null) {
1748 return -1;
1749 }
1750
1751 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001752 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001753
1754 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001755 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001756 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001757 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001758 return -1;
1759 }
1760
1761 // Print the original and new value.
1762 String originalValueString = ccValueToString(key, type, originalValues);
1763 String newValueString = ccValueToString(key, type, newValues);
1764 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1765 getOutPrintWriter().println("New value: \n" + newValueString);
1766
1767 return 0;
1768 }
1769
Allen Xuee00f0e2022-03-14 21:04:49 +00001770 // cc set-values-from-xml
1771 private int handleCcSetValuesFromXml() {
1772 PrintWriter errPw = getErrPrintWriter();
1773 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1774
1775 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001776 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001777 if (options == null) {
1778 return -1;
1779 }
1780
1781 // Get bundle containing all current carrier configuration values.
1782 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1783 if (originalValues == null) {
1784 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1785 return -1;
1786 }
1787
1788 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1789 if (overrideBundle == null) {
1790 return -1;
1791 }
1792
1793 // Verify all values are valid types
1794 for (String key : overrideBundle.keySet()) {
1795 CcType type = getType(tag, key, originalValues);
1796 if (type == CcType.UNKNOWN) {
1797 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1798 return -1;
1799 }
1800 }
1801
1802 // Override the value
1803 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1804
1805 // Find bundle containing all new carrier configuration values after the override.
1806 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1807 if (newValues == null) {
1808 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1809 return -1;
1810 }
1811
1812 // Print the original and new values
1813 overrideBundle.keySet().forEach(key -> {
1814 CcType type = getType(tag, key, originalValues);
1815 String originalValueString = ccValueToString(key, type, originalValues);
1816 String newValueString = ccValueToString(key, type, newValues);
1817 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1818 getOutPrintWriter().println("New value: \n" + newValueString);
1819 });
1820
1821 return 0;
1822 }
1823
1824 private PersistableBundle readPersistableBundleFromXml(String tag) {
1825 PersistableBundle subIdBundles;
1826 try {
1827 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1828 } catch (IOException | RuntimeException e) {
1829 PrintWriter errPw = getErrPrintWriter();
1830 errPw.println(tag + e);
1831 return null;
1832 }
1833
1834 return subIdBundles;
1835 }
1836
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001837 // cc clear-values
1838 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001839 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1840
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001841 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001842 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001843 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001844 return -1;
1845 }
1846
1847 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001848 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001849 getOutPrintWriter()
1850 .println("All previously set carrier config override values has been cleared");
1851 return 0;
1852 }
1853
1854 private CcType getType(String tag, String key, PersistableBundle bundle) {
1855 // Find the type by checking the type of the current value stored in the bundle.
1856 Object value = bundle.get(key);
1857
1858 if (CC_TYPE_MAP.containsKey(key)) {
1859 return CC_TYPE_MAP.get(key);
1860 } else if (value != null) {
1861 if (value instanceof Boolean) {
1862 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001863 }
1864 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001865 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001866 }
1867 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001868 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001869 }
1870 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001871 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001872 }
1873 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001874 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001875 }
1876 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001877 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001878 }
1879 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001880 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001881 }
1882 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001883 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001884 }
1885 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001886 return CcType.STRING_ARRAY;
1887 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001888 if (value instanceof PersistableBundle) {
1889 return CcType.PERSISTABLE_BUNDLE;
1890 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001891 } else {
1892 // Current value was null and can therefore not be used in order to find the type.
1893 // Check the name of the key to infer the type. This check is not needed for primitive
1894 // data types (boolean, double, int and long), since they can not be null.
1895 if (key.endsWith("double_array")) {
1896 return CcType.DOUBLE_ARRAY;
1897 }
1898 if (key.endsWith("int_array")) {
1899 return CcType.INT_ARRAY;
1900 }
1901 if (key.endsWith("long_array")) {
1902 return CcType.LONG_ARRAY;
1903 }
1904 if (key.endsWith("string")) {
1905 return CcType.STRING;
1906 }
1907 if (key.endsWith("string_array") || key.endsWith("strings")) {
1908 return CcType.STRING_ARRAY;
1909 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001910 if (key.endsWith("bundle")) {
1911 return CcType.PERSISTABLE_BUNDLE;
1912 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001913 }
1914
1915 // Not possible to infer the type by looking at the current value or the key.
1916 PrintWriter errPw = getErrPrintWriter();
1917 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1918 return CcType.UNKNOWN;
1919 }
1920
1921 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1922 String result;
1923 StringBuilder valueString = new StringBuilder();
1924 String typeString = type.toString();
1925 Object value = bundle.get(key);
1926
1927 if (value == null) {
1928 valueString.append("null");
1929 } else {
1930 switch (type) {
1931 case DOUBLE_ARRAY: {
1932 // Format the string representation of the int array as value1 value2......
1933 double[] valueArray = (double[]) value;
1934 for (int i = 0; i < valueArray.length; i++) {
1935 if (i != 0) {
1936 valueString.append(" ");
1937 }
1938 valueString.append(valueArray[i]);
1939 }
1940 break;
1941 }
1942 case INT_ARRAY: {
1943 // Format the string representation of the int array as value1 value2......
1944 int[] valueArray = (int[]) value;
1945 for (int i = 0; i < valueArray.length; i++) {
1946 if (i != 0) {
1947 valueString.append(" ");
1948 }
1949 valueString.append(valueArray[i]);
1950 }
1951 break;
1952 }
1953 case LONG_ARRAY: {
1954 // Format the string representation of the int array as value1 value2......
1955 long[] valueArray = (long[]) value;
1956 for (int i = 0; i < valueArray.length; i++) {
1957 if (i != 0) {
1958 valueString.append(" ");
1959 }
1960 valueString.append(valueArray[i]);
1961 }
1962 break;
1963 }
1964 case STRING: {
1965 valueString.append("\"" + value.toString() + "\"");
1966 break;
1967 }
1968 case STRING_ARRAY: {
1969 // Format the string representation of the string array as "value1" "value2"....
1970 String[] valueArray = (String[]) value;
1971 for (int i = 0; i < valueArray.length; i++) {
1972 if (i != 0) {
1973 valueString.append(" ");
1974 }
1975 if (valueArray[i] != null) {
1976 valueString.append("\"" + valueArray[i] + "\"");
1977 } else {
1978 valueString.append("null");
1979 }
1980 }
1981 break;
1982 }
1983 default: {
1984 valueString.append(value.toString());
1985 }
1986 }
1987 }
1988 return String.format("%-70s %-15s %s", key, typeString, valueString);
1989 }
1990
1991 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1992 ArrayList<String> valueList) {
1993 PrintWriter errPw = getErrPrintWriter();
1994 PersistableBundle bundle = new PersistableBundle();
1995
1996 // First verify that a valid number of values has been provided for the type.
1997 switch (type) {
1998 case BOOLEAN:
1999 case DOUBLE:
2000 case INT:
2001 case LONG: {
2002 if (valueList.size() != 1) {
2003 errPw.println(tag + "Expected 1 value for type " + type
2004 + ". Found: " + valueList.size());
2005 return null;
2006 }
2007 break;
2008 }
2009 case STRING: {
2010 if (valueList.size() > 1) {
2011 errPw.println(tag + "Expected 0 or 1 values for type " + type
2012 + ". Found: " + valueList.size());
2013 return null;
2014 }
2015 break;
2016 }
2017 }
2018
2019 // Parse the value according to type and add it to the Bundle.
2020 switch (type) {
2021 case BOOLEAN: {
2022 if ("true".equalsIgnoreCase(valueList.get(0))) {
2023 bundle.putBoolean(key, true);
2024 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2025 bundle.putBoolean(key, false);
2026 } else {
2027 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2028 return null;
2029 }
2030 break;
2031 }
2032 case DOUBLE: {
2033 try {
2034 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2035 } catch (NumberFormatException nfe) {
2036 // Not a valid double
2037 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2038 return null;
2039 }
2040 break;
2041 }
2042 case DOUBLE_ARRAY: {
2043 double[] valueDoubleArray = null;
2044 if (valueList.size() > 0) {
2045 valueDoubleArray = new double[valueList.size()];
2046 for (int i = 0; i < valueList.size(); i++) {
2047 try {
2048 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2049 } catch (NumberFormatException nfe) {
2050 // Not a valid double
2051 errPw.println(
2052 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2053 return null;
2054 }
2055 }
2056 }
2057 bundle.putDoubleArray(key, valueDoubleArray);
2058 break;
2059 }
2060 case INT: {
2061 try {
2062 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2063 } catch (NumberFormatException nfe) {
2064 // Not a valid integer
2065 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2066 return null;
2067 }
2068 break;
2069 }
2070 case INT_ARRAY: {
2071 int[] valueIntArray = null;
2072 if (valueList.size() > 0) {
2073 valueIntArray = new int[valueList.size()];
2074 for (int i = 0; i < valueList.size(); i++) {
2075 try {
2076 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2077 } catch (NumberFormatException nfe) {
2078 // Not a valid integer
2079 errPw.println(tag
2080 + "Unable to parse " + valueList.get(i) + " as an integer.");
2081 return null;
2082 }
2083 }
2084 }
2085 bundle.putIntArray(key, valueIntArray);
2086 break;
2087 }
2088 case LONG: {
2089 try {
2090 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2091 } catch (NumberFormatException nfe) {
2092 // Not a valid long
2093 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2094 return null;
2095 }
2096 break;
2097 }
2098 case LONG_ARRAY: {
2099 long[] valueLongArray = null;
2100 if (valueList.size() > 0) {
2101 valueLongArray = new long[valueList.size()];
2102 for (int i = 0; i < valueList.size(); i++) {
2103 try {
2104 valueLongArray[i] = Long.parseLong(valueList.get(i));
2105 } catch (NumberFormatException nfe) {
2106 // Not a valid long
2107 errPw.println(
2108 tag + "Unable to parse " + valueList.get(i) + " as a long");
2109 return null;
2110 }
2111 }
2112 }
2113 bundle.putLongArray(key, valueLongArray);
2114 break;
2115 }
2116 case STRING: {
2117 String value = null;
2118 if (valueList.size() > 0) {
2119 value = valueList.get(0);
2120 }
2121 bundle.putString(key, value);
2122 break;
2123 }
2124 case STRING_ARRAY: {
2125 String[] valueStringArray = null;
2126 if (valueList.size() > 0) {
2127 valueStringArray = new String[valueList.size()];
2128 valueList.toArray(valueStringArray);
2129 }
2130 bundle.putStringArray(key, valueStringArray);
2131 break;
2132 }
2133 }
2134 return bundle;
2135 }
Shuo Qian489d9282020-07-09 11:30:03 -07002136
2137 private int handleEndBlockSuppressionCommand() {
2138 if (!checkShellUid()) {
2139 return -1;
2140 }
2141
2142 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2143 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2144 }
2145 return 0;
2146 }
Hui Wang641e81c2020-10-12 12:14:23 -07002147
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002148 private int handleEuiccCommand() {
2149 String arg = getNextArg();
2150 if (arg == null) {
2151 onHelpEuicc();
2152 return 0;
2153 }
2154
2155 switch (arg) {
2156 case EUICC_SET_UI_COMPONENT: {
2157 return handleEuiccServiceCommand();
2158 }
2159 }
2160 return -1;
2161 }
2162
2163 private int handleEuiccServiceCommand() {
2164 String uiComponent = getNextArg();
2165 String packageName = getNextArg();
2166 if (packageName == null || uiComponent == null) {
2167 return -1;
2168 }
2169 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2170 if (VDBG) {
2171 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2172 + packageName);
2173 }
2174 return 0;
2175 }
2176
Michele Berionne54af4632020-12-28 20:23:16 +00002177 private int handleRestartModemCommand() {
2178 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2179 // non user build.
2180 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2181 getErrPrintWriter().println("RestartModem: Permission denied.");
2182 return -1;
2183 }
2184
2185 boolean result = TelephonyManager.getDefault().rebootRadio();
2186 getOutPrintWriter().println(result);
2187
2188 return result ? 0 : -1;
2189 }
2190
Ling Ma4fbab492022-01-25 22:36:16 +00002191 private int handleGetImei() {
2192 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2193 // non user build.
2194 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2195 getErrPrintWriter().println("Device IMEI: Permission denied.");
2196 return -1;
2197 }
2198
2199 final long identity = Binder.clearCallingIdentity();
2200
2201 String imei = null;
2202 String arg = getNextArg();
2203 if (arg != null) {
2204 try {
2205 int specifiedSlotIndex = Integer.parseInt(arg);
2206 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2207 } catch (NumberFormatException exception) {
2208 PrintWriter errPw = getErrPrintWriter();
2209 errPw.println("-s requires an integer as slot index.");
2210 return -1;
2211 }
2212
2213 } else {
2214 imei = TelephonyManager.from(mContext).getImei();
2215 }
2216 getOutPrintWriter().println("Device IMEI: " + imei);
2217
2218 Binder.restoreCallingIdentity(identity);
2219 return 0;
2220 }
2221
Michele Berionne5e411512020-11-13 02:36:59 +00002222 private int handleUnattendedReboot() {
2223 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2224 // non user build.
2225 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2226 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2227 return -1;
2228 }
2229
2230 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2231 getOutPrintWriter().println("result: " + result);
2232
2233 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2234 }
2235
Aman Gupta07124872022-02-09 08:02:14 +00002236 private int handleGetSimSlotsMapping() {
2237 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2238 // non user build.
2239 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2240 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2241 return -1;
2242 }
2243 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2244 String result = telephonyManager.getSimSlotMapping().toString();
2245 getOutPrintWriter().println("simSlotsMapping: " + result);
2246
2247 return 0;
2248 }
2249
Hui Wang641e81c2020-10-12 12:14:23 -07002250 private int handleGbaCommand() {
2251 String arg = getNextArg();
2252 if (arg == null) {
2253 onHelpGba();
2254 return 0;
2255 }
2256
2257 switch (arg) {
2258 case GBA_SET_SERVICE: {
2259 return handleGbaSetServiceCommand();
2260 }
2261 case GBA_GET_SERVICE: {
2262 return handleGbaGetServiceCommand();
2263 }
2264 case GBA_SET_RELEASE_TIME: {
2265 return handleGbaSetReleaseCommand();
2266 }
2267 case GBA_GET_RELEASE_TIME: {
2268 return handleGbaGetReleaseCommand();
2269 }
2270 }
2271
2272 return -1;
2273 }
2274
2275 private int getSubId(String cmd) {
2276 int slotId = getDefaultSlot();
2277 String opt = getNextOption();
2278 if (opt != null && opt.equals("-s")) {
2279 try {
2280 slotId = Integer.parseInt(getNextArgRequired());
2281 } catch (NumberFormatException e) {
2282 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2283 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2284 }
2285 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002286 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002287 }
2288
2289 private int handleGbaSetServiceCommand() {
2290 int subId = getSubId("gba set-service");
2291 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2292 return -1;
2293 }
2294
2295 String packageName = getNextArg();
2296 try {
2297 if (packageName == null) {
2298 packageName = "";
2299 }
2300 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2301 if (VDBG) {
2302 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2303 + packageName + ", result=" + result);
2304 }
2305 getOutPrintWriter().println(result);
2306 } catch (RemoteException e) {
2307 Log.w(LOG_TAG, "gba set-service " + subId + " "
2308 + packageName + ", error" + e.getMessage());
2309 getErrPrintWriter().println("Exception: " + e.getMessage());
2310 return -1;
2311 }
2312 return 0;
2313 }
2314
2315 private int handleGbaGetServiceCommand() {
2316 String result;
2317
2318 int subId = getSubId("gba get-service");
2319 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2320 return -1;
2321 }
2322
2323 try {
2324 result = mInterface.getBoundGbaService(subId);
2325 } catch (RemoteException e) {
2326 return -1;
2327 }
2328 if (VDBG) {
2329 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2330 }
2331 getOutPrintWriter().println(result);
2332 return 0;
2333 }
2334
2335 private int handleGbaSetReleaseCommand() {
2336 //the release time value could be -1
2337 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2338 : SubscriptionManager.getDefaultSubscriptionId();
2339 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2340 return -1;
2341 }
2342
2343 String intervalStr = getNextArg();
2344 if (intervalStr == null) {
2345 return -1;
2346 }
2347
2348 try {
2349 int interval = Integer.parseInt(intervalStr);
2350 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2351 if (VDBG) {
2352 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2353 + intervalStr + ", result=" + result);
2354 }
2355 getOutPrintWriter().println(result);
2356 } catch (NumberFormatException | RemoteException e) {
2357 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2358 + intervalStr + ", error" + e.getMessage());
2359 getErrPrintWriter().println("Exception: " + e.getMessage());
2360 return -1;
2361 }
2362 return 0;
2363 }
2364
2365 private int handleGbaGetReleaseCommand() {
2366 int subId = getSubId("gba get-release");
2367 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2368 return -1;
2369 }
2370
2371 int result = 0;
2372 try {
2373 result = mInterface.getGbaReleaseTime(subId);
2374 } catch (RemoteException e) {
2375 return -1;
2376 }
2377 if (VDBG) {
2378 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2379 }
2380 getOutPrintWriter().println(result);
2381 return 0;
2382 }
Hui Wang761a6682020-10-31 05:12:53 +00002383
2384 private int handleSingleRegistrationConfigCommand() {
2385 String arg = getNextArg();
2386 if (arg == null) {
2387 onHelpSrc();
2388 return 0;
2389 }
2390
2391 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002392 case SRC_SET_TEST_ENABLED: {
2393 return handleSrcSetTestEnabledCommand();
2394 }
2395 case SRC_GET_TEST_ENABLED: {
2396 return handleSrcGetTestEnabledCommand();
2397 }
Hui Wang761a6682020-10-31 05:12:53 +00002398 case SRC_SET_DEVICE_ENABLED: {
2399 return handleSrcSetDeviceEnabledCommand();
2400 }
2401 case SRC_GET_DEVICE_ENABLED: {
2402 return handleSrcGetDeviceEnabledCommand();
2403 }
2404 case SRC_SET_CARRIER_ENABLED: {
2405 return handleSrcSetCarrierEnabledCommand();
2406 }
2407 case SRC_GET_CARRIER_ENABLED: {
2408 return handleSrcGetCarrierEnabledCommand();
2409 }
Hui Wangb647abe2021-02-26 09:33:38 -08002410 case SRC_SET_FEATURE_ENABLED: {
2411 return handleSrcSetFeatureValidationCommand();
2412 }
2413 case SRC_GET_FEATURE_ENABLED: {
2414 return handleSrcGetFeatureValidationCommand();
2415 }
Hui Wang761a6682020-10-31 05:12:53 +00002416 }
2417
2418 return -1;
2419 }
2420
James.cf Linbcdf8b32021-01-14 16:44:13 +08002421 private int handleRcsUceCommand() {
2422 String arg = getNextArg();
2423 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002424 onHelpUce();
2425 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002426 }
2427
2428 switch (arg) {
2429 case UCE_REMOVE_EAB_CONTACT:
2430 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002431 case UCE_GET_EAB_CONTACT:
2432 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002433 case UCE_GET_EAB_CAPABILITY:
2434 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002435 case UCE_GET_DEVICE_ENABLED:
2436 return handleUceGetDeviceEnabledCommand();
2437 case UCE_SET_DEVICE_ENABLED:
2438 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002439 case UCE_OVERRIDE_PUBLISH_CAPS:
2440 return handleUceOverridePublishCaps();
2441 case UCE_GET_LAST_PIDF_XML:
2442 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002443 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2444 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002445 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2446 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002447 }
2448 return -1;
2449 }
2450
2451 private int handleRemovingEabContactCommand() {
2452 int subId = getSubId("uce remove-eab-contact");
2453 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2454 return -1;
2455 }
2456
2457 String phoneNumber = getNextArgRequired();
2458 if (TextUtils.isEmpty(phoneNumber)) {
2459 return -1;
2460 }
2461 int result = 0;
2462 try {
2463 result = mInterface.removeContactFromEab(subId, phoneNumber);
2464 } catch (RemoteException e) {
2465 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2466 getErrPrintWriter().println("Exception: " + e.getMessage());
2467 return -1;
2468 }
2469
2470 if (VDBG) {
2471 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2472 }
calvinpan293ea1b2021-02-04 17:52:13 +08002473 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002474 }
2475
calvinpane4a8a1d2021-01-25 13:51:18 +08002476 private int handleGettingEabContactCommand() {
2477 String phoneNumber = getNextArgRequired();
2478 if (TextUtils.isEmpty(phoneNumber)) {
2479 return -1;
2480 }
2481 String result = "";
2482 try {
2483 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002484 } catch (RemoteException e) {
2485 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2486 getErrPrintWriter().println("Exception: " + e.getMessage());
2487 return -1;
2488 }
2489
2490 if (VDBG) {
2491 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2492 }
calvinpan293ea1b2021-02-04 17:52:13 +08002493 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002494 return 0;
2495 }
2496
Calvin Pana1434322021-07-01 19:27:01 +08002497 private int handleGettingEabCapabilityCommand() {
2498 String phoneNumber = getNextArgRequired();
2499 if (TextUtils.isEmpty(phoneNumber)) {
2500 return -1;
2501 }
2502 String result = "";
2503 try {
2504 result = mInterface.getCapabilityFromEab(phoneNumber);
2505 } catch (RemoteException e) {
2506 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2507 getErrPrintWriter().println("Exception: " + e.getMessage());
2508 return -1;
2509 }
2510
2511 if (VDBG) {
2512 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2513 }
2514 getOutPrintWriter().println(result);
2515 return 0;
2516 }
2517
James.cf Lin4b784aa2021-01-31 03:25:15 +08002518 private int handleUceGetDeviceEnabledCommand() {
2519 boolean result = false;
2520 try {
2521 result = mInterface.getDeviceUceEnabled();
2522 } catch (RemoteException e) {
2523 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2524 return -1;
2525 }
2526 if (VDBG) {
2527 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2528 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002529 getOutPrintWriter().println(result);
2530 return 0;
2531 }
2532
James.cf Lin4b784aa2021-01-31 03:25:15 +08002533 private int handleUceSetDeviceEnabledCommand() {
2534 String enabledStr = getNextArg();
2535 if (TextUtils.isEmpty(enabledStr)) {
2536 return -1;
2537 }
2538
2539 try {
2540 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2541 mInterface.setDeviceUceEnabled(isEnabled);
2542 if (VDBG) {
2543 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2544 }
2545 } catch (NumberFormatException | RemoteException e) {
2546 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2547 getErrPrintWriter().println("Exception: " + e.getMessage());
2548 return -1;
2549 }
2550 return 0;
2551 }
2552
James.cf Line8713a42021-04-29 16:04:26 +08002553 private int handleUceRemoveRequestDisallowedStatus() {
2554 int subId = getSubId("uce remove-request-disallowed-status");
2555 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2556 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2557 return -1;
2558 }
2559 boolean result;
2560 try {
2561 result = mInterface.removeUceRequestDisallowedStatus(subId);
2562 } catch (RemoteException e) {
2563 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2564 return -1;
2565 }
2566 if (VDBG) {
2567 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2568 }
2569 getOutPrintWriter().println(result);
2570 return 0;
2571 }
2572
James.cf Lin0fc71b02021-05-25 01:37:38 +08002573 private int handleUceSetCapRequestTimeout() {
2574 int subId = getSubId("uce set-capabilities-request-timeout");
2575 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2576 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2577 return -1;
2578 }
2579 long timeoutAfterMs = Long.valueOf(getNextArg());
2580 boolean result;
2581 try {
2582 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2583 } catch (RemoteException e) {
2584 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2585 return -1;
2586 }
2587 if (VDBG) {
2588 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2589 }
2590 getOutPrintWriter().println(result);
2591 return 0;
2592 }
2593
Hui Wangbaaee6a2021-02-19 20:45:36 -08002594 private int handleSrcSetTestEnabledCommand() {
2595 String enabledStr = getNextArg();
2596 if (enabledStr == null) {
2597 return -1;
2598 }
2599
2600 try {
2601 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2602 if (VDBG) {
2603 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2604 }
2605 getOutPrintWriter().println("Done");
2606 } catch (NumberFormatException | RemoteException e) {
2607 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2608 getErrPrintWriter().println("Exception: " + e.getMessage());
2609 return -1;
2610 }
2611 return 0;
2612 }
2613
2614 private int handleSrcGetTestEnabledCommand() {
2615 boolean result = false;
2616 try {
2617 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2618 } catch (RemoteException e) {
2619 return -1;
2620 }
2621 if (VDBG) {
2622 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2623 }
2624 getOutPrintWriter().println(result);
2625 return 0;
2626 }
2627
Brad Ebinger14d467f2021-02-12 06:18:28 +00002628 private int handleUceOverridePublishCaps() {
2629 int subId = getSubId("uce override-published-caps");
2630 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2631 return -1;
2632 }
2633 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2634 String operation = getNextArgRequired();
2635 String caps = getNextArg();
2636 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2637 && !"list".equals(operation)) {
2638 getErrPrintWriter().println("Invalid operation: " + operation);
2639 return -1;
2640 }
2641
2642 // add/remove requires capabilities to be specified.
2643 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2644 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2645 + "specified");
2646 return -1;
2647 }
2648
2649 ArraySet<String> capSet = new ArraySet<>();
2650 if (!TextUtils.isEmpty(caps)) {
2651 String[] capArray = caps.split(":");
2652 for (String cap : capArray) {
2653 // Allow unknown tags to be passed in as well.
2654 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2655 }
2656 }
2657
2658 RcsContactUceCapability result = null;
2659 try {
2660 switch (operation) {
2661 case "add":
2662 result = mInterface.addUceRegistrationOverrideShell(subId,
2663 new ArrayList<>(capSet));
2664 break;
2665 case "remove":
2666 result = mInterface.removeUceRegistrationOverrideShell(subId,
2667 new ArrayList<>(capSet));
2668 break;
2669 case "clear":
2670 result = mInterface.clearUceRegistrationOverrideShell(subId);
2671 break;
2672 case "list":
2673 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2674 break;
2675 }
2676 } catch (RemoteException e) {
2677 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2678 getErrPrintWriter().println("Exception: " + e.getMessage());
2679 return -1;
2680 } catch (ServiceSpecificException sse) {
2681 // Reconstruct ImsException
2682 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2683 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2684 getErrPrintWriter().println("Exception: " + imsException);
2685 return -1;
2686 }
2687 if (result == null) {
2688 getErrPrintWriter().println("Service not available");
2689 return -1;
2690 }
2691 getOutPrintWriter().println(result);
2692 return 0;
2693 }
2694
2695 private int handleUceGetPidfXml() {
2696 int subId = getSubId("uce get-last-publish-pidf");
2697 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2698 return -1;
2699 }
2700
2701 String result;
2702 try {
2703 result = mInterface.getLastUcePidfXmlShell(subId);
2704 } catch (RemoteException e) {
2705 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2706 getErrPrintWriter().println("Exception: " + e.getMessage());
2707 return -1;
2708 } catch (ServiceSpecificException sse) {
2709 // Reconstruct ImsException
2710 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2711 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2712 getErrPrintWriter().println("Exception: " + imsException);
2713 return -1;
2714 }
2715 if (result == null) {
2716 getErrPrintWriter().println("Service not available");
2717 return -1;
2718 }
2719 getOutPrintWriter().println(result);
2720 return 0;
2721 }
2722
Hui Wang761a6682020-10-31 05:12:53 +00002723 private int handleSrcSetDeviceEnabledCommand() {
2724 String enabledStr = getNextArg();
2725 if (enabledStr == null) {
2726 return -1;
2727 }
2728
2729 try {
2730 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2731 if (VDBG) {
2732 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2733 }
2734 getOutPrintWriter().println("Done");
2735 } catch (NumberFormatException | RemoteException e) {
2736 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2737 getErrPrintWriter().println("Exception: " + e.getMessage());
2738 return -1;
2739 }
2740 return 0;
2741 }
2742
2743 private int handleSrcGetDeviceEnabledCommand() {
2744 boolean result = false;
2745 try {
2746 result = mInterface.getDeviceSingleRegistrationEnabled();
2747 } catch (RemoteException e) {
2748 return -1;
2749 }
2750 if (VDBG) {
2751 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2752 }
2753 getOutPrintWriter().println(result);
2754 return 0;
2755 }
2756
2757 private int handleSrcSetCarrierEnabledCommand() {
2758 //the release time value could be -1
2759 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2760 : SubscriptionManager.getDefaultSubscriptionId();
2761 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2762 return -1;
2763 }
2764
2765 String enabledStr = getNextArg();
2766 if (enabledStr == null) {
2767 return -1;
2768 }
2769
2770 try {
2771 boolean result =
2772 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2773 if (VDBG) {
2774 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2775 + enabledStr + ", result=" + result);
2776 }
2777 getOutPrintWriter().println(result);
2778 } catch (NumberFormatException | RemoteException e) {
2779 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2780 + enabledStr + ", error" + e.getMessage());
2781 getErrPrintWriter().println("Exception: " + e.getMessage());
2782 return -1;
2783 }
2784 return 0;
2785 }
2786
2787 private int handleSrcGetCarrierEnabledCommand() {
2788 int subId = getSubId("src get-carrier-enabled");
2789 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2790 return -1;
2791 }
2792
2793 boolean result = false;
2794 try {
2795 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2796 } catch (RemoteException e) {
2797 return -1;
2798 }
2799 if (VDBG) {
2800 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2801 }
2802 getOutPrintWriter().println(result);
2803 return 0;
2804 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002805
Hui Wangb647abe2021-02-26 09:33:38 -08002806 private int handleSrcSetFeatureValidationCommand() {
2807 //the release time value could be -1
2808 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2809 : SubscriptionManager.getDefaultSubscriptionId();
2810 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2811 return -1;
2812 }
2813
2814 String enabledStr = getNextArg();
2815 if (enabledStr == null) {
2816 return -1;
2817 }
2818
2819 try {
2820 boolean result =
2821 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2822 if (VDBG) {
2823 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2824 + enabledStr + ", result=" + result);
2825 }
2826 getOutPrintWriter().println(result);
2827 } catch (NumberFormatException | RemoteException e) {
2828 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2829 + enabledStr + ", error" + e.getMessage());
2830 getErrPrintWriter().println("Exception: " + e.getMessage());
2831 return -1;
2832 }
2833 return 0;
2834 }
2835
2836 private int handleSrcGetFeatureValidationCommand() {
2837 int subId = getSubId("src get-feature-validation");
2838 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2839 return -1;
2840 }
2841
2842 Boolean result = false;
2843 try {
2844 result = mInterface.getImsFeatureValidationOverride(subId);
2845 } catch (RemoteException e) {
2846 return -1;
2847 }
2848 if (VDBG) {
2849 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2850 }
2851 getOutPrintWriter().println(result);
2852 return 0;
2853 }
2854
2855
Hall Liuaa4211e2021-01-20 15:43:39 -08002856 private void onHelpCallComposer() {
2857 PrintWriter pw = getOutPrintWriter();
2858 pw.println("Call composer commands");
2859 pw.println(" callcomposer test-mode enable|disable|query");
2860 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2861 pw.println(" upload/download from carrier servers is disabled, and operations are");
2862 pw.println(" performed using emulated local files instead.");
2863 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2864 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2865 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002866 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2867 pw.println(" Enables or disables the user setting for call composer, as set by");
2868 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002869 }
2870
2871 private int handleCallComposerCommand() {
2872 String arg = getNextArg();
2873 if (arg == null) {
2874 onHelpCallComposer();
2875 return 0;
2876 }
2877
2878 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2879 "MODIFY_PHONE_STATE required for call composer shell cmds");
2880 switch (arg) {
2881 case CALL_COMPOSER_TEST_MODE: {
2882 String enabledStr = getNextArg();
2883 if (ENABLE.equals(enabledStr)) {
2884 CallComposerPictureManager.sTestMode = true;
2885 } else if (DISABLE.equals(enabledStr)) {
2886 CallComposerPictureManager.sTestMode = false;
2887 } else if (QUERY.equals(enabledStr)) {
2888 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2889 } else {
2890 onHelpCallComposer();
2891 return 1;
2892 }
2893 break;
2894 }
2895 case CALL_COMPOSER_SIMULATE_CALL: {
2896 int subscriptionId = Integer.valueOf(getNextArg());
2897 String uuidString = getNextArg();
2898 UUID uuid = UUID.fromString(uuidString);
2899 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2900 Binder.withCleanCallingIdentity(() -> {
2901 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2902 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2903 });
2904 try {
2905 Uri uri = storageUriFuture.get();
2906 getOutPrintWriter().println(String.valueOf(uri));
2907 } catch (Exception e) {
2908 throw new RuntimeException(e);
2909 }
2910 break;
2911 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002912 case CALL_COMPOSER_USER_SETTING: {
2913 try {
2914 int subscriptionId = Integer.valueOf(getNextArg());
2915 String enabledStr = getNextArg();
2916 if (ENABLE.equals(enabledStr)) {
2917 mInterface.setCallComposerStatus(subscriptionId,
2918 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2919 } else if (DISABLE.equals(enabledStr)) {
2920 mInterface.setCallComposerStatus(subscriptionId,
2921 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2922 } else if (QUERY.equals(enabledStr)) {
2923 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2924 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2925 } else {
2926 onHelpCallComposer();
2927 return 1;
2928 }
2929 } catch (RemoteException e) {
2930 e.printStackTrace(getOutPrintWriter());
2931 return 1;
2932 }
2933 break;
2934 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002935 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002936 return 0;
2937 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002938
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002939 private int handleHasCarrierPrivilegesCommand() {
2940 String packageName = getNextArgRequired();
2941
2942 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002943 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002944 try {
2945 hasCarrierPrivileges =
2946 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2947 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2948 } catch (RemoteException e) {
2949 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2950 getErrPrintWriter().println("Exception: " + e.getMessage());
2951 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002952 } finally {
2953 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002954 }
2955
2956 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002957 return 0;
2958 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002959
2960 private int handleAllowedNetworkTypesCommand(String command) {
2961 if (!checkShellUid()) {
2962 return -1;
2963 }
2964
2965 PrintWriter errPw = getErrPrintWriter();
2966 String tag = command + ": ";
2967 String opt;
2968 int subId = -1;
2969 Log.v(LOG_TAG, command + " start");
2970
2971 while ((opt = getNextOption()) != null) {
2972 if (opt.equals("-s")) {
2973 try {
2974 subId = slotStringToSubId(tag, getNextArgRequired());
2975 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2976 errPw.println(tag + "No valid subscription found.");
2977 return -1;
2978 }
2979 } catch (IllegalArgumentException e) {
2980 // Missing slot id
2981 errPw.println(tag + "SLOT_ID expected after -s.");
2982 return -1;
2983 }
2984 } else {
2985 errPw.println(tag + "Unknown option " + opt);
2986 return -1;
2987 }
2988 }
2989
2990 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2991 return handleGetAllowedNetworkTypesCommand(subId);
2992 }
2993 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2994 return handleSetAllowedNetworkTypesCommand(subId);
2995 }
2996 return -1;
2997 }
2998
2999 private int handleGetAllowedNetworkTypesCommand(int subId) {
3000 PrintWriter errPw = getErrPrintWriter();
3001
3002 long result = -1;
3003 try {
3004 if (mInterface != null) {
3005 result = mInterface.getAllowedNetworkTypesForReason(subId,
3006 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3007 } else {
3008 throw new IllegalStateException("telephony service is null.");
3009 }
3010 } catch (RemoteException e) {
3011 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3012 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3013 return -1;
3014 }
3015
3016 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3017 return 0;
3018 }
3019
3020 private int handleSetAllowedNetworkTypesCommand(int subId) {
3021 PrintWriter errPw = getErrPrintWriter();
3022
3023 String bitmaskString = getNextArg();
3024 if (TextUtils.isEmpty(bitmaskString)) {
3025 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3026 return -1;
3027 }
3028 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3029 if (allowedNetworkTypes < 0) {
3030 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3031 return -1;
3032 }
3033 boolean result = false;
3034 try {
3035 if (mInterface != null) {
3036 result = mInterface.setAllowedNetworkTypesForReason(subId,
3037 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3038 } else {
3039 throw new IllegalStateException("telephony service is null.");
3040 }
3041 } catch (RemoteException e) {
3042 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3043 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3044 return -1;
3045 }
3046
3047 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3048 if (result) {
3049 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3050 }
3051 getOutPrintWriter().println(resultMessage);
3052 return 0;
3053 }
3054
3055 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3056 if (TextUtils.isEmpty(bitmaskString)) {
3057 return -1;
3058 }
3059 if (VDBG) {
3060 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3061 + ", length: " + bitmaskString.length());
3062 }
3063 try {
3064 return Long.parseLong(bitmaskString, 2);
3065 } catch (NumberFormatException e) {
3066 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3067 return -1;
3068 }
3069 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003070
jimsun3b9ccac2021-10-26 15:01:23 +08003071 private int handleRadioSetModemServiceCommand() {
3072 PrintWriter errPw = getErrPrintWriter();
3073 String serviceName = null;
3074
3075 String opt;
3076 while ((opt = getNextOption()) != null) {
3077 switch (opt) {
3078 case "-s": {
3079 serviceName = getNextArgRequired();
3080 break;
3081 }
3082 }
3083 }
3084
3085 try {
3086 boolean result = mInterface.setModemService(serviceName);
3087 if (VDBG) {
3088 Log.v(LOG_TAG,
3089 "RadioSetModemService " + serviceName + ", result = " + result);
3090 }
3091 getOutPrintWriter().println(result);
3092 } catch (RemoteException e) {
3093 Log.w(LOG_TAG,
3094 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3095 errPw.println("Exception: " + e.getMessage());
3096 return -1;
3097 }
3098 return 0;
3099 }
3100
3101 private int handleRadioGetModemServiceCommand() {
3102 PrintWriter errPw = getErrPrintWriter();
3103 String result;
3104
3105 try {
3106 result = mInterface.getModemService();
3107 getOutPrintWriter().println(result);
3108 } catch (RemoteException e) {
3109 errPw.println("Exception: " + e.getMessage());
3110 return -1;
3111 }
3112 if (VDBG) {
3113 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3114 }
3115 return 0;
3116 }
3117
3118 private int handleRadioCommand() {
3119 String arg = getNextArg();
3120 if (arg == null) {
3121 onHelpRadio();
3122 return 0;
3123 }
3124
3125 switch (arg) {
3126 case RADIO_SET_MODEM_SERVICE:
3127 return handleRadioSetModemServiceCommand();
3128
3129 case RADIO_GET_MODEM_SERVICE:
3130 return handleRadioGetModemServiceCommand();
3131 }
3132
3133 return -1;
3134 }
arunvoddud7401012022-12-15 16:08:12 +00003135
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003136 private int handleSetSatelliteServicePackageNameCommand() {
3137 PrintWriter errPw = getErrPrintWriter();
3138 String serviceName = null;
3139
3140 String opt;
3141 while ((opt = getNextOption()) != null) {
3142 switch (opt) {
3143 case "-s": {
3144 serviceName = getNextArgRequired();
3145 break;
3146 }
3147 }
3148 }
3149 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3150 + serviceName);
3151
3152 try {
3153 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3154 if (VDBG) {
3155 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3156 + ", result = " + result);
3157 }
3158 getOutPrintWriter().println(result);
3159 } catch (RemoteException e) {
3160 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3161 + ", error = " + e.getMessage());
3162 errPw.println("Exception: " + e.getMessage());
3163 return -1;
3164 }
3165 return 0;
3166 }
3167
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003168 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3169 PrintWriter errPw = getErrPrintWriter();
3170 String serviceName = null;
3171
3172 String opt;
3173 while ((opt = getNextOption()) != null) {
3174 switch (opt) {
3175 case "-s": {
3176 serviceName = getNextArgRequired();
3177 break;
3178 }
3179 }
3180 }
3181 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3182 + serviceName);
3183
3184 try {
3185 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3186 if (VDBG) {
3187 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3188 + ", result = " + result);
3189 }
3190 getOutPrintWriter().println(result);
3191 } catch (RemoteException e) {
3192 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3193 + ", error = " + e.getMessage());
3194 errPw.println("Exception: " + e.getMessage());
3195 return -1;
3196 }
3197 return 0;
3198 }
3199
Thomas Nguyen87dce732023-04-20 18:27:16 -07003200 private int handleSetSatellitePointingUiClassNameCommand() {
3201 PrintWriter errPw = getErrPrintWriter();
3202 String packageName = null;
3203 String className = null;
3204
3205 String opt;
3206 while ((opt = getNextOption()) != null) {
3207 switch (opt) {
3208 case "-p": {
3209 packageName = getNextArgRequired();
3210 break;
3211 }
3212 case "-c": {
3213 className = getNextArgRequired();
3214 break;
3215 }
3216 }
3217 }
3218 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3219 + packageName + ", className=" + className);
3220
3221 try {
3222 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3223 if (VDBG) {
3224 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3225 }
3226 getOutPrintWriter().println(result);
3227 } catch (RemoteException e) {
3228 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3229 + ", error = " + e.getMessage());
3230 errPw.println("Exception: " + e.getMessage());
3231 return -1;
3232 }
3233 return 0;
3234 }
3235
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003236 private int handleSetEmergencyCallToSatelliteHandoverType() {
3237 PrintWriter errPw = getErrPrintWriter();
3238 int handoverType = -1;
3239 int delaySeconds = 0;
3240
3241 String opt;
3242 while ((opt = getNextOption()) != null) {
3243 switch (opt) {
3244 case "-t": {
3245 try {
3246 handoverType = Integer.parseInt(getNextArgRequired());
3247 } catch (NumberFormatException e) {
3248 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3249 + " for handoverType");
3250 return -1;
3251 }
3252 break;
3253 }
3254 case "-d": {
3255 try {
3256 delaySeconds = Integer.parseInt(getNextArgRequired());
3257 } catch (NumberFormatException e) {
3258 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3259 + " for delaySeconds");
3260 return -1;
3261 }
3262 break;
3263 }
3264 }
3265 }
3266 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3267 + handoverType + ", delaySeconds=" + delaySeconds);
3268
3269 try {
3270 boolean result =
3271 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3272 if (VDBG) {
3273 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3274 }
3275 getOutPrintWriter().println(result);
3276 } catch (RemoteException e) {
3277 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3278 + ", error = " + e.getMessage());
3279 errPw.println("Exception: " + e.getMessage());
3280 return -1;
3281 }
3282 return 0;
3283 }
3284
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003285 private int handleSetSatelliteListeningTimeoutDuration() {
3286 PrintWriter errPw = getErrPrintWriter();
3287 long timeoutMillis = 0;
3288
3289 String opt;
3290 while ((opt = getNextOption()) != null) {
3291 switch (opt) {
3292 case "-t": {
3293 timeoutMillis = Long.parseLong(getNextArgRequired());
3294 break;
3295 }
3296 }
3297 }
3298 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3299 + timeoutMillis);
3300
3301 try {
3302 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3303 if (VDBG) {
3304 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3305 + ", result = " + result);
3306 }
3307 getOutPrintWriter().println(result);
3308 } catch (RemoteException e) {
3309 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3310 + ", error = " + e.getMessage());
3311 errPw.println("Exception: " + e.getMessage());
3312 return -1;
3313 }
3314 return 0;
3315 }
3316
Hakjun Choiae365972023-04-25 11:00:31 +00003317 private int handleSettSatelliteDeviceAlignedTimeoutDuration() {
3318 PrintWriter errPw = getErrPrintWriter();
3319 long timeoutMillis = 0;
3320
3321 String opt;
3322 while ((opt = getNextOption()) != null) {
3323 switch (opt) {
3324 case "-t": {
3325 timeoutMillis = Long.parseLong(getNextArgRequired());
3326 break;
3327 }
3328 }
3329 }
3330 Log.d(LOG_TAG, "handleSettSatelliteDeviceAlignedTimeoutDuration: timeoutMillis="
3331 + timeoutMillis);
3332
3333 try {
3334 boolean result = mInterface.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
3335 if (VDBG) {
3336 Log.v(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration " + timeoutMillis
3337 + ", result = " + result);
3338 }
3339 getOutPrintWriter().println(result);
3340 } catch (RemoteException e) {
3341 Log.w(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration: " + timeoutMillis
3342 + ", error = " + e.getMessage());
3343 errPw.println("Exception: " + e.getMessage());
3344 return -1;
3345 }
3346 return 0;
3347 }
3348
Hakjun Choibc6ce992023-11-07 16:04:33 +00003349 private int handleSetShouldSendDatagramToModemInDemoMode() {
3350 PrintWriter errPw = getErrPrintWriter();
3351 String opt;
3352 boolean shouldSendToDemoMode;
3353
3354 if ((opt = getNextArg()) == null) {
3355 errPw.println(
3356 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3357 + " Invalid Argument");
3358 return -1;
3359 } else {
3360 switch (opt) {
3361 case "true": {
3362 shouldSendToDemoMode = true;
3363 break;
3364 }
3365 case "false": {
3366 shouldSendToDemoMode = false;
3367 break;
3368 }
3369 default:
3370 errPw.println(
3371 "adb shell cmd phone set-should-send-datagram-to-modem-in-demo-mode :"
3372 + " Invalid Argument");
3373 return -1;
3374 }
3375 }
3376
3377 Log.d(LOG_TAG,
3378 "handleSetShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode + ")");
3379
3380 try {
3381 boolean result = mInterface.setShouldSendDatagramToModemInDemoMode(
3382 shouldSendToDemoMode);
3383 if (VDBG) {
3384 Log.v(LOG_TAG, "handleSetShouldSendDatagramToModemInDemoMode returns: "
3385 + result);
3386 }
3387 getOutPrintWriter().println(false);
3388 } catch (RemoteException e) {
3389 Log.w(LOG_TAG, "setShouldSendDatagramToModemInDemoMode(" + shouldSendToDemoMode
3390 + "), error = " + e.getMessage());
3391 errPw.println("Exception: " + e.getMessage());
3392 return -1;
3393 }
3394 return 0;
3395 }
3396
arunvoddud7401012022-12-15 16:08:12 +00003397 private int handleCarrierRestrictionStatusCommand() {
3398 try {
3399 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3400 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3401 mInterface.getModemService()))) {
3402 Log.v(LOG_TAG,
3403 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3404 + " checkShellUid fails");
3405 return -1;
3406 }
3407 } catch (RemoteException ex) {
3408 ex.printStackTrace();
3409 }
3410 String callerInfo = getNextOption();
3411 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3412 if (TextUtils.isEmpty(callerInfo)) {
3413 // reset the Json content after testing
3414 allowListInfo.updateJsonForTest(null);
3415 return 0;
3416 }
3417 if (callerInfo.startsWith("--")) {
3418 callerInfo = callerInfo.replace("--", "");
3419 }
3420 String params[] = callerInfo.split(",");
3421 StringBuffer jsonStrBuffer = new StringBuffer();
3422 String tokens;
3423 for (int index = 0; index < params.length; index++) {
3424 tokens = convertToJsonString(index, params[index]);
3425 if (TextUtils.isEmpty(tokens)) {
3426 // received wrong format from CTS
3427 if (VDBG) {
3428 Log.v(LOG_TAG,
3429 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3430 }
3431 return -1;
3432 }
3433 jsonStrBuffer.append(tokens);
3434 }
3435 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3436 return result;
3437 }
3438
Benedict Wong66477622023-02-03 23:30:57 +00003439 // set-carrier-service-package-override
3440 private int setCarrierServicePackageOverride() {
3441 PrintWriter errPw = getErrPrintWriter();
3442 int subId = SubscriptionManager.getDefaultSubscriptionId();
3443
3444 String opt;
3445 while ((opt = getNextOption()) != null) {
3446 switch (opt) {
3447 case "-s":
3448 try {
3449 subId = Integer.parseInt(getNextArgRequired());
3450 } catch (NumberFormatException e) {
3451 errPw.println(
3452 "set-carrier-service-package-override requires an integer as a"
3453 + " subscription ID.");
3454 return -1;
3455 }
3456 break;
3457 }
3458 }
3459
3460 String packageName = getNextArg();
3461 if (packageName == null) {
3462 errPw.println("set-carrier-service-package-override requires a override package name.");
3463 return -1;
3464 }
3465
3466 try {
3467 mInterface.setCarrierServicePackageOverride(
3468 subId, packageName, mContext.getOpPackageName());
3469
3470 if (VDBG) {
3471 Log.v(
3472 LOG_TAG,
3473 "set-carrier-service-package-override -s " + subId + " " + packageName);
3474 }
3475 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3476 Log.w(
3477 LOG_TAG,
3478 "set-carrier-service-package-override -s "
3479 + subId
3480 + " "
3481 + packageName
3482 + ", error"
3483 + e.getMessage());
3484 errPw.println("Exception: " + e.getMessage());
3485 return -1;
3486 }
3487 return 0;
3488 }
3489
3490 // clear-carrier-service-package-override
3491 private int clearCarrierServicePackageOverride() {
3492 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003493 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003494
3495 String opt;
3496 while ((opt = getNextOption()) != null) {
3497 switch (opt) {
3498 case "-s":
3499 try {
3500 subId = Integer.parseInt(getNextArgRequired());
3501 } catch (NumberFormatException e) {
3502 errPw.println(
3503 "clear-carrier-service-package-override requires an integer as a"
3504 + " subscription ID.");
3505 return -1;
3506 }
3507 break;
3508 }
3509 }
3510
3511 try {
3512 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3513
3514 if (VDBG) {
3515 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3516 }
3517 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3518 Log.w(
3519 LOG_TAG,
3520 "clear-carrier-service-package-override -s "
3521 + subId
3522 + ", error"
3523 + e.getMessage());
3524 errPw.println("Exception: " + e.getMessage());
3525 return -1;
3526 }
3527 return 0;
3528 }
arunvoddud7401012022-12-15 16:08:12 +00003529
3530 /**
3531 * Building the string that can be used to build the JsonObject which supports to stub the data
3532 * in CarrierAllowListInfo for CTS testing. sample format is like
3533 * {"com.android.example":{"carrierId":"10000","callerSHA1Id":["XXXXXXXXXXXXXX"]}}
3534 */
3535 private String convertToJsonString(int index, String param) {
3536
3537 String token[] = param.split(":");
3538 String jSonString;
3539 switch (index) {
3540 case 0:
3541 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3542 break;
3543 case 1:
3544 jSonString =
3545 "{" + QUOTES + token[0] + QUOTES + ":" + QUOTES + token[1] + QUOTES + ",";
3546 break;
3547 case 2:
3548 jSonString =
3549 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
3550 break;
3551 default:
3552 jSonString = null;
3553 }
3554 return jSonString;
3555 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003556}