blob: 1ee48c44261f5b8e408b005bfa4a20e0c482e51c [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";
Jack Nudelman644b91a2021-03-12 14:09:48 -0800192
Grant Menke567d48f2022-08-18 20:19:10 +0000193 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
194 + "'*', '#' or '+') needs to be specified after -a in the command ";
195
196 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
197 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
198 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
199
SongFerngWang98dd5992021-05-13 17:50:00 +0800200 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
201 "get-allowed-network-types-for-users";
202 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
203 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000204 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000205 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700206 // Take advantage of existing methods that already contain permissions checks when possible.
207 private final ITelephony mInterface;
208
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100209 private SubscriptionManager mSubscriptionManager;
210 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700211 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700212 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100213
214 private enum CcType {
215 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000216 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100217 }
218
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100219 private class CcOptionParseResult {
220 public int mSubId;
221 public boolean mPersistent;
222 }
223
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100224 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
225 // keys by looking at the end of the string which usually tells the type.
226 // For instance: "xxxx_string", "xxxx_string_array", etc.
227 // The carrier config keys in this map does not follow this convention. It is therefore not
228 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700229 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
230 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
231 CcType.STRING),
232 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
233 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
234 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
235 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
236 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
237 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
238 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
239 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
240 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
241 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
242 CcType.STRING),
243 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
244 CcType.STRING_ARRAY),
245 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
246 CcType.STRING_ARRAY),
247 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
248 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
249 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
250 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
251 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
252 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
253 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
254 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100255
Brad Ebinger14d467f2021-02-12 06:18:28 +0000256 /**
257 * Map from a shorthand string to the feature tags required in registration required in order
258 * for the RCS feature to be considered "capable".
259 */
260 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
261 static {
262 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
263 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
264 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
265 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
266 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
267 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
268 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
269 FeatureTags.FEATURE_TAG_VIDEO)));
270 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
271 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
272 map.put("call_comp",
273 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
274 map.put("call_comp_mmtel",
275 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
276 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
277 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
278 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
279 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
280 // version
281 map.put("chatbot", new ArraySet<>(Arrays.asList(
282 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
283 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
284 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
285 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000286 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000287 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
288 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
289 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
290 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
291 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000292 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000293 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
294 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
295 }
296
297
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100298 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700299 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100300 mCarrierConfigManager =
301 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
302 mSubscriptionManager = (SubscriptionManager)
303 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700304 mTelephonyRegistryManager = (TelephonyRegistryManager)
305 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700306 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700307 }
308
309 @Override
310 public int onCommand(String cmd) {
311 if (cmd == null) {
312 return handleDefaultCommands(null);
313 }
314
315 switch (cmd) {
316 case IMS_SUBCOMMAND: {
317 return handleImsCommand();
318 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800319 case RCS_UCE_COMMAND:
320 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800321 case NUMBER_VERIFICATION_SUBCOMMAND:
322 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800323 case EMERGENCY_CALLBACK_MODE:
324 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800325 case EMERGENCY_NUMBER_TEST_MODE:
326 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100327 case CARRIER_CONFIG_SUBCOMMAND: {
328 return handleCcCommand();
329 }
Shuo Qianf5125122019-12-16 17:03:07 -0800330 case DATA_TEST_MODE:
331 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700332 case END_BLOCK_SUPPRESSION:
333 return handleEndBlockSuppressionCommand();
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000334 case EUICC_SUBCOMMAND:
335 return handleEuiccCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700336 case GBA_SUBCOMMAND:
337 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800338 case D2D_SUBCOMMAND:
339 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700340 case BARRING_SUBCOMMAND:
341 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000342 case SINGLE_REGISTATION_CONFIG:
343 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000344 case RESTART_MODEM:
345 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800346 case CALL_COMPOSER_SUBCOMMAND:
347 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000348 case UNATTENDED_REBOOT:
349 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800350 case HAS_CARRIER_PRIVILEGES_COMMAND:
351 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800352 case THERMAL_MITIGATION_COMMAND:
353 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700354 case DISABLE_PHYSICAL_SUBSCRIPTION:
355 return handleEnablePhysicalSubscription(false);
356 case ENABLE_PHYSICAL_SUBSCRIPTION:
357 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800358 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
359 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
360 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000361 case GET_IMEI:
362 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000363 case GET_SIM_SLOTS_MAPPING:
364 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800365 case RADIO_SUBCOMMAND:
366 return handleRadioCommand();
arunvoddud7401012022-12-15 16:08:12 +0000367 case CARRIER_RESTRICTION_STATUS_TEST:
368 return handleCarrierRestrictionStatusCommand();
Benedict Wong66477622023-02-03 23:30:57 +0000369 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
370 return setCarrierServicePackageOverride();
371 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
372 return clearCarrierServicePackageOverride();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700373 case SET_SATELLITE_SERVICE_PACKAGE_NAME:
374 return handleSetSatelliteServicePackageNameCommand();
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700375 case SET_SATELLITE_GATEWAY_SERVICE_PACKAGE_NAME:
376 return handleSetSatelliteGatewayServicePackageNameCommand();
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700377 case SET_SATELLITE_LISTENING_TIMEOUT_DURATION:
378 return handleSetSatelliteListeningTimeoutDuration();
Thomas Nguyen87dce732023-04-20 18:27:16 -0700379 case SET_SATELLITE_POINTING_UI_CLASS_NAME:
380 return handleSetSatellitePointingUiClassNameCommand();
Hakjun Choiae365972023-04-25 11:00:31 +0000381 case SET_SATELLITE_DEVICE_ALIGNED_TIMEOUT_DURATION:
382 return handleSettSatelliteDeviceAlignedTimeoutDuration();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700383 default: {
384 return handleDefaultCommands(cmd);
385 }
386 }
387 }
388
389 @Override
390 public void onHelp() {
391 PrintWriter pw = getOutPrintWriter();
392 pw.println("Telephony Commands:");
393 pw.println(" help");
394 pw.println(" Print this help text.");
395 pw.println(" ims");
396 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800397 pw.println(" uce");
398 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800399 pw.println(" emergency-number-test-mode");
400 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700401 pw.println(" end-block-suppression");
402 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800403 pw.println(" data");
404 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100405 pw.println(" cc");
406 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700407 pw.println(" gba");
408 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000409 pw.println(" src");
410 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000411 pw.println(" restart-modem");
412 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000413 pw.println(" unattended-reboot");
414 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800415 pw.println(" has-carrier-privileges [package]");
416 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800417 pw.println(" get-allowed-network-types-for-users");
418 pw.println(" Get the Allowed Network Types.");
419 pw.println(" set-allowed-network-types-for-users");
420 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800421 pw.println(" radio");
422 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700423 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800424 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800425 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700426 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800427 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100428 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700429 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000430 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800431 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700432 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800433 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800434 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000435 onHelpImei();
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700436 onHelpSatellite();
Tyler Gunn92479152021-01-20 16:30:10 -0800437 }
438
439 private void onHelpD2D() {
440 PrintWriter pw = getOutPrintWriter();
441 pw.println("D2D Comms Commands:");
442 pw.println(" d2d send TYPE VALUE");
443 pw.println(" Sends a D2D message of specified type and value.");
444 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
445 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
446 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
447 MESSAGE_CALL_AUDIO_CODEC));
448 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
449 + Communicator.messageToString(
450 MESSAGE_DEVICE_BATTERY_STATE));
451 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
452 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800453 pw.println(" d2d transport TYPE");
454 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
455 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700456 pw.println(" d2d set-device-support true/default");
457 pw.println(" true - forces device support to be enabled for D2D.");
458 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
459 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700460 }
461
Nazanin014f41e2021-05-06 17:26:31 -0700462 private void onHelpBarring() {
463 PrintWriter pw = getOutPrintWriter();
464 pw.println("Barring Commands:");
465 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
466 + " -t CONDITIONAL_BARRING_TIME_SECS");
467 pw.println(" Notifies of a barring info change for the specified slot id.");
468 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
469 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
470 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
471 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
472 }
473
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700474 private void onHelpIms() {
475 PrintWriter pw = getOutPrintWriter();
476 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800477 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700478 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
479 pw.println(" ImsService. Options are:");
480 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
481 pw.println(" is specified, it will choose the default voice SIM slot.");
482 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
483 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800484 pw.println(" -f: Set the feature that this override if for, if no option is");
485 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700486 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
487 pw.println(" Gets the package name of the currently defined ImsService.");
488 pw.println(" Options are:");
489 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
490 pw.println(" is specified, it will choose the default voice SIM slot.");
491 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000492 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800493 pw.println(" -f: The feature type that the query will be requested for. If none is");
494 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800495 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
496 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
497 pw.println(" configuration overrides. Options are:");
498 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
499 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700500 pw.println(" ims enable [-s SLOT_ID]");
501 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
502 pw.println(" if none is specified.");
503 pw.println(" ims disable [-s SLOT_ID]");
504 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
505 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700506 pw.println(" ims conference-event-package [enable/disable]");
507 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700508 }
509
James.cf Linbcdf8b32021-01-14 16:44:13 +0800510 private void onHelpUce() {
511 PrintWriter pw = getOutPrintWriter();
512 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800513 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
514 pw.println(" Get the EAB contacts from the EAB database.");
515 pw.println(" Options are:");
516 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
517 pw.println(" Expected output format :");
518 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800519 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
520 pw.println(" Remove the EAB contacts from the EAB database.");
521 pw.println(" Options are:");
522 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
523 pw.println(" is specified, it will choose the default voice SIM slot.");
524 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800525 pw.println(" uce get-device-enabled");
526 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
527 pw.println(" uce set-device-enabled true|false");
528 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
529 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000530 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
531 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
532 pw.println(" Options are:");
533 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
534 pw.println(" is specified, it will choose the default voice SIM slot.");
535 pw.println(" add [CAPABILITY]: add a new capability");
536 pw.println(" remove [CAPABILITY]: remove a capability");
537 pw.println(" clear: clear all capability overrides");
538 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
539 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
540 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
541 pw.println(" chatbot_sa, chatbot_role] as well as full length");
542 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
543 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
544 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
545 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800546 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
547 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800548 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
549 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800550 }
551
Hall Liud892bec2018-11-30 14:51:45 -0800552 private void onHelpNumberVerification() {
553 PrintWriter pw = getOutPrintWriter();
554 pw.println("Number verification commands");
555 pw.println(" numverify override-package PACKAGE_NAME;");
556 pw.println(" Set the authorized package for number verification.");
557 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800558 pw.println(" numverify fake-call NUMBER;");
559 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
560 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800561 }
562
Jack Nudelman644b91a2021-03-12 14:09:48 -0800563 private void onHelpThermalMitigation() {
564 PrintWriter pw = getOutPrintWriter();
565 pw.println("Thermal mitigation commands");
566 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
567 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
568 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
569 pw.println(" Remove the package from one of the authorized packages for thermal "
570 + "mitigation.");
571 }
572
Jordan Liu0ccee222021-04-27 11:55:13 -0700573 private void onHelpDisableOrEnablePhysicalSubscription() {
574 PrintWriter pw = getOutPrintWriter();
575 pw.println("Disable or enable a physical subscription");
576 pw.println(" disable-physical-subscription SUB_ID");
577 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
578 pw.println(" enable-physical-subscription SUB_ID");
579 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
580 }
581
Shuo Qianf5125122019-12-16 17:03:07 -0800582 private void onHelpDataTestMode() {
583 PrintWriter pw = getOutPrintWriter();
584 pw.println("Mobile Data Test Mode Commands:");
585 pw.println(" data enable: enable mobile data connectivity");
586 pw.println(" data disable: disable mobile data connectivity");
587 }
588
sqian9d4df8b2019-01-15 18:32:07 -0800589 private void onHelpEmergencyNumber() {
590 PrintWriter pw = getOutPrintWriter();
591 pw.println("Emergency Number Test Mode Commands:");
592 pw.println(" emergency-number-test-mode ");
593 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
594 + " the test mode");
595 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700596 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800597 pw.println(" -c: clear the emergency number list in the test mode.");
598 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700599 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800600 pw.println(" -p: get the full emergency number list in the test mode.");
601 }
602
Shuo Qian489d9282020-07-09 11:30:03 -0700603 private void onHelpEndBlockSupperssion() {
604 PrintWriter pw = getOutPrintWriter();
605 pw.println("End Block Suppression command:");
606 pw.println(" end-block-suppression: disable suppressing blocking by contact");
607 pw.println(" with emergency services.");
608 }
609
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100610 private void onHelpCc() {
611 PrintWriter pw = getOutPrintWriter();
612 pw.println("Carrier Config Commands:");
613 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
614 pw.println(" Print carrier config values.");
615 pw.println(" Options are:");
616 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
617 pw.println(" is specified, it will choose the default voice SIM slot.");
618 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
619 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100620 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100621 pw.println(" Set carrier config KEY to NEW_VALUE.");
622 pw.println(" Options are:");
623 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
624 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100625 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100626 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
627 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
628 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
629 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000630 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
631 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
632 pw.println(" provided through standard input and follow CarrierConfig XML format.");
633 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
634 pw.println(" Options are:");
635 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
636 pw.println(" is specified, it will choose the default voice SIM slot.");
637 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100638 pw.println(" cc clear-values [-s SLOT_ID]");
639 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000640 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100641 pw.println(" Options are:");
642 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
643 pw.println(" is specified, it will choose the default voice SIM slot.");
644 }
645
Shivakumar Neginal9cd61892022-12-19 04:38:52 +0000646 private void onHelpEuicc() {
647 PrintWriter pw = getOutPrintWriter();
648 pw.println("Euicc Commands:");
649 pw.println(" euicc set-euicc-uicomponent COMPONENT_NAME PACKAGE_NAME");
650 pw.println(" Sets the Euicc Ui-Component which handles EuiccService Actions.");
651 pw.println(" COMPONENT_NAME: The component name which handles UI Actions.");
652 pw.println(" PACKAGE_NAME: THe package name in which ui component belongs.");
653 }
654
Hui Wang641e81c2020-10-12 12:14:23 -0700655 private void onHelpGba() {
656 PrintWriter pw = getOutPrintWriter();
657 pw.println("Gba Commands:");
658 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
659 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
660 pw.println(" Options are:");
661 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
662 pw.println(" is specified, it will choose the default voice SIM slot.");
663 pw.println(" gba get-service [-s SLOT_ID]");
664 pw.println(" Gets the package name of the currently defined GbaService.");
665 pw.println(" Options are:");
666 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
667 pw.println(" is specified, it will choose the default voice SIM slot.");
668 pw.println(" gba set-release [-s SLOT_ID] n");
669 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
670 pw.println(" Do not release/unbind if n is -1.");
671 pw.println(" Options are:");
672 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
673 pw.println(" is specified, it will choose the default voice SIM slot.");
674 pw.println(" gba get-release [-s SLOT_ID]");
675 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
676 pw.println(" Options are:");
677 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
678 pw.println(" is specified, it will choose the default voice SIM slot.");
679 }
680
Hui Wang761a6682020-10-31 05:12:53 +0000681 private void onHelpSrc() {
682 PrintWriter pw = getOutPrintWriter();
683 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800684 pw.println(" src set-test-enabled true|false");
685 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
686 pw.println(" The value could be true, false, or null(undefined).");
687 pw.println(" src get-test-enabled");
688 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000689 pw.println(" src set-device-enabled true|false|null");
690 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
691 pw.println(" The value could be true, false, or null(undefined).");
692 pw.println(" src get-device-enabled");
693 pw.println(" Gets the device config for RCS VoLTE single registration.");
694 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
695 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
696 pw.println(" The value could be true, false, or null(undefined).");
697 pw.println(" Options are:");
698 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
699 pw.println(" is specified, it will choose the default voice SIM slot.");
700 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
701 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
702 pw.println(" Options are:");
703 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
704 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800705 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
706 pw.println(" Sets ims feature validation result.");
707 pw.println(" The value could be true, false, or null(undefined).");
708 pw.println(" Options are:");
709 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
710 pw.println(" is specified, it will choose the default voice SIM slot.");
711 pw.println(" src get-feature-validation [-s SLOT_ID]");
712 pw.println(" Gets ims feature validation override value.");
713 pw.println(" Options are:");
714 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
715 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000716 }
717
SongFerngWang98dd5992021-05-13 17:50:00 +0800718 private void onHelpAllowedNetworkTypes() {
719 PrintWriter pw = getOutPrintWriter();
720 pw.println("Allowed Network Types Commands:");
721 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
722 pw.println(" Print allowed network types value.");
723 pw.println(" Options are:");
724 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
725 pw.println(" option is specified, it will choose the default voice SIM slot.");
726 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
727 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
728 pw.println(" Options are:");
729 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
730 pw.println(" option is specified, it will choose the default voice SIM slot.");
731 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
732 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
733 pw.println(" at TelephonyManager.java");
734 pw.println(" For example:");
735 pw.println(" NR only : 10000000000000000000");
736 pw.println(" NR|LTE : 11000001000000000000");
737 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
738 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
739 pw.println(" LTE only : 01000001000000000000");
740 }
741
jimsun3b9ccac2021-10-26 15:01:23 +0800742 private void onHelpRadio() {
743 PrintWriter pw = getOutPrintWriter();
744 pw.println("Radio Commands:");
745 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
746 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
747 pw.println(" to be the bound. Options are:");
748 pw.println(" -s: the service name that the modem service should be bound for.");
749 pw.println(" If no option is specified, it will bind to the default.");
750 pw.println(" radio get-modem-service");
751 pw.println(" Gets the service name of the currently defined modem service.");
752 pw.println(" If it is binding to default, 'default' returns.");
753 pw.println(" If it doesn't bind to any modem service for some reasons,");
754 pw.println(" the result would be 'unknown'.");
755 }
756
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700757 private void onHelpSatellite() {
758 PrintWriter pw = getOutPrintWriter();
759 pw.println("Satellite Commands:");
760 pw.println(" set-satellite-service-package-name [-s SERVICE_PACKAGE_NAME]");
761 pw.println(" Sets the package name of satellite service defined in");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700762 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700763 pw.println(" -s: the satellite service package name that Telephony will bind to.");
764 pw.println(" If no option is specified, it will bind to the default.");
Thomas Nguyen1854a5a2023-04-04 09:31:47 -0700765 pw.println(" set-satellite-gateway-service-package-name [-s SERVICE_PACKAGE_NAME]");
766 pw.println(" Sets the package name of satellite gateway service defined in");
767 pw.println(" SERVICE_PACKAGE_NAME to be bound. Options are:");
768 pw.println(" -s: the satellite gateway service package name that Telephony will bind");
769 pw.println(" to. If no option is specified, it will bind to the default.");
Thomas Nguyenf9a533c2023-04-06 20:48:41 -0700770 pw.println(" set-satellite-listening-timeout-duration [-t TIMEOUT_MILLIS]");
771 pw.println(" Sets the timeout duration in millis that satellite will stay at listening");
772 pw.println(" mode. Options are:");
773 pw.println(" -t: the timeout duration in milliseconds.");
774 pw.println(" If no option is specified, it will use the default values.");
Thomas Nguyen87dce732023-04-20 18:27:16 -0700775 pw.println(" set-satellite-pointing-ui-class-name [-p PACKAGE_NAME -c CLASS_NAME]");
776 pw.println(" Sets the package and class name of satellite pointing UI app defined in");
777 pw.println(" PACKAGE_NAME and CLASS_NAME to be launched. Options are:");
778 pw.println(" -p: the satellite pointing UI app package name that Telephony will");
779 pw.println(" launch. If no option is specified, it will launch the default.");
780 pw.println(" -c: the satellite pointing UI app class name that Telephony will");
781 pw.println(" launch.");
Thomas Nguyend34a5fc2023-03-23 21:07:03 -0700782 }
783
Ling Ma4fbab492022-01-25 22:36:16 +0000784 private void onHelpImei() {
785 PrintWriter pw = getOutPrintWriter();
786 pw.println("IMEI Commands:");
787 pw.println(" get-imei [-s SLOT_ID]");
788 pw.println(" Gets the device IMEI. Options are:");
789 pw.println(" -s: the slot ID to get the IMEI. If no option");
790 pw.println(" is specified, it will choose the default voice SIM slot.");
791 }
792
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700793 private int handleImsCommand() {
794 String arg = getNextArg();
795 if (arg == null) {
796 onHelpIms();
797 return 0;
798 }
799
800 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800801 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700802 return handleImsSetServiceCommand();
803 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800804 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700805 return handleImsGetServiceCommand();
806 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800807 case IMS_CLEAR_SERVICE_OVERRIDE: {
808 return handleImsClearCarrierServiceCommand();
809 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800810 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700811 return handleEnableIms();
812 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800813 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700814 return handleDisableIms();
815 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700816 case IMS_CEP: {
817 return handleCepChange();
818 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700819 }
820
821 return -1;
822 }
823
Shuo Qianf5125122019-12-16 17:03:07 -0800824 private int handleDataTestModeCommand() {
825 PrintWriter errPw = getErrPrintWriter();
826 String arg = getNextArgRequired();
827 if (arg == null) {
828 onHelpDataTestMode();
829 return 0;
830 }
831 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800832 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800833 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700834 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800835 } catch (RemoteException ex) {
836 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
837 errPw.println("Exception: " + ex.getMessage());
838 return -1;
839 }
840 break;
841 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800842 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800843 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700844 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800845 } catch (RemoteException ex) {
846 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
847 errPw.println("Exception: " + ex.getMessage());
848 return -1;
849 }
850 break;
851 }
852 default:
853 onHelpDataTestMode();
854 break;
855 }
856 return 0;
857 }
858
Shuo Qianccbaf742021-02-22 18:32:21 -0800859 private int handleEmergencyCallbackModeCommand() {
860 PrintWriter errPw = getErrPrintWriter();
861 try {
862 mInterface.startEmergencyCallbackMode();
863 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
864 } catch (RemoteException ex) {
865 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
866 errPw.println("Exception: " + ex.getMessage());
867 return -1;
868 }
869 return 0;
870 }
871
Grant Menke567d48f2022-08-18 20:19:10 +0000872 private void removeEmergencyNumberTestMode(String emergencyNumber) {
873 PrintWriter errPw = getErrPrintWriter();
874 for (int routingType : ROUTING_TYPES) {
875 try {
876 mInterface.updateEmergencyNumberListTestMode(
877 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
878 new EmergencyNumber(emergencyNumber, "", "",
879 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
880 new ArrayList<String>(),
881 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
882 routingType));
883 } catch (RemoteException ex) {
884 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
885 errPw.println("Exception: " + ex.getMessage());
886 }
887 }
888 }
889
sqian9d4df8b2019-01-15 18:32:07 -0800890 private int handleEmergencyNumberTestModeCommand() {
891 PrintWriter errPw = getErrPrintWriter();
892 String opt = getNextOption();
893 if (opt == null) {
894 onHelpEmergencyNumber();
895 return 0;
896 }
sqian9d4df8b2019-01-15 18:32:07 -0800897 switch (opt) {
898 case "-a": {
899 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000900 if (emergencyNumberCmd == null){
901 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800902 return -1;
903 }
Grant Menke567d48f2022-08-18 20:19:10 +0000904 String[] params = emergencyNumberCmd.split(":");
905 String emergencyNumber;
906 if (params[0] == null ||
907 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
908 errPw.println(INVALID_ENTRY_ERROR);
909 return -1;
910 } else {
911 emergencyNumber = params[0];
912 }
913 removeEmergencyNumberTestMode(emergencyNumber);
914 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
915 if (params.length > 1) {
916 switch (params[1].toLowerCase(Locale.ROOT)) {
917 case "emergency":
918 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
919 break;
920 case "normal":
921 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
922 break;
923 case "unknown":
924 break;
925 default:
926 errPw.println("\"" + params[1] + "\" is not a valid specification for "
927 + "emergency call routing. Please enter either \"normal\", "
928 + "\"unknown\", or \"emergency\" for call routing. "
929 + "(-a 1234:normal)");
930 return -1;
931 }
932 }
sqian9d4df8b2019-01-15 18:32:07 -0800933 try {
934 mInterface.updateEmergencyNumberListTestMode(
935 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +0000936 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -0800937 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
938 new ArrayList<String>(),
939 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +0000940 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -0800941 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +0000942 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -0800943 + ", error " + ex.getMessage());
944 errPw.println("Exception: " + ex.getMessage());
945 return -1;
946 }
947 break;
948 }
949 case "-c": {
950 try {
951 mInterface.updateEmergencyNumberListTestMode(
952 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
953 } catch (RemoteException ex) {
954 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
955 errPw.println("Exception: " + ex.getMessage());
956 return -1;
957 }
958 break;
959 }
960 case "-r": {
961 String emergencyNumberCmd = getNextArgRequired();
962 if (emergencyNumberCmd == null
963 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700964 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800965 + " to be specified after -r in the command ");
966 return -1;
967 }
Grant Menke567d48f2022-08-18 20:19:10 +0000968 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -0800969 break;
970 }
971 case "-p": {
972 try {
973 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
974 } catch (RemoteException ex) {
975 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
976 errPw.println("Exception: " + ex.getMessage());
977 return -1;
978 }
979 break;
980 }
981 default:
982 onHelpEmergencyNumber();
983 break;
984 }
985 return 0;
986 }
987
Hall Liud892bec2018-11-30 14:51:45 -0800988 private int handleNumberVerificationCommand() {
989 String arg = getNextArg();
990 if (arg == null) {
991 onHelpNumberVerification();
992 return 0;
993 }
994
Hall Liuca5af3a2018-12-04 16:58:23 -0800995 if (!checkShellUid()) {
996 return -1;
997 }
998
Hall Liud892bec2018-11-30 14:51:45 -0800999 switch (arg) {
1000 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -08001001 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
1002 return 0;
1003 }
Hall Liuca5af3a2018-12-04 16:58:23 -08001004 case NUMBER_VERIFICATION_FAKE_CALL: {
1005 boolean val = NumberVerificationManager.getInstance()
1006 .checkIncomingCall(getNextArg());
1007 getOutPrintWriter().println(val ? "1" : "0");
1008 return 0;
1009 }
Hall Liud892bec2018-11-30 14:51:45 -08001010 }
1011
1012 return -1;
1013 }
1014
Jordan Liu0ccee222021-04-27 11:55:13 -07001015 private boolean subIsEsim(int subId) {
1016 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
1017 if (info != null) {
1018 return info.isEmbedded();
1019 }
1020 return false;
1021 }
1022
1023 private int handleEnablePhysicalSubscription(boolean enable) {
1024 PrintWriter errPw = getErrPrintWriter();
1025 int subId = 0;
1026 try {
1027 subId = Integer.parseInt(getNextArgRequired());
1028 } catch (NumberFormatException e) {
1029 errPw.println((enable ? "enable" : "disable")
1030 + "-physical-subscription requires an integer as a subId.");
1031 return -1;
1032 }
1033 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1034 // non user build.
1035 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1036 errPw.println("cc: Permission denied.");
1037 return -1;
1038 }
1039 // Verify that the subId represents a physical sub
1040 if (subIsEsim(subId)) {
1041 errPw.println("SubId " + subId + " is not for a physical subscription");
1042 return -1;
1043 }
1044 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
1045 + " physical subscription with subId=" + subId);
1046 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
1047 return 0;
1048 }
1049
Jack Nudelman644b91a2021-03-12 14:09:48 -08001050 private int handleThermalMitigationCommand() {
1051 String arg = getNextArg();
1052 String packageName = getNextArg();
1053 if (arg == null || packageName == null) {
1054 onHelpThermalMitigation();
1055 return 0;
1056 }
1057
1058 if (!checkShellUid()) {
1059 return -1;
1060 }
1061
1062 switch (arg) {
1063 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1064 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
1065 return 0;
1066 }
1067 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
1068 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
1069 mContext);
1070 return 0;
1071 }
1072 default:
1073 onHelpThermalMitigation();
1074 }
1075
1076 return -1;
1077
1078 }
1079
Tyler Gunn92479152021-01-20 16:30:10 -08001080 private int handleD2dCommand() {
1081 String arg = getNextArg();
1082 if (arg == null) {
1083 onHelpD2D();
1084 return 0;
1085 }
1086
1087 switch (arg) {
1088 case D2D_SEND: {
1089 return handleD2dSendCommand();
1090 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001091 case D2D_TRANSPORT: {
1092 return handleD2dTransportCommand();
1093 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001094 case D2D_SET_DEVICE_SUPPORT: {
1095 return handleD2dDeviceSupportedCommand();
1096 }
Tyler Gunn92479152021-01-20 16:30:10 -08001097 }
1098
1099 return -1;
1100 }
1101
1102 private int handleD2dSendCommand() {
1103 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001104 int messageType = -1;
1105 int messageValue = -1;
1106
Tyler Gunn92479152021-01-20 16:30:10 -08001107 String arg = getNextArg();
1108 if (arg == null) {
1109 onHelpD2D();
1110 return 0;
1111 }
1112 try {
1113 messageType = Integer.parseInt(arg);
1114 } catch (NumberFormatException e) {
1115 errPw.println("message type must be a valid integer");
1116 return -1;
1117 }
1118
1119 arg = getNextArg();
1120 if (arg == null) {
1121 onHelpD2D();
1122 return 0;
1123 }
1124 try {
1125 messageValue = Integer.parseInt(arg);
1126 } catch (NumberFormatException e) {
1127 errPw.println("message value must be a valid integer");
1128 return -1;
1129 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001130
Tyler Gunn92479152021-01-20 16:30:10 -08001131 try {
1132 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1133 } catch (RemoteException e) {
1134 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1135 errPw.println("Exception: " + e.getMessage());
1136 return -1;
1137 }
1138
1139 return 0;
1140 }
1141
Tyler Gunnbabbda02021-02-10 11:05:02 -08001142 private int handleD2dTransportCommand() {
1143 PrintWriter errPw = getErrPrintWriter();
1144
1145 String arg = getNextArg();
1146 if (arg == null) {
1147 onHelpD2D();
1148 return 0;
1149 }
1150
1151 try {
1152 mInterface.setActiveDeviceToDeviceTransport(arg);
1153 } catch (RemoteException e) {
1154 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1155 errPw.println("Exception: " + e.getMessage());
1156 return -1;
1157 }
1158 return 0;
1159 }
Nazanin014f41e2021-05-06 17:26:31 -07001160 private int handleBarringCommand() {
1161 String arg = getNextArg();
1162 if (arg == null) {
1163 onHelpBarring();
1164 return 0;
1165 }
1166
1167 switch (arg) {
1168 case BARRING_SEND_INFO: {
1169 return handleBarringSendCommand();
1170 }
1171 }
1172 return -1;
1173 }
1174
1175 private int handleBarringSendCommand() {
1176 PrintWriter errPw = getErrPrintWriter();
1177 int slotId = getDefaultSlot();
Jack Yu00ece8c2022-11-19 22:29:12 -08001178 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001179 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1180 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1181 boolean isConditionallyBarred = false;
1182 int conditionalBarringTimeSeconds = 0;
1183
1184 String opt;
1185 while ((opt = getNextOption()) != null) {
1186 switch (opt) {
1187 case "-s": {
1188 try {
1189 slotId = Integer.parseInt(getNextArgRequired());
Jack Yu00ece8c2022-11-19 22:29:12 -08001190 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001191 } catch (NumberFormatException e) {
1192 errPw.println("barring send requires an integer as a SLOT_ID.");
1193 return -1;
1194 }
1195 break;
1196 }
1197 case "-b": {
1198 try {
1199 barringType = Integer.parseInt(getNextArgRequired());
1200 if (barringType < -1 || barringType > 2) {
1201 throw new NumberFormatException();
1202 }
1203
1204 } catch (NumberFormatException e) {
1205 errPw.println("barring send requires an integer in range [-1,2] as "
1206 + "a BARRING_TYPE.");
1207 return -1;
1208 }
1209 break;
1210 }
1211 case "-c": {
1212 try {
1213 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1214 } catch (Exception e) {
1215 errPw.println("barring send requires a boolean after -c indicating"
1216 + " conditional barring");
1217 return -1;
1218 }
1219 break;
1220 }
1221 case "-t": {
1222 try {
1223 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1224 } catch (NumberFormatException e) {
1225 errPw.println("barring send requires an integer for time of barring"
1226 + " in seconds after -t for conditional barring");
1227 return -1;
1228 }
1229 break;
1230 }
1231 }
1232 }
1233 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1234 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1235 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1236 barringServiceInfos.append(0, bsi);
1237 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1238 try {
1239 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1240 } catch (Exception e) {
1241 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1242 errPw.println("Exception: " + e.getMessage());
1243 return -1;
1244 }
1245 return 0;
1246 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001247
Tyler Gunnd4575212021-05-03 14:46:49 -07001248 private int handleD2dDeviceSupportedCommand() {
1249 PrintWriter errPw = getErrPrintWriter();
1250
1251 String arg = getNextArg();
1252 if (arg == null) {
1253 onHelpD2D();
1254 return 0;
1255 }
1256
Jack Yua533d632022-09-30 13:53:46 -07001257 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001258 try {
1259 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1260 } catch (RemoteException e) {
1261 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1262 errPw.println("Exception: " + e.getMessage());
1263 return -1;
1264 }
1265 return 0;
1266 }
1267
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001268 // ims set-ims-service
1269 private int handleImsSetServiceCommand() {
1270 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001271 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001272 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001273 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001274
1275 String opt;
1276 while ((opt = getNextOption()) != null) {
1277 switch (opt) {
1278 case "-s": {
1279 try {
1280 slotId = Integer.parseInt(getNextArgRequired());
1281 } catch (NumberFormatException e) {
1282 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1283 return -1;
1284 }
1285 break;
1286 }
1287 case "-c": {
1288 isCarrierService = true;
1289 break;
1290 }
1291 case "-d": {
1292 isCarrierService = false;
1293 break;
1294 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001295 case "-f": {
1296 String featureString = getNextArgRequired();
1297 String[] features = featureString.split(",");
1298 for (int i = 0; i < features.length; i++) {
1299 try {
1300 Integer result = Integer.parseInt(features[i]);
1301 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1302 || result >= ImsFeature.FEATURE_MAX) {
1303 errPw.println("ims set-ims-service -f " + result
1304 + " is an invalid feature.");
1305 return -1;
1306 }
1307 featuresList.add(result);
1308 } catch (NumberFormatException e) {
1309 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1310 + " as an integer.");
1311 return -1;
1312 }
1313 }
1314 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001315 }
1316 }
1317 // Mandatory param, either -c or -d
1318 if (isCarrierService == null) {
1319 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1320 return -1;
1321 }
1322
1323 String packageName = getNextArg();
1324
1325 try {
1326 if (packageName == null) {
1327 packageName = "";
1328 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001329 int[] featureArray = new int[featuresList.size()];
1330 for (int i = 0; i < featuresList.size(); i++) {
1331 featureArray[i] = featuresList.get(i);
1332 }
1333 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1334 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001335 if (VDBG) {
1336 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001337 + (isCarrierService ? "-c " : "-d ")
1338 + "-f " + featuresList + " "
1339 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001340 }
1341 getOutPrintWriter().println(result);
1342 } catch (RemoteException e) {
1343 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001344 + (isCarrierService ? "-c " : "-d ")
1345 + "-f " + featuresList + " "
1346 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001347 errPw.println("Exception: " + e.getMessage());
1348 return -1;
1349 }
1350 return 0;
1351 }
1352
Brad Ebinger999d3302020-11-25 14:31:39 -08001353 // ims clear-ims-service-override
1354 private int handleImsClearCarrierServiceCommand() {
1355 PrintWriter errPw = getErrPrintWriter();
1356 int slotId = getDefaultSlot();
1357
1358 String opt;
1359 while ((opt = getNextOption()) != null) {
1360 switch (opt) {
1361 case "-s": {
1362 try {
1363 slotId = Integer.parseInt(getNextArgRequired());
1364 } catch (NumberFormatException e) {
1365 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1366 return -1;
1367 }
1368 break;
1369 }
1370 }
1371 }
1372
1373 try {
1374 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1375 if (VDBG) {
1376 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1377 + ", result=" + result);
1378 }
1379 getOutPrintWriter().println(result);
1380 } catch (RemoteException e) {
1381 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1382 + ", error" + e.getMessage());
1383 errPw.println("Exception: " + e.getMessage());
1384 return -1;
1385 }
1386 return 0;
1387 }
1388
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001389 // ims get-ims-service
1390 private int handleImsGetServiceCommand() {
1391 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001392 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001393 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001394 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001395
1396 String opt;
1397 while ((opt = getNextOption()) != null) {
1398 switch (opt) {
1399 case "-s": {
1400 try {
1401 slotId = Integer.parseInt(getNextArgRequired());
1402 } catch (NumberFormatException e) {
1403 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1404 return -1;
1405 }
1406 break;
1407 }
1408 case "-c": {
1409 isCarrierService = true;
1410 break;
1411 }
1412 case "-d": {
1413 isCarrierService = false;
1414 break;
1415 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001416 case "-f": {
1417 try {
1418 featureType = Integer.parseInt(getNextArg());
1419 } catch (NumberFormatException e) {
1420 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1421 return -1;
1422 }
1423 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1424 || featureType >= ImsFeature.FEATURE_MAX) {
1425 errPw.println("ims get-ims-service -f invalid feature.");
1426 return -1;
1427 }
1428 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001429 }
1430 }
1431 // Mandatory param, either -c or -d
1432 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001433 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001434 return -1;
1435 }
1436
1437 String result;
1438 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001439 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001440 } catch (RemoteException e) {
1441 return -1;
1442 }
1443 if (VDBG) {
1444 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001445 + (isCarrierService ? "-c " : "-d ")
1446 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1447 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001448 }
1449 getOutPrintWriter().println(result);
1450 return 0;
1451 }
1452
1453 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001454 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001455 String opt;
1456 while ((opt = getNextOption()) != null) {
1457 switch (opt) {
1458 case "-s": {
1459 try {
1460 slotId = Integer.parseInt(getNextArgRequired());
1461 } catch (NumberFormatException e) {
1462 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1463 return -1;
1464 }
1465 break;
1466 }
1467 }
1468 }
1469 try {
1470 mInterface.enableIms(slotId);
1471 } catch (RemoteException e) {
1472 return -1;
1473 }
1474 if (VDBG) {
1475 Log.v(LOG_TAG, "ims enable -s " + slotId);
1476 }
1477 return 0;
1478 }
1479
1480 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001481 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001482 String opt;
1483 while ((opt = getNextOption()) != null) {
1484 switch (opt) {
1485 case "-s": {
1486 try {
1487 slotId = Integer.parseInt(getNextArgRequired());
1488 } catch (NumberFormatException e) {
1489 getErrPrintWriter().println(
1490 "ims disable requires an integer as a SLOT_ID.");
1491 return -1;
1492 }
1493 break;
1494 }
1495 }
1496 }
1497 try {
1498 mInterface.disableIms(slotId);
1499 } catch (RemoteException e) {
1500 return -1;
1501 }
1502 if (VDBG) {
1503 Log.v(LOG_TAG, "ims disable -s " + slotId);
1504 }
1505 return 0;
1506 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001507
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001508 private int handleCepChange() {
1509 Log.i(LOG_TAG, "handleCepChange");
1510 String opt = getNextArg();
1511 if (opt == null) {
1512 return -1;
1513 }
1514 boolean isCepEnabled = opt.equals("enable");
1515
1516 try {
1517 mInterface.setCepEnabled(isCepEnabled);
1518 } catch (RemoteException e) {
1519 return -1;
1520 }
1521 return 0;
1522 }
1523
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001524 private int getDefaultSlot() {
1525 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1526 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1527 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1528 // If there is no default, default to slot 0.
1529 slotId = DEFAULT_PHONE_ID;
1530 }
1531 return slotId;
1532 }
sqian2fff4a32018-11-05 14:18:37 -08001533
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001534 // Parse options related to Carrier Config Commands.
1535 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001536 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001537 CcOptionParseResult result = new CcOptionParseResult();
1538 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1539 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001540
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001541 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001542 while ((opt = getNextOption()) != null) {
1543 switch (opt) {
1544 case "-s": {
1545 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001546 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1547 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1548 errPw.println(tag + "No valid subscription found.");
1549 return null;
1550 }
1551
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001552 } catch (IllegalArgumentException e) {
1553 // Missing slot id
1554 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001555 return null;
1556 }
1557 break;
1558 }
1559 case "-p": {
1560 if (allowOptionPersistent) {
1561 result.mPersistent = true;
1562 } else {
1563 errPw.println(tag + "Unexpected option " + opt);
1564 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001565 }
1566 break;
1567 }
1568 default: {
1569 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001570 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001571 }
1572 }
1573 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001574 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001575 }
1576
1577 private int slotStringToSubId(String tag, String slotString) {
1578 int slotId = -1;
1579 try {
1580 slotId = Integer.parseInt(slotString);
1581 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001582 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1583 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1584 }
1585
1586 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001587 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1588 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1589 }
1590
Qiong Liuf25799b2020-09-10 10:13:46 +08001591 Phone phone = PhoneFactory.getPhone(slotId);
1592 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001593 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1594 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1595 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001596 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001597 }
1598
Hall Liud892bec2018-11-30 14:51:45 -08001599 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001600 // adb can run as root or as shell, depending on whether the device is rooted.
1601 return Binder.getCallingUid() == Process.SHELL_UID
1602 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001603 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001604
1605 private int handleCcCommand() {
1606 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1607 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001608 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001609 getErrPrintWriter().println("cc: Permission denied.");
1610 return -1;
1611 }
1612
1613 String arg = getNextArg();
1614 if (arg == null) {
1615 onHelpCc();
1616 return 0;
1617 }
1618
1619 switch (arg) {
1620 case CC_GET_VALUE: {
1621 return handleCcGetValue();
1622 }
1623 case CC_SET_VALUE: {
1624 return handleCcSetValue();
1625 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001626 case CC_SET_VALUES_FROM_XML: {
1627 return handleCcSetValuesFromXml();
1628 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001629 case CC_CLEAR_VALUES: {
1630 return handleCcClearValues();
1631 }
1632 default: {
1633 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1634 }
1635 }
1636 return -1;
1637 }
1638
1639 // cc get-value
1640 private int handleCcGetValue() {
1641 PrintWriter errPw = getErrPrintWriter();
1642 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1643 String key = null;
1644
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001645 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001646 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001647 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001648 return -1;
1649 }
1650
1651 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001652 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001653 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001654 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001655 return -1;
1656 }
1657
1658 // Get the key.
1659 key = getNextArg();
1660 if (key != null) {
1661 // A key was provided. Verify if it is a valid key
1662 if (!bundle.containsKey(key)) {
1663 errPw.println(tag + key + " is not a valid key.");
1664 return -1;
1665 }
1666
1667 // Print the carrier config value for key.
1668 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1669 } else {
1670 // No key provided. Show all values.
1671 // Iterate over a sorted list of all carrier config keys and print them.
1672 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1673 for (String k : sortedSet) {
1674 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1675 }
1676 }
1677 return 0;
1678 }
1679
1680 // cc set-value
1681 private int handleCcSetValue() {
1682 PrintWriter errPw = getErrPrintWriter();
1683 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1684
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001685 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001686 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001687 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001688 return -1;
1689 }
1690
1691 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001692 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001693 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001694 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001695 return -1;
1696 }
1697
1698 // Get the key.
1699 String key = getNextArg();
1700 if (key == null || key.equals("")) {
1701 errPw.println(tag + "KEY is missing");
1702 return -1;
1703 }
1704
1705 // Verify if the key is valid
1706 if (!originalValues.containsKey(key)) {
1707 errPw.println(tag + key + " is not a valid key.");
1708 return -1;
1709 }
1710
1711 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1712 ArrayList<String> valueList = new ArrayList<String>();
1713 while (peekNextArg() != null) {
1714 valueList.add(getNextArg());
1715 }
1716
1717 // Find the type of the carrier config value
1718 CcType type = getType(tag, key, originalValues);
1719 if (type == CcType.UNKNOWN) {
1720 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1721 return -1;
1722 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001723 if (type == CcType.PERSISTABLE_BUNDLE) {
1724 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1725 + "Use set-values-from-xml instead.");
1726 return -1;
1727 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001728
1729 // Create an override bundle containing the key and value that should be overriden.
1730 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1731 if (overrideBundle == null) {
1732 return -1;
1733 }
1734
1735 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001736 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001737
1738 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001739 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001740 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001741 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001742 return -1;
1743 }
1744
1745 // Print the original and new value.
1746 String originalValueString = ccValueToString(key, type, originalValues);
1747 String newValueString = ccValueToString(key, type, newValues);
1748 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1749 getOutPrintWriter().println("New value: \n" + newValueString);
1750
1751 return 0;
1752 }
1753
Allen Xuee00f0e2022-03-14 21:04:49 +00001754 // cc set-values-from-xml
1755 private int handleCcSetValuesFromXml() {
1756 PrintWriter errPw = getErrPrintWriter();
1757 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1758
1759 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001760 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001761 if (options == null) {
1762 return -1;
1763 }
1764
1765 // Get bundle containing all current carrier configuration values.
1766 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1767 if (originalValues == null) {
1768 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1769 return -1;
1770 }
1771
1772 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1773 if (overrideBundle == null) {
1774 return -1;
1775 }
1776
1777 // Verify all values are valid types
1778 for (String key : overrideBundle.keySet()) {
1779 CcType type = getType(tag, key, originalValues);
1780 if (type == CcType.UNKNOWN) {
1781 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1782 return -1;
1783 }
1784 }
1785
1786 // Override the value
1787 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1788
1789 // Find bundle containing all new carrier configuration values after the override.
1790 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1791 if (newValues == null) {
1792 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1793 return -1;
1794 }
1795
1796 // Print the original and new values
1797 overrideBundle.keySet().forEach(key -> {
1798 CcType type = getType(tag, key, originalValues);
1799 String originalValueString = ccValueToString(key, type, originalValues);
1800 String newValueString = ccValueToString(key, type, newValues);
1801 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1802 getOutPrintWriter().println("New value: \n" + newValueString);
1803 });
1804
1805 return 0;
1806 }
1807
1808 private PersistableBundle readPersistableBundleFromXml(String tag) {
1809 PersistableBundle subIdBundles;
1810 try {
1811 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1812 } catch (IOException | RuntimeException e) {
1813 PrintWriter errPw = getErrPrintWriter();
1814 errPw.println(tag + e);
1815 return null;
1816 }
1817
1818 return subIdBundles;
1819 }
1820
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001821 // cc clear-values
1822 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001823 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1824
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001825 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001826 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001827 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001828 return -1;
1829 }
1830
1831 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001832 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001833 getOutPrintWriter()
1834 .println("All previously set carrier config override values has been cleared");
1835 return 0;
1836 }
1837
1838 private CcType getType(String tag, String key, PersistableBundle bundle) {
1839 // Find the type by checking the type of the current value stored in the bundle.
1840 Object value = bundle.get(key);
1841
1842 if (CC_TYPE_MAP.containsKey(key)) {
1843 return CC_TYPE_MAP.get(key);
1844 } else if (value != null) {
1845 if (value instanceof Boolean) {
1846 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001847 }
1848 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001849 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001850 }
1851 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001852 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001853 }
1854 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001855 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001856 }
1857 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001858 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001859 }
1860 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001861 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001862 }
1863 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001864 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001865 }
1866 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001867 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001868 }
1869 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001870 return CcType.STRING_ARRAY;
1871 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001872 if (value instanceof PersistableBundle) {
1873 return CcType.PERSISTABLE_BUNDLE;
1874 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001875 } else {
1876 // Current value was null and can therefore not be used in order to find the type.
1877 // Check the name of the key to infer the type. This check is not needed for primitive
1878 // data types (boolean, double, int and long), since they can not be null.
1879 if (key.endsWith("double_array")) {
1880 return CcType.DOUBLE_ARRAY;
1881 }
1882 if (key.endsWith("int_array")) {
1883 return CcType.INT_ARRAY;
1884 }
1885 if (key.endsWith("long_array")) {
1886 return CcType.LONG_ARRAY;
1887 }
1888 if (key.endsWith("string")) {
1889 return CcType.STRING;
1890 }
1891 if (key.endsWith("string_array") || key.endsWith("strings")) {
1892 return CcType.STRING_ARRAY;
1893 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001894 if (key.endsWith("bundle")) {
1895 return CcType.PERSISTABLE_BUNDLE;
1896 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001897 }
1898
1899 // Not possible to infer the type by looking at the current value or the key.
1900 PrintWriter errPw = getErrPrintWriter();
1901 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1902 return CcType.UNKNOWN;
1903 }
1904
1905 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1906 String result;
1907 StringBuilder valueString = new StringBuilder();
1908 String typeString = type.toString();
1909 Object value = bundle.get(key);
1910
1911 if (value == null) {
1912 valueString.append("null");
1913 } else {
1914 switch (type) {
1915 case DOUBLE_ARRAY: {
1916 // Format the string representation of the int array as value1 value2......
1917 double[] valueArray = (double[]) value;
1918 for (int i = 0; i < valueArray.length; i++) {
1919 if (i != 0) {
1920 valueString.append(" ");
1921 }
1922 valueString.append(valueArray[i]);
1923 }
1924 break;
1925 }
1926 case INT_ARRAY: {
1927 // Format the string representation of the int array as value1 value2......
1928 int[] valueArray = (int[]) value;
1929 for (int i = 0; i < valueArray.length; i++) {
1930 if (i != 0) {
1931 valueString.append(" ");
1932 }
1933 valueString.append(valueArray[i]);
1934 }
1935 break;
1936 }
1937 case LONG_ARRAY: {
1938 // Format the string representation of the int array as value1 value2......
1939 long[] valueArray = (long[]) value;
1940 for (int i = 0; i < valueArray.length; i++) {
1941 if (i != 0) {
1942 valueString.append(" ");
1943 }
1944 valueString.append(valueArray[i]);
1945 }
1946 break;
1947 }
1948 case STRING: {
1949 valueString.append("\"" + value.toString() + "\"");
1950 break;
1951 }
1952 case STRING_ARRAY: {
1953 // Format the string representation of the string array as "value1" "value2"....
1954 String[] valueArray = (String[]) value;
1955 for (int i = 0; i < valueArray.length; i++) {
1956 if (i != 0) {
1957 valueString.append(" ");
1958 }
1959 if (valueArray[i] != null) {
1960 valueString.append("\"" + valueArray[i] + "\"");
1961 } else {
1962 valueString.append("null");
1963 }
1964 }
1965 break;
1966 }
1967 default: {
1968 valueString.append(value.toString());
1969 }
1970 }
1971 }
1972 return String.format("%-70s %-15s %s", key, typeString, valueString);
1973 }
1974
1975 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1976 ArrayList<String> valueList) {
1977 PrintWriter errPw = getErrPrintWriter();
1978 PersistableBundle bundle = new PersistableBundle();
1979
1980 // First verify that a valid number of values has been provided for the type.
1981 switch (type) {
1982 case BOOLEAN:
1983 case DOUBLE:
1984 case INT:
1985 case LONG: {
1986 if (valueList.size() != 1) {
1987 errPw.println(tag + "Expected 1 value for type " + type
1988 + ". Found: " + valueList.size());
1989 return null;
1990 }
1991 break;
1992 }
1993 case STRING: {
1994 if (valueList.size() > 1) {
1995 errPw.println(tag + "Expected 0 or 1 values for type " + type
1996 + ". Found: " + valueList.size());
1997 return null;
1998 }
1999 break;
2000 }
2001 }
2002
2003 // Parse the value according to type and add it to the Bundle.
2004 switch (type) {
2005 case BOOLEAN: {
2006 if ("true".equalsIgnoreCase(valueList.get(0))) {
2007 bundle.putBoolean(key, true);
2008 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
2009 bundle.putBoolean(key, false);
2010 } else {
2011 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2012 return null;
2013 }
2014 break;
2015 }
2016 case DOUBLE: {
2017 try {
2018 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
2019 } catch (NumberFormatException nfe) {
2020 // Not a valid double
2021 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2022 return null;
2023 }
2024 break;
2025 }
2026 case DOUBLE_ARRAY: {
2027 double[] valueDoubleArray = null;
2028 if (valueList.size() > 0) {
2029 valueDoubleArray = new double[valueList.size()];
2030 for (int i = 0; i < valueList.size(); i++) {
2031 try {
2032 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
2033 } catch (NumberFormatException nfe) {
2034 // Not a valid double
2035 errPw.println(
2036 tag + "Unable to parse " + valueList.get(i) + " as a double.");
2037 return null;
2038 }
2039 }
2040 }
2041 bundle.putDoubleArray(key, valueDoubleArray);
2042 break;
2043 }
2044 case INT: {
2045 try {
2046 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
2047 } catch (NumberFormatException nfe) {
2048 // Not a valid integer
2049 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
2050 return null;
2051 }
2052 break;
2053 }
2054 case INT_ARRAY: {
2055 int[] valueIntArray = null;
2056 if (valueList.size() > 0) {
2057 valueIntArray = new int[valueList.size()];
2058 for (int i = 0; i < valueList.size(); i++) {
2059 try {
2060 valueIntArray[i] = Integer.parseInt(valueList.get(i));
2061 } catch (NumberFormatException nfe) {
2062 // Not a valid integer
2063 errPw.println(tag
2064 + "Unable to parse " + valueList.get(i) + " as an integer.");
2065 return null;
2066 }
2067 }
2068 }
2069 bundle.putIntArray(key, valueIntArray);
2070 break;
2071 }
2072 case LONG: {
2073 try {
2074 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2075 } catch (NumberFormatException nfe) {
2076 // Not a valid long
2077 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2078 return null;
2079 }
2080 break;
2081 }
2082 case LONG_ARRAY: {
2083 long[] valueLongArray = null;
2084 if (valueList.size() > 0) {
2085 valueLongArray = new long[valueList.size()];
2086 for (int i = 0; i < valueList.size(); i++) {
2087 try {
2088 valueLongArray[i] = Long.parseLong(valueList.get(i));
2089 } catch (NumberFormatException nfe) {
2090 // Not a valid long
2091 errPw.println(
2092 tag + "Unable to parse " + valueList.get(i) + " as a long");
2093 return null;
2094 }
2095 }
2096 }
2097 bundle.putLongArray(key, valueLongArray);
2098 break;
2099 }
2100 case STRING: {
2101 String value = null;
2102 if (valueList.size() > 0) {
2103 value = valueList.get(0);
2104 }
2105 bundle.putString(key, value);
2106 break;
2107 }
2108 case STRING_ARRAY: {
2109 String[] valueStringArray = null;
2110 if (valueList.size() > 0) {
2111 valueStringArray = new String[valueList.size()];
2112 valueList.toArray(valueStringArray);
2113 }
2114 bundle.putStringArray(key, valueStringArray);
2115 break;
2116 }
2117 }
2118 return bundle;
2119 }
Shuo Qian489d9282020-07-09 11:30:03 -07002120
2121 private int handleEndBlockSuppressionCommand() {
2122 if (!checkShellUid()) {
2123 return -1;
2124 }
2125
2126 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2127 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2128 }
2129 return 0;
2130 }
Hui Wang641e81c2020-10-12 12:14:23 -07002131
Shivakumar Neginal9cd61892022-12-19 04:38:52 +00002132 private int handleEuiccCommand() {
2133 String arg = getNextArg();
2134 if (arg == null) {
2135 onHelpEuicc();
2136 return 0;
2137 }
2138
2139 switch (arg) {
2140 case EUICC_SET_UI_COMPONENT: {
2141 return handleEuiccServiceCommand();
2142 }
2143 }
2144 return -1;
2145 }
2146
2147 private int handleEuiccServiceCommand() {
2148 String uiComponent = getNextArg();
2149 String packageName = getNextArg();
2150 if (packageName == null || uiComponent == null) {
2151 return -1;
2152 }
2153 EuiccUiDispatcherActivity.setTestEuiccUiComponent(packageName, uiComponent);
2154 if (VDBG) {
2155 Log.v(LOG_TAG, "euicc set-euicc-uicomponent " + uiComponent +" "
2156 + packageName);
2157 }
2158 return 0;
2159 }
2160
Michele Berionne54af4632020-12-28 20:23:16 +00002161 private int handleRestartModemCommand() {
2162 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2163 // non user build.
2164 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2165 getErrPrintWriter().println("RestartModem: Permission denied.");
2166 return -1;
2167 }
2168
2169 boolean result = TelephonyManager.getDefault().rebootRadio();
2170 getOutPrintWriter().println(result);
2171
2172 return result ? 0 : -1;
2173 }
2174
Ling Ma4fbab492022-01-25 22:36:16 +00002175 private int handleGetImei() {
2176 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2177 // non user build.
2178 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2179 getErrPrintWriter().println("Device IMEI: Permission denied.");
2180 return -1;
2181 }
2182
2183 final long identity = Binder.clearCallingIdentity();
2184
2185 String imei = null;
2186 String arg = getNextArg();
2187 if (arg != null) {
2188 try {
2189 int specifiedSlotIndex = Integer.parseInt(arg);
2190 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2191 } catch (NumberFormatException exception) {
2192 PrintWriter errPw = getErrPrintWriter();
2193 errPw.println("-s requires an integer as slot index.");
2194 return -1;
2195 }
2196
2197 } else {
2198 imei = TelephonyManager.from(mContext).getImei();
2199 }
2200 getOutPrintWriter().println("Device IMEI: " + imei);
2201
2202 Binder.restoreCallingIdentity(identity);
2203 return 0;
2204 }
2205
Michele Berionne5e411512020-11-13 02:36:59 +00002206 private int handleUnattendedReboot() {
2207 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2208 // non user build.
2209 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2210 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2211 return -1;
2212 }
2213
2214 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2215 getOutPrintWriter().println("result: " + result);
2216
2217 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2218 }
2219
Aman Gupta07124872022-02-09 08:02:14 +00002220 private int handleGetSimSlotsMapping() {
2221 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2222 // non user build.
2223 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2224 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2225 return -1;
2226 }
2227 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2228 String result = telephonyManager.getSimSlotMapping().toString();
2229 getOutPrintWriter().println("simSlotsMapping: " + result);
2230
2231 return 0;
2232 }
2233
Hui Wang641e81c2020-10-12 12:14:23 -07002234 private int handleGbaCommand() {
2235 String arg = getNextArg();
2236 if (arg == null) {
2237 onHelpGba();
2238 return 0;
2239 }
2240
2241 switch (arg) {
2242 case GBA_SET_SERVICE: {
2243 return handleGbaSetServiceCommand();
2244 }
2245 case GBA_GET_SERVICE: {
2246 return handleGbaGetServiceCommand();
2247 }
2248 case GBA_SET_RELEASE_TIME: {
2249 return handleGbaSetReleaseCommand();
2250 }
2251 case GBA_GET_RELEASE_TIME: {
2252 return handleGbaGetReleaseCommand();
2253 }
2254 }
2255
2256 return -1;
2257 }
2258
2259 private int getSubId(String cmd) {
2260 int slotId = getDefaultSlot();
2261 String opt = getNextOption();
2262 if (opt != null && opt.equals("-s")) {
2263 try {
2264 slotId = Integer.parseInt(getNextArgRequired());
2265 } catch (NumberFormatException e) {
2266 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2267 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2268 }
2269 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002270 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002271 }
2272
2273 private int handleGbaSetServiceCommand() {
2274 int subId = getSubId("gba set-service");
2275 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2276 return -1;
2277 }
2278
2279 String packageName = getNextArg();
2280 try {
2281 if (packageName == null) {
2282 packageName = "";
2283 }
2284 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2285 if (VDBG) {
2286 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2287 + packageName + ", result=" + result);
2288 }
2289 getOutPrintWriter().println(result);
2290 } catch (RemoteException e) {
2291 Log.w(LOG_TAG, "gba set-service " + subId + " "
2292 + packageName + ", error" + e.getMessage());
2293 getErrPrintWriter().println("Exception: " + e.getMessage());
2294 return -1;
2295 }
2296 return 0;
2297 }
2298
2299 private int handleGbaGetServiceCommand() {
2300 String result;
2301
2302 int subId = getSubId("gba get-service");
2303 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2304 return -1;
2305 }
2306
2307 try {
2308 result = mInterface.getBoundGbaService(subId);
2309 } catch (RemoteException e) {
2310 return -1;
2311 }
2312 if (VDBG) {
2313 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2314 }
2315 getOutPrintWriter().println(result);
2316 return 0;
2317 }
2318
2319 private int handleGbaSetReleaseCommand() {
2320 //the release time value could be -1
2321 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2322 : SubscriptionManager.getDefaultSubscriptionId();
2323 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2324 return -1;
2325 }
2326
2327 String intervalStr = getNextArg();
2328 if (intervalStr == null) {
2329 return -1;
2330 }
2331
2332 try {
2333 int interval = Integer.parseInt(intervalStr);
2334 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2335 if (VDBG) {
2336 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2337 + intervalStr + ", result=" + result);
2338 }
2339 getOutPrintWriter().println(result);
2340 } catch (NumberFormatException | RemoteException e) {
2341 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2342 + intervalStr + ", error" + e.getMessage());
2343 getErrPrintWriter().println("Exception: " + e.getMessage());
2344 return -1;
2345 }
2346 return 0;
2347 }
2348
2349 private int handleGbaGetReleaseCommand() {
2350 int subId = getSubId("gba get-release");
2351 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2352 return -1;
2353 }
2354
2355 int result = 0;
2356 try {
2357 result = mInterface.getGbaReleaseTime(subId);
2358 } catch (RemoteException e) {
2359 return -1;
2360 }
2361 if (VDBG) {
2362 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2363 }
2364 getOutPrintWriter().println(result);
2365 return 0;
2366 }
Hui Wang761a6682020-10-31 05:12:53 +00002367
2368 private int handleSingleRegistrationConfigCommand() {
2369 String arg = getNextArg();
2370 if (arg == null) {
2371 onHelpSrc();
2372 return 0;
2373 }
2374
2375 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002376 case SRC_SET_TEST_ENABLED: {
2377 return handleSrcSetTestEnabledCommand();
2378 }
2379 case SRC_GET_TEST_ENABLED: {
2380 return handleSrcGetTestEnabledCommand();
2381 }
Hui Wang761a6682020-10-31 05:12:53 +00002382 case SRC_SET_DEVICE_ENABLED: {
2383 return handleSrcSetDeviceEnabledCommand();
2384 }
2385 case SRC_GET_DEVICE_ENABLED: {
2386 return handleSrcGetDeviceEnabledCommand();
2387 }
2388 case SRC_SET_CARRIER_ENABLED: {
2389 return handleSrcSetCarrierEnabledCommand();
2390 }
2391 case SRC_GET_CARRIER_ENABLED: {
2392 return handleSrcGetCarrierEnabledCommand();
2393 }
Hui Wangb647abe2021-02-26 09:33:38 -08002394 case SRC_SET_FEATURE_ENABLED: {
2395 return handleSrcSetFeatureValidationCommand();
2396 }
2397 case SRC_GET_FEATURE_ENABLED: {
2398 return handleSrcGetFeatureValidationCommand();
2399 }
Hui Wang761a6682020-10-31 05:12:53 +00002400 }
2401
2402 return -1;
2403 }
2404
James.cf Linbcdf8b32021-01-14 16:44:13 +08002405 private int handleRcsUceCommand() {
2406 String arg = getNextArg();
2407 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002408 onHelpUce();
2409 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002410 }
2411
2412 switch (arg) {
2413 case UCE_REMOVE_EAB_CONTACT:
2414 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002415 case UCE_GET_EAB_CONTACT:
2416 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002417 case UCE_GET_EAB_CAPABILITY:
2418 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002419 case UCE_GET_DEVICE_ENABLED:
2420 return handleUceGetDeviceEnabledCommand();
2421 case UCE_SET_DEVICE_ENABLED:
2422 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002423 case UCE_OVERRIDE_PUBLISH_CAPS:
2424 return handleUceOverridePublishCaps();
2425 case UCE_GET_LAST_PIDF_XML:
2426 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002427 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2428 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002429 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2430 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002431 }
2432 return -1;
2433 }
2434
2435 private int handleRemovingEabContactCommand() {
2436 int subId = getSubId("uce remove-eab-contact");
2437 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2438 return -1;
2439 }
2440
2441 String phoneNumber = getNextArgRequired();
2442 if (TextUtils.isEmpty(phoneNumber)) {
2443 return -1;
2444 }
2445 int result = 0;
2446 try {
2447 result = mInterface.removeContactFromEab(subId, phoneNumber);
2448 } catch (RemoteException e) {
2449 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2450 getErrPrintWriter().println("Exception: " + e.getMessage());
2451 return -1;
2452 }
2453
2454 if (VDBG) {
2455 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2456 }
calvinpan293ea1b2021-02-04 17:52:13 +08002457 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002458 }
2459
calvinpane4a8a1d2021-01-25 13:51:18 +08002460 private int handleGettingEabContactCommand() {
2461 String phoneNumber = getNextArgRequired();
2462 if (TextUtils.isEmpty(phoneNumber)) {
2463 return -1;
2464 }
2465 String result = "";
2466 try {
2467 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002468 } catch (RemoteException e) {
2469 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2470 getErrPrintWriter().println("Exception: " + e.getMessage());
2471 return -1;
2472 }
2473
2474 if (VDBG) {
2475 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2476 }
calvinpan293ea1b2021-02-04 17:52:13 +08002477 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002478 return 0;
2479 }
2480
Calvin Pana1434322021-07-01 19:27:01 +08002481 private int handleGettingEabCapabilityCommand() {
2482 String phoneNumber = getNextArgRequired();
2483 if (TextUtils.isEmpty(phoneNumber)) {
2484 return -1;
2485 }
2486 String result = "";
2487 try {
2488 result = mInterface.getCapabilityFromEab(phoneNumber);
2489 } catch (RemoteException e) {
2490 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2491 getErrPrintWriter().println("Exception: " + e.getMessage());
2492 return -1;
2493 }
2494
2495 if (VDBG) {
2496 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2497 }
2498 getOutPrintWriter().println(result);
2499 return 0;
2500 }
2501
James.cf Lin4b784aa2021-01-31 03:25:15 +08002502 private int handleUceGetDeviceEnabledCommand() {
2503 boolean result = false;
2504 try {
2505 result = mInterface.getDeviceUceEnabled();
2506 } catch (RemoteException e) {
2507 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2508 return -1;
2509 }
2510 if (VDBG) {
2511 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2512 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002513 getOutPrintWriter().println(result);
2514 return 0;
2515 }
2516
James.cf Lin4b784aa2021-01-31 03:25:15 +08002517 private int handleUceSetDeviceEnabledCommand() {
2518 String enabledStr = getNextArg();
2519 if (TextUtils.isEmpty(enabledStr)) {
2520 return -1;
2521 }
2522
2523 try {
2524 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2525 mInterface.setDeviceUceEnabled(isEnabled);
2526 if (VDBG) {
2527 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2528 }
2529 } catch (NumberFormatException | RemoteException e) {
2530 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2531 getErrPrintWriter().println("Exception: " + e.getMessage());
2532 return -1;
2533 }
2534 return 0;
2535 }
2536
James.cf Line8713a42021-04-29 16:04:26 +08002537 private int handleUceRemoveRequestDisallowedStatus() {
2538 int subId = getSubId("uce remove-request-disallowed-status");
2539 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2540 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2541 return -1;
2542 }
2543 boolean result;
2544 try {
2545 result = mInterface.removeUceRequestDisallowedStatus(subId);
2546 } catch (RemoteException e) {
2547 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2548 return -1;
2549 }
2550 if (VDBG) {
2551 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2552 }
2553 getOutPrintWriter().println(result);
2554 return 0;
2555 }
2556
James.cf Lin0fc71b02021-05-25 01:37:38 +08002557 private int handleUceSetCapRequestTimeout() {
2558 int subId = getSubId("uce set-capabilities-request-timeout");
2559 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2560 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2561 return -1;
2562 }
2563 long timeoutAfterMs = Long.valueOf(getNextArg());
2564 boolean result;
2565 try {
2566 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2567 } catch (RemoteException e) {
2568 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2569 return -1;
2570 }
2571 if (VDBG) {
2572 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2573 }
2574 getOutPrintWriter().println(result);
2575 return 0;
2576 }
2577
Hui Wangbaaee6a2021-02-19 20:45:36 -08002578 private int handleSrcSetTestEnabledCommand() {
2579 String enabledStr = getNextArg();
2580 if (enabledStr == null) {
2581 return -1;
2582 }
2583
2584 try {
2585 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2586 if (VDBG) {
2587 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2588 }
2589 getOutPrintWriter().println("Done");
2590 } catch (NumberFormatException | RemoteException e) {
2591 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2592 getErrPrintWriter().println("Exception: " + e.getMessage());
2593 return -1;
2594 }
2595 return 0;
2596 }
2597
2598 private int handleSrcGetTestEnabledCommand() {
2599 boolean result = false;
2600 try {
2601 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2602 } catch (RemoteException e) {
2603 return -1;
2604 }
2605 if (VDBG) {
2606 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2607 }
2608 getOutPrintWriter().println(result);
2609 return 0;
2610 }
2611
Brad Ebinger14d467f2021-02-12 06:18:28 +00002612 private int handleUceOverridePublishCaps() {
2613 int subId = getSubId("uce override-published-caps");
2614 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2615 return -1;
2616 }
2617 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2618 String operation = getNextArgRequired();
2619 String caps = getNextArg();
2620 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2621 && !"list".equals(operation)) {
2622 getErrPrintWriter().println("Invalid operation: " + operation);
2623 return -1;
2624 }
2625
2626 // add/remove requires capabilities to be specified.
2627 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2628 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2629 + "specified");
2630 return -1;
2631 }
2632
2633 ArraySet<String> capSet = new ArraySet<>();
2634 if (!TextUtils.isEmpty(caps)) {
2635 String[] capArray = caps.split(":");
2636 for (String cap : capArray) {
2637 // Allow unknown tags to be passed in as well.
2638 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2639 }
2640 }
2641
2642 RcsContactUceCapability result = null;
2643 try {
2644 switch (operation) {
2645 case "add":
2646 result = mInterface.addUceRegistrationOverrideShell(subId,
2647 new ArrayList<>(capSet));
2648 break;
2649 case "remove":
2650 result = mInterface.removeUceRegistrationOverrideShell(subId,
2651 new ArrayList<>(capSet));
2652 break;
2653 case "clear":
2654 result = mInterface.clearUceRegistrationOverrideShell(subId);
2655 break;
2656 case "list":
2657 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2658 break;
2659 }
2660 } catch (RemoteException e) {
2661 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2662 getErrPrintWriter().println("Exception: " + e.getMessage());
2663 return -1;
2664 } catch (ServiceSpecificException sse) {
2665 // Reconstruct ImsException
2666 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2667 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2668 getErrPrintWriter().println("Exception: " + imsException);
2669 return -1;
2670 }
2671 if (result == null) {
2672 getErrPrintWriter().println("Service not available");
2673 return -1;
2674 }
2675 getOutPrintWriter().println(result);
2676 return 0;
2677 }
2678
2679 private int handleUceGetPidfXml() {
2680 int subId = getSubId("uce get-last-publish-pidf");
2681 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2682 return -1;
2683 }
2684
2685 String result;
2686 try {
2687 result = mInterface.getLastUcePidfXmlShell(subId);
2688 } catch (RemoteException e) {
2689 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2690 getErrPrintWriter().println("Exception: " + e.getMessage());
2691 return -1;
2692 } catch (ServiceSpecificException sse) {
2693 // Reconstruct ImsException
2694 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2695 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2696 getErrPrintWriter().println("Exception: " + imsException);
2697 return -1;
2698 }
2699 if (result == null) {
2700 getErrPrintWriter().println("Service not available");
2701 return -1;
2702 }
2703 getOutPrintWriter().println(result);
2704 return 0;
2705 }
2706
Hui Wang761a6682020-10-31 05:12:53 +00002707 private int handleSrcSetDeviceEnabledCommand() {
2708 String enabledStr = getNextArg();
2709 if (enabledStr == null) {
2710 return -1;
2711 }
2712
2713 try {
2714 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2715 if (VDBG) {
2716 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2717 }
2718 getOutPrintWriter().println("Done");
2719 } catch (NumberFormatException | RemoteException e) {
2720 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2721 getErrPrintWriter().println("Exception: " + e.getMessage());
2722 return -1;
2723 }
2724 return 0;
2725 }
2726
2727 private int handleSrcGetDeviceEnabledCommand() {
2728 boolean result = false;
2729 try {
2730 result = mInterface.getDeviceSingleRegistrationEnabled();
2731 } catch (RemoteException e) {
2732 return -1;
2733 }
2734 if (VDBG) {
2735 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2736 }
2737 getOutPrintWriter().println(result);
2738 return 0;
2739 }
2740
2741 private int handleSrcSetCarrierEnabledCommand() {
2742 //the release time value could be -1
2743 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2744 : SubscriptionManager.getDefaultSubscriptionId();
2745 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2746 return -1;
2747 }
2748
2749 String enabledStr = getNextArg();
2750 if (enabledStr == null) {
2751 return -1;
2752 }
2753
2754 try {
2755 boolean result =
2756 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2757 if (VDBG) {
2758 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2759 + enabledStr + ", result=" + result);
2760 }
2761 getOutPrintWriter().println(result);
2762 } catch (NumberFormatException | RemoteException e) {
2763 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2764 + enabledStr + ", error" + e.getMessage());
2765 getErrPrintWriter().println("Exception: " + e.getMessage());
2766 return -1;
2767 }
2768 return 0;
2769 }
2770
2771 private int handleSrcGetCarrierEnabledCommand() {
2772 int subId = getSubId("src get-carrier-enabled");
2773 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2774 return -1;
2775 }
2776
2777 boolean result = false;
2778 try {
2779 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2780 } catch (RemoteException e) {
2781 return -1;
2782 }
2783 if (VDBG) {
2784 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2785 }
2786 getOutPrintWriter().println(result);
2787 return 0;
2788 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002789
Hui Wangb647abe2021-02-26 09:33:38 -08002790 private int handleSrcSetFeatureValidationCommand() {
2791 //the release time value could be -1
2792 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2793 : SubscriptionManager.getDefaultSubscriptionId();
2794 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2795 return -1;
2796 }
2797
2798 String enabledStr = getNextArg();
2799 if (enabledStr == null) {
2800 return -1;
2801 }
2802
2803 try {
2804 boolean result =
2805 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2806 if (VDBG) {
2807 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2808 + enabledStr + ", result=" + result);
2809 }
2810 getOutPrintWriter().println(result);
2811 } catch (NumberFormatException | RemoteException e) {
2812 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2813 + enabledStr + ", error" + e.getMessage());
2814 getErrPrintWriter().println("Exception: " + e.getMessage());
2815 return -1;
2816 }
2817 return 0;
2818 }
2819
2820 private int handleSrcGetFeatureValidationCommand() {
2821 int subId = getSubId("src get-feature-validation");
2822 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2823 return -1;
2824 }
2825
2826 Boolean result = false;
2827 try {
2828 result = mInterface.getImsFeatureValidationOverride(subId);
2829 } catch (RemoteException e) {
2830 return -1;
2831 }
2832 if (VDBG) {
2833 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2834 }
2835 getOutPrintWriter().println(result);
2836 return 0;
2837 }
2838
2839
Hall Liuaa4211e2021-01-20 15:43:39 -08002840 private void onHelpCallComposer() {
2841 PrintWriter pw = getOutPrintWriter();
2842 pw.println("Call composer commands");
2843 pw.println(" callcomposer test-mode enable|disable|query");
2844 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2845 pw.println(" upload/download from carrier servers is disabled, and operations are");
2846 pw.println(" performed using emulated local files instead.");
2847 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2848 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2849 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002850 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2851 pw.println(" Enables or disables the user setting for call composer, as set by");
2852 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002853 }
2854
2855 private int handleCallComposerCommand() {
2856 String arg = getNextArg();
2857 if (arg == null) {
2858 onHelpCallComposer();
2859 return 0;
2860 }
2861
2862 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2863 "MODIFY_PHONE_STATE required for call composer shell cmds");
2864 switch (arg) {
2865 case CALL_COMPOSER_TEST_MODE: {
2866 String enabledStr = getNextArg();
2867 if (ENABLE.equals(enabledStr)) {
2868 CallComposerPictureManager.sTestMode = true;
2869 } else if (DISABLE.equals(enabledStr)) {
2870 CallComposerPictureManager.sTestMode = false;
2871 } else if (QUERY.equals(enabledStr)) {
2872 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2873 } else {
2874 onHelpCallComposer();
2875 return 1;
2876 }
2877 break;
2878 }
2879 case CALL_COMPOSER_SIMULATE_CALL: {
2880 int subscriptionId = Integer.valueOf(getNextArg());
2881 String uuidString = getNextArg();
2882 UUID uuid = UUID.fromString(uuidString);
2883 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2884 Binder.withCleanCallingIdentity(() -> {
2885 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2886 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2887 });
2888 try {
2889 Uri uri = storageUriFuture.get();
2890 getOutPrintWriter().println(String.valueOf(uri));
2891 } catch (Exception e) {
2892 throw new RuntimeException(e);
2893 }
2894 break;
2895 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002896 case CALL_COMPOSER_USER_SETTING: {
2897 try {
2898 int subscriptionId = Integer.valueOf(getNextArg());
2899 String enabledStr = getNextArg();
2900 if (ENABLE.equals(enabledStr)) {
2901 mInterface.setCallComposerStatus(subscriptionId,
2902 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2903 } else if (DISABLE.equals(enabledStr)) {
2904 mInterface.setCallComposerStatus(subscriptionId,
2905 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2906 } else if (QUERY.equals(enabledStr)) {
2907 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2908 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2909 } else {
2910 onHelpCallComposer();
2911 return 1;
2912 }
2913 } catch (RemoteException e) {
2914 e.printStackTrace(getOutPrintWriter());
2915 return 1;
2916 }
2917 break;
2918 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002919 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002920 return 0;
2921 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002922
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002923 private int handleHasCarrierPrivilegesCommand() {
2924 String packageName = getNextArgRequired();
2925
2926 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002927 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002928 try {
2929 hasCarrierPrivileges =
2930 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2931 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2932 } catch (RemoteException e) {
2933 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2934 getErrPrintWriter().println("Exception: " + e.getMessage());
2935 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002936 } finally {
2937 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002938 }
2939
2940 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002941 return 0;
2942 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002943
2944 private int handleAllowedNetworkTypesCommand(String command) {
2945 if (!checkShellUid()) {
2946 return -1;
2947 }
2948
2949 PrintWriter errPw = getErrPrintWriter();
2950 String tag = command + ": ";
2951 String opt;
2952 int subId = -1;
2953 Log.v(LOG_TAG, command + " start");
2954
2955 while ((opt = getNextOption()) != null) {
2956 if (opt.equals("-s")) {
2957 try {
2958 subId = slotStringToSubId(tag, getNextArgRequired());
2959 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2960 errPw.println(tag + "No valid subscription found.");
2961 return -1;
2962 }
2963 } catch (IllegalArgumentException e) {
2964 // Missing slot id
2965 errPw.println(tag + "SLOT_ID expected after -s.");
2966 return -1;
2967 }
2968 } else {
2969 errPw.println(tag + "Unknown option " + opt);
2970 return -1;
2971 }
2972 }
2973
2974 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2975 return handleGetAllowedNetworkTypesCommand(subId);
2976 }
2977 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2978 return handleSetAllowedNetworkTypesCommand(subId);
2979 }
2980 return -1;
2981 }
2982
2983 private int handleGetAllowedNetworkTypesCommand(int subId) {
2984 PrintWriter errPw = getErrPrintWriter();
2985
2986 long result = -1;
2987 try {
2988 if (mInterface != null) {
2989 result = mInterface.getAllowedNetworkTypesForReason(subId,
2990 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2991 } else {
2992 throw new IllegalStateException("telephony service is null.");
2993 }
2994 } catch (RemoteException e) {
2995 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2996 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2997 return -1;
2998 }
2999
3000 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
3001 return 0;
3002 }
3003
3004 private int handleSetAllowedNetworkTypesCommand(int subId) {
3005 PrintWriter errPw = getErrPrintWriter();
3006
3007 String bitmaskString = getNextArg();
3008 if (TextUtils.isEmpty(bitmaskString)) {
3009 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
3010 return -1;
3011 }
3012 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
3013 if (allowedNetworkTypes < 0) {
3014 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
3015 return -1;
3016 }
3017 boolean result = false;
3018 try {
3019 if (mInterface != null) {
3020 result = mInterface.setAllowedNetworkTypesForReason(subId,
3021 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
3022 } else {
3023 throw new IllegalStateException("telephony service is null.");
3024 }
3025 } catch (RemoteException e) {
3026 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
3027 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
3028 return -1;
3029 }
3030
3031 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
3032 if (result) {
3033 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
3034 }
3035 getOutPrintWriter().println(resultMessage);
3036 return 0;
3037 }
3038
3039 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
3040 if (TextUtils.isEmpty(bitmaskString)) {
3041 return -1;
3042 }
3043 if (VDBG) {
3044 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
3045 + ", length: " + bitmaskString.length());
3046 }
3047 try {
3048 return Long.parseLong(bitmaskString, 2);
3049 } catch (NumberFormatException e) {
3050 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
3051 return -1;
3052 }
3053 }
Jack Yu4c0a5502021-12-03 23:58:26 -08003054
jimsun3b9ccac2021-10-26 15:01:23 +08003055 private int handleRadioSetModemServiceCommand() {
3056 PrintWriter errPw = getErrPrintWriter();
3057 String serviceName = null;
3058
3059 String opt;
3060 while ((opt = getNextOption()) != null) {
3061 switch (opt) {
3062 case "-s": {
3063 serviceName = getNextArgRequired();
3064 break;
3065 }
3066 }
3067 }
3068
3069 try {
3070 boolean result = mInterface.setModemService(serviceName);
3071 if (VDBG) {
3072 Log.v(LOG_TAG,
3073 "RadioSetModemService " + serviceName + ", result = " + result);
3074 }
3075 getOutPrintWriter().println(result);
3076 } catch (RemoteException e) {
3077 Log.w(LOG_TAG,
3078 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
3079 errPw.println("Exception: " + e.getMessage());
3080 return -1;
3081 }
3082 return 0;
3083 }
3084
3085 private int handleRadioGetModemServiceCommand() {
3086 PrintWriter errPw = getErrPrintWriter();
3087 String result;
3088
3089 try {
3090 result = mInterface.getModemService();
3091 getOutPrintWriter().println(result);
3092 } catch (RemoteException e) {
3093 errPw.println("Exception: " + e.getMessage());
3094 return -1;
3095 }
3096 if (VDBG) {
3097 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3098 }
3099 return 0;
3100 }
3101
3102 private int handleRadioCommand() {
3103 String arg = getNextArg();
3104 if (arg == null) {
3105 onHelpRadio();
3106 return 0;
3107 }
3108
3109 switch (arg) {
3110 case RADIO_SET_MODEM_SERVICE:
3111 return handleRadioSetModemServiceCommand();
3112
3113 case RADIO_GET_MODEM_SERVICE:
3114 return handleRadioGetModemServiceCommand();
3115 }
3116
3117 return -1;
3118 }
arunvoddud7401012022-12-15 16:08:12 +00003119
Thomas Nguyend34a5fc2023-03-23 21:07:03 -07003120 private int handleSetSatelliteServicePackageNameCommand() {
3121 PrintWriter errPw = getErrPrintWriter();
3122 String serviceName = null;
3123
3124 String opt;
3125 while ((opt = getNextOption()) != null) {
3126 switch (opt) {
3127 case "-s": {
3128 serviceName = getNextArgRequired();
3129 break;
3130 }
3131 }
3132 }
3133 Log.d(LOG_TAG, "handleSetSatelliteServicePackageNameCommand: serviceName="
3134 + serviceName);
3135
3136 try {
3137 boolean result = mInterface.setSatelliteServicePackageName(serviceName);
3138 if (VDBG) {
3139 Log.v(LOG_TAG, "SetSatelliteServicePackageName " + serviceName
3140 + ", result = " + result);
3141 }
3142 getOutPrintWriter().println(result);
3143 } catch (RemoteException e) {
3144 Log.w(LOG_TAG, "SetSatelliteServicePackageName: " + serviceName
3145 + ", error = " + e.getMessage());
3146 errPw.println("Exception: " + e.getMessage());
3147 return -1;
3148 }
3149 return 0;
3150 }
3151
Thomas Nguyen1854a5a2023-04-04 09:31:47 -07003152 private int handleSetSatelliteGatewayServicePackageNameCommand() {
3153 PrintWriter errPw = getErrPrintWriter();
3154 String serviceName = null;
3155
3156 String opt;
3157 while ((opt = getNextOption()) != null) {
3158 switch (opt) {
3159 case "-s": {
3160 serviceName = getNextArgRequired();
3161 break;
3162 }
3163 }
3164 }
3165 Log.d(LOG_TAG, "handleSetSatelliteGatewayServicePackageNameCommand: serviceName="
3166 + serviceName);
3167
3168 try {
3169 boolean result = mInterface.setSatelliteGatewayServicePackageName(serviceName);
3170 if (VDBG) {
3171 Log.v(LOG_TAG, "setSatelliteGatewayServicePackageName " + serviceName
3172 + ", result = " + result);
3173 }
3174 getOutPrintWriter().println(result);
3175 } catch (RemoteException e) {
3176 Log.w(LOG_TAG, "setSatelliteGatewayServicePackageName: " + serviceName
3177 + ", error = " + e.getMessage());
3178 errPw.println("Exception: " + e.getMessage());
3179 return -1;
3180 }
3181 return 0;
3182 }
3183
Thomas Nguyen87dce732023-04-20 18:27:16 -07003184 private int handleSetSatellitePointingUiClassNameCommand() {
3185 PrintWriter errPw = getErrPrintWriter();
3186 String packageName = null;
3187 String className = null;
3188
3189 String opt;
3190 while ((opt = getNextOption()) != null) {
3191 switch (opt) {
3192 case "-p": {
3193 packageName = getNextArgRequired();
3194 break;
3195 }
3196 case "-c": {
3197 className = getNextArgRequired();
3198 break;
3199 }
3200 }
3201 }
3202 Log.d(LOG_TAG, "handleSetSatellitePointingUiClassNameCommand: packageName="
3203 + packageName + ", className=" + className);
3204
3205 try {
3206 boolean result = mInterface.setSatellitePointingUiClassName(packageName, className);
3207 if (VDBG) {
3208 Log.v(LOG_TAG, "setSatellitePointingUiClassName result =" + result);
3209 }
3210 getOutPrintWriter().println(result);
3211 } catch (RemoteException e) {
3212 Log.e(LOG_TAG, "setSatellitePointingUiClassName: " + packageName
3213 + ", error = " + e.getMessage());
3214 errPw.println("Exception: " + e.getMessage());
3215 return -1;
3216 }
3217 return 0;
3218 }
3219
Thomas Nguyenf9a533c2023-04-06 20:48:41 -07003220 private int handleSetSatelliteListeningTimeoutDuration() {
3221 PrintWriter errPw = getErrPrintWriter();
3222 long timeoutMillis = 0;
3223
3224 String opt;
3225 while ((opt = getNextOption()) != null) {
3226 switch (opt) {
3227 case "-t": {
3228 timeoutMillis = Long.parseLong(getNextArgRequired());
3229 break;
3230 }
3231 }
3232 }
3233 Log.d(LOG_TAG, "handleSetSatelliteListeningTimeoutDuration: timeoutMillis="
3234 + timeoutMillis);
3235
3236 try {
3237 boolean result = mInterface.setSatelliteListeningTimeoutDuration(timeoutMillis);
3238 if (VDBG) {
3239 Log.v(LOG_TAG, "setSatelliteListeningTimeoutDuration " + timeoutMillis
3240 + ", result = " + result);
3241 }
3242 getOutPrintWriter().println(result);
3243 } catch (RemoteException e) {
3244 Log.w(LOG_TAG, "setSatelliteListeningTimeoutDuration: " + timeoutMillis
3245 + ", error = " + e.getMessage());
3246 errPw.println("Exception: " + e.getMessage());
3247 return -1;
3248 }
3249 return 0;
3250 }
3251
Hakjun Choiae365972023-04-25 11:00:31 +00003252 private int handleSettSatelliteDeviceAlignedTimeoutDuration() {
3253 PrintWriter errPw = getErrPrintWriter();
3254 long timeoutMillis = 0;
3255
3256 String opt;
3257 while ((opt = getNextOption()) != null) {
3258 switch (opt) {
3259 case "-t": {
3260 timeoutMillis = Long.parseLong(getNextArgRequired());
3261 break;
3262 }
3263 }
3264 }
3265 Log.d(LOG_TAG, "handleSettSatelliteDeviceAlignedTimeoutDuration: timeoutMillis="
3266 + timeoutMillis);
3267
3268 try {
3269 boolean result = mInterface.setSatelliteDeviceAlignedTimeoutDuration(timeoutMillis);
3270 if (VDBG) {
3271 Log.v(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration " + timeoutMillis
3272 + ", result = " + result);
3273 }
3274 getOutPrintWriter().println(result);
3275 } catch (RemoteException e) {
3276 Log.w(LOG_TAG, "setSatelliteDeviceAlignedTimeoutDuration: " + timeoutMillis
3277 + ", error = " + e.getMessage());
3278 errPw.println("Exception: " + e.getMessage());
3279 return -1;
3280 }
3281 return 0;
3282 }
3283
arunvoddud7401012022-12-15 16:08:12 +00003284 private int handleCarrierRestrictionStatusCommand() {
3285 try {
3286 String MOCK_MODEM_SERVICE_NAME = "android.telephony.mockmodem.MockModemService";
3287 if (!(checkShellUid() && MOCK_MODEM_SERVICE_NAME.equalsIgnoreCase(
3288 mInterface.getModemService()))) {
3289 Log.v(LOG_TAG,
3290 "handleCarrierRestrictionStatusCommand, MockModem service check fails or "
3291 + " checkShellUid fails");
3292 return -1;
3293 }
3294 } catch (RemoteException ex) {
3295 ex.printStackTrace();
3296 }
3297 String callerInfo = getNextOption();
3298 CarrierAllowListInfo allowListInfo = CarrierAllowListInfo.loadInstance(mContext);
3299 if (TextUtils.isEmpty(callerInfo)) {
3300 // reset the Json content after testing
3301 allowListInfo.updateJsonForTest(null);
3302 return 0;
3303 }
3304 if (callerInfo.startsWith("--")) {
3305 callerInfo = callerInfo.replace("--", "");
3306 }
3307 String params[] = callerInfo.split(",");
3308 StringBuffer jsonStrBuffer = new StringBuffer();
3309 String tokens;
3310 for (int index = 0; index < params.length; index++) {
3311 tokens = convertToJsonString(index, params[index]);
3312 if (TextUtils.isEmpty(tokens)) {
3313 // received wrong format from CTS
3314 if (VDBG) {
3315 Log.v(LOG_TAG,
3316 "handleCarrierRestrictionStatusCommand, Shell command parsing error");
3317 }
3318 return -1;
3319 }
3320 jsonStrBuffer.append(tokens);
3321 }
3322 int result = allowListInfo.updateJsonForTest(jsonStrBuffer.toString());
3323 return result;
3324 }
3325
Benedict Wong66477622023-02-03 23:30:57 +00003326 // set-carrier-service-package-override
3327 private int setCarrierServicePackageOverride() {
3328 PrintWriter errPw = getErrPrintWriter();
3329 int subId = SubscriptionManager.getDefaultSubscriptionId();
3330
3331 String opt;
3332 while ((opt = getNextOption()) != null) {
3333 switch (opt) {
3334 case "-s":
3335 try {
3336 subId = Integer.parseInt(getNextArgRequired());
3337 } catch (NumberFormatException e) {
3338 errPw.println(
3339 "set-carrier-service-package-override requires an integer as a"
3340 + " subscription ID.");
3341 return -1;
3342 }
3343 break;
3344 }
3345 }
3346
3347 String packageName = getNextArg();
3348 if (packageName == null) {
3349 errPw.println("set-carrier-service-package-override requires a override package name.");
3350 return -1;
3351 }
3352
3353 try {
3354 mInterface.setCarrierServicePackageOverride(
3355 subId, packageName, mContext.getOpPackageName());
3356
3357 if (VDBG) {
3358 Log.v(
3359 LOG_TAG,
3360 "set-carrier-service-package-override -s " + subId + " " + packageName);
3361 }
3362 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3363 Log.w(
3364 LOG_TAG,
3365 "set-carrier-service-package-override -s "
3366 + subId
3367 + " "
3368 + packageName
3369 + ", error"
3370 + e.getMessage());
3371 errPw.println("Exception: " + e.getMessage());
3372 return -1;
3373 }
3374 return 0;
3375 }
3376
3377 // clear-carrier-service-package-override
3378 private int clearCarrierServicePackageOverride() {
3379 PrintWriter errPw = getErrPrintWriter();
Chalard Jean71706f42023-09-22 18:22:47 +09003380 int subId = SubscriptionManager.getDefaultSubscriptionId();
Benedict Wong66477622023-02-03 23:30:57 +00003381
3382 String opt;
3383 while ((opt = getNextOption()) != null) {
3384 switch (opt) {
3385 case "-s":
3386 try {
3387 subId = Integer.parseInt(getNextArgRequired());
3388 } catch (NumberFormatException e) {
3389 errPw.println(
3390 "clear-carrier-service-package-override requires an integer as a"
3391 + " subscription ID.");
3392 return -1;
3393 }
3394 break;
3395 }
3396 }
3397
3398 try {
3399 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3400
3401 if (VDBG) {
3402 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3403 }
3404 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3405 Log.w(
3406 LOG_TAG,
3407 "clear-carrier-service-package-override -s "
3408 + subId
3409 + ", error"
3410 + e.getMessage());
3411 errPw.println("Exception: " + e.getMessage());
3412 return -1;
3413 }
3414 return 0;
3415 }
arunvoddud7401012022-12-15 16:08:12 +00003416
3417 /**
3418 * Building the string that can be used to build the JsonObject which supports to stub the data
3419 * in CarrierAllowListInfo for CTS testing. sample format is like
3420 * {"com.android.example":{"carrierId":"10000","callerSHA1Id":["XXXXXXXXXXXXXX"]}}
3421 */
3422 private String convertToJsonString(int index, String param) {
3423
3424 String token[] = param.split(":");
3425 String jSonString;
3426 switch (index) {
3427 case 0:
3428 jSonString = "{" + QUOTES + token[1] + QUOTES + ":";
3429 break;
3430 case 1:
3431 jSonString =
3432 "{" + QUOTES + token[0] + QUOTES + ":" + QUOTES + token[1] + QUOTES + ",";
3433 break;
3434 case 2:
3435 jSonString =
3436 QUOTES + token[0] + QUOTES + ":" + "[" + QUOTES + token[1] + QUOTES + "]}}";
3437 break;
3438 default:
3439 jSonString = null;
3440 }
3441 return jSonString;
3442 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003443}