blob: d6ecc485d7860852966ac5bb4d9e92bebe0740c1 [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";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800194
Grant Menke567d48f2022-08-18 20:19:10 +0000195 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
196 + "'*', '#' or '+') needs to be specified after -a in the command ";
197
198 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
199 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
200 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
201
SongFerngWang98dd5992021-05-13 17:50:00 +0800202 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
203 "get-allowed-network-types-for-users";
204 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
205 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000206 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000207 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700208 // Take advantage of existing methods that already contain permissions checks when possible.
209 private final ITelephony mInterface;
210
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100211 private SubscriptionManager mSubscriptionManager;
212 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700213 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700214 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100215
216 private enum CcType {
217 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000218 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100219 }
220
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100221 private class CcOptionParseResult {
222 public int mSubId;
223 public boolean mPersistent;
224 }
225
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100226 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
227 // keys by looking at the end of the string which usually tells the type.
228 // For instance: "xxxx_string", "xxxx_string_array", etc.
229 // The carrier config keys in this map does not follow this convention. It is therefore not
230 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700231 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
232 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
233 CcType.STRING),
234 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
235 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
236 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
237 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
238 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
239 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
240 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
241 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
242 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
243 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
244 CcType.STRING),
245 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
246 CcType.STRING_ARRAY),
247 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
248 CcType.STRING_ARRAY),
249 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
250 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
251 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
252 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
253 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
254 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
255 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
256 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100257
Brad Ebinger14d467f2021-02-12 06:18:28 +0000258 /**
259 * Map from a shorthand string to the feature tags required in registration required in order
260 * for the RCS feature to be considered "capable".
261 */
262 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
263 static {
264 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
265 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
266 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
267 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
268 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
269 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
270 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
271 FeatureTags.FEATURE_TAG_VIDEO)));
272 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
273 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
274 map.put("call_comp",
275 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
276 map.put("call_comp_mmtel",
277 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
278 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
279 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
280 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
281 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
282 // version
283 map.put("chatbot", new ArraySet<>(Arrays.asList(
284 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
285 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
286 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
287 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000288 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000289 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
290 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
291 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
292 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
293 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000294 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000295 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
296 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
297 }
298
299
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100300 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700301 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100302 mCarrierConfigManager =
303 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
304 mSubscriptionManager = (SubscriptionManager)
305 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700306 mTelephonyRegistryManager = (TelephonyRegistryManager)
307 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700308 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700309 }
310
311 @Override
312 public int onCommand(String cmd) {
313 if (cmd == null) {
314 return handleDefaultCommands(null);
315 }
316
317 switch (cmd) {
318 case IMS_SUBCOMMAND: {
319 return handleImsCommand();
320 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800321 case RCS_UCE_COMMAND:
322 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800323 case NUMBER_VERIFICATION_SUBCOMMAND:
324 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800325 case EMERGENCY_CALLBACK_MODE:
326 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800327 case EMERGENCY_NUMBER_TEST_MODE:
328 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100329 case CARRIER_CONFIG_SUBCOMMAND: {
330 return handleCcCommand();
331 }
Shuo Qianf5125122019-12-16 17:03:07 -0800332 case DATA_TEST_MODE:
333 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700334 case END_BLOCK_SUPPRESSION:
335 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000336 case EUICC_SUBCOMMAND:
337 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700338 case GBA_SUBCOMMAND:
339 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800340 case D2D_SUBCOMMAND:
341 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700342 case BARRING_SUBCOMMAND:
343 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000344 case SINGLE_REGISTATION_CONFIG:
345 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000346 case RESTART_MODEM:
347 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800348 case CALL_COMPOSER_SUBCOMMAND:
349 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000350 case UNATTENDED_REBOOT:
351 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800352 case HAS_CARRIER_PRIVILEGES_COMMAND:
353 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800354 case THERMAL_MITIGATION_COMMAND:
355 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700356 case DISABLE_PHYSICAL_SUBSCRIPTION:
357 return handleEnablePhysicalSubscription(false);
358 case ENABLE_PHYSICAL_SUBSCRIPTION:
359 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800360 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
361 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
362 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000363 case GET_IMEI:
364 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000365 case GET_SIM_SLOTS_MAPPING:
366 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800367 case RADIO_SUBCOMMAND:
368 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000369 case CARRIER_RESTRICTION_STATUS_TEST:
370 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000371 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
372 return setCarrierServicePackageOverride();
373 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
374 return clearCarrierServicePackageOverride();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700375 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
376 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700377 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
378 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700379 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
380 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700381 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
382 return handleSetSatellitePointingUiClassNameCommand();
Hakjun Choiae365972023-04-25 11:00:31 +0000383 case SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION:
384 return handleSettSatelliteDeviceAlignedTimeoutDuration();
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700385 case SET_EMERGENCY_CALL_TO_SATELLITE_HANDOVER_TYPE:
386 return handleSetEmergencyCallToSatelliteHandoverType();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700387 default: {
388 return handleDefaultCommands(cmd);
389 }
390 }
391 }
392
393 @Override
394 public void onHelp() {
395 PrintWriter pw = getOutPrintWriter();
396 pw.println("Telephony Commands:");
397 pw.println(" help");
398 pw.println(" Print this help text.");
399 pw.println(" ims");
400 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800401 pw.println(" uce");
402 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800403 pw.println(" emergency-number-test-mode");
404 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700405 pw.println(" end-block-suppression");
406 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800407 pw.println(" data");
408 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100409 pw.println(" cc");
410 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700411 pw.println(" gba");
412 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000413 pw.println(" src");
414 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000415 pw.println(" restart-modem");
416 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000417 pw.println(" unattended-reboot");
418 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800419 pw.println(" has-carrier-privileges [package]");
420 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800421 pw.println(" get-allowed-network-types-for-users");
422 pw.println(" Get the Allowed Network Types.");
423 pw.println(" set-allowed-network-types-for-users");
424 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800425 pw.println(" radio");
426 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700427 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800428 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800429 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700430 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800431 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100432 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700433 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000434 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800435 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700436 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800437 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800438 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000439 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700440 onHelpSatellite();
Tyler Gunn92479152021-01-20 16:30:10 -0800441 }
442
443 private void onHelpD2D() {
444 PrintWriter pw = getOutPrintWriter();
445 pw.println("D2D Comms Commands:");
446 pw.println(" d2d send TYPE VALUE");
447 pw.println(" Sends a D2D message of specified type and value.");
448 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
449 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
450 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
451 MESSAGE_CALL_AUDIO_CODEC));
452 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
453 + Communicator.messageToString(
454 MESSAGE_DEVICE_BATTERY_STATE));
455 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
456 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800457 pw.println(" d2d transport TYPE");
458 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
459 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700460 pw.println(" d2d set-device-support true/default");
461 pw.println(" true - forces device support to be enabled for D2D.");
462 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
463 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700464 }
465
Nazanin014f41e2021-05-06 17:26:31 -0700466 private void onHelpBarring() {
467 PrintWriter pw = getOutPrintWriter();
468 pw.println("Barring Commands:");
469 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
470 + " -t CONDITIONAL_BARRING_TIME_SECS");
471 pw.println(" Notifies of a barring info change for the specified slot id.");
472 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
473 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
474 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
475 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
476 }
477
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700478 private void onHelpIms() {
479 PrintWriter pw = getOutPrintWriter();
480 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800481 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700482 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
483 pw.println(" ImsService. Options are:");
484 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
485 pw.println(" is specified, it will choose the default voice SIM slot.");
486 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
487 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800488 pw.println(" -f: Set the feature that this override if for, if no option is");
489 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700490 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
491 pw.println(" Gets the package name of the currently defined ImsService.");
492 pw.println(" Options are:");
493 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
494 pw.println(" is specified, it will choose the default voice SIM slot.");
495 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000496 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800497 pw.println(" -f: The feature type that the query will be requested for. If none is");
498 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800499 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
500 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
501 pw.println(" configuration overrides. Options are:");
502 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
503 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700504 pw.println(" ims enable [-s SLOT_ID]");
505 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
506 pw.println(" if none is specified.");
507 pw.println(" ims disable [-s SLOT_ID]");
508 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
509 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700510 pw.println(" ims conference-event-package [enable/disable]");
511 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700512 }
513
James.cf Linbcdf8b32021-01-14 16:44:13 +0800514 private void onHelpUce() {
515 PrintWriter pw = getOutPrintWriter();
516 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800517 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
518 pw.println(" Get the EAB contacts from the EAB database.");
519 pw.println(" Options are:");
520 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
521 pw.println(" Expected output format :");
522 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800523 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
524 pw.println(" Remove the EAB contacts from the EAB database.");
525 pw.println(" Options are:");
526 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
527 pw.println(" is specified, it will choose the default voice SIM slot.");
528 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800529 pw.println(" uce get-device-enabled");
530 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
531 pw.println(" uce set-device-enabled true|false");
532 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
533 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000534 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
535 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
536 pw.println(" Options are:");
537 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
538 pw.println(" is specified, it will choose the default voice SIM slot.");
539 pw.println(" add [CAPABILITY]: add a new capability");
540 pw.println(" remove [CAPABILITY]: remove a capability");
541 pw.println(" clear: clear all capability overrides");
542 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
543 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
544 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
545 pw.println(" chatbot_sa, chatbot_role] as well as full length");
546 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
547 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
548 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
549 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800550 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
551 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800552 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
553 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800554 }
555
Hall Liud892bec2018-11-30 14:51:45 -0800556 private void onHelpNumberVerification() {
557 PrintWriter pw = getOutPrintWriter();
558 pw.println("Number verification commands");
559 pw.println(" numverify override-package PACKAGE_NAME;");
560 pw.println(" Set the authorized package for number verification.");
561 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800562 pw.println(" numverify fake-call NUMBER;");
563 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
564 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800565 }
566
Jack Nudelman644b91a2021-03-12 14:09:48 -0800567 private void onHelpThermalMitigation() {
568 PrintWriter pw = getOutPrintWriter();
569 pw.println("Thermal mitigation commands");
570 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
571 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
572 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
573 pw.println(" Remove the package from one of the authorized packages for thermal "
574 + "mitigation.");
575 }
576
Jordan Liu0ccee222021-04-27 11:55:13 -0700577 private void onHelpDisableOrEnablePhysicalSubscription() {
578 PrintWriter pw = getOutPrintWriter();
579 pw.println("Disable or enable a physical subscription");
580 pw.println(" disable-physical-subscription SUB_ID");
581 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
582 pw.println(" enable-physical-subscription SUB_ID");
583 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
584 }
585
Shuo Qianf5125122019-12-16 17:03:07 -0800586 private void onHelpDataTestMode() {
587 PrintWriter pw = getOutPrintWriter();
588 pw.println("Mobile Data Test Mode Commands:");
589 pw.println(" data enable: enable mobile data connectivity");
590 pw.println(" data disable: disable mobile data connectivity");
591 }
592
sqian9d4df8b2019-01-15 18:32:07 -0800593 private void onHelpEmergencyNumber() {
594 PrintWriter pw = getOutPrintWriter();
595 pw.println("Emergency Number Test Mode Commands:");
596 pw.println(" emergency-number-test-mode ");
597 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
598 + " the test mode");
599 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700600 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800601 pw.println(" -c: clear the emergency number list in the test mode.");
602 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700603 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800604 pw.println(" -p: get the full emergency number list in the test mode.");
605 }
606
Shuo Qian489d9282020-07-09 11:30:03 -0700607 private void onHelpEndBlockSupperssion() {
608 PrintWriter pw = getOutPrintWriter();
609 pw.println("End Block Suppression command:");
610 pw.println(" end-block-suppression: disable suppressing blocking by contact");
611 pw.println(" with emergency services.");
612 }
613
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100614 private void onHelpCc() {
615 PrintWriter pw = getOutPrintWriter();
616 pw.println("Carrier Config Commands:");
617 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
618 pw.println(" Print carrier config values.");
619 pw.println(" Options are:");
620 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
621 pw.println(" is specified, it will choose the default voice SIM slot.");
622 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
623 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100624 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100625 pw.println(" Set carrier config KEY to NEW_VALUE.");
626 pw.println(" Options are:");
627 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
628 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100629 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100630 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
631 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
632 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
633 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000634 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
635 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
636 pw.println(" provided through standard input and follow CarrierConfig XML format.");
637 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
638 pw.println(" Options are:");
639 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
640 pw.println(" is specified, it will choose the default voice SIM slot.");
641 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100642 pw.println(" cc clear-values [-s SLOT_ID]");
643 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000644 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100645 pw.println(" Options are:");
646 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
647 pw.println(" is specified, it will choose the default voice SIM slot.");
648 }
649
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000650 private void onHelpEuicc() {
651 PrintWriter pw = getOutPrintWriter();
652 pw.println("Euicc Commands:");
653 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
654 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
655 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
656 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
657 }
658
Hui Wang641e81c2020-10-12 12:14:23 -0700659 private void onHelpGba() {
660 PrintWriter pw = getOutPrintWriter();
661 pw.println("Gba Commands:");
662 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
663 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
664 pw.println(" Options are:");
665 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
666 pw.println(" is specified, it will choose the default voice SIM slot.");
667 pw.println(" gba get-service [-s SLOT_ID]");
668 pw.println(" Gets the package name of the currently defined GbaService.");
669 pw.println(" Options are:");
670 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
671 pw.println(" is specified, it will choose the default voice SIM slot.");
672 pw.println(" gba set-release [-s SLOT_ID] n");
673 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
674 pw.println(" Do not release/unbind if n is -1.");
675 pw.println(" Options are:");
676 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
677 pw.println(" is specified, it will choose the default voice SIM slot.");
678 pw.println(" gba get-release [-s SLOT_ID]");
679 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
680 pw.println(" Options are:");
681 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
682 pw.println(" is specified, it will choose the default voice SIM slot.");
683 }
684
Hui Wang761a6682020-10-31 05:12:53 +0000685 private void onHelpSrc() {
686 PrintWriter pw = getOutPrintWriter();
687 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800688 pw.println(" src set-test-enabled true|false");
689 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
690 pw.println(" The value could be true, false, or null(undefined).");
691 pw.println(" src get-test-enabled");
692 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000693 pw.println(" src set-device-enabled true|false|null");
694 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
695 pw.println(" The value could be true, false, or null(undefined).");
696 pw.println(" src get-device-enabled");
697 pw.println(" Gets the device config for RCS VoLTE single registration.");
698 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
699 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
700 pw.println(" The value could be true, false, or null(undefined).");
701 pw.println(" Options are:");
702 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
703 pw.println(" is specified, it will choose the default voice SIM slot.");
704 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
705 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
706 pw.println(" Options are:");
707 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
708 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800709 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
710 pw.println(" Sets ims feature validation result.");
711 pw.println(" The value could be true, false, or null(undefined).");
712 pw.println(" Options are:");
713 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
714 pw.println(" is specified, it will choose the default voice SIM slot.");
715 pw.println(" src get-feature-validation [-s SLOT_ID]");
716 pw.println(" Gets ims feature validation override value.");
717 pw.println(" Options are:");
718 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
719 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000720 }
721
SongFerngWang98dd5992021-05-13 17:50:00 +0800722 private void onHelpAllowedNetworkTypes() {
723 PrintWriter pw = getOutPrintWriter();
724 pw.println("Allowed Network Types Commands:");
725 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
726 pw.println(" Print allowed network types value.");
727 pw.println(" Options are:");
728 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
729 pw.println(" option is specified, it will choose the default voice SIM slot.");
730 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
731 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
732 pw.println(" Options are:");
733 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
734 pw.println(" option is specified, it will choose the default voice SIM slot.");
735 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
736 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
737 pw.println(" at TelephonyManager.java");
738 pw.println(" For example:");
739 pw.println(" NR only : 10000000000000000000");
740 pw.println(" NR|LTE : 11000001000000000000");
741 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
742 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
743 pw.println(" LTE only : 01000001000000000000");
744 }
745
jimsun3b9ccac2021-10-26 15:01:23 +0800746 private void onHelpRadio() {
747 PrintWriter pw = getOutPrintWriter();
748 pw.println("Radio Commands:");
749 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
750 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
751 pw.println(" to be the bound. Options are:");
752 pw.println(" -s: the service name that the modem service should be bound for.");
753 pw.println(" If no option is specified, it will bind to the default.");
754 pw.println(" radio get-modem-service");
755 pw.println(" Gets the service name of the currently defined modem service.");
756 pw.println(" If it is binding to default, 'default' returns.");
757 pw.println(" If it doesn't bind to any modem service for some reasons,");
758 pw.println(" the result would be 'unknown'.");
759 }
760
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700761 private void onHelpSatellite() {
762 PrintWriter pw = getOutPrintWriter();
763 pw.println("Satellite Commands:");
764 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
765 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700766 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700767 pw.println(" -s: the satellite service package name that Telephony will bind to.");
768 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700769 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
770 pw.println(" Sets the package name of satellite gateway service defined in");
771 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
772 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
773 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700774 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
775 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
776 pw.println(" mode. Options are:");
777 pw.println(" -t: the timeout duration in milliseconds.");
778 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700779 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
780 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
781 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
782 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
783 pw.println(" launch. If no option is specified, it will launch the default.");
784 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
785 pw.println(" launch.");
Thomas Nguyen11a051f2023-10-25 10:14:55 -0700786 pw.println(" set-emergency-call-to-satellite-handover-type [-t HANDOVER_TYPE ");
787 pw.println(" -d DELAY_SECONDS] Override connectivity status in monitoring emergency ");
788 pw.println(" call and sending EVENT_DISPLAY_EMERGENCY_MESSAGE to Dialer.");
789 pw.println(" Options are:");
790 pw.println(" -t: the emergency call to satellite handover type.");
791 pw.println(" If no option is specified, override is disabled.");
792 pw.println(" -d: the delay in seconds in sending EVENT_DISPLAY_EMERGENCY_MESSAGE.");
793 pw.println(" If no option is specified, there is no delay in sending the event.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700794 }
795
Ling Ma4fbab492022-01-25 22:36:16 +0000796 private void onHelpImei() {
797 PrintWriter pw = getOutPrintWriter();
798 pw.println("IMEI Commands:");
799 pw.println(" get-imei [-s SLOT_ID]");
800 pw.println(" Gets the device IMEI. Options are:");
801 pw.println(" -s: the slot ID to get the IMEI. If no option");
802 pw.println(" is specified, it will choose the default voice SIM slot.");
803 }
804
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700805 private int handleImsCommand() {
806 String arg = getNextArg();
807 if (arg == null) {
808 onHelpIms();
809 return 0;
810 }
811
812 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800813 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700814 return handleImsSetServiceCommand();
815 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800816 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700817 return handleImsGetServiceCommand();
818 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800819 case IMS_CLEAR_SERVICE_OVERRIDE: {
820 return handleImsClearCarrierServiceCommand();
821 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800822 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700823 return handleEnableIms();
824 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800825 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700826 return handleDisableIms();
827 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700828 case IMS_CEP: {
829 return handleCepChange();
830 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700831 }
832
833 return -1;
834 }
835
Shuo Qianf5125122019-12-16 17:03:07 -0800836 private int handleDataTestModeCommand() {
837 PrintWriter errPw = getErrPrintWriter();
838 String arg = getNextArgRequired();
839 if (arg == null) {
840 onHelpDataTestMode();
841 return 0;
842 }
843 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800844 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800845 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700846 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800847 } catch (RemoteException ex) {
848 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
849 errPw.println("Exception: " + ex.getMessage());
850 return -1;
851 }
852 break;
853 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800854 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800855 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700856 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800857 } catch (RemoteException ex) {
858 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
859 errPw.println("Exception: " + ex.getMessage());
860 return -1;
861 }
862 break;
863 }
864 default:
865 onHelpDataTestMode();
866 break;
867 }
868 return 0;
869 }
870
Shuo Qianccbaf742021-02-22 18:32:21 -0800871 private int handleEmergencyCallbackModeCommand() {
872 PrintWriter errPw = getErrPrintWriter();
873 try {
874 mInterface.startEmergencyCallbackMode();
875 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
876 } catch (RemoteException ex) {
877 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
878 errPw.println("Exception: " + ex.getMessage());
879 return -1;
880 }
881 return 0;
882 }
883
Grant Menke567d48f2022-08-18 20:19:10 +0000884 private void removeEmergencyNumberTestMode(String emergencyNumber) {
885 PrintWriter errPw = getErrPrintWriter();
886 for (int routingType : ROUTING_TYPES) {
887 try {
888 mInterface.updateEmergencyNumberListTestMode(
889 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
890 new EmergencyNumber(emergencyNumber, "", "",
891 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
892 new ArrayList<String>(),
893 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
894 routingType));
895 } catch (RemoteException ex) {
896 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
897 errPw.println("Exception: " + ex.getMessage());
898 }
899 }
900 }
901
sqian9d4df8b2019-01-15 18:32:07 -0800902 private int handleEmergencyNumberTestModeCommand() {
903 PrintWriter errPw = getErrPrintWriter();
904 String opt = getNextOption();
905 if (opt == null) {
906 onHelpEmergencyNumber();
907 return 0;
908 }
sqian9d4df8b2019-01-15 18:32:07 -0800909 switch (opt) {
910 case "-a": {
911 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000912 if (emergencyNumberCmd == null){
913 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800914 return -1;
915 }
Grant Menke567d48f2022-08-18 20:19:10 +0000916 String[] params = emergencyNumberCmd.split(":");
917 String emergencyNumber;
918 if (params[0] == null ||
919 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
920 errPw.println(INVALID_ENTRY_ERROR);
921 return -1;
922 } else {
923 emergencyNumber = params[0];
924 }
925 removeEmergencyNumberTestMode(emergencyNumber);
926 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
927 if (params.length > 1) {
928 switch (params[1].toLowerCase(Locale.ROOT)) {
929 case "emergency":
930 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
931 break;
932 case "normal":
933 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
934 break;
935 case "unknown":
936 break;
937 default:
938 errPw.println("\"" + params[1] + "\" is not a valid specification for "
939 + "emergency call routing. Please enter either \"normal\", "
940 + "\"unknown\", or \"emergency\" for call routing. "
941 + "(-a 1234:normal)");
942 return -1;
943 }
944 }
sqian9d4df8b2019-01-15 18:32:07 -0800945 try {
946 mInterface.updateEmergencyNumberListTestMode(
947 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +0000948 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -0800949 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
950 new ArrayList<String>(),
951 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +0000952 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -0800953 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +0000954 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -0800955 + ", error " + ex.getMessage());
956 errPw.println("Exception: " + ex.getMessage());
957 return -1;
958 }
959 break;
960 }
961 case "-c": {
962 try {
963 mInterface.updateEmergencyNumberListTestMode(
964 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
965 } catch (RemoteException ex) {
966 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
967 errPw.println("Exception: " + ex.getMessage());
968 return -1;
969 }
970 break;
971 }
972 case "-r": {
973 String emergencyNumberCmd = getNextArgRequired();
974 if (emergencyNumberCmd == null
975 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700976 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800977 + " to be specified after -r in the command ");
978 return -1;
979 }
Grant Menke567d48f2022-08-18 20:19:10 +0000980 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -0800981 break;
982 }
983 case "-p": {
984 try {
985 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
986 } catch (RemoteException ex) {
987 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
988 errPw.println("Exception: " + ex.getMessage());
989 return -1;
990 }
991 break;
992 }
993 default:
994 onHelpEmergencyNumber();
995 break;
996 }
997 return 0;
998 }
999
Hall Liud892bec2018-11-30 14:51:45 -08001000 private int handleNumberVerificationCommand() {
1001 String arg = getNextArg();
1002 if (arg == null) {
1003 onHelpNumberVerification();
1004 return 0;
1005 }
1006
Hall Liuca5af3a2018-12-04 16:58:23 -08001007 if (!checkShellUid()) {
1008 return -1;
1009 }
1010
Hall Liud892bec2018-11-30 14:51:45 -08001011 switch (arg) {
1012 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001013 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1014 return 0;
1015 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001016 case NUMBER_VERIFICATION_FAKE_CALL: {
1017 boolean val = NumberVerificationManager.getInstance()
1018 .checkIncomingCall(getNextArg());
1019 getOutPrintWriter().println(val ? "1" : "0");
1020 return 0;
1021 }
Hall Liud892bec2018-11-30 14:51:45 -08001022 }
1023
1024 return -1;
1025 }
1026
Jordan Liu0ccee222021-04-27 11:55:13 -07001027 private boolean subIsEsim(int subId) {
1028 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1029 if (info != null) {
1030 return info.isEmbedded();
1031 }
1032 return false;
1033 }
1034
1035 private int handleEnablePhysicalSubscription(boolean enable) {
1036 PrintWriter errPw = getErrPrintWriter();
1037 int subId = 0;
1038 try {
1039 subId = Integer.parseInt(getNextArgRequired());
1040 } catch (NumberFormatException e) {
1041 errPw.println((enable ? "enable" : "disable")
1042 + "-physical-subscription requires an integer as a subId.");
1043 return -1;
1044 }
1045 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1046 // non user build.
1047 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1048 errPw.println("cc: Permission denied.");
1049 return -1;
1050 }
1051 // Verify that the subId represents a physical sub
1052 if (subIsEsim(subId)) {
1053 errPw.println("SubId " + subId + " is not for a physical subscription");
1054 return -1;
1055 }
1056 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1057 + " physical subscription with subId=" + subId);
1058 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1059 return 0;
1060 }
1061
Jack Nudelman644b91a2021-03-12 14:09:48 -08001062 private int handleThermalMitigationCommand() {
1063 String arg = getNextArg();
1064 String packageName = getNextArg();
1065 if (arg == null || packageName == null) {
1066 onHelpThermalMitigation();
1067 return 0;
1068 }
1069
1070 if (!checkShellUid()) {
1071 return -1;
1072 }
1073
1074 switch (arg) {
1075 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1076 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1077 return 0;
1078 }
1079 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1080 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1081 mContext);
1082 return 0;
1083 }
1084 default:
1085 onHelpThermalMitigation();
1086 }
1087
1088 return -1;
1089
1090 }
1091
Tyler Gunn92479152021-01-20 16:30:10 -08001092 private int handleD2dCommand() {
1093 String arg = getNextArg();
1094 if (arg == null) {
1095 onHelpD2D();
1096 return 0;
1097 }
1098
1099 switch (arg) {
1100 case D2D_SEND: {
1101 return handleD2dSendCommand();
1102 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001103 case D2D_TRANSPORT: {
1104 return handleD2dTransportCommand();
1105 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001106 case D2D_SET_DEVICE_SUPPORT: {
1107 return handleD2dDeviceSupportedCommand();
1108 }
Tyler Gunn92479152021-01-20 16:30:10 -08001109 }
1110
1111 return -1;
1112 }
1113
1114 private int handleD2dSendCommand() {
1115 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001116 int messageType = -1;
1117 int messageValue = -1;
1118
Tyler Gunn92479152021-01-20 16:30:10 -08001119 String arg = getNextArg();
1120 if (arg == null) {
1121 onHelpD2D();
1122 return 0;
1123 }
1124 try {
1125 messageType = Integer.parseInt(arg);
1126 } catch (NumberFormatException e) {
1127 errPw.println("message type must be a valid integer");
1128 return -1;
1129 }
1130
1131 arg = getNextArg();
1132 if (arg == null) {
1133 onHelpD2D();
1134 return 0;
1135 }
1136 try {
1137 messageValue = Integer.parseInt(arg);
1138 } catch (NumberFormatException e) {
1139 errPw.println("message value must be a valid integer");
1140 return -1;
1141 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001142
Tyler Gunn92479152021-01-20 16:30:10 -08001143 try {
1144 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1145 } catch (RemoteException e) {
1146 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1147 errPw.println("Exception: " + e.getMessage());
1148 return -1;
1149 }
1150
1151 return 0;
1152 }
1153
Tyler Gunnbabbda02021-02-10 11:05:02 -08001154 private int handleD2dTransportCommand() {
1155 PrintWriter errPw = getErrPrintWriter();
1156
1157 String arg = getNextArg();
1158 if (arg == null) {
1159 onHelpD2D();
1160 return 0;
1161 }
1162
1163 try {
1164 mInterface.setActiveDeviceToDeviceTransport(arg);
1165 } catch (RemoteException e) {
1166 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1167 errPw.println("Exception: " + e.getMessage());
1168 return -1;
1169 }
1170 return 0;
1171 }
Nazanin014f41e2021-05-06 17:26:31 -07001172 private int handleBarringCommand() {
1173 String arg = getNextArg();
1174 if (arg == null) {
1175 onHelpBarring();
1176 return 0;
1177 }
1178
1179 switch (arg) {
1180 case BARRING_SEND_INFO: {
1181 return handleBarringSendCommand();
1182 }
1183 }
1184 return -1;
1185 }
1186
1187 private int handleBarringSendCommand() {
1188 PrintWriter errPw = getErrPrintWriter();
1189 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001190 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001191 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1192 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1193 boolean isConditionallyBarred = false;
1194 int conditionalBarringTimeSeconds = 0;
1195
1196 String opt;
1197 while ((opt = getNextOption()) != null) {
1198 switch (opt) {
1199 case "-s": {
1200 try {
1201 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001202 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001203 } catch (NumberFormatException e) {
1204 errPw.println("barring send requires an integer as a SLOT_ID.");
1205 return -1;
1206 }
1207 break;
1208 }
1209 case "-b": {
1210 try {
1211 barringType = Integer.parseInt(getNextArgRequired());
1212 if (barringType < -1 || barringType > 2) {
1213 throw new NumberFormatException();
1214 }
1215
1216 } catch (NumberFormatException e) {
1217 errPw.println("barring send requires an integer in range [-1,2] as "
1218 + "a BARRING_TYPE.");
1219 return -1;
1220 }
1221 break;
1222 }
1223 case "-c": {
1224 try {
1225 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1226 } catch (Exception e) {
1227 errPw.println("barring send requires a boolean after -c indicating"
1228 + " conditional barring");
1229 return -1;
1230 }
1231 break;
1232 }
1233 case "-t": {
1234 try {
1235 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1236 } catch (NumberFormatException e) {
1237 errPw.println("barring send requires an integer for time of barring"
1238 + " in seconds after -t for conditional barring");
1239 return -1;
1240 }
1241 break;
1242 }
1243 }
1244 }
1245 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1246 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1247 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1248 barringServiceInfos.append(0, bsi);
1249 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1250 try {
1251 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1252 } catch (Exception e) {
1253 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1254 errPw.println("Exception: " + e.getMessage());
1255 return -1;
1256 }
1257 return 0;
1258 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001259
Tyler Gunnd4575212021-05-03 14:46:49 -07001260 private int handleD2dDeviceSupportedCommand() {
1261 PrintWriter errPw = getErrPrintWriter();
1262
1263 String arg = getNextArg();
1264 if (arg == null) {
1265 onHelpD2D();
1266 return 0;
1267 }
1268
Jack Yua533d632022-09-30 13:53:46 -07001269 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001270 try {
1271 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1272 } catch (RemoteException e) {
1273 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1274 errPw.println("Exception: " + e.getMessage());
1275 return -1;
1276 }
1277 return 0;
1278 }
1279
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001280 // ims set-ims-service
1281 private int handleImsSetServiceCommand() {
1282 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001283 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001284 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001285 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001286
1287 String opt;
1288 while ((opt = getNextOption()) != null) {
1289 switch (opt) {
1290 case "-s": {
1291 try {
1292 slotId = Integer.parseInt(getNextArgRequired());
1293 } catch (NumberFormatException e) {
1294 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1295 return -1;
1296 }
1297 break;
1298 }
1299 case "-c": {
1300 isCarrierService = true;
1301 break;
1302 }
1303 case "-d": {
1304 isCarrierService = false;
1305 break;
1306 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001307 case "-f": {
1308 String featureString = getNextArgRequired();
1309 String[] features = featureString.split(",");
1310 for (int i = 0; i < features.length; i++) {
1311 try {
1312 Integer result = Integer.parseInt(features[i]);
1313 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1314 || result >= ImsFeature.FEATURE_MAX) {
1315 errPw.println("ims set-ims-service -f " + result
1316 + " is an invalid feature.");
1317 return -1;
1318 }
1319 featuresList.add(result);
1320 } catch (NumberFormatException e) {
1321 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1322 + " as an integer.");
1323 return -1;
1324 }
1325 }
1326 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001327 }
1328 }
1329 // Mandatory param, either -c or -d
1330 if (isCarrierService == null) {
1331 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1332 return -1;
1333 }
1334
1335 String packageName = getNextArg();
1336
1337 try {
1338 if (packageName == null) {
1339 packageName = "";
1340 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001341 int[] featureArray = new int[featuresList.size()];
1342 for (int i = 0; i < featuresList.size(); i++) {
1343 featureArray[i] = featuresList.get(i);
1344 }
1345 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1346 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 if (VDBG) {
1348 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001349 + (isCarrierService ? "-c " : "-d ")
1350 + "-f " + featuresList + " "
1351 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001352 }
1353 getOutPrintWriter().println(result);
1354 } catch (RemoteException e) {
1355 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001356 + (isCarrierService ? "-c " : "-d ")
1357 + "-f " + featuresList + " "
1358 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001359 errPw.println("Exception: " + e.getMessage());
1360 return -1;
1361 }
1362 return 0;
1363 }
1364
Brad Ebinger999d3302020-11-25 14:31:39 -08001365 // ims clear-ims-service-override
1366 private int handleImsClearCarrierServiceCommand() {
1367 PrintWriter errPw = getErrPrintWriter();
1368 int slotId = getDefaultSlot();
1369
1370 String opt;
1371 while ((opt = getNextOption()) != null) {
1372 switch (opt) {
1373 case "-s": {
1374 try {
1375 slotId = Integer.parseInt(getNextArgRequired());
1376 } catch (NumberFormatException e) {
1377 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1378 return -1;
1379 }
1380 break;
1381 }
1382 }
1383 }
1384
1385 try {
1386 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1387 if (VDBG) {
1388 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1389 + ", result=" + result);
1390 }
1391 getOutPrintWriter().println(result);
1392 } catch (RemoteException e) {
1393 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1394 + ", error" + e.getMessage());
1395 errPw.println("Exception: " + e.getMessage());
1396 return -1;
1397 }
1398 return 0;
1399 }
1400
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001401 // ims get-ims-service
1402 private int handleImsGetServiceCommand() {
1403 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001404 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001405 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001406 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001407
1408 String opt;
1409 while ((opt = getNextOption()) != null) {
1410 switch (opt) {
1411 case "-s": {
1412 try {
1413 slotId = Integer.parseInt(getNextArgRequired());
1414 } catch (NumberFormatException e) {
1415 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1416 return -1;
1417 }
1418 break;
1419 }
1420 case "-c": {
1421 isCarrierService = true;
1422 break;
1423 }
1424 case "-d": {
1425 isCarrierService = false;
1426 break;
1427 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001428 case "-f": {
1429 try {
1430 featureType = Integer.parseInt(getNextArg());
1431 } catch (NumberFormatException e) {
1432 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1433 return -1;
1434 }
1435 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1436 || featureType >= ImsFeature.FEATURE_MAX) {
1437 errPw.println("ims get-ims-service -f invalid feature.");
1438 return -1;
1439 }
1440 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001441 }
1442 }
1443 // Mandatory param, either -c or -d
1444 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001445 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001446 return -1;
1447 }
1448
1449 String result;
1450 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001451 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001452 } catch (RemoteException e) {
1453 return -1;
1454 }
1455 if (VDBG) {
1456 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001457 + (isCarrierService ? "-c " : "-d ")
1458 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1459 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001460 }
1461 getOutPrintWriter().println(result);
1462 return 0;
1463 }
1464
1465 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001466 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001467 String opt;
1468 while ((opt = getNextOption()) != null) {
1469 switch (opt) {
1470 case "-s": {
1471 try {
1472 slotId = Integer.parseInt(getNextArgRequired());
1473 } catch (NumberFormatException e) {
1474 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1475 return -1;
1476 }
1477 break;
1478 }
1479 }
1480 }
1481 try {
1482 mInterface.enableIms(slotId);
1483 } catch (RemoteException e) {
1484 return -1;
1485 }
1486 if (VDBG) {
1487 Log.v(LOG_TAG, "ims enable -s " + slotId);
1488 }
1489 return 0;
1490 }
1491
1492 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001493 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001494 String opt;
1495 while ((opt = getNextOption()) != null) {
1496 switch (opt) {
1497 case "-s": {
1498 try {
1499 slotId = Integer.parseInt(getNextArgRequired());
1500 } catch (NumberFormatException e) {
1501 getErrPrintWriter().println(
1502 "ims disable requires an integer as a SLOT_ID.");
1503 return -1;
1504 }
1505 break;
1506 }
1507 }
1508 }
1509 try {
1510 mInterface.disableIms(slotId);
1511 } catch (RemoteException e) {
1512 return -1;
1513 }
1514 if (VDBG) {
1515 Log.v(LOG_TAG, "ims disable -s " + slotId);
1516 }
1517 return 0;
1518 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001519
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001520 private int handleCepChange() {
1521 Log.i(LOG_TAG, "handleCepChange");
1522 String opt = getNextArg();
1523 if (opt == null) {
1524 return -1;
1525 }
1526 boolean isCepEnabled = opt.equals("enable");
1527
1528 try {
1529 mInterface.setCepEnabled(isCepEnabled);
1530 } catch (RemoteException e) {
1531 return -1;
1532 }
1533 return 0;
1534 }
1535
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001536 private int getDefaultSlot() {
1537 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1538 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1539 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1540 // If there is no default, default to slot 0.
1541 slotId = DEFAULT_PHONE_ID;
1542 }
1543 return slotId;
1544 }
sqian2fff4a32018-11-05 14:18:37 -08001545
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001546 // Parse options related to Carrier Config Commands.
1547 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001548 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001549 CcOptionParseResult result = new CcOptionParseResult();
1550 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1551 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001552
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001553 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001554 while ((opt = getNextOption()) != null) {
1555 switch (opt) {
1556 case "-s": {
1557 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001558 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1559 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1560 errPw.println(tag + "No valid subscription found.");
1561 return null;
1562 }
1563
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001564 } catch (IllegalArgumentException e) {
1565 // Missing slot id
1566 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001567 return null;
1568 }
1569 break;
1570 }
1571 case "-p": {
1572 if (allowOptionPersistent) {
1573 result.mPersistent = true;
1574 } else {
1575 errPw.println(tag + "Unexpected option " + opt);
1576 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001577 }
1578 break;
1579 }
1580 default: {
1581 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001582 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001583 }
1584 }
1585 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001586 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001587 }
1588
1589 private int slotStringToSubId(String tag, String slotString) {
1590 int slotId = -1;
1591 try {
1592 slotId = Integer.parseInt(slotString);
1593 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001594 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1595 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1596 }
1597
1598 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001599 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1600 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1601 }
1602
Qiong Liuf25799b2020-09-10 10:13:46 +08001603 Phone phone = PhoneFactory.getPhone(slotId);
1604 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001605 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1606 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1607 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001608 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001609 }
1610
Hall Liud892bec2018-11-30 14:51:45 -08001611 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001612 // adb can run as root or as shell, depending on whether the device is rooted.
1613 return Binder.getCallingUid() == Process.SHELL_UID
1614 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001615 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001616
1617 private int handleCcCommand() {
1618 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1619 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001620 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001621 getErrPrintWriter().println("cc: Permission denied.");
1622 return -1;
1623 }
1624
1625 String arg = getNextArg();
1626 if (arg == null) {
1627 onHelpCc();
1628 return 0;
1629 }
1630
1631 switch (arg) {
1632 case CC_GET_VALUE: {
1633 return handleCcGetValue();
1634 }
1635 case CC_SET_VALUE: {
1636 return handleCcSetValue();
1637 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001638 case CC_SET_VALUES_FROM_XML: {
1639 return handleCcSetValuesFromXml();
1640 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001641 case CC_CLEAR_VALUES: {
1642 return handleCcClearValues();
1643 }
1644 default: {
1645 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1646 }
1647 }
1648 return -1;
1649 }
1650
1651 // cc get-value
1652 private int handleCcGetValue() {
1653 PrintWriter errPw = getErrPrintWriter();
1654 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1655 String key = null;
1656
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001657 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001658 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001659 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001660 return -1;
1661 }
1662
1663 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001664 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001665 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001666 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001667 return -1;
1668 }
1669
1670 // Get the key.
1671 key = getNextArg();
1672 if (key != null) {
1673 // A key was provided. Verify if it is a valid key
1674 if (!bundle.containsKey(key)) {
1675 errPw.println(tag + key + " is not a valid key.");
1676 return -1;
1677 }
1678
1679 // Print the carrier config value for key.
1680 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1681 } else {
1682 // No key provided. Show all values.
1683 // Iterate over a sorted list of all carrier config keys and print them.
1684 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1685 for (String k : sortedSet) {
1686 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1687 }
1688 }
1689 return 0;
1690 }
1691
1692 // cc set-value
1693 private int handleCcSetValue() {
1694 PrintWriter errPw = getErrPrintWriter();
1695 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1696
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001697 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001698 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001699 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001700 return -1;
1701 }
1702
1703 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001704 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001705 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001706 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001707 return -1;
1708 }
1709
1710 // Get the key.
1711 String key = getNextArg();
1712 if (key == null || key.equals("")) {
1713 errPw.println(tag + "KEY is missing");
1714 return -1;
1715 }
1716
1717 // Verify if the key is valid
1718 if (!originalValues.containsKey(key)) {
1719 errPw.println(tag + key + " is not a valid key.");
1720 return -1;
1721 }
1722
1723 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1724 ArrayList<String> valueList = new ArrayList<String>();
1725 while (peekNextArg() != null) {
1726 valueList.add(getNextArg());
1727 }
1728
1729 // Find the type of the carrier config value
1730 CcType type = getType(tag, key, originalValues);
1731 if (type == CcType.UNKNOWN) {
1732 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1733 return -1;
1734 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001735 if (type == CcType.PERSISTABLE_BUNDLE) {
1736 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1737 + "Use set-values-from-xml instead.");
1738 return -1;
1739 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001740
1741 // Create an override bundle containing the key and value that should be overriden.
1742 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1743 if (overrideBundle == null) {
1744 return -1;
1745 }
1746
1747 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001748 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001749
1750 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001751 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001752 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001753 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001754 return -1;
1755 }
1756
1757 // Print the original and new value.
1758 String originalValueString = ccValueToString(key, type, originalValues);
1759 String newValueString = ccValueToString(key, type, newValues);
1760 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1761 getOutPrintWriter().println("New value: \n" + newValueString);
1762
1763 return 0;
1764 }
1765
Allen Xuee00f0e2022-03-14 21:04:49 +00001766 // cc set-values-from-xml
1767 private int handleCcSetValuesFromXml() {
1768 PrintWriter errPw = getErrPrintWriter();
1769 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1770
1771 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001772 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001773 if (options == null) {
1774 return -1;
1775 }
1776
1777 // Get bundle containing all current carrier configuration values.
1778 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1779 if (originalValues == null) {
1780 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1781 return -1;
1782 }
1783
1784 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1785 if (overrideBundle == null) {
1786 return -1;
1787 }
1788
1789 // Verify all values are valid types
1790 for (String key : overrideBundle.keySet()) {
1791 CcType type = getType(tag, key, originalValues);
1792 if (type == CcType.UNKNOWN) {
1793 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1794 return -1;
1795 }
1796 }
1797
1798 // Override the value
1799 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1800
1801 // Find bundle containing all new carrier configuration values after the override.
1802 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1803 if (newValues == null) {
1804 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1805 return -1;
1806 }
1807
1808 // Print the original and new values
1809 overrideBundle.keySet().forEach(key -> {
1810 CcType type = getType(tag, key, originalValues);
1811 String originalValueString = ccValueToString(key, type, originalValues);
1812 String newValueString = ccValueToString(key, type, newValues);
1813 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1814 getOutPrintWriter().println("New value: \n" + newValueString);
1815 });
1816
1817 return 0;
1818 }
1819
1820 private PersistableBundle readPersistableBundleFromXml(String tag) {
1821 PersistableBundle subIdBundles;
1822 try {
1823 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1824 } catch (IOException | RuntimeException e) {
1825 PrintWriter errPw = getErrPrintWriter();
1826 errPw.println(tag + e);
1827 return null;
1828 }
1829
1830 return subIdBundles;
1831 }
1832
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001833 // cc clear-values
1834 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001835 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1836
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001837 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001838 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001839 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001840 return -1;
1841 }
1842
1843 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001844 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001845 getOutPrintWriter()
1846 .println("All previously set carrier config override values has been cleared");
1847 return 0;
1848 }
1849
1850 private CcType getType(String tag, String key, PersistableBundle bundle) {
1851 // Find the type by checking the type of the current value stored in the bundle.
1852 Object value = bundle.get(key);
1853
1854 if (CC_TYPE_MAP.containsKey(key)) {
1855 return CC_TYPE_MAP.get(key);
1856 } else if (value != null) {
1857 if (value instanceof Boolean) {
1858 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001859 }
1860 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001861 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001862 }
1863 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001864 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001865 }
1866 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001867 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001868 }
1869 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001870 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001871 }
1872 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001873 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001874 }
1875 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001876 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001877 }
1878 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001879 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001880 }
1881 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001882 return CcType.STRING_ARRAY;
1883 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001884 if (value instanceof PersistableBundle) {
1885 return CcType.PERSISTABLE_BUNDLE;
1886 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001887 } else {
1888 // Current value was null and can therefore not be used in order to find the type.
1889 // Check the name of the key to infer the type. This check is not needed for primitive
1890 // data types (boolean, double, int and long), since they can not be null.
1891 if (key.endsWith("double_array")) {
1892 return CcType.DOUBLE_ARRAY;
1893 }
1894 if (key.endsWith("int_array")) {
1895 return CcType.INT_ARRAY;
1896 }
1897 if (key.endsWith("long_array")) {
1898 return CcType.LONG_ARRAY;
1899 }
1900 if (key.endsWith("string")) {
1901 return CcType.STRING;
1902 }
1903 if (key.endsWith("string_array") || key.endsWith("strings")) {
1904 return CcType.STRING_ARRAY;
1905 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001906 if (key.endsWith("bundle")) {
1907 return CcType.PERSISTABLE_BUNDLE;
1908 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001909 }
1910
1911 // Not possible to infer the type by looking at the current value or the key.
1912 PrintWriter errPw = getErrPrintWriter();
1913 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1914 return CcType.UNKNOWN;
1915 }
1916
1917 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1918 String result;
1919 StringBuilder valueString = new StringBuilder();
1920 String typeString = type.toString();
1921 Object value = bundle.get(key);
1922
1923 if (value == null) {
1924 valueString.append("null");
1925 } else {
1926 switch (type) {
1927 case DOUBLE_ARRAY: {
1928 // Format the string representation of the int array as value1 value2......
1929 double[] valueArray = (double[]) value;
1930 for (int i = 0; i < valueArray.length; i++) {
1931 if (i != 0) {
1932 valueString.append(" ");
1933 }
1934 valueString.append(valueArray[i]);
1935 }
1936 break;
1937 }
1938 case INT_ARRAY: {
1939 // Format the string representation of the int array as value1 value2......
1940 int[] valueArray = (int[]) value;
1941 for (int i = 0; i < valueArray.length; i++) {
1942 if (i != 0) {
1943 valueString.append(" ");
1944 }
1945 valueString.append(valueArray[i]);
1946 }
1947 break;
1948 }
1949 case LONG_ARRAY: {
1950 // Format the string representation of the int array as value1 value2......
1951 long[] valueArray = (long[]) value;
1952 for (int i = 0; i < valueArray.length; i++) {
1953 if (i != 0) {
1954 valueString.append(" ");
1955 }
1956 valueString.append(valueArray[i]);
1957 }
1958 break;
1959 }
1960 case STRING: {
1961 valueString.append("\"" + value.toString() + "\"");
1962 break;
1963 }
1964 case STRING_ARRAY: {
1965 // Format the string representation of the string array as "value1" "value2"....
1966 String[] valueArray = (String[]) value;
1967 for (int i = 0; i < valueArray.length; i++) {
1968 if (i != 0) {
1969 valueString.append(" ");
1970 }
1971 if (valueArray[i] != null) {
1972 valueString.append("\"" + valueArray[i] + "\"");
1973 } else {
1974 valueString.append("null");
1975 }
1976 }
1977 break;
1978 }
1979 default: {
1980 valueString.append(value.toString());
1981 }
1982 }
1983 }
1984 return String.format("%-70s %-15s %s", key, typeString, valueString);
1985 }
1986
1987 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1988 ArrayList<String> valueList) {
1989 PrintWriter errPw = getErrPrintWriter();
1990 PersistableBundle bundle = new PersistableBundle();
1991
1992 // First verify that a valid number of values has been provided for the type.
1993 switch (type) {
1994 case BOOLEAN:
1995 case DOUBLE:
1996 case INT:
1997 case LONG: {
1998 if (valueList.size() != 1) {
1999 errPw.println(tag + "Expected 1 value for type " + type
2000 + ". Found: " + valueList.size());
2001 return null;
2002 }
2003 break;
2004 }
2005 case STRING: {
2006 if (valueList.size() > 1) {
2007 errPw.println(tag + "Expected 0 or 1 values for type " + type
2008 + ". Found: " + valueList.size());
2009 return null;
2010 }
2011 break;
2012 }
2013 }
2014
2015 // Parse the value according to type and add it to the Bundle.
2016 switch (type) {
2017 case BOOLEAN: {
2018 if ("true".equalsIgnoreCase(valueList.get(0))) {
2019 bundle.putBoolean(key, true);
2020 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2021 bundle.putBoolean(key, false);
2022 } else {
2023 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2024 return null;
2025 }
2026 break;
2027 }
2028 case DOUBLE: {
2029 try {
2030 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2031 } catch (NumberFormatException nfe) {
2032 // Not a valid double
2033 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2034 return null;
2035 }
2036 break;
2037 }
2038 case DOUBLE_ARRAY: {
2039 double[] valueDoubleArray = null;
2040 if (valueList.size() > 0) {
2041 valueDoubleArray = new double[valueList.size()];
2042 for (int i = 0; i < valueList.size(); i++) {
2043 try {
2044 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2045 } catch (NumberFormatException nfe) {
2046 // Not a valid double
2047 errPw.println(
2048 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2049 return null;
2050 }
2051 }
2052 }
2053 bundle.putDoubleArray(key, valueDoubleArray);
2054 break;
2055 }
2056 case INT: {
2057 try {
2058 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2059 } catch (NumberFormatException nfe) {
2060 // Not a valid integer
2061 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2062 return null;
2063 }
2064 break;
2065 }
2066 case INT_ARRAY: {
2067 int[] valueIntArray = null;
2068 if (valueList.size() > 0) {
2069 valueIntArray = new int[valueList.size()];
2070 for (int i = 0; i < valueList.size(); i++) {
2071 try {
2072 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2073 } catch (NumberFormatException nfe) {
2074 // Not a valid integer
2075 errPw.println(tag
2076 + "Unable to parse " + valueList.get(i) + " as an integer.");
2077 return null;
2078 }
2079 }
2080 }
2081 bundle.putIntArray(key, valueIntArray);
2082 break;
2083 }
2084 case LONG: {
2085 try {
2086 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2087 } catch (NumberFormatException nfe) {
2088 // Not a valid long
2089 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2090 return null;
2091 }
2092 break;
2093 }
2094 case LONG_ARRAY: {
2095 long[] valueLongArray = null;
2096 if (valueList.size() > 0) {
2097 valueLongArray = new long[valueList.size()];
2098 for (int i = 0; i < valueList.size(); i++) {
2099 try {
2100 valueLongArray[i] = Long.parseLong(valueList.get(i));
2101 } catch (NumberFormatException nfe) {
2102 // Not a valid long
2103 errPw.println(
2104 tag + "Unable to parse " + valueList.get(i) + " as a long");
2105 return null;
2106 }
2107 }
2108 }
2109 bundle.putLongArray(key, valueLongArray);
2110 break;
2111 }
2112 case STRING: {
2113 String value = null;
2114 if (valueList.size() > 0) {
2115 value = valueList.get(0);
2116 }
2117 bundle.putString(key, value);
2118 break;
2119 }
2120 case STRING_ARRAY: {
2121 String[] valueStringArray = null;
2122 if (valueList.size() > 0) {
2123 valueStringArray = new String[valueList.size()];
2124 valueList.toArray(valueStringArray);
2125 }
2126 bundle.putStringArray(key, valueStringArray);
2127 break;
2128 }
2129 }
2130 return bundle;
2131 }
Shuo Qian489d9282020-07-09 11:30:03 -07002132
2133 private int handleEndBlockSuppressionCommand() {
2134 if (!checkShellUid()) {
2135 return -1;
2136 }
2137
2138 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2139 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2140 }
2141 return 0;
2142 }
Hui Wang641e81c2020-10-12 12:14:23 -07002143
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002144 private int handleEuiccCommand() {
2145 String arg = getNextArg();
2146 if (arg == null) {
2147 onHelpEuicc();
2148 return 0;
2149 }
2150
2151 switch (arg) {
2152 case EUICC_SET_UI_COMPONENT: {
2153 return handleEuiccServiceCommand();
2154 }
2155 }
2156 return -1;
2157 }
2158
2159 private int handleEuiccServiceCommand() {
2160 String uiComponent = getNextArg();
2161 String packageName = getNextArg();
2162 if (packageName == null || uiComponent == null) {
2163 return -1;
2164 }
2165 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2166 if (VDBG) {
2167 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2168 + packageName);
2169 }
2170 return 0;
2171 }
2172
Michele Berionne54af4632020-12-28 20:23:16 +00002173 private int handleRestartModemCommand() {
2174 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2175 // non user build.
2176 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2177 getErrPrintWriter().println("RestartModem: Permission denied.");
2178 return -1;
2179 }
2180
2181 boolean result = TelephonyManager.getDefault().rebootRadio();
2182 getOutPrintWriter().println(result);
2183
2184 return result ? 0 : -1;
2185 }
2186
Ling Ma4fbab492022-01-25 22:36:16 +00002187 private int handleGetImei() {
2188 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2189 // non user build.
2190 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2191 getErrPrintWriter().println("Device IMEI: Permission denied.");
2192 return -1;
2193 }
2194
2195 final long identity = Binder.clearCallingIdentity();
2196
2197 String imei = null;
2198 String arg = getNextArg();
2199 if (arg != null) {
2200 try {
2201 int specifiedSlotIndex = Integer.parseInt(arg);
2202 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2203 } catch (NumberFormatException exception) {
2204 PrintWriter errPw = getErrPrintWriter();
2205 errPw.println("-s requires an integer as slot index.");
2206 return -1;
2207 }
2208
2209 } else {
2210 imei = TelephonyManager.from(mContext).getImei();
2211 }
2212 getOutPrintWriter().println("Device IMEI: " + imei);
2213
2214 Binder.restoreCallingIdentity(identity);
2215 return 0;
2216 }
2217
Michele Berionne5e411512020-11-13 02:36:59 +00002218 private int handleUnattendedReboot() {
2219 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2220 // non user build.
2221 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2222 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2223 return -1;
2224 }
2225
2226 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2227 getOutPrintWriter().println("result: " + result);
2228
2229 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2230 }
2231
Aman Gupta07124872022-02-09 08:02:14 +00002232 private int handleGetSimSlotsMapping() {
2233 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2234 // non user build.
2235 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2236 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2237 return -1;
2238 }
2239 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2240 String result = telephonyManager.getSimSlotMapping().toString();
2241 getOutPrintWriter().println("simSlotsMapping: " + result);
2242
2243 return 0;
2244 }
2245
Hui Wang641e81c2020-10-12 12:14:23 -07002246 private int handleGbaCommand() {
2247 String arg = getNextArg();
2248 if (arg == null) {
2249 onHelpGba();
2250 return 0;
2251 }
2252
2253 switch (arg) {
2254 case GBA_SET_SERVICE: {
2255 return handleGbaSetServiceCommand();
2256 }
2257 case GBA_GET_SERVICE: {
2258 return handleGbaGetServiceCommand();
2259 }
2260 case GBA_SET_RELEASE_TIME: {
2261 return handleGbaSetReleaseCommand();
2262 }
2263 case GBA_GET_RELEASE_TIME: {
2264 return handleGbaGetReleaseCommand();
2265 }
2266 }
2267
2268 return -1;
2269 }
2270
2271 private int getSubId(String cmd) {
2272 int slotId = getDefaultSlot();
2273 String opt = getNextOption();
2274 if (opt != null && opt.equals("-s")) {
2275 try {
2276 slotId = Integer.parseInt(getNextArgRequired());
2277 } catch (NumberFormatException e) {
2278 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2279 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2280 }
2281 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002282 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002283 }
2284
2285 private int handleGbaSetServiceCommand() {
2286 int subId = getSubId("gba set-service");
2287 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2288 return -1;
2289 }
2290
2291 String packageName = getNextArg();
2292 try {
2293 if (packageName == null) {
2294 packageName = "";
2295 }
2296 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2297 if (VDBG) {
2298 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2299 + packageName + ", result=" + result);
2300 }
2301 getOutPrintWriter().println(result);
2302 } catch (RemoteException e) {
2303 Log.w(LOG_TAG, "gba set-service " + subId + " "
2304 + packageName + ", error" + e.getMessage());
2305 getErrPrintWriter().println("Exception: " + e.getMessage());
2306 return -1;
2307 }
2308 return 0;
2309 }
2310
2311 private int handleGbaGetServiceCommand() {
2312 String result;
2313
2314 int subId = getSubId("gba get-service");
2315 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2316 return -1;
2317 }
2318
2319 try {
2320 result = mInterface.getBoundGbaService(subId);
2321 } catch (RemoteException e) {
2322 return -1;
2323 }
2324 if (VDBG) {
2325 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2326 }
2327 getOutPrintWriter().println(result);
2328 return 0;
2329 }
2330
2331 private int handleGbaSetReleaseCommand() {
2332 //the release time value could be -1
2333 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2334 : SubscriptionManager.getDefaultSubscriptionId();
2335 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2336 return -1;
2337 }
2338
2339 String intervalStr = getNextArg();
2340 if (intervalStr == null) {
2341 return -1;
2342 }
2343
2344 try {
2345 int interval = Integer.parseInt(intervalStr);
2346 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2347 if (VDBG) {
2348 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2349 + intervalStr + ", result=" + result);
2350 }
2351 getOutPrintWriter().println(result);
2352 } catch (NumberFormatException | RemoteException e) {
2353 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2354 + intervalStr + ", error" + e.getMessage());
2355 getErrPrintWriter().println("Exception: " + e.getMessage());
2356 return -1;
2357 }
2358 return 0;
2359 }
2360
2361 private int handleGbaGetReleaseCommand() {
2362 int subId = getSubId("gba get-release");
2363 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2364 return -1;
2365 }
2366
2367 int result = 0;
2368 try {
2369 result = mInterface.getGbaReleaseTime(subId);
2370 } catch (RemoteException e) {
2371 return -1;
2372 }
2373 if (VDBG) {
2374 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2375 }
2376 getOutPrintWriter().println(result);
2377 return 0;
2378 }
Hui Wang761a6682020-10-31 05:12:53 +00002379
2380 private int handleSingleRegistrationConfigCommand() {
2381 String arg = getNextArg();
2382 if (arg == null) {
2383 onHelpSrc();
2384 return 0;
2385 }
2386
2387 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002388 case SRC_SET_TEST_ENABLED: {
2389 return handleSrcSetTestEnabledCommand();
2390 }
2391 case SRC_GET_TEST_ENABLED: {
2392 return handleSrcGetTestEnabledCommand();
2393 }
Hui Wang761a6682020-10-31 05:12:53 +00002394 case SRC_SET_DEVICE_ENABLED: {
2395 return handleSrcSetDeviceEnabledCommand();
2396 }
2397 case SRC_GET_DEVICE_ENABLED: {
2398 return handleSrcGetDeviceEnabledCommand();
2399 }
2400 case SRC_SET_CARRIER_ENABLED: {
2401 return handleSrcSetCarrierEnabledCommand();
2402 }
2403 case SRC_GET_CARRIER_ENABLED: {
2404 return handleSrcGetCarrierEnabledCommand();
2405 }
Hui Wangb647abe2021-02-26 09:33:38 -08002406 case SRC_SET_FEATURE_ENABLED: {
2407 return handleSrcSetFeatureValidationCommand();
2408 }
2409 case SRC_GET_FEATURE_ENABLED: {
2410 return handleSrcGetFeatureValidationCommand();
2411 }
Hui Wang761a6682020-10-31 05:12:53 +00002412 }
2413
2414 return -1;
2415 }
2416
James.cf Linbcdf8b32021-01-14 16:44:13 +08002417 private int handleRcsUceCommand() {
2418 String arg = getNextArg();
2419 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002420 onHelpUce();
2421 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002422 }
2423
2424 switch (arg) {
2425 case UCE_REMOVE_EAB_CONTACT:
2426 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002427 case UCE_GET_EAB_CONTACT:
2428 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002429 case UCE_GET_EAB_CAPABILITY:
2430 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002431 case UCE_GET_DEVICE_ENABLED:
2432 return handleUceGetDeviceEnabledCommand();
2433 case UCE_SET_DEVICE_ENABLED:
2434 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002435 case UCE_OVERRIDE_PUBLISH_CAPS:
2436 return handleUceOverridePublishCaps();
2437 case UCE_GET_LAST_PIDF_XML:
2438 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002439 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2440 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002441 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2442 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002443 }
2444 return -1;
2445 }
2446
2447 private int handleRemovingEabContactCommand() {
2448 int subId = getSubId("uce remove-eab-contact");
2449 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2450 return -1;
2451 }
2452
2453 String phoneNumber = getNextArgRequired();
2454 if (TextUtils.isEmpty(phoneNumber)) {
2455 return -1;
2456 }
2457 int result = 0;
2458 try {
2459 result = mInterface.removeContactFromEab(subId, phoneNumber);
2460 } catch (RemoteException e) {
2461 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2462 getErrPrintWriter().println("Exception: " + e.getMessage());
2463 return -1;
2464 }
2465
2466 if (VDBG) {
2467 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2468 }
calvinpan293ea1b2021-02-04 17:52:13 +08002469 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002470 }
2471
calvinpane4a8a1d2021-01-25 13:51:18 +08002472 private int handleGettingEabContactCommand() {
2473 String phoneNumber = getNextArgRequired();
2474 if (TextUtils.isEmpty(phoneNumber)) {
2475 return -1;
2476 }
2477 String result = "";
2478 try {
2479 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002480 } catch (RemoteException e) {
2481 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2482 getErrPrintWriter().println("Exception: " + e.getMessage());
2483 return -1;
2484 }
2485
2486 if (VDBG) {
2487 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2488 }
calvinpan293ea1b2021-02-04 17:52:13 +08002489 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002490 return 0;
2491 }
2492
Calvin Pana1434322021-07-01 19:27:01 +08002493 private int handleGettingEabCapabilityCommand() {
2494 String phoneNumber = getNextArgRequired();
2495 if (TextUtils.isEmpty(phoneNumber)) {
2496 return -1;
2497 }
2498 String result = "";
2499 try {
2500 result = mInterface.getCapabilityFromEab(phoneNumber);
2501 } catch (RemoteException e) {
2502 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2503 getErrPrintWriter().println("Exception: " + e.getMessage());
2504 return -1;
2505 }
2506
2507 if (VDBG) {
2508 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2509 }
2510 getOutPrintWriter().println(result);
2511 return 0;
2512 }
2513
James.cf Lin4b784aa2021-01-31 03:25:15 +08002514 private int handleUceGetDeviceEnabledCommand() {
2515 boolean result = false;
2516 try {
2517 result = mInterface.getDeviceUceEnabled();
2518 } catch (RemoteException e) {
2519 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2520 return -1;
2521 }
2522 if (VDBG) {
2523 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2524 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002525 getOutPrintWriter().println(result);
2526 return 0;
2527 }
2528
James.cf Lin4b784aa2021-01-31 03:25:15 +08002529 private int handleUceSetDeviceEnabledCommand() {
2530 String enabledStr = getNextArg();
2531 if (TextUtils.isEmpty(enabledStr)) {
2532 return -1;
2533 }
2534
2535 try {
2536 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2537 mInterface.setDeviceUceEnabled(isEnabled);
2538 if (VDBG) {
2539 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2540 }
2541 } catch (NumberFormatException | RemoteException e) {
2542 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2543 getErrPrintWriter().println("Exception: " + e.getMessage());
2544 return -1;
2545 }
2546 return 0;
2547 }
2548
James.cf Line8713a42021-04-29 16:04:26 +08002549 private int handleUceRemoveRequestDisallowedStatus() {
2550 int subId = getSubId("uce remove-request-disallowed-status");
2551 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2552 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2553 return -1;
2554 }
2555 boolean result;
2556 try {
2557 result = mInterface.removeUceRequestDisallowedStatus(subId);
2558 } catch (RemoteException e) {
2559 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2560 return -1;
2561 }
2562 if (VDBG) {
2563 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2564 }
2565 getOutPrintWriter().println(result);
2566 return 0;
2567 }
2568
James.cf Lin0fc71b02021-05-25 01:37:38 +08002569 private int handleUceSetCapRequestTimeout() {
2570 int subId = getSubId("uce set-capabilities-request-timeout");
2571 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2572 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2573 return -1;
2574 }
2575 long timeoutAfterMs = Long.valueOf(getNextArg());
2576 boolean result;
2577 try {
2578 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2579 } catch (RemoteException e) {
2580 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2581 return -1;
2582 }
2583 if (VDBG) {
2584 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2585 }
2586 getOutPrintWriter().println(result);
2587 return 0;
2588 }
2589
Hui Wangbaaee6a2021-02-19 20:45:36 -08002590 private int handleSrcSetTestEnabledCommand() {
2591 String enabledStr = getNextArg();
2592 if (enabledStr == null) {
2593 return -1;
2594 }
2595
2596 try {
2597 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2598 if (VDBG) {
2599 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2600 }
2601 getOutPrintWriter().println("Done");
2602 } catch (NumberFormatException | RemoteException e) {
2603 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2604 getErrPrintWriter().println("Exception: " + e.getMessage());
2605 return -1;
2606 }
2607 return 0;
2608 }
2609
2610 private int handleSrcGetTestEnabledCommand() {
2611 boolean result = false;
2612 try {
2613 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2614 } catch (RemoteException e) {
2615 return -1;
2616 }
2617 if (VDBG) {
2618 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2619 }
2620 getOutPrintWriter().println(result);
2621 return 0;
2622 }
2623
Brad Ebinger14d467f2021-02-12 06:18:28 +00002624 private int handleUceOverridePublishCaps() {
2625 int subId = getSubId("uce override-published-caps");
2626 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2627 return -1;
2628 }
2629 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2630 String operation = getNextArgRequired();
2631 String caps = getNextArg();
2632 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2633 && !"list".equals(operation)) {
2634 getErrPrintWriter().println("Invalid operation: " + operation);
2635 return -1;
2636 }
2637
2638 // add/remove requires capabilities to be specified.
2639 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2640 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2641 + "specified");
2642 return -1;
2643 }
2644
2645 ArraySet<String> capSet = new ArraySet<>();
2646 if (!TextUtils.isEmpty(caps)) {
2647 String[] capArray = caps.split(":");
2648 for (String cap : capArray) {
2649 // Allow unknown tags to be passed in as well.
2650 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2651 }
2652 }
2653
2654 RcsContactUceCapability result = null;
2655 try {
2656 switch (operation) {
2657 case "add":
2658 result = mInterface.addUceRegistrationOverrideShell(subId,
2659 new ArrayList<>(capSet));
2660 break;
2661 case "remove":
2662 result = mInterface.removeUceRegistrationOverrideShell(subId,
2663 new ArrayList<>(capSet));
2664 break;
2665 case "clear":
2666 result = mInterface.clearUceRegistrationOverrideShell(subId);
2667 break;
2668 case "list":
2669 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2670 break;
2671 }
2672 } catch (RemoteException e) {
2673 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2674 getErrPrintWriter().println("Exception: " + e.getMessage());
2675 return -1;
2676 } catch (ServiceSpecificException sse) {
2677 // Reconstruct ImsException
2678 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2679 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2680 getErrPrintWriter().println("Exception: " + imsException);
2681 return -1;
2682 }
2683 if (result == null) {
2684 getErrPrintWriter().println("Service not available");
2685 return -1;
2686 }
2687 getOutPrintWriter().println(result);
2688 return 0;
2689 }
2690
2691 private int handleUceGetPidfXml() {
2692 int subId = getSubId("uce get-last-publish-pidf");
2693 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2694 return -1;
2695 }
2696
2697 String result;
2698 try {
2699 result = mInterface.getLastUcePidfXmlShell(subId);
2700 } catch (RemoteException e) {
2701 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2702 getErrPrintWriter().println("Exception: " + e.getMessage());
2703 return -1;
2704 } catch (ServiceSpecificException sse) {
2705 // Reconstruct ImsException
2706 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2707 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2708 getErrPrintWriter().println("Exception: " + imsException);
2709 return -1;
2710 }
2711 if (result == null) {
2712 getErrPrintWriter().println("Service not available");
2713 return -1;
2714 }
2715 getOutPrintWriter().println(result);
2716 return 0;
2717 }
2718
Hui Wang761a6682020-10-31 05:12:53 +00002719 private int handleSrcSetDeviceEnabledCommand() {
2720 String enabledStr = getNextArg();
2721 if (enabledStr == null) {
2722 return -1;
2723 }
2724
2725 try {
2726 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2727 if (VDBG) {
2728 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2729 }
2730 getOutPrintWriter().println("Done");
2731 } catch (NumberFormatException | RemoteException e) {
2732 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2733 getErrPrintWriter().println("Exception: " + e.getMessage());
2734 return -1;
2735 }
2736 return 0;
2737 }
2738
2739 private int handleSrcGetDeviceEnabledCommand() {
2740 boolean result = false;
2741 try {
2742 result = mInterface.getDeviceSingleRegistrationEnabled();
2743 } catch (RemoteException e) {
2744 return -1;
2745 }
2746 if (VDBG) {
2747 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2748 }
2749 getOutPrintWriter().println(result);
2750 return 0;
2751 }
2752
2753 private int handleSrcSetCarrierEnabledCommand() {
2754 //the release time value could be -1
2755 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2756 : SubscriptionManager.getDefaultSubscriptionId();
2757 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2758 return -1;
2759 }
2760
2761 String enabledStr = getNextArg();
2762 if (enabledStr == null) {
2763 return -1;
2764 }
2765
2766 try {
2767 boolean result =
2768 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2769 if (VDBG) {
2770 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2771 + enabledStr + ", result=" + result);
2772 }
2773 getOutPrintWriter().println(result);
2774 } catch (NumberFormatException | RemoteException e) {
2775 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2776 + enabledStr + ", error" + e.getMessage());
2777 getErrPrintWriter().println("Exception: " + e.getMessage());
2778 return -1;
2779 }
2780 return 0;
2781 }
2782
2783 private int handleSrcGetCarrierEnabledCommand() {
2784 int subId = getSubId("src get-carrier-enabled");
2785 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2786 return -1;
2787 }
2788
2789 boolean result = false;
2790 try {
2791 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2792 } catch (RemoteException e) {
2793 return -1;
2794 }
2795 if (VDBG) {
2796 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2797 }
2798 getOutPrintWriter().println(result);
2799 return 0;
2800 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002801
Hui Wangb647abe2021-02-26 09:33:38 -08002802 private int handleSrcSetFeatureValidationCommand() {
2803 //the release time value could be -1
2804 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2805 : SubscriptionManager.getDefaultSubscriptionId();
2806 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2807 return -1;
2808 }
2809
2810 String enabledStr = getNextArg();
2811 if (enabledStr == null) {
2812 return -1;
2813 }
2814
2815 try {
2816 boolean result =
2817 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2818 if (VDBG) {
2819 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2820 + enabledStr + ", result=" + result);
2821 }
2822 getOutPrintWriter().println(result);
2823 } catch (NumberFormatException | RemoteException e) {
2824 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2825 + enabledStr + ", error" + e.getMessage());
2826 getErrPrintWriter().println("Exception: " + e.getMessage());
2827 return -1;
2828 }
2829 return 0;
2830 }
2831
2832 private int handleSrcGetFeatureValidationCommand() {
2833 int subId = getSubId("src get-feature-validation");
2834 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2835 return -1;
2836 }
2837
2838 Boolean result = false;
2839 try {
2840 result = mInterface.getImsFeatureValidationOverride(subId);
2841 } catch (RemoteException e) {
2842 return -1;
2843 }
2844 if (VDBG) {
2845 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2846 }
2847 getOutPrintWriter().println(result);
2848 return 0;
2849 }
2850
2851
Hall Liuaa4211e2021-01-20 15:43:39 -08002852 private void onHelpCallComposer() {
2853 PrintWriter pw = getOutPrintWriter();
2854 pw.println("Call composer commands");
2855 pw.println(" callcomposer test-mode enable|disable|query");
2856 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2857 pw.println(" upload/download from carrier servers is disabled, and operations are");
2858 pw.println(" performed using emulated local files instead.");
2859 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2860 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2861 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002862 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2863 pw.println(" Enables or disables the user setting for call composer, as set by");
2864 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002865 }
2866
2867 private int handleCallComposerCommand() {
2868 String arg = getNextArg();
2869 if (arg == null) {
2870 onHelpCallComposer();
2871 return 0;
2872 }
2873
2874 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2875 "MODIFY_PHONE_STATE required for call composer shell cmds");
2876 switch (arg) {
2877 case CALL_COMPOSER_TEST_MODE: {
2878 String enabledStr = getNextArg();
2879 if (ENABLE.equals(enabledStr)) {
2880 CallComposerPictureManager.sTestMode = true;
2881 } else if (DISABLE.equals(enabledStr)) {
2882 CallComposerPictureManager.sTestMode = false;
2883 } else if (QUERY.equals(enabledStr)) {
2884 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2885 } else {
2886 onHelpCallComposer();
2887 return 1;
2888 }
2889 break;
2890 }
2891 case CALL_COMPOSER_SIMULATE_CALL: {
2892 int subscriptionId = Integer.valueOf(getNextArg());
2893 String uuidString = getNextArg();
2894 UUID uuid = UUID.fromString(uuidString);
2895 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2896 Binder.withCleanCallingIdentity(() -> {
2897 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2898 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2899 });
2900 try {
2901 Uri uri = storageUriFuture.get();
2902 getOutPrintWriter().println(String.valueOf(uri));
2903 } catch (Exception e) {
2904 throw new RuntimeException(e);
2905 }
2906 break;
2907 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002908 case CALL_COMPOSER_USER_SETTING: {
2909 try {
2910 int subscriptionId = Integer.valueOf(getNextArg());
2911 String enabledStr = getNextArg();
2912 if (ENABLE.equals(enabledStr)) {
2913 mInterface.setCallComposerStatus(subscriptionId,
2914 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2915 } else if (DISABLE.equals(enabledStr)) {
2916 mInterface.setCallComposerStatus(subscriptionId,
2917 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2918 } else if (QUERY.equals(enabledStr)) {
2919 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2920 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2921 } else {
2922 onHelpCallComposer();
2923 return 1;
2924 }
2925 } catch (RemoteException e) {
2926 e.printStackTrace(getOutPrintWriter());
2927 return 1;
2928 }
2929 break;
2930 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002931 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002932 return 0;
2933 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002934
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002935 private int handleHasCarrierPrivilegesCommand() {
2936 String packageName = getNextArgRequired();
2937
2938 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002939 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002940 try {
2941 hasCarrierPrivileges =
2942 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2943 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2944 } catch (RemoteException e) {
2945 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2946 getErrPrintWriter().println("Exception: " + e.getMessage());
2947 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002948 } finally {
2949 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002950 }
2951
2952 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002953 return 0;
2954 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002955
2956 private int handleAllowedNetworkTypesCommand(String command) {
2957 if (!checkShellUid()) {
2958 return -1;
2959 }
2960
2961 PrintWriter errPw = getErrPrintWriter();
2962 String tag = command + ": ";
2963 String opt;
2964 int subId = -1;
2965 Log.v(LOG_TAG, command + " start");
2966
2967 while ((opt = getNextOption()) != null) {
2968 if (opt.equals("-s")) {
2969 try {
2970 subId = slotStringToSubId(tag, getNextArgRequired());
2971 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2972 errPw.println(tag + "No valid subscription found.");
2973 return -1;
2974 }
2975 } catch (IllegalArgumentException e) {
2976 // Missing slot id
2977 errPw.println(tag + "SLOT_ID expected after -s.");
2978 return -1;
2979 }
2980 } else {
2981 errPw.println(tag + "Unknown option " + opt);
2982 return -1;
2983 }
2984 }
2985
2986 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2987 return handleGetAllowedNetworkTypesCommand(subId);
2988 }
2989 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2990 return handleSetAllowedNetworkTypesCommand(subId);
2991 }
2992 return -1;
2993 }
2994
2995 private int handleGetAllowedNetworkTypesCommand(int subId) {
2996 PrintWriter errPw = getErrPrintWriter();
2997
2998 long result = -1;
2999 try {
3000 if (mInterface != null) {
3001 result = mInterface.getAllowedNetworkTypesForReason(subId,
3002 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
3003 } else {
3004 throw new IllegalStateException("telephony service is null.");
3005 }
3006 } catch (RemoteException e) {
3007 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
3008 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
3009 return -1;
3010 }
3011
3012 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3013 return 0;
3014 }
3015
3016 private int handleSetAllowedNetworkTypesCommand(int subId) {
3017 PrintWriter errPw = getErrPrintWriter();
3018
3019 String bitmaskString = getNextArg();
3020 if (TextUtils.isEmpty(bitmaskString)) {
3021 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3022 return -1;
3023 }
3024 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3025 if (allowedNetworkTypes < 0) {
3026 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3027 return -1;
3028 }
3029 boolean result = false;
3030 try {
3031 if (mInterface != null) {
3032 result = mInterface.setAllowedNetworkTypesForReason(subId,
3033 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3034 } else {
3035 throw new IllegalStateException("telephony service is null.");
3036 }
3037 } catch (RemoteException e) {
3038 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3039 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3040 return -1;
3041 }
3042
3043 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3044 if (result) {
3045 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3046 }
3047 getOutPrintWriter().println(resultMessage);
3048 return 0;
3049 }
3050
3051 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3052 if (TextUtils.isEmpty(bitmaskString)) {
3053 return -1;
3054 }
3055 if (VDBG) {
3056 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3057 + ", length: " + bitmaskString.length());
3058 }
3059 try {
3060 return Long.parseLong(bitmaskString, 2);
3061 } catch (NumberFormatException e) {
3062 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3063 return -1;
3064 }
3065 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003066
jimsun3b9ccac2021-10-26 15:01:23 +08003067 private int handleRadioSetModemServiceCommand() {
3068 PrintWriter errPw = getErrPrintWriter();
3069 String serviceName = null;
3070
3071 String opt;
3072 while ((opt = getNextOption()) != null) {
3073 switch (opt) {
3074 case "-s": {
3075 serviceName = getNextArgRequired();
3076 break;
3077 }
3078 }
3079 }
3080
3081 try {
3082 boolean result = mInterface.setModemService(serviceName);
3083 if (VDBG) {
3084 Log.v(LOG_TAG,
3085 "RadioSetModemService " + serviceName + ", result = " + result);
3086 }
3087 getOutPrintWriter().println(result);
3088 } catch (RemoteException e) {
3089 Log.w(LOG_TAG,
3090 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3091 errPw.println("Exception: " + e.getMessage());
3092 return -1;
3093 }
3094 return 0;
3095 }
3096
3097 private int handleRadioGetModemServiceCommand() {
3098 PrintWriter errPw = getErrPrintWriter();
3099 String result;
3100
3101 try {
3102 result = mInterface.getModemService();
3103 getOutPrintWriter().println(result);
3104 } catch (RemoteException e) {
3105 errPw.println("Exception: " + e.getMessage());
3106 return -1;
3107 }
3108 if (VDBG) {
3109 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3110 }
3111 return 0;
3112 }
3113
3114 private int handleRadioCommand() {
3115 String arg = getNextArg();
3116 if (arg == null) {
3117 onHelpRadio();
3118 return 0;
3119 }
3120
3121 switch (arg) {
3122 case RADIO_SET_MODEM_SERVICE:
3123 return handleRadioSetModemServiceCommand();
3124
3125 case RADIO_GET_MODEM_SERVICE:
3126 return handleRadioGetModemServiceCommand();
3127 }
3128
3129 return -1;
3130 }
arunvoddud7401012022-12-15 16:08:12 +00003131
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003132 private int handleSetSatelliteServicePackageNameCommand() {
3133 PrintWriter errPw = getErrPrintWriter();
3134 String serviceName = null;
3135
3136 String opt;
3137 while ((opt = getNextOption()) != null) {
3138 switch (opt) {
3139 case "-s": {
3140 serviceName = getNextArgRequired();
3141 break;
3142 }
3143 }
3144 }
3145 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3146 + serviceName);
3147
3148 try {
3149 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3150 if (VDBG) {
3151 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3152 + ", result = " + result);
3153 }
3154 getOutPrintWriter().println(result);
3155 } catch (RemoteException e) {
3156 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3157 + ", error = " + e.getMessage());
3158 errPw.println("Exception: " + e.getMessage());
3159 return -1;
3160 }
3161 return 0;
3162 }
3163
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003164 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3165 PrintWriter errPw = getErrPrintWriter();
3166 String serviceName = null;
3167
3168 String opt;
3169 while ((opt = getNextOption()) != null) {
3170 switch (opt) {
3171 case "-s": {
3172 serviceName = getNextArgRequired();
3173 break;
3174 }
3175 }
3176 }
3177 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3178 + serviceName);
3179
3180 try {
3181 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3182 if (VDBG) {
3183 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3184 + ", result = " + result);
3185 }
3186 getOutPrintWriter().println(result);
3187 } catch (RemoteException e) {
3188 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3189 + ", error = " + e.getMessage());
3190 errPw.println("Exception: " + e.getMessage());
3191 return -1;
3192 }
3193 return 0;
3194 }
3195
Thomas Nguyen87dce732023-04-20 18:27:16 -07003196 private int handleSetSatellitePointingUiClassNameCommand() {
3197 PrintWriter errPw = getErrPrintWriter();
3198 String packageName = null;
3199 String className = null;
3200
3201 String opt;
3202 while ((opt = getNextOption()) != null) {
3203 switch (opt) {
3204 case "-p": {
3205 packageName = getNextArgRequired();
3206 break;
3207 }
3208 case "-c": {
3209 className = getNextArgRequired();
3210 break;
3211 }
3212 }
3213 }
3214 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3215 + packageName + ", className=" + className);
3216
3217 try {
3218 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3219 if (VDBG) {
3220 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3221 }
3222 getOutPrintWriter().println(result);
3223 } catch (RemoteException e) {
3224 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3225 + ", error = " + e.getMessage());
3226 errPw.println("Exception: " + e.getMessage());
3227 return -1;
3228 }
3229 return 0;
3230 }
3231
Thomas Nguyen11a051f2023-10-25 10:14:55 -07003232 private int handleSetEmergencyCallToSatelliteHandoverType() {
3233 PrintWriter errPw = getErrPrintWriter();
3234 int handoverType = -1;
3235 int delaySeconds = 0;
3236
3237 String opt;
3238 while ((opt = getNextOption()) != null) {
3239 switch (opt) {
3240 case "-t": {
3241 try {
3242 handoverType = Integer.parseInt(getNextArgRequired());
3243 } catch (NumberFormatException e) {
3244 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3245 + " for handoverType");
3246 return -1;
3247 }
3248 break;
3249 }
3250 case "-d": {
3251 try {
3252 delaySeconds = Integer.parseInt(getNextArgRequired());
3253 } catch (NumberFormatException e) {
3254 errPw.println("SetEmergencyCallToSatelliteHandoverType: require an integer"
3255 + " for delaySeconds");
3256 return -1;
3257 }
3258 break;
3259 }
3260 }
3261 }
3262 Log.d(LOG_TAG, "handleSetEmergencyCallToSatelliteHandoverType: handoverType="
3263 + handoverType + ", delaySeconds=" + delaySeconds);
3264
3265 try {
3266 boolean result =
3267 mInterface.setEmergencyCallToSatelliteHandoverType(handoverType, delaySeconds);
3268 if (VDBG) {
3269 Log.v(LOG_TAG, "setEmergencyCallToSatelliteHandoverType result =" + result);
3270 }
3271 getOutPrintWriter().println(result);
3272 } catch (RemoteException e) {
3273 Log.e(LOG_TAG, "setEmergencyCallToSatelliteHandoverType: " + handoverType
3274 + ", error = " + e.getMessage());
3275 errPw.println("Exception: " + e.getMessage());
3276 return -1;
3277 }
3278 return 0;
3279 }
3280
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003281 private int handleSetSatelliteListeningTimeoutDuration() {
3282 PrintWriter errPw = getErrPrintWriter();
3283 long timeoutMillis = 0;
3284
3285 String opt;
3286 while ((opt = getNextOption()) != null) {
3287 switch (opt) {
3288 case "-t": {
3289 timeoutMillis = Long.parseLong(getNextArgRequired());
3290 break;
3291 }
3292 }
3293 }
3294 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3295 + timeoutMillis);
3296
3297 try {
3298 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3299 if (VDBG) {
3300 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3301 + ", result = " + result);
3302 }
3303 getOutPrintWriter().println(result);
3304 } catch (RemoteException e) {
3305 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3306 + ", error = " + e.getMessage());
3307 errPw.println("Exception: " + e.getMessage());
3308 return -1;
3309 }
3310 return 0;
3311 }
3312
Hakjun Choiae365972023-04-25 11:00:31 +00003313 private int handleSettSatelliteDeviceAlignedTimeoutDuration() {
3314 PrintWriter errPw = getErrPrintWriter();
3315 long timeoutMillis = 0;
3316
3317 String opt;
3318 while ((opt = getNextOption()) != null) {
3319 switch (opt) {
3320 case "-t": {
3321 timeoutMillis = Long.parseLong(getNextArgRequired());
3322 break;
3323 }
3324 }
3325 }
3326 Log.d(LOG_TAG, "handleSettSatelliteDeviceAlignedTimeoutDuration: timeoutMillis="
3327 + timeoutMillis);
3328
3329 try {
3330 boolean result = mInterface.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
3331 if (VDBG) {
3332 Log.v(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration " + timeoutMillis
3333 + ", result = " + result);
3334 }
3335 getOutPrintWriter().println(result);
3336 } catch (RemoteException e) {
3337 Log.w(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration: " + timeoutMillis
3338 + ", error = " + e.getMessage());
3339 errPw.println("Exception: " + e.getMessage());
3340 return -1;
3341 }
3342 return 0;
3343 }
3344
arunvoddud7401012022-12-15 16:08:12 +00003345 private int handleCarrierRestrictionStatusCommand() {
3346 try {
3347 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3348 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3349 mInterface.getModemService()))) {
3350 Log.v(LOG_TAG,
3351 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3352 + " checkShellUid fails");
3353 return -1;
3354 }
3355 } catch (RemoteException ex) {
3356 ex.printStackTrace();
3357 }
3358 String callerInfo = getNextOption();
3359 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3360 if (TextUtils.isEmpty(callerInfo)) {
3361 // reset the Json content after testing
3362 allowListInfo.updateJsonForTest(null);
3363 return 0;
3364 }
3365 if (callerInfo.startsWith("--")) {
3366 callerInfo = callerInfo.replace("--", "");
3367 }
3368 String params[] = callerInfo.split(",");
3369 StringBuffer jsonStrBuffer = new StringBuffer();
3370 String tokens;
3371 for (int index = 0; index < params.length; index++) {
3372 tokens = convertToJsonString(index, params[index]);
3373 if (TextUtils.isEmpty(tokens)) {
3374 // received wrong format from CTS
3375 if (VDBG) {
3376 Log.v(LOG_TAG,
3377 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3378 }
3379 return -1;
3380 }
3381 jsonStrBuffer.append(tokens);
3382 }
3383 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3384 return result;
3385 }
3386
Benedict Wong66477622023-02-03 23:30:57 +00003387 // set-carrier-service-package-override
3388 private int setCarrierServicePackageOverride() {
3389 PrintWriter errPw = getErrPrintWriter();
3390 int subId = SubscriptionManager.getDefaultSubscriptionId();
3391
3392 String opt;
3393 while ((opt = getNextOption()) != null) {
3394 switch (opt) {
3395 case "-s":
3396 try {
3397 subId = Integer.parseInt(getNextArgRequired());
3398 } catch (NumberFormatException e) {
3399 errPw.println(
3400 "set-carrier-service-package-override requires an integer as a"
3401 + " subscription ID.");
3402 return -1;
3403 }
3404 break;
3405 }
3406 }
3407
3408 String packageName = getNextArg();
3409 if (packageName == null) {
3410 errPw.println("set-carrier-service-package-override requires a override package name.");
3411 return -1;
3412 }
3413
3414 try {
3415 mInterface.setCarrierServicePackageOverride(
3416 subId, packageName, mContext.getOpPackageName());
3417
3418 if (VDBG) {
3419 Log.v(
3420 LOG_TAG,
3421 "set-carrier-service-package-override -s " + subId + " " + packageName);
3422 }
3423 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3424 Log.w(
3425 LOG_TAG,
3426 "set-carrier-service-package-override -s "
3427 + subId
3428 + " "
3429 + packageName
3430 + ", error"
3431 + e.getMessage());
3432 errPw.println("Exception: " + e.getMessage());
3433 return -1;
3434 }
3435 return 0;
3436 }
3437
3438 // clear-carrier-service-package-override
3439 private int clearCarrierServicePackageOverride() {
3440 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003441 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003442
3443 String opt;
3444 while ((opt = getNextOption()) != null) {
3445 switch (opt) {
3446 case "-s":
3447 try {
3448 subId = Integer.parseInt(getNextArgRequired());
3449 } catch (NumberFormatException e) {
3450 errPw.println(
3451 "clear-carrier-service-package-override requires an integer as a"
3452 + " subscription ID.");
3453 return -1;
3454 }
3455 break;
3456 }
3457 }
3458
3459 try {
3460 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3461
3462 if (VDBG) {
3463 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3464 }
3465 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3466 Log.w(
3467 LOG_TAG,
3468 "clear-carrier-service-package-override -s "
3469 + subId
3470 + ", error"
3471 + e.getMessage());
3472 errPw.println("Exception: " + e.getMessage());
3473 return -1;
3474 }
3475 return 0;
3476 }
arunvoddud7401012022-12-15 16:08:12 +00003477
3478 /**
3479 * Building the string that can be used to build the JsonObject which supports to stub the data
3480 * in CarrierAllowListInfo for CTS testing. sample format is like
3481 * {"com.android.example":{"carrierId":"10000","callerSHA1Id":["XXXXXXXXXXXXXX"]}}
3482 */
3483 private String convertToJsonString(int index, String param) {
3484
3485 String token[] = param.split(":");
3486 String jSonString;
3487 switch (index) {
3488 case 0:
3489 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3490 break;
3491 case 1:
3492 jSonString =
3493 "{" + QUOTES + token[0] + QUOTES + ":" + QUOTES + token[1] + QUOTES + ",";
3494 break;
3495 case 2:
3496 jSonString =
3497 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
3498 break;
3499 default:
3500 jSonString = null;
3501 }
3502 return jSonString;
3503 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003504}