blob: 97676fc8f8bed99a04d6d8043e09c49dde848f28 [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
Hall Liuaa4211e2021-01-20 15:43:39 -080024import android.Manifest;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010025import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080027import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010028import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070030import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000031import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070032import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070033import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010034import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070035import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070036import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000037import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070038import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080039import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000040import android.telephony.ims.ImsException;
41import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080042import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080043import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000044import android.util.ArrayMap;
45import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070046import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070047import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070048
Brad Ebinger14d467f2021-02-12 06:18:28 +000049import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080051import com.android.internal.telephony.Phone;
52import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080053import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080054import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080055import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080056import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080057import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070058
Allen Xuee00f0e2022-03-14 21:04:49 +000059import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070060import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080061import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000062import java.util.Arrays;
63import java.util.Collections;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010064import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080065import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010066import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000067import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010068import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080069import java.util.UUID;
70import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070071
72/**
73 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
74 * permission checks have been done before onCommand was called. Make sure any commands processed
75 * here also contain the appropriate permissions checks.
76 */
77
Hall Liua1548bd2019-12-24 14:14:12 -080078public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070079
80 private static final String LOG_TAG = "TelephonyShellCommand";
81 // Don't commit with this true.
82 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070083 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070084
Hall Liuaa4211e2021-01-20 15:43:39 -080085 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070086 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080087 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080088 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080089 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070090 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000091 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000092 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010093 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080094 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080095 private static final String ENABLE = "enable";
96 private static final String DISABLE = "disable";
97 private static final String QUERY = "query";
98
Hall Liu7135e502021-02-04 16:58:17 -080099 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800100 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800101 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800102
Brad Ebinger999d3302020-11-25 14:31:39 -0800103 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
104 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
105 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700106 // Used to disable or enable processing of conference event package data from the network.
107 // This is handy for testing scenarios where CEP data does not exist on a network which does
108 // support CEP data.
109 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700110
Hall Liud892bec2018-11-30 14:51:45 -0800111 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800112 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800113
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100114 private static final String CC_GET_VALUE = "get-value";
115 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000116 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100117 private static final String CC_CLEAR_VALUES = "clear-values";
118
Hui Wang641e81c2020-10-12 12:14:23 -0700119 private static final String GBA_SUBCOMMAND = "gba";
120 private static final String GBA_SET_SERVICE = "set-service";
121 private static final String GBA_GET_SERVICE = "get-service";
122 private static final String GBA_SET_RELEASE_TIME = "set-release";
123 private static final String GBA_GET_RELEASE_TIME = "get-release";
124
Hui Wang761a6682020-10-31 05:12:53 +0000125 private static final String SINGLE_REGISTATION_CONFIG = "src";
126 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
127 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
128 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
129 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800130 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
131 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800132 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
133 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000134
Tyler Gunn92479152021-01-20 16:30:10 -0800135 private static final String D2D_SUBCOMMAND = "d2d";
136 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800137 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700138 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800139
Nazanin014f41e2021-05-06 17:26:31 -0700140 private static final String BARRING_SUBCOMMAND = "barring";
141 private static final String BARRING_SEND_INFO = "send";
142
James.cf Linbcdf8b32021-01-14 16:44:13 +0800143 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800144 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800145 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800146 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800147 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
148 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000149 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
150 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800151 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
152 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800153 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
154 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800155
jimsun3b9ccac2021-10-26 15:01:23 +0800156 private static final String RADIO_SUBCOMMAND = "radio";
157 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
158 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
159
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800160 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
161 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
162
Jordan Liu0ccee222021-04-27 11:55:13 -0700163 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
164 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
165
Jack Nudelman644b91a2021-03-12 14:09:48 -0800166 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
167 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
168 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
169
SongFerngWang98dd5992021-05-13 17:50:00 +0800170 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
171 "get-allowed-network-types-for-users";
172 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
173 "set-allowed-network-types-for-users";
Jack Yu4c0a5502021-12-03 23:58:26 -0800174 // Check if telephony new data stack is enabled.
175 private static final String GET_DATA_MODE = "get-data-mode";
Ling Ma4fbab492022-01-25 22:36:16 +0000176 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000177 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700178 // Take advantage of existing methods that already contain permissions checks when possible.
179 private final ITelephony mInterface;
180
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100181 private SubscriptionManager mSubscriptionManager;
182 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700183 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700184 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100185
186 private enum CcType {
187 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000188 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100189 }
190
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100191 private class CcOptionParseResult {
192 public int mSubId;
193 public boolean mPersistent;
194 }
195
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100196 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
197 // keys by looking at the end of the string which usually tells the type.
198 // For instance: "xxxx_string", "xxxx_string_array", etc.
199 // The carrier config keys in this map does not follow this convention. It is therefore not
200 // possible to infer the type for these keys by looking at the string.
201 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
202 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
203 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
204 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
205 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
206 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
207 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
208 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
209 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
210 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
211 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
212 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
213 CcType.STRING);
214 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
215 CcType.STRING_ARRAY);
216 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
217 CcType.STRING_ARRAY);
218 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
219 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
220 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
221 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
222 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
223 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
224 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
225 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
226 }
227 };
228
Brad Ebinger14d467f2021-02-12 06:18:28 +0000229 /**
230 * Map from a shorthand string to the feature tags required in registration required in order
231 * for the RCS feature to be considered "capable".
232 */
233 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
234 static {
235 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
236 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
237 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
238 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
239 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
240 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
241 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
242 FeatureTags.FEATURE_TAG_VIDEO)));
243 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
244 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
245 map.put("call_comp",
246 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
247 map.put("call_comp_mmtel",
248 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
249 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
250 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
251 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
252 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
253 // version
254 map.put("chatbot", new ArraySet<>(Arrays.asList(
255 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
256 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
257 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
258 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000259 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000260 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
261 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
262 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
263 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
264 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000265 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000266 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
267 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
268 }
269
270
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100271 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700272 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100273 mCarrierConfigManager =
274 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
275 mSubscriptionManager = (SubscriptionManager)
276 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700277 mTelephonyRegistryManager = (TelephonyRegistryManager)
278 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700279 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700280 }
281
282 @Override
283 public int onCommand(String cmd) {
284 if (cmd == null) {
285 return handleDefaultCommands(null);
286 }
287
288 switch (cmd) {
289 case IMS_SUBCOMMAND: {
290 return handleImsCommand();
291 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800292 case RCS_UCE_COMMAND:
293 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800294 case NUMBER_VERIFICATION_SUBCOMMAND:
295 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800296 case EMERGENCY_CALLBACK_MODE:
297 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800298 case EMERGENCY_NUMBER_TEST_MODE:
299 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100300 case CARRIER_CONFIG_SUBCOMMAND: {
301 return handleCcCommand();
302 }
Shuo Qianf5125122019-12-16 17:03:07 -0800303 case DATA_TEST_MODE:
304 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700305 case END_BLOCK_SUPPRESSION:
306 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700307 case GBA_SUBCOMMAND:
308 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800309 case D2D_SUBCOMMAND:
310 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700311 case BARRING_SUBCOMMAND:
312 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000313 case SINGLE_REGISTATION_CONFIG:
314 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000315 case RESTART_MODEM:
316 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800317 case CALL_COMPOSER_SUBCOMMAND:
318 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000319 case UNATTENDED_REBOOT:
320 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800321 case HAS_CARRIER_PRIVILEGES_COMMAND:
322 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800323 case THERMAL_MITIGATION_COMMAND:
324 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700325 case DISABLE_PHYSICAL_SUBSCRIPTION:
326 return handleEnablePhysicalSubscription(false);
327 case ENABLE_PHYSICAL_SUBSCRIPTION:
328 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800329 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
330 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
331 return handleAllowedNetworkTypesCommand(cmd);
Jack Yu4c0a5502021-12-03 23:58:26 -0800332 case GET_DATA_MODE:
333 return handleGetDataMode();
Ling Ma4fbab492022-01-25 22:36:16 +0000334 case GET_IMEI:
335 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000336 case GET_SIM_SLOTS_MAPPING:
337 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800338 case RADIO_SUBCOMMAND:
339 return handleRadioCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700340 default: {
341 return handleDefaultCommands(cmd);
342 }
343 }
344 }
345
346 @Override
347 public void onHelp() {
348 PrintWriter pw = getOutPrintWriter();
349 pw.println("Telephony Commands:");
350 pw.println(" help");
351 pw.println(" Print this help text.");
352 pw.println(" ims");
353 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800354 pw.println(" uce");
355 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800356 pw.println(" emergency-number-test-mode");
357 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700358 pw.println(" end-block-suppression");
359 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800360 pw.println(" data");
361 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100362 pw.println(" cc");
363 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700364 pw.println(" gba");
365 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000366 pw.println(" src");
367 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000368 pw.println(" restart-modem");
369 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000370 pw.println(" unattended-reboot");
371 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800372 pw.println(" has-carrier-privileges [package]");
373 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800374 pw.println(" get-allowed-network-types-for-users");
375 pw.println(" Get the Allowed Network Types.");
376 pw.println(" set-allowed-network-types-for-users");
377 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800378 pw.println(" radio");
379 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700380 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800381 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800382 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700383 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800384 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100385 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700386 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000387 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800388 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700389 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800390 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800391 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000392 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800393 }
394
395 private void onHelpD2D() {
396 PrintWriter pw = getOutPrintWriter();
397 pw.println("D2D Comms Commands:");
398 pw.println(" d2d send TYPE VALUE");
399 pw.println(" Sends a D2D message of specified type and value.");
400 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
401 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
402 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
403 MESSAGE_CALL_AUDIO_CODEC));
404 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
405 + Communicator.messageToString(
406 MESSAGE_DEVICE_BATTERY_STATE));
407 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
408 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800409 pw.println(" d2d transport TYPE");
410 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
411 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700412 pw.println(" d2d set-device-support true/default");
413 pw.println(" true - forces device support to be enabled for D2D.");
414 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
415 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700416 }
417
Nazanin014f41e2021-05-06 17:26:31 -0700418 private void onHelpBarring() {
419 PrintWriter pw = getOutPrintWriter();
420 pw.println("Barring Commands:");
421 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
422 + " -t CONDITIONAL_BARRING_TIME_SECS");
423 pw.println(" Notifies of a barring info change for the specified slot id.");
424 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
425 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
426 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
427 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
428 }
429
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700430 private void onHelpIms() {
431 PrintWriter pw = getOutPrintWriter();
432 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800433 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700434 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
435 pw.println(" ImsService. Options are:");
436 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
437 pw.println(" is specified, it will choose the default voice SIM slot.");
438 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
439 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800440 pw.println(" -f: Set the feature that this override if for, if no option is");
441 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700442 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
443 pw.println(" Gets the package name of the currently defined ImsService.");
444 pw.println(" Options are:");
445 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
446 pw.println(" is specified, it will choose the default voice SIM slot.");
447 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000448 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800449 pw.println(" -f: The feature type that the query will be requested for. If none is");
450 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800451 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
452 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
453 pw.println(" configuration overrides. Options are:");
454 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
455 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700456 pw.println(" ims enable [-s SLOT_ID]");
457 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
458 pw.println(" if none is specified.");
459 pw.println(" ims disable [-s SLOT_ID]");
460 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
461 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700462 pw.println(" ims conference-event-package [enable/disable]");
463 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700464 }
465
James.cf Linbcdf8b32021-01-14 16:44:13 +0800466 private void onHelpUce() {
467 PrintWriter pw = getOutPrintWriter();
468 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800469 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
470 pw.println(" Get the EAB contacts from the EAB database.");
471 pw.println(" Options are:");
472 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
473 pw.println(" Expected output format :");
474 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800475 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
476 pw.println(" Remove the EAB contacts from the EAB database.");
477 pw.println(" Options are:");
478 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
479 pw.println(" is specified, it will choose the default voice SIM slot.");
480 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800481 pw.println(" uce get-device-enabled");
482 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
483 pw.println(" uce set-device-enabled true|false");
484 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
485 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000486 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
487 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
488 pw.println(" Options are:");
489 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
490 pw.println(" is specified, it will choose the default voice SIM slot.");
491 pw.println(" add [CAPABILITY]: add a new capability");
492 pw.println(" remove [CAPABILITY]: remove a capability");
493 pw.println(" clear: clear all capability overrides");
494 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
495 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
496 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
497 pw.println(" chatbot_sa, chatbot_role] as well as full length");
498 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
499 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
500 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
501 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800502 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
503 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800504 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
505 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800506 }
507
Hall Liud892bec2018-11-30 14:51:45 -0800508 private void onHelpNumberVerification() {
509 PrintWriter pw = getOutPrintWriter();
510 pw.println("Number verification commands");
511 pw.println(" numverify override-package PACKAGE_NAME;");
512 pw.println(" Set the authorized package for number verification.");
513 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800514 pw.println(" numverify fake-call NUMBER;");
515 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
516 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800517 }
518
Jack Nudelman644b91a2021-03-12 14:09:48 -0800519 private void onHelpThermalMitigation() {
520 PrintWriter pw = getOutPrintWriter();
521 pw.println("Thermal mitigation commands");
522 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
523 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
524 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
525 pw.println(" Remove the package from one of the authorized packages for thermal "
526 + "mitigation.");
527 }
528
Jordan Liu0ccee222021-04-27 11:55:13 -0700529 private void onHelpDisableOrEnablePhysicalSubscription() {
530 PrintWriter pw = getOutPrintWriter();
531 pw.println("Disable or enable a physical subscription");
532 pw.println(" disable-physical-subscription SUB_ID");
533 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
534 pw.println(" enable-physical-subscription SUB_ID");
535 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
536 }
537
Shuo Qianf5125122019-12-16 17:03:07 -0800538 private void onHelpDataTestMode() {
539 PrintWriter pw = getOutPrintWriter();
540 pw.println("Mobile Data Test Mode Commands:");
541 pw.println(" data enable: enable mobile data connectivity");
542 pw.println(" data disable: disable mobile data connectivity");
543 }
544
sqian9d4df8b2019-01-15 18:32:07 -0800545 private void onHelpEmergencyNumber() {
546 PrintWriter pw = getOutPrintWriter();
547 pw.println("Emergency Number Test Mode Commands:");
548 pw.println(" emergency-number-test-mode ");
549 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
550 + " the test mode");
551 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700552 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800553 pw.println(" -c: clear the emergency number list in the test mode.");
554 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700555 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800556 pw.println(" -p: get the full emergency number list in the test mode.");
557 }
558
Shuo Qian489d9282020-07-09 11:30:03 -0700559 private void onHelpEndBlockSupperssion() {
560 PrintWriter pw = getOutPrintWriter();
561 pw.println("End Block Suppression command:");
562 pw.println(" end-block-suppression: disable suppressing blocking by contact");
563 pw.println(" with emergency services.");
564 }
565
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100566 private void onHelpCc() {
567 PrintWriter pw = getOutPrintWriter();
568 pw.println("Carrier Config Commands:");
569 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
570 pw.println(" Print carrier config values.");
571 pw.println(" Options are:");
572 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
573 pw.println(" is specified, it will choose the default voice SIM slot.");
574 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
575 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100576 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100577 pw.println(" Set carrier config KEY to NEW_VALUE.");
578 pw.println(" Options are:");
579 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
580 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100581 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100582 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
583 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
584 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
585 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000586 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
587 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
588 pw.println(" provided through standard input and follow CarrierConfig XML format.");
589 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
590 pw.println(" Options are:");
591 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
592 pw.println(" is specified, it will choose the default voice SIM slot.");
593 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100594 pw.println(" cc clear-values [-s SLOT_ID]");
595 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000596 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100597 pw.println(" Options are:");
598 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
599 pw.println(" is specified, it will choose the default voice SIM slot.");
600 }
601
Hui Wang641e81c2020-10-12 12:14:23 -0700602 private void onHelpGba() {
603 PrintWriter pw = getOutPrintWriter();
604 pw.println("Gba Commands:");
605 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
606 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
607 pw.println(" Options are:");
608 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
609 pw.println(" is specified, it will choose the default voice SIM slot.");
610 pw.println(" gba get-service [-s SLOT_ID]");
611 pw.println(" Gets the package name of the currently defined GbaService.");
612 pw.println(" Options are:");
613 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
614 pw.println(" is specified, it will choose the default voice SIM slot.");
615 pw.println(" gba set-release [-s SLOT_ID] n");
616 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
617 pw.println(" Do not release/unbind if n is -1.");
618 pw.println(" Options are:");
619 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
620 pw.println(" is specified, it will choose the default voice SIM slot.");
621 pw.println(" gba get-release [-s SLOT_ID]");
622 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
623 pw.println(" Options are:");
624 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
625 pw.println(" is specified, it will choose the default voice SIM slot.");
626 }
627
Hui Wang761a6682020-10-31 05:12:53 +0000628 private void onHelpSrc() {
629 PrintWriter pw = getOutPrintWriter();
630 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800631 pw.println(" src set-test-enabled true|false");
632 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
633 pw.println(" The value could be true, false, or null(undefined).");
634 pw.println(" src get-test-enabled");
635 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000636 pw.println(" src set-device-enabled true|false|null");
637 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
638 pw.println(" The value could be true, false, or null(undefined).");
639 pw.println(" src get-device-enabled");
640 pw.println(" Gets the device config for RCS VoLTE single registration.");
641 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
642 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
643 pw.println(" The value could be true, false, or null(undefined).");
644 pw.println(" Options are:");
645 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
646 pw.println(" is specified, it will choose the default voice SIM slot.");
647 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
648 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
649 pw.println(" Options are:");
650 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
651 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800652 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
653 pw.println(" Sets ims feature validation result.");
654 pw.println(" The value could be true, false, or null(undefined).");
655 pw.println(" Options are:");
656 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
657 pw.println(" is specified, it will choose the default voice SIM slot.");
658 pw.println(" src get-feature-validation [-s SLOT_ID]");
659 pw.println(" Gets ims feature validation override value.");
660 pw.println(" Options are:");
661 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
662 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000663 }
664
SongFerngWang98dd5992021-05-13 17:50:00 +0800665 private void onHelpAllowedNetworkTypes() {
666 PrintWriter pw = getOutPrintWriter();
667 pw.println("Allowed Network Types Commands:");
668 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
669 pw.println(" Print allowed network types value.");
670 pw.println(" Options are:");
671 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
672 pw.println(" option is specified, it will choose the default voice SIM slot.");
673 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
674 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
675 pw.println(" Options are:");
676 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
677 pw.println(" option is specified, it will choose the default voice SIM slot.");
678 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
679 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
680 pw.println(" at TelephonyManager.java");
681 pw.println(" For example:");
682 pw.println(" NR only : 10000000000000000000");
683 pw.println(" NR|LTE : 11000001000000000000");
684 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
685 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
686 pw.println(" LTE only : 01000001000000000000");
687 }
688
jimsun3b9ccac2021-10-26 15:01:23 +0800689 private void onHelpRadio() {
690 PrintWriter pw = getOutPrintWriter();
691 pw.println("Radio Commands:");
692 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
693 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
694 pw.println(" to be the bound. Options are:");
695 pw.println(" -s: the service name that the modem service should be bound for.");
696 pw.println(" If no option is specified, it will bind to the default.");
697 pw.println(" radio get-modem-service");
698 pw.println(" Gets the service name of the currently defined modem service.");
699 pw.println(" If it is binding to default, 'default' returns.");
700 pw.println(" If it doesn't bind to any modem service for some reasons,");
701 pw.println(" the result would be 'unknown'.");
702 }
703
Ling Ma4fbab492022-01-25 22:36:16 +0000704 private void onHelpImei() {
705 PrintWriter pw = getOutPrintWriter();
706 pw.println("IMEI Commands:");
707 pw.println(" get-imei [-s SLOT_ID]");
708 pw.println(" Gets the device IMEI. Options are:");
709 pw.println(" -s: the slot ID to get the IMEI. If no option");
710 pw.println(" is specified, it will choose the default voice SIM slot.");
711 }
712
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700713 private int handleImsCommand() {
714 String arg = getNextArg();
715 if (arg == null) {
716 onHelpIms();
717 return 0;
718 }
719
720 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800721 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700722 return handleImsSetServiceCommand();
723 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800724 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700725 return handleImsGetServiceCommand();
726 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800727 case IMS_CLEAR_SERVICE_OVERRIDE: {
728 return handleImsClearCarrierServiceCommand();
729 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800730 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700731 return handleEnableIms();
732 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800733 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700734 return handleDisableIms();
735 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700736 case IMS_CEP: {
737 return handleCepChange();
738 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700739 }
740
741 return -1;
742 }
743
Shuo Qianf5125122019-12-16 17:03:07 -0800744 private int handleDataTestModeCommand() {
745 PrintWriter errPw = getErrPrintWriter();
746 String arg = getNextArgRequired();
747 if (arg == null) {
748 onHelpDataTestMode();
749 return 0;
750 }
751 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800752 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800753 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700754 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800755 } catch (RemoteException ex) {
756 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
757 errPw.println("Exception: " + ex.getMessage());
758 return -1;
759 }
760 break;
761 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800762 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800763 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700764 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800765 } catch (RemoteException ex) {
766 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
767 errPw.println("Exception: " + ex.getMessage());
768 return -1;
769 }
770 break;
771 }
772 default:
773 onHelpDataTestMode();
774 break;
775 }
776 return 0;
777 }
778
Shuo Qianccbaf742021-02-22 18:32:21 -0800779 private int handleEmergencyCallbackModeCommand() {
780 PrintWriter errPw = getErrPrintWriter();
781 try {
782 mInterface.startEmergencyCallbackMode();
783 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
784 } catch (RemoteException ex) {
785 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
786 errPw.println("Exception: " + ex.getMessage());
787 return -1;
788 }
789 return 0;
790 }
791
sqian9d4df8b2019-01-15 18:32:07 -0800792 private int handleEmergencyNumberTestModeCommand() {
793 PrintWriter errPw = getErrPrintWriter();
794 String opt = getNextOption();
795 if (opt == null) {
796 onHelpEmergencyNumber();
797 return 0;
798 }
799
800 switch (opt) {
801 case "-a": {
802 String emergencyNumberCmd = getNextArgRequired();
803 if (emergencyNumberCmd == null
804 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700805 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800806 + " to be specified after -a in the command ");
807 return -1;
808 }
809 try {
810 mInterface.updateEmergencyNumberListTestMode(
811 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
812 new EmergencyNumber(emergencyNumberCmd, "", "",
813 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
814 new ArrayList<String>(),
815 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
816 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
817 } catch (RemoteException ex) {
818 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
819 + ", error " + ex.getMessage());
820 errPw.println("Exception: " + ex.getMessage());
821 return -1;
822 }
823 break;
824 }
825 case "-c": {
826 try {
827 mInterface.updateEmergencyNumberListTestMode(
828 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
829 } catch (RemoteException ex) {
830 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
831 errPw.println("Exception: " + ex.getMessage());
832 return -1;
833 }
834 break;
835 }
836 case "-r": {
837 String emergencyNumberCmd = getNextArgRequired();
838 if (emergencyNumberCmd == null
839 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700840 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800841 + " to be specified after -r in the command ");
842 return -1;
843 }
844 try {
845 mInterface.updateEmergencyNumberListTestMode(
846 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
847 new EmergencyNumber(emergencyNumberCmd, "", "",
848 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
849 new ArrayList<String>(),
850 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
851 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
852 } catch (RemoteException ex) {
853 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
854 + ", error " + ex.getMessage());
855 errPw.println("Exception: " + ex.getMessage());
856 return -1;
857 }
858 break;
859 }
860 case "-p": {
861 try {
862 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
863 } catch (RemoteException ex) {
864 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
865 errPw.println("Exception: " + ex.getMessage());
866 return -1;
867 }
868 break;
869 }
870 default:
871 onHelpEmergencyNumber();
872 break;
873 }
874 return 0;
875 }
876
Hall Liud892bec2018-11-30 14:51:45 -0800877 private int handleNumberVerificationCommand() {
878 String arg = getNextArg();
879 if (arg == null) {
880 onHelpNumberVerification();
881 return 0;
882 }
883
Hall Liuca5af3a2018-12-04 16:58:23 -0800884 if (!checkShellUid()) {
885 return -1;
886 }
887
Hall Liud892bec2018-11-30 14:51:45 -0800888 switch (arg) {
889 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800890 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
891 return 0;
892 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800893 case NUMBER_VERIFICATION_FAKE_CALL: {
894 boolean val = NumberVerificationManager.getInstance()
895 .checkIncomingCall(getNextArg());
896 getOutPrintWriter().println(val ? "1" : "0");
897 return 0;
898 }
Hall Liud892bec2018-11-30 14:51:45 -0800899 }
900
901 return -1;
902 }
903
Jordan Liu0ccee222021-04-27 11:55:13 -0700904 private boolean subIsEsim(int subId) {
905 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
906 if (info != null) {
907 return info.isEmbedded();
908 }
909 return false;
910 }
911
912 private int handleEnablePhysicalSubscription(boolean enable) {
913 PrintWriter errPw = getErrPrintWriter();
914 int subId = 0;
915 try {
916 subId = Integer.parseInt(getNextArgRequired());
917 } catch (NumberFormatException e) {
918 errPw.println((enable ? "enable" : "disable")
919 + "-physical-subscription requires an integer as a subId.");
920 return -1;
921 }
922 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
923 // non user build.
924 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
925 errPw.println("cc: Permission denied.");
926 return -1;
927 }
928 // Verify that the subId represents a physical sub
929 if (subIsEsim(subId)) {
930 errPw.println("SubId " + subId + " is not for a physical subscription");
931 return -1;
932 }
933 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
934 + " physical subscription with subId=" + subId);
935 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
936 return 0;
937 }
938
Jack Nudelman644b91a2021-03-12 14:09:48 -0800939 private int handleThermalMitigationCommand() {
940 String arg = getNextArg();
941 String packageName = getNextArg();
942 if (arg == null || packageName == null) {
943 onHelpThermalMitigation();
944 return 0;
945 }
946
947 if (!checkShellUid()) {
948 return -1;
949 }
950
951 switch (arg) {
952 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
953 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
954 return 0;
955 }
956 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
957 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
958 mContext);
959 return 0;
960 }
961 default:
962 onHelpThermalMitigation();
963 }
964
965 return -1;
966
967 }
968
Tyler Gunn92479152021-01-20 16:30:10 -0800969 private int handleD2dCommand() {
970 String arg = getNextArg();
971 if (arg == null) {
972 onHelpD2D();
973 return 0;
974 }
975
976 switch (arg) {
977 case D2D_SEND: {
978 return handleD2dSendCommand();
979 }
Tyler Gunnbabbda02021-02-10 11:05:02 -0800980 case D2D_TRANSPORT: {
981 return handleD2dTransportCommand();
982 }
Tyler Gunnd4575212021-05-03 14:46:49 -0700983 case D2D_SET_DEVICE_SUPPORT: {
984 return handleD2dDeviceSupportedCommand();
985 }
Tyler Gunn92479152021-01-20 16:30:10 -0800986 }
987
988 return -1;
989 }
990
991 private int handleD2dSendCommand() {
992 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -0800993 int messageType = -1;
994 int messageValue = -1;
995
Tyler Gunn92479152021-01-20 16:30:10 -0800996 String arg = getNextArg();
997 if (arg == null) {
998 onHelpD2D();
999 return 0;
1000 }
1001 try {
1002 messageType = Integer.parseInt(arg);
1003 } catch (NumberFormatException e) {
1004 errPw.println("message type must be a valid integer");
1005 return -1;
1006 }
1007
1008 arg = getNextArg();
1009 if (arg == null) {
1010 onHelpD2D();
1011 return 0;
1012 }
1013 try {
1014 messageValue = Integer.parseInt(arg);
1015 } catch (NumberFormatException e) {
1016 errPw.println("message value must be a valid integer");
1017 return -1;
1018 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001019
Tyler Gunn92479152021-01-20 16:30:10 -08001020 try {
1021 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1022 } catch (RemoteException e) {
1023 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1024 errPw.println("Exception: " + e.getMessage());
1025 return -1;
1026 }
1027
1028 return 0;
1029 }
1030
Tyler Gunnbabbda02021-02-10 11:05:02 -08001031 private int handleD2dTransportCommand() {
1032 PrintWriter errPw = getErrPrintWriter();
1033
1034 String arg = getNextArg();
1035 if (arg == null) {
1036 onHelpD2D();
1037 return 0;
1038 }
1039
1040 try {
1041 mInterface.setActiveDeviceToDeviceTransport(arg);
1042 } catch (RemoteException e) {
1043 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1044 errPw.println("Exception: " + e.getMessage());
1045 return -1;
1046 }
1047 return 0;
1048 }
Nazanin014f41e2021-05-06 17:26:31 -07001049 private int handleBarringCommand() {
1050 String arg = getNextArg();
1051 if (arg == null) {
1052 onHelpBarring();
1053 return 0;
1054 }
1055
1056 switch (arg) {
1057 case BARRING_SEND_INFO: {
1058 return handleBarringSendCommand();
1059 }
1060 }
1061 return -1;
1062 }
1063
1064 private int handleBarringSendCommand() {
1065 PrintWriter errPw = getErrPrintWriter();
1066 int slotId = getDefaultSlot();
1067 int subId = SubscriptionManager.getSubId(slotId)[0];
1068 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1069 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1070 boolean isConditionallyBarred = false;
1071 int conditionalBarringTimeSeconds = 0;
1072
1073 String opt;
1074 while ((opt = getNextOption()) != null) {
1075 switch (opt) {
1076 case "-s": {
1077 try {
1078 slotId = Integer.parseInt(getNextArgRequired());
1079 subId = SubscriptionManager.getSubId(slotId)[0];
1080 } catch (NumberFormatException e) {
1081 errPw.println("barring send requires an integer as a SLOT_ID.");
1082 return -1;
1083 }
1084 break;
1085 }
1086 case "-b": {
1087 try {
1088 barringType = Integer.parseInt(getNextArgRequired());
1089 if (barringType < -1 || barringType > 2) {
1090 throw new NumberFormatException();
1091 }
1092
1093 } catch (NumberFormatException e) {
1094 errPw.println("barring send requires an integer in range [-1,2] as "
1095 + "a BARRING_TYPE.");
1096 return -1;
1097 }
1098 break;
1099 }
1100 case "-c": {
1101 try {
1102 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1103 } catch (Exception e) {
1104 errPw.println("barring send requires a boolean after -c indicating"
1105 + " conditional barring");
1106 return -1;
1107 }
1108 break;
1109 }
1110 case "-t": {
1111 try {
1112 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1113 } catch (NumberFormatException e) {
1114 errPw.println("barring send requires an integer for time of barring"
1115 + " in seconds after -t for conditional barring");
1116 return -1;
1117 }
1118 break;
1119 }
1120 }
1121 }
1122 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1123 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1124 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1125 barringServiceInfos.append(0, bsi);
1126 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1127 try {
1128 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1129 } catch (Exception e) {
1130 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1131 errPw.println("Exception: " + e.getMessage());
1132 return -1;
1133 }
1134 return 0;
1135 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001136
Tyler Gunnd4575212021-05-03 14:46:49 -07001137 private int handleD2dDeviceSupportedCommand() {
1138 PrintWriter errPw = getErrPrintWriter();
1139
1140 String arg = getNextArg();
1141 if (arg == null) {
1142 onHelpD2D();
1143 return 0;
1144 }
1145
1146 boolean isEnabled = "true".equals(arg.toLowerCase());
1147 try {
1148 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1149 } catch (RemoteException e) {
1150 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1151 errPw.println("Exception: " + e.getMessage());
1152 return -1;
1153 }
1154 return 0;
1155 }
1156
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001157 // ims set-ims-service
1158 private int handleImsSetServiceCommand() {
1159 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001160 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001161 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001162 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001163
1164 String opt;
1165 while ((opt = getNextOption()) != null) {
1166 switch (opt) {
1167 case "-s": {
1168 try {
1169 slotId = Integer.parseInt(getNextArgRequired());
1170 } catch (NumberFormatException e) {
1171 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1172 return -1;
1173 }
1174 break;
1175 }
1176 case "-c": {
1177 isCarrierService = true;
1178 break;
1179 }
1180 case "-d": {
1181 isCarrierService = false;
1182 break;
1183 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001184 case "-f": {
1185 String featureString = getNextArgRequired();
1186 String[] features = featureString.split(",");
1187 for (int i = 0; i < features.length; i++) {
1188 try {
1189 Integer result = Integer.parseInt(features[i]);
1190 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1191 || result >= ImsFeature.FEATURE_MAX) {
1192 errPw.println("ims set-ims-service -f " + result
1193 + " is an invalid feature.");
1194 return -1;
1195 }
1196 featuresList.add(result);
1197 } catch (NumberFormatException e) {
1198 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1199 + " as an integer.");
1200 return -1;
1201 }
1202 }
1203 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001204 }
1205 }
1206 // Mandatory param, either -c or -d
1207 if (isCarrierService == null) {
1208 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1209 return -1;
1210 }
1211
1212 String packageName = getNextArg();
1213
1214 try {
1215 if (packageName == null) {
1216 packageName = "";
1217 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001218 int[] featureArray = new int[featuresList.size()];
1219 for (int i = 0; i < featuresList.size(); i++) {
1220 featureArray[i] = featuresList.get(i);
1221 }
1222 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1223 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001224 if (VDBG) {
1225 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001226 + (isCarrierService ? "-c " : "-d ")
1227 + "-f " + featuresList + " "
1228 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001229 }
1230 getOutPrintWriter().println(result);
1231 } catch (RemoteException e) {
1232 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001233 + (isCarrierService ? "-c " : "-d ")
1234 + "-f " + featuresList + " "
1235 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001236 errPw.println("Exception: " + e.getMessage());
1237 return -1;
1238 }
1239 return 0;
1240 }
1241
Brad Ebinger999d3302020-11-25 14:31:39 -08001242 // ims clear-ims-service-override
1243 private int handleImsClearCarrierServiceCommand() {
1244 PrintWriter errPw = getErrPrintWriter();
1245 int slotId = getDefaultSlot();
1246
1247 String opt;
1248 while ((opt = getNextOption()) != null) {
1249 switch (opt) {
1250 case "-s": {
1251 try {
1252 slotId = Integer.parseInt(getNextArgRequired());
1253 } catch (NumberFormatException e) {
1254 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1255 return -1;
1256 }
1257 break;
1258 }
1259 }
1260 }
1261
1262 try {
1263 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1264 if (VDBG) {
1265 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1266 + ", result=" + result);
1267 }
1268 getOutPrintWriter().println(result);
1269 } catch (RemoteException e) {
1270 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1271 + ", error" + e.getMessage());
1272 errPw.println("Exception: " + e.getMessage());
1273 return -1;
1274 }
1275 return 0;
1276 }
1277
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001278 // ims get-ims-service
1279 private int handleImsGetServiceCommand() {
1280 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001281 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001282 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001283 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001284
1285 String opt;
1286 while ((opt = getNextOption()) != null) {
1287 switch (opt) {
1288 case "-s": {
1289 try {
1290 slotId = Integer.parseInt(getNextArgRequired());
1291 } catch (NumberFormatException e) {
1292 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1293 return -1;
1294 }
1295 break;
1296 }
1297 case "-c": {
1298 isCarrierService = true;
1299 break;
1300 }
1301 case "-d": {
1302 isCarrierService = false;
1303 break;
1304 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001305 case "-f": {
1306 try {
1307 featureType = Integer.parseInt(getNextArg());
1308 } catch (NumberFormatException e) {
1309 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1310 return -1;
1311 }
1312 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1313 || featureType >= ImsFeature.FEATURE_MAX) {
1314 errPw.println("ims get-ims-service -f invalid feature.");
1315 return -1;
1316 }
1317 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001318 }
1319 }
1320 // Mandatory param, either -c or -d
1321 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001322 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001323 return -1;
1324 }
1325
1326 String result;
1327 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001328 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001329 } catch (RemoteException e) {
1330 return -1;
1331 }
1332 if (VDBG) {
1333 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001334 + (isCarrierService ? "-c " : "-d ")
1335 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1336 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001337 }
1338 getOutPrintWriter().println(result);
1339 return 0;
1340 }
1341
1342 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001343 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001344 String opt;
1345 while ((opt = getNextOption()) != null) {
1346 switch (opt) {
1347 case "-s": {
1348 try {
1349 slotId = Integer.parseInt(getNextArgRequired());
1350 } catch (NumberFormatException e) {
1351 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1352 return -1;
1353 }
1354 break;
1355 }
1356 }
1357 }
1358 try {
1359 mInterface.enableIms(slotId);
1360 } catch (RemoteException e) {
1361 return -1;
1362 }
1363 if (VDBG) {
1364 Log.v(LOG_TAG, "ims enable -s " + slotId);
1365 }
1366 return 0;
1367 }
1368
1369 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001370 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001371 String opt;
1372 while ((opt = getNextOption()) != null) {
1373 switch (opt) {
1374 case "-s": {
1375 try {
1376 slotId = Integer.parseInt(getNextArgRequired());
1377 } catch (NumberFormatException e) {
1378 getErrPrintWriter().println(
1379 "ims disable requires an integer as a SLOT_ID.");
1380 return -1;
1381 }
1382 break;
1383 }
1384 }
1385 }
1386 try {
1387 mInterface.disableIms(slotId);
1388 } catch (RemoteException e) {
1389 return -1;
1390 }
1391 if (VDBG) {
1392 Log.v(LOG_TAG, "ims disable -s " + slotId);
1393 }
1394 return 0;
1395 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001396
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001397 private int handleCepChange() {
1398 Log.i(LOG_TAG, "handleCepChange");
1399 String opt = getNextArg();
1400 if (opt == null) {
1401 return -1;
1402 }
1403 boolean isCepEnabled = opt.equals("enable");
1404
1405 try {
1406 mInterface.setCepEnabled(isCepEnabled);
1407 } catch (RemoteException e) {
1408 return -1;
1409 }
1410 return 0;
1411 }
1412
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001413 private int getDefaultSlot() {
1414 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1415 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1416 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1417 // If there is no default, default to slot 0.
1418 slotId = DEFAULT_PHONE_ID;
1419 }
1420 return slotId;
1421 }
sqian2fff4a32018-11-05 14:18:37 -08001422
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001423 // Parse options related to Carrier Config Commands.
1424 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001425 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001426 CcOptionParseResult result = new CcOptionParseResult();
1427 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1428 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001429
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001430 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001431 while ((opt = getNextOption()) != null) {
1432 switch (opt) {
1433 case "-s": {
1434 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001435 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1436 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1437 errPw.println(tag + "No valid subscription found.");
1438 return null;
1439 }
1440
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001441 } catch (IllegalArgumentException e) {
1442 // Missing slot id
1443 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001444 return null;
1445 }
1446 break;
1447 }
1448 case "-p": {
1449 if (allowOptionPersistent) {
1450 result.mPersistent = true;
1451 } else {
1452 errPw.println(tag + "Unexpected option " + opt);
1453 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001454 }
1455 break;
1456 }
1457 default: {
1458 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001459 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001460 }
1461 }
1462 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001463 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001464 }
1465
1466 private int slotStringToSubId(String tag, String slotString) {
1467 int slotId = -1;
1468 try {
1469 slotId = Integer.parseInt(slotString);
1470 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001471 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1472 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1473 }
1474
1475 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001476 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1477 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1478 }
1479
Qiong Liuf25799b2020-09-10 10:13:46 +08001480 Phone phone = PhoneFactory.getPhone(slotId);
1481 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001482 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1483 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1484 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001485 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001486 }
1487
Hall Liud892bec2018-11-30 14:51:45 -08001488 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001489 // adb can run as root or as shell, depending on whether the device is rooted.
1490 return Binder.getCallingUid() == Process.SHELL_UID
1491 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001492 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001493
1494 private int handleCcCommand() {
1495 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1496 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001497 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001498 getErrPrintWriter().println("cc: Permission denied.");
1499 return -1;
1500 }
1501
1502 String arg = getNextArg();
1503 if (arg == null) {
1504 onHelpCc();
1505 return 0;
1506 }
1507
1508 switch (arg) {
1509 case CC_GET_VALUE: {
1510 return handleCcGetValue();
1511 }
1512 case CC_SET_VALUE: {
1513 return handleCcSetValue();
1514 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001515 case CC_SET_VALUES_FROM_XML: {
1516 return handleCcSetValuesFromXml();
1517 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001518 case CC_CLEAR_VALUES: {
1519 return handleCcClearValues();
1520 }
1521 default: {
1522 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1523 }
1524 }
1525 return -1;
1526 }
1527
1528 // cc get-value
1529 private int handleCcGetValue() {
1530 PrintWriter errPw = getErrPrintWriter();
1531 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1532 String key = null;
1533
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001534 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001535 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001536 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001537 return -1;
1538 }
1539
1540 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001541 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001542 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001543 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001544 return -1;
1545 }
1546
1547 // Get the key.
1548 key = getNextArg();
1549 if (key != null) {
1550 // A key was provided. Verify if it is a valid key
1551 if (!bundle.containsKey(key)) {
1552 errPw.println(tag + key + " is not a valid key.");
1553 return -1;
1554 }
1555
1556 // Print the carrier config value for key.
1557 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1558 } else {
1559 // No key provided. Show all values.
1560 // Iterate over a sorted list of all carrier config keys and print them.
1561 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1562 for (String k : sortedSet) {
1563 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1564 }
1565 }
1566 return 0;
1567 }
1568
1569 // cc set-value
1570 private int handleCcSetValue() {
1571 PrintWriter errPw = getErrPrintWriter();
1572 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1573
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001574 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001575 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001576 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001577 return -1;
1578 }
1579
1580 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001581 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001582 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001583 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001584 return -1;
1585 }
1586
1587 // Get the key.
1588 String key = getNextArg();
1589 if (key == null || key.equals("")) {
1590 errPw.println(tag + "KEY is missing");
1591 return -1;
1592 }
1593
1594 // Verify if the key is valid
1595 if (!originalValues.containsKey(key)) {
1596 errPw.println(tag + key + " is not a valid key.");
1597 return -1;
1598 }
1599
1600 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1601 ArrayList<String> valueList = new ArrayList<String>();
1602 while (peekNextArg() != null) {
1603 valueList.add(getNextArg());
1604 }
1605
1606 // Find the type of the carrier config value
1607 CcType type = getType(tag, key, originalValues);
1608 if (type == CcType.UNKNOWN) {
1609 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1610 return -1;
1611 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001612 if (type == CcType.PERSISTABLE_BUNDLE) {
1613 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1614 + "Use set-values-from-xml instead.");
1615 return -1;
1616 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001617
1618 // Create an override bundle containing the key and value that should be overriden.
1619 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1620 if (overrideBundle == null) {
1621 return -1;
1622 }
1623
1624 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001625 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001626
1627 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001628 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001629 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001630 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001631 return -1;
1632 }
1633
1634 // Print the original and new value.
1635 String originalValueString = ccValueToString(key, type, originalValues);
1636 String newValueString = ccValueToString(key, type, newValues);
1637 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1638 getOutPrintWriter().println("New value: \n" + newValueString);
1639
1640 return 0;
1641 }
1642
Allen Xuee00f0e2022-03-14 21:04:49 +00001643 // cc set-values-from-xml
1644 private int handleCcSetValuesFromXml() {
1645 PrintWriter errPw = getErrPrintWriter();
1646 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1647
1648 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001649 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001650 if (options == null) {
1651 return -1;
1652 }
1653
1654 // Get bundle containing all current carrier configuration values.
1655 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1656 if (originalValues == null) {
1657 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1658 return -1;
1659 }
1660
1661 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1662 if (overrideBundle == null) {
1663 return -1;
1664 }
1665
1666 // Verify all values are valid types
1667 for (String key : overrideBundle.keySet()) {
1668 CcType type = getType(tag, key, originalValues);
1669 if (type == CcType.UNKNOWN) {
1670 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1671 return -1;
1672 }
1673 }
1674
1675 // Override the value
1676 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1677
1678 // Find bundle containing all new carrier configuration values after the override.
1679 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1680 if (newValues == null) {
1681 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1682 return -1;
1683 }
1684
1685 // Print the original and new values
1686 overrideBundle.keySet().forEach(key -> {
1687 CcType type = getType(tag, key, originalValues);
1688 String originalValueString = ccValueToString(key, type, originalValues);
1689 String newValueString = ccValueToString(key, type, newValues);
1690 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1691 getOutPrintWriter().println("New value: \n" + newValueString);
1692 });
1693
1694 return 0;
1695 }
1696
1697 private PersistableBundle readPersistableBundleFromXml(String tag) {
1698 PersistableBundle subIdBundles;
1699 try {
1700 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1701 } catch (IOException | RuntimeException e) {
1702 PrintWriter errPw = getErrPrintWriter();
1703 errPw.println(tag + e);
1704 return null;
1705 }
1706
1707 return subIdBundles;
1708 }
1709
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001710 // cc clear-values
1711 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001712 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1713
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001714 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001715 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001716 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001717 return -1;
1718 }
1719
1720 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001721 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001722 getOutPrintWriter()
1723 .println("All previously set carrier config override values has been cleared");
1724 return 0;
1725 }
1726
1727 private CcType getType(String tag, String key, PersistableBundle bundle) {
1728 // Find the type by checking the type of the current value stored in the bundle.
1729 Object value = bundle.get(key);
1730
1731 if (CC_TYPE_MAP.containsKey(key)) {
1732 return CC_TYPE_MAP.get(key);
1733 } else if (value != null) {
1734 if (value instanceof Boolean) {
1735 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001736 }
1737 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001738 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001739 }
1740 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001741 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001742 }
1743 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001744 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001745 }
1746 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001747 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001748 }
1749 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001750 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001751 }
1752 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001753 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001754 }
1755 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001756 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001757 }
1758 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001759 return CcType.STRING_ARRAY;
1760 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001761 if (value instanceof PersistableBundle) {
1762 return CcType.PERSISTABLE_BUNDLE;
1763 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001764 } else {
1765 // Current value was null and can therefore not be used in order to find the type.
1766 // Check the name of the key to infer the type. This check is not needed for primitive
1767 // data types (boolean, double, int and long), since they can not be null.
1768 if (key.endsWith("double_array")) {
1769 return CcType.DOUBLE_ARRAY;
1770 }
1771 if (key.endsWith("int_array")) {
1772 return CcType.INT_ARRAY;
1773 }
1774 if (key.endsWith("long_array")) {
1775 return CcType.LONG_ARRAY;
1776 }
1777 if (key.endsWith("string")) {
1778 return CcType.STRING;
1779 }
1780 if (key.endsWith("string_array") || key.endsWith("strings")) {
1781 return CcType.STRING_ARRAY;
1782 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001783 if (key.endsWith("bundle")) {
1784 return CcType.PERSISTABLE_BUNDLE;
1785 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001786 }
1787
1788 // Not possible to infer the type by looking at the current value or the key.
1789 PrintWriter errPw = getErrPrintWriter();
1790 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1791 return CcType.UNKNOWN;
1792 }
1793
1794 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1795 String result;
1796 StringBuilder valueString = new StringBuilder();
1797 String typeString = type.toString();
1798 Object value = bundle.get(key);
1799
1800 if (value == null) {
1801 valueString.append("null");
1802 } else {
1803 switch (type) {
1804 case DOUBLE_ARRAY: {
1805 // Format the string representation of the int array as value1 value2......
1806 double[] valueArray = (double[]) value;
1807 for (int i = 0; i < valueArray.length; i++) {
1808 if (i != 0) {
1809 valueString.append(" ");
1810 }
1811 valueString.append(valueArray[i]);
1812 }
1813 break;
1814 }
1815 case INT_ARRAY: {
1816 // Format the string representation of the int array as value1 value2......
1817 int[] valueArray = (int[]) value;
1818 for (int i = 0; i < valueArray.length; i++) {
1819 if (i != 0) {
1820 valueString.append(" ");
1821 }
1822 valueString.append(valueArray[i]);
1823 }
1824 break;
1825 }
1826 case LONG_ARRAY: {
1827 // Format the string representation of the int array as value1 value2......
1828 long[] valueArray = (long[]) value;
1829 for (int i = 0; i < valueArray.length; i++) {
1830 if (i != 0) {
1831 valueString.append(" ");
1832 }
1833 valueString.append(valueArray[i]);
1834 }
1835 break;
1836 }
1837 case STRING: {
1838 valueString.append("\"" + value.toString() + "\"");
1839 break;
1840 }
1841 case STRING_ARRAY: {
1842 // Format the string representation of the string array as "value1" "value2"....
1843 String[] valueArray = (String[]) value;
1844 for (int i = 0; i < valueArray.length; i++) {
1845 if (i != 0) {
1846 valueString.append(" ");
1847 }
1848 if (valueArray[i] != null) {
1849 valueString.append("\"" + valueArray[i] + "\"");
1850 } else {
1851 valueString.append("null");
1852 }
1853 }
1854 break;
1855 }
1856 default: {
1857 valueString.append(value.toString());
1858 }
1859 }
1860 }
1861 return String.format("%-70s %-15s %s", key, typeString, valueString);
1862 }
1863
1864 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1865 ArrayList<String> valueList) {
1866 PrintWriter errPw = getErrPrintWriter();
1867 PersistableBundle bundle = new PersistableBundle();
1868
1869 // First verify that a valid number of values has been provided for the type.
1870 switch (type) {
1871 case BOOLEAN:
1872 case DOUBLE:
1873 case INT:
1874 case LONG: {
1875 if (valueList.size() != 1) {
1876 errPw.println(tag + "Expected 1 value for type " + type
1877 + ". Found: " + valueList.size());
1878 return null;
1879 }
1880 break;
1881 }
1882 case STRING: {
1883 if (valueList.size() > 1) {
1884 errPw.println(tag + "Expected 0 or 1 values for type " + type
1885 + ". Found: " + valueList.size());
1886 return null;
1887 }
1888 break;
1889 }
1890 }
1891
1892 // Parse the value according to type and add it to the Bundle.
1893 switch (type) {
1894 case BOOLEAN: {
1895 if ("true".equalsIgnoreCase(valueList.get(0))) {
1896 bundle.putBoolean(key, true);
1897 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1898 bundle.putBoolean(key, false);
1899 } else {
1900 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1901 return null;
1902 }
1903 break;
1904 }
1905 case DOUBLE: {
1906 try {
1907 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1908 } catch (NumberFormatException nfe) {
1909 // Not a valid double
1910 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1911 return null;
1912 }
1913 break;
1914 }
1915 case DOUBLE_ARRAY: {
1916 double[] valueDoubleArray = null;
1917 if (valueList.size() > 0) {
1918 valueDoubleArray = new double[valueList.size()];
1919 for (int i = 0; i < valueList.size(); i++) {
1920 try {
1921 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1922 } catch (NumberFormatException nfe) {
1923 // Not a valid double
1924 errPw.println(
1925 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1926 return null;
1927 }
1928 }
1929 }
1930 bundle.putDoubleArray(key, valueDoubleArray);
1931 break;
1932 }
1933 case INT: {
1934 try {
1935 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1936 } catch (NumberFormatException nfe) {
1937 // Not a valid integer
1938 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1939 return null;
1940 }
1941 break;
1942 }
1943 case INT_ARRAY: {
1944 int[] valueIntArray = null;
1945 if (valueList.size() > 0) {
1946 valueIntArray = new int[valueList.size()];
1947 for (int i = 0; i < valueList.size(); i++) {
1948 try {
1949 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1950 } catch (NumberFormatException nfe) {
1951 // Not a valid integer
1952 errPw.println(tag
1953 + "Unable to parse " + valueList.get(i) + " as an integer.");
1954 return null;
1955 }
1956 }
1957 }
1958 bundle.putIntArray(key, valueIntArray);
1959 break;
1960 }
1961 case LONG: {
1962 try {
1963 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1964 } catch (NumberFormatException nfe) {
1965 // Not a valid long
1966 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1967 return null;
1968 }
1969 break;
1970 }
1971 case LONG_ARRAY: {
1972 long[] valueLongArray = null;
1973 if (valueList.size() > 0) {
1974 valueLongArray = new long[valueList.size()];
1975 for (int i = 0; i < valueList.size(); i++) {
1976 try {
1977 valueLongArray[i] = Long.parseLong(valueList.get(i));
1978 } catch (NumberFormatException nfe) {
1979 // Not a valid long
1980 errPw.println(
1981 tag + "Unable to parse " + valueList.get(i) + " as a long");
1982 return null;
1983 }
1984 }
1985 }
1986 bundle.putLongArray(key, valueLongArray);
1987 break;
1988 }
1989 case STRING: {
1990 String value = null;
1991 if (valueList.size() > 0) {
1992 value = valueList.get(0);
1993 }
1994 bundle.putString(key, value);
1995 break;
1996 }
1997 case STRING_ARRAY: {
1998 String[] valueStringArray = null;
1999 if (valueList.size() > 0) {
2000 valueStringArray = new String[valueList.size()];
2001 valueList.toArray(valueStringArray);
2002 }
2003 bundle.putStringArray(key, valueStringArray);
2004 break;
2005 }
2006 }
2007 return bundle;
2008 }
Shuo Qian489d9282020-07-09 11:30:03 -07002009
2010 private int handleEndBlockSuppressionCommand() {
2011 if (!checkShellUid()) {
2012 return -1;
2013 }
2014
2015 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2016 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2017 }
2018 return 0;
2019 }
Hui Wang641e81c2020-10-12 12:14:23 -07002020
Michele Berionne54af4632020-12-28 20:23:16 +00002021 private int handleRestartModemCommand() {
2022 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2023 // non user build.
2024 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2025 getErrPrintWriter().println("RestartModem: Permission denied.");
2026 return -1;
2027 }
2028
2029 boolean result = TelephonyManager.getDefault().rebootRadio();
2030 getOutPrintWriter().println(result);
2031
2032 return result ? 0 : -1;
2033 }
2034
Ling Ma4fbab492022-01-25 22:36:16 +00002035 private int handleGetImei() {
2036 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2037 // non user build.
2038 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2039 getErrPrintWriter().println("Device IMEI: Permission denied.");
2040 return -1;
2041 }
2042
2043 final long identity = Binder.clearCallingIdentity();
2044
2045 String imei = null;
2046 String arg = getNextArg();
2047 if (arg != null) {
2048 try {
2049 int specifiedSlotIndex = Integer.parseInt(arg);
2050 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2051 } catch (NumberFormatException exception) {
2052 PrintWriter errPw = getErrPrintWriter();
2053 errPw.println("-s requires an integer as slot index.");
2054 return -1;
2055 }
2056
2057 } else {
2058 imei = TelephonyManager.from(mContext).getImei();
2059 }
2060 getOutPrintWriter().println("Device IMEI: " + imei);
2061
2062 Binder.restoreCallingIdentity(identity);
2063 return 0;
2064 }
2065
Michele Berionne5e411512020-11-13 02:36:59 +00002066 private int handleUnattendedReboot() {
2067 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2068 // non user build.
2069 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2070 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2071 return -1;
2072 }
2073
2074 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2075 getOutPrintWriter().println("result: " + result);
2076
2077 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2078 }
2079
Aman Gupta07124872022-02-09 08:02:14 +00002080 private int handleGetSimSlotsMapping() {
2081 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2082 // non user build.
2083 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2084 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2085 return -1;
2086 }
2087 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2088 String result = telephonyManager.getSimSlotMapping().toString();
2089 getOutPrintWriter().println("simSlotsMapping: " + result);
2090
2091 return 0;
2092 }
2093
Hui Wang641e81c2020-10-12 12:14:23 -07002094 private int handleGbaCommand() {
2095 String arg = getNextArg();
2096 if (arg == null) {
2097 onHelpGba();
2098 return 0;
2099 }
2100
2101 switch (arg) {
2102 case GBA_SET_SERVICE: {
2103 return handleGbaSetServiceCommand();
2104 }
2105 case GBA_GET_SERVICE: {
2106 return handleGbaGetServiceCommand();
2107 }
2108 case GBA_SET_RELEASE_TIME: {
2109 return handleGbaSetReleaseCommand();
2110 }
2111 case GBA_GET_RELEASE_TIME: {
2112 return handleGbaGetReleaseCommand();
2113 }
2114 }
2115
2116 return -1;
2117 }
2118
2119 private int getSubId(String cmd) {
2120 int slotId = getDefaultSlot();
2121 String opt = getNextOption();
2122 if (opt != null && opt.equals("-s")) {
2123 try {
2124 slotId = Integer.parseInt(getNextArgRequired());
2125 } catch (NumberFormatException e) {
2126 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2127 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2128 }
2129 }
2130 int[] subIds = SubscriptionManager.getSubId(slotId);
2131 return subIds[0];
2132 }
2133
2134 private int handleGbaSetServiceCommand() {
2135 int subId = getSubId("gba set-service");
2136 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2137 return -1;
2138 }
2139
2140 String packageName = getNextArg();
2141 try {
2142 if (packageName == null) {
2143 packageName = "";
2144 }
2145 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2146 if (VDBG) {
2147 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2148 + packageName + ", result=" + result);
2149 }
2150 getOutPrintWriter().println(result);
2151 } catch (RemoteException e) {
2152 Log.w(LOG_TAG, "gba set-service " + subId + " "
2153 + packageName + ", error" + e.getMessage());
2154 getErrPrintWriter().println("Exception: " + e.getMessage());
2155 return -1;
2156 }
2157 return 0;
2158 }
2159
2160 private int handleGbaGetServiceCommand() {
2161 String result;
2162
2163 int subId = getSubId("gba get-service");
2164 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2165 return -1;
2166 }
2167
2168 try {
2169 result = mInterface.getBoundGbaService(subId);
2170 } catch (RemoteException e) {
2171 return -1;
2172 }
2173 if (VDBG) {
2174 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2175 }
2176 getOutPrintWriter().println(result);
2177 return 0;
2178 }
2179
2180 private int handleGbaSetReleaseCommand() {
2181 //the release time value could be -1
2182 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2183 : SubscriptionManager.getDefaultSubscriptionId();
2184 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2185 return -1;
2186 }
2187
2188 String intervalStr = getNextArg();
2189 if (intervalStr == null) {
2190 return -1;
2191 }
2192
2193 try {
2194 int interval = Integer.parseInt(intervalStr);
2195 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2196 if (VDBG) {
2197 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2198 + intervalStr + ", result=" + result);
2199 }
2200 getOutPrintWriter().println(result);
2201 } catch (NumberFormatException | RemoteException e) {
2202 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2203 + intervalStr + ", error" + e.getMessage());
2204 getErrPrintWriter().println("Exception: " + e.getMessage());
2205 return -1;
2206 }
2207 return 0;
2208 }
2209
2210 private int handleGbaGetReleaseCommand() {
2211 int subId = getSubId("gba get-release");
2212 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2213 return -1;
2214 }
2215
2216 int result = 0;
2217 try {
2218 result = mInterface.getGbaReleaseTime(subId);
2219 } catch (RemoteException e) {
2220 return -1;
2221 }
2222 if (VDBG) {
2223 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2224 }
2225 getOutPrintWriter().println(result);
2226 return 0;
2227 }
Hui Wang761a6682020-10-31 05:12:53 +00002228
2229 private int handleSingleRegistrationConfigCommand() {
2230 String arg = getNextArg();
2231 if (arg == null) {
2232 onHelpSrc();
2233 return 0;
2234 }
2235
2236 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002237 case SRC_SET_TEST_ENABLED: {
2238 return handleSrcSetTestEnabledCommand();
2239 }
2240 case SRC_GET_TEST_ENABLED: {
2241 return handleSrcGetTestEnabledCommand();
2242 }
Hui Wang761a6682020-10-31 05:12:53 +00002243 case SRC_SET_DEVICE_ENABLED: {
2244 return handleSrcSetDeviceEnabledCommand();
2245 }
2246 case SRC_GET_DEVICE_ENABLED: {
2247 return handleSrcGetDeviceEnabledCommand();
2248 }
2249 case SRC_SET_CARRIER_ENABLED: {
2250 return handleSrcSetCarrierEnabledCommand();
2251 }
2252 case SRC_GET_CARRIER_ENABLED: {
2253 return handleSrcGetCarrierEnabledCommand();
2254 }
Hui Wangb647abe2021-02-26 09:33:38 -08002255 case SRC_SET_FEATURE_ENABLED: {
2256 return handleSrcSetFeatureValidationCommand();
2257 }
2258 case SRC_GET_FEATURE_ENABLED: {
2259 return handleSrcGetFeatureValidationCommand();
2260 }
Hui Wang761a6682020-10-31 05:12:53 +00002261 }
2262
2263 return -1;
2264 }
2265
James.cf Linbcdf8b32021-01-14 16:44:13 +08002266 private int handleRcsUceCommand() {
2267 String arg = getNextArg();
2268 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002269 onHelpUce();
2270 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002271 }
2272
2273 switch (arg) {
2274 case UCE_REMOVE_EAB_CONTACT:
2275 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002276 case UCE_GET_EAB_CONTACT:
2277 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002278 case UCE_GET_EAB_CAPABILITY:
2279 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002280 case UCE_GET_DEVICE_ENABLED:
2281 return handleUceGetDeviceEnabledCommand();
2282 case UCE_SET_DEVICE_ENABLED:
2283 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002284 case UCE_OVERRIDE_PUBLISH_CAPS:
2285 return handleUceOverridePublishCaps();
2286 case UCE_GET_LAST_PIDF_XML:
2287 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002288 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2289 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002290 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2291 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002292 }
2293 return -1;
2294 }
2295
2296 private int handleRemovingEabContactCommand() {
2297 int subId = getSubId("uce remove-eab-contact");
2298 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2299 return -1;
2300 }
2301
2302 String phoneNumber = getNextArgRequired();
2303 if (TextUtils.isEmpty(phoneNumber)) {
2304 return -1;
2305 }
2306 int result = 0;
2307 try {
2308 result = mInterface.removeContactFromEab(subId, phoneNumber);
2309 } catch (RemoteException e) {
2310 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2311 getErrPrintWriter().println("Exception: " + e.getMessage());
2312 return -1;
2313 }
2314
2315 if (VDBG) {
2316 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2317 }
calvinpan293ea1b2021-02-04 17:52:13 +08002318 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002319 }
2320
calvinpane4a8a1d2021-01-25 13:51:18 +08002321 private int handleGettingEabContactCommand() {
2322 String phoneNumber = getNextArgRequired();
2323 if (TextUtils.isEmpty(phoneNumber)) {
2324 return -1;
2325 }
2326 String result = "";
2327 try {
2328 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002329 } catch (RemoteException e) {
2330 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2331 getErrPrintWriter().println("Exception: " + e.getMessage());
2332 return -1;
2333 }
2334
2335 if (VDBG) {
2336 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2337 }
calvinpan293ea1b2021-02-04 17:52:13 +08002338 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002339 return 0;
2340 }
2341
Calvin Pana1434322021-07-01 19:27:01 +08002342 private int handleGettingEabCapabilityCommand() {
2343 String phoneNumber = getNextArgRequired();
2344 if (TextUtils.isEmpty(phoneNumber)) {
2345 return -1;
2346 }
2347 String result = "";
2348 try {
2349 result = mInterface.getCapabilityFromEab(phoneNumber);
2350 } catch (RemoteException e) {
2351 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2352 getErrPrintWriter().println("Exception: " + e.getMessage());
2353 return -1;
2354 }
2355
2356 if (VDBG) {
2357 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2358 }
2359 getOutPrintWriter().println(result);
2360 return 0;
2361 }
2362
James.cf Lin4b784aa2021-01-31 03:25:15 +08002363 private int handleUceGetDeviceEnabledCommand() {
2364 boolean result = false;
2365 try {
2366 result = mInterface.getDeviceUceEnabled();
2367 } catch (RemoteException e) {
2368 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2369 return -1;
2370 }
2371 if (VDBG) {
2372 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2373 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002374 getOutPrintWriter().println(result);
2375 return 0;
2376 }
2377
James.cf Lin4b784aa2021-01-31 03:25:15 +08002378 private int handleUceSetDeviceEnabledCommand() {
2379 String enabledStr = getNextArg();
2380 if (TextUtils.isEmpty(enabledStr)) {
2381 return -1;
2382 }
2383
2384 try {
2385 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2386 mInterface.setDeviceUceEnabled(isEnabled);
2387 if (VDBG) {
2388 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2389 }
2390 } catch (NumberFormatException | RemoteException e) {
2391 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2392 getErrPrintWriter().println("Exception: " + e.getMessage());
2393 return -1;
2394 }
2395 return 0;
2396 }
2397
James.cf Line8713a42021-04-29 16:04:26 +08002398 private int handleUceRemoveRequestDisallowedStatus() {
2399 int subId = getSubId("uce remove-request-disallowed-status");
2400 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2401 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2402 return -1;
2403 }
2404 boolean result;
2405 try {
2406 result = mInterface.removeUceRequestDisallowedStatus(subId);
2407 } catch (RemoteException e) {
2408 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2409 return -1;
2410 }
2411 if (VDBG) {
2412 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2413 }
2414 getOutPrintWriter().println(result);
2415 return 0;
2416 }
2417
James.cf Lin0fc71b02021-05-25 01:37:38 +08002418 private int handleUceSetCapRequestTimeout() {
2419 int subId = getSubId("uce set-capabilities-request-timeout");
2420 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2421 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2422 return -1;
2423 }
2424 long timeoutAfterMs = Long.valueOf(getNextArg());
2425 boolean result;
2426 try {
2427 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2428 } catch (RemoteException e) {
2429 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2430 return -1;
2431 }
2432 if (VDBG) {
2433 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2434 }
2435 getOutPrintWriter().println(result);
2436 return 0;
2437 }
2438
Hui Wangbaaee6a2021-02-19 20:45:36 -08002439 private int handleSrcSetTestEnabledCommand() {
2440 String enabledStr = getNextArg();
2441 if (enabledStr == null) {
2442 return -1;
2443 }
2444
2445 try {
2446 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2447 if (VDBG) {
2448 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2449 }
2450 getOutPrintWriter().println("Done");
2451 } catch (NumberFormatException | RemoteException e) {
2452 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2453 getErrPrintWriter().println("Exception: " + e.getMessage());
2454 return -1;
2455 }
2456 return 0;
2457 }
2458
2459 private int handleSrcGetTestEnabledCommand() {
2460 boolean result = false;
2461 try {
2462 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2463 } catch (RemoteException e) {
2464 return -1;
2465 }
2466 if (VDBG) {
2467 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2468 }
2469 getOutPrintWriter().println(result);
2470 return 0;
2471 }
2472
Brad Ebinger14d467f2021-02-12 06:18:28 +00002473 private int handleUceOverridePublishCaps() {
2474 int subId = getSubId("uce override-published-caps");
2475 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2476 return -1;
2477 }
2478 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2479 String operation = getNextArgRequired();
2480 String caps = getNextArg();
2481 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2482 && !"list".equals(operation)) {
2483 getErrPrintWriter().println("Invalid operation: " + operation);
2484 return -1;
2485 }
2486
2487 // add/remove requires capabilities to be specified.
2488 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2489 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2490 + "specified");
2491 return -1;
2492 }
2493
2494 ArraySet<String> capSet = new ArraySet<>();
2495 if (!TextUtils.isEmpty(caps)) {
2496 String[] capArray = caps.split(":");
2497 for (String cap : capArray) {
2498 // Allow unknown tags to be passed in as well.
2499 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2500 }
2501 }
2502
2503 RcsContactUceCapability result = null;
2504 try {
2505 switch (operation) {
2506 case "add":
2507 result = mInterface.addUceRegistrationOverrideShell(subId,
2508 new ArrayList<>(capSet));
2509 break;
2510 case "remove":
2511 result = mInterface.removeUceRegistrationOverrideShell(subId,
2512 new ArrayList<>(capSet));
2513 break;
2514 case "clear":
2515 result = mInterface.clearUceRegistrationOverrideShell(subId);
2516 break;
2517 case "list":
2518 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2519 break;
2520 }
2521 } catch (RemoteException e) {
2522 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2523 getErrPrintWriter().println("Exception: " + e.getMessage());
2524 return -1;
2525 } catch (ServiceSpecificException sse) {
2526 // Reconstruct ImsException
2527 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2528 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2529 getErrPrintWriter().println("Exception: " + imsException);
2530 return -1;
2531 }
2532 if (result == null) {
2533 getErrPrintWriter().println("Service not available");
2534 return -1;
2535 }
2536 getOutPrintWriter().println(result);
2537 return 0;
2538 }
2539
2540 private int handleUceGetPidfXml() {
2541 int subId = getSubId("uce get-last-publish-pidf");
2542 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2543 return -1;
2544 }
2545
2546 String result;
2547 try {
2548 result = mInterface.getLastUcePidfXmlShell(subId);
2549 } catch (RemoteException e) {
2550 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2551 getErrPrintWriter().println("Exception: " + e.getMessage());
2552 return -1;
2553 } catch (ServiceSpecificException sse) {
2554 // Reconstruct ImsException
2555 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2556 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2557 getErrPrintWriter().println("Exception: " + imsException);
2558 return -1;
2559 }
2560 if (result == null) {
2561 getErrPrintWriter().println("Service not available");
2562 return -1;
2563 }
2564 getOutPrintWriter().println(result);
2565 return 0;
2566 }
2567
Hui Wang761a6682020-10-31 05:12:53 +00002568 private int handleSrcSetDeviceEnabledCommand() {
2569 String enabledStr = getNextArg();
2570 if (enabledStr == null) {
2571 return -1;
2572 }
2573
2574 try {
2575 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2576 if (VDBG) {
2577 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2578 }
2579 getOutPrintWriter().println("Done");
2580 } catch (NumberFormatException | RemoteException e) {
2581 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2582 getErrPrintWriter().println("Exception: " + e.getMessage());
2583 return -1;
2584 }
2585 return 0;
2586 }
2587
2588 private int handleSrcGetDeviceEnabledCommand() {
2589 boolean result = false;
2590 try {
2591 result = mInterface.getDeviceSingleRegistrationEnabled();
2592 } catch (RemoteException e) {
2593 return -1;
2594 }
2595 if (VDBG) {
2596 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2597 }
2598 getOutPrintWriter().println(result);
2599 return 0;
2600 }
2601
2602 private int handleSrcSetCarrierEnabledCommand() {
2603 //the release time value could be -1
2604 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2605 : SubscriptionManager.getDefaultSubscriptionId();
2606 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2607 return -1;
2608 }
2609
2610 String enabledStr = getNextArg();
2611 if (enabledStr == null) {
2612 return -1;
2613 }
2614
2615 try {
2616 boolean result =
2617 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2618 if (VDBG) {
2619 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2620 + enabledStr + ", result=" + result);
2621 }
2622 getOutPrintWriter().println(result);
2623 } catch (NumberFormatException | RemoteException e) {
2624 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2625 + enabledStr + ", error" + e.getMessage());
2626 getErrPrintWriter().println("Exception: " + e.getMessage());
2627 return -1;
2628 }
2629 return 0;
2630 }
2631
2632 private int handleSrcGetCarrierEnabledCommand() {
2633 int subId = getSubId("src get-carrier-enabled");
2634 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2635 return -1;
2636 }
2637
2638 boolean result = false;
2639 try {
2640 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2641 } catch (RemoteException e) {
2642 return -1;
2643 }
2644 if (VDBG) {
2645 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2646 }
2647 getOutPrintWriter().println(result);
2648 return 0;
2649 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002650
Hui Wangb647abe2021-02-26 09:33:38 -08002651 private int handleSrcSetFeatureValidationCommand() {
2652 //the release time value could be -1
2653 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2654 : SubscriptionManager.getDefaultSubscriptionId();
2655 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2656 return -1;
2657 }
2658
2659 String enabledStr = getNextArg();
2660 if (enabledStr == null) {
2661 return -1;
2662 }
2663
2664 try {
2665 boolean result =
2666 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2667 if (VDBG) {
2668 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2669 + enabledStr + ", result=" + result);
2670 }
2671 getOutPrintWriter().println(result);
2672 } catch (NumberFormatException | RemoteException e) {
2673 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2674 + enabledStr + ", error" + e.getMessage());
2675 getErrPrintWriter().println("Exception: " + e.getMessage());
2676 return -1;
2677 }
2678 return 0;
2679 }
2680
2681 private int handleSrcGetFeatureValidationCommand() {
2682 int subId = getSubId("src get-feature-validation");
2683 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2684 return -1;
2685 }
2686
2687 Boolean result = false;
2688 try {
2689 result = mInterface.getImsFeatureValidationOverride(subId);
2690 } catch (RemoteException e) {
2691 return -1;
2692 }
2693 if (VDBG) {
2694 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2695 }
2696 getOutPrintWriter().println(result);
2697 return 0;
2698 }
2699
2700
Hall Liuaa4211e2021-01-20 15:43:39 -08002701 private void onHelpCallComposer() {
2702 PrintWriter pw = getOutPrintWriter();
2703 pw.println("Call composer commands");
2704 pw.println(" callcomposer test-mode enable|disable|query");
2705 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2706 pw.println(" upload/download from carrier servers is disabled, and operations are");
2707 pw.println(" performed using emulated local files instead.");
2708 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2709 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2710 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002711 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2712 pw.println(" Enables or disables the user setting for call composer, as set by");
2713 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002714 }
2715
2716 private int handleCallComposerCommand() {
2717 String arg = getNextArg();
2718 if (arg == null) {
2719 onHelpCallComposer();
2720 return 0;
2721 }
2722
2723 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2724 "MODIFY_PHONE_STATE required for call composer shell cmds");
2725 switch (arg) {
2726 case CALL_COMPOSER_TEST_MODE: {
2727 String enabledStr = getNextArg();
2728 if (ENABLE.equals(enabledStr)) {
2729 CallComposerPictureManager.sTestMode = true;
2730 } else if (DISABLE.equals(enabledStr)) {
2731 CallComposerPictureManager.sTestMode = false;
2732 } else if (QUERY.equals(enabledStr)) {
2733 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2734 } else {
2735 onHelpCallComposer();
2736 return 1;
2737 }
2738 break;
2739 }
2740 case CALL_COMPOSER_SIMULATE_CALL: {
2741 int subscriptionId = Integer.valueOf(getNextArg());
2742 String uuidString = getNextArg();
2743 UUID uuid = UUID.fromString(uuidString);
2744 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2745 Binder.withCleanCallingIdentity(() -> {
2746 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2747 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2748 });
2749 try {
2750 Uri uri = storageUriFuture.get();
2751 getOutPrintWriter().println(String.valueOf(uri));
2752 } catch (Exception e) {
2753 throw new RuntimeException(e);
2754 }
2755 break;
2756 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002757 case CALL_COMPOSER_USER_SETTING: {
2758 try {
2759 int subscriptionId = Integer.valueOf(getNextArg());
2760 String enabledStr = getNextArg();
2761 if (ENABLE.equals(enabledStr)) {
2762 mInterface.setCallComposerStatus(subscriptionId,
2763 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2764 } else if (DISABLE.equals(enabledStr)) {
2765 mInterface.setCallComposerStatus(subscriptionId,
2766 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2767 } else if (QUERY.equals(enabledStr)) {
2768 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2769 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2770 } else {
2771 onHelpCallComposer();
2772 return 1;
2773 }
2774 } catch (RemoteException e) {
2775 e.printStackTrace(getOutPrintWriter());
2776 return 1;
2777 }
2778 break;
2779 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002780 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002781 return 0;
2782 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002783
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002784 private int handleHasCarrierPrivilegesCommand() {
2785 String packageName = getNextArgRequired();
2786
2787 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002788 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002789 try {
2790 hasCarrierPrivileges =
2791 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2792 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2793 } catch (RemoteException e) {
2794 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2795 getErrPrintWriter().println("Exception: " + e.getMessage());
2796 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002797 } finally {
2798 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002799 }
2800
2801 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002802 return 0;
2803 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002804
2805 private int handleAllowedNetworkTypesCommand(String command) {
2806 if (!checkShellUid()) {
2807 return -1;
2808 }
2809
2810 PrintWriter errPw = getErrPrintWriter();
2811 String tag = command + ": ";
2812 String opt;
2813 int subId = -1;
2814 Log.v(LOG_TAG, command + " start");
2815
2816 while ((opt = getNextOption()) != null) {
2817 if (opt.equals("-s")) {
2818 try {
2819 subId = slotStringToSubId(tag, getNextArgRequired());
2820 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2821 errPw.println(tag + "No valid subscription found.");
2822 return -1;
2823 }
2824 } catch (IllegalArgumentException e) {
2825 // Missing slot id
2826 errPw.println(tag + "SLOT_ID expected after -s.");
2827 return -1;
2828 }
2829 } else {
2830 errPw.println(tag + "Unknown option " + opt);
2831 return -1;
2832 }
2833 }
2834
2835 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2836 return handleGetAllowedNetworkTypesCommand(subId);
2837 }
2838 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2839 return handleSetAllowedNetworkTypesCommand(subId);
2840 }
2841 return -1;
2842 }
2843
2844 private int handleGetAllowedNetworkTypesCommand(int subId) {
2845 PrintWriter errPw = getErrPrintWriter();
2846
2847 long result = -1;
2848 try {
2849 if (mInterface != null) {
2850 result = mInterface.getAllowedNetworkTypesForReason(subId,
2851 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2852 } else {
2853 throw new IllegalStateException("telephony service is null.");
2854 }
2855 } catch (RemoteException e) {
2856 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2857 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2858 return -1;
2859 }
2860
2861 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2862 return 0;
2863 }
2864
2865 private int handleSetAllowedNetworkTypesCommand(int subId) {
2866 PrintWriter errPw = getErrPrintWriter();
2867
2868 String bitmaskString = getNextArg();
2869 if (TextUtils.isEmpty(bitmaskString)) {
2870 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2871 return -1;
2872 }
2873 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2874 if (allowedNetworkTypes < 0) {
2875 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2876 return -1;
2877 }
2878 boolean result = false;
2879 try {
2880 if (mInterface != null) {
2881 result = mInterface.setAllowedNetworkTypesForReason(subId,
2882 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2883 } else {
2884 throw new IllegalStateException("telephony service is null.");
2885 }
2886 } catch (RemoteException e) {
2887 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2888 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2889 return -1;
2890 }
2891
2892 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2893 if (result) {
2894 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2895 }
2896 getOutPrintWriter().println(resultMessage);
2897 return 0;
2898 }
2899
2900 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2901 if (TextUtils.isEmpty(bitmaskString)) {
2902 return -1;
2903 }
2904 if (VDBG) {
2905 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2906 + ", length: " + bitmaskString.length());
2907 }
2908 try {
2909 return Long.parseLong(bitmaskString, 2);
2910 } catch (NumberFormatException e) {
2911 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2912 return -1;
2913 }
2914 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002915
2916 private int handleGetDataMode() {
2917 if (!checkShellUid()) {
2918 return -1;
2919 }
2920
2921 boolean newDataStackEnabled = false;
2922 try {
2923 newDataStackEnabled = mInterface.isUsingNewDataStack();
2924 } catch (RemoteException e) {
2925 getOutPrintWriter().println("Something went wrong. " + e);
2926 return -1;
2927 }
2928
Jack Yu2f509862022-01-25 10:13:40 -08002929 getOutPrintWriter().println("Telephony is running with the "
2930 + (newDataStackEnabled ? "new" : "old") + " data stack.");
Jack Yu4c0a5502021-12-03 23:58:26 -08002931 return 0;
2932 }
jimsun3b9ccac2021-10-26 15:01:23 +08002933
2934 private int handleRadioSetModemServiceCommand() {
2935 PrintWriter errPw = getErrPrintWriter();
2936 String serviceName = null;
2937
2938 String opt;
2939 while ((opt = getNextOption()) != null) {
2940 switch (opt) {
2941 case "-s": {
2942 serviceName = getNextArgRequired();
2943 break;
2944 }
2945 }
2946 }
2947
2948 try {
2949 boolean result = mInterface.setModemService(serviceName);
2950 if (VDBG) {
2951 Log.v(LOG_TAG,
2952 "RadioSetModemService " + serviceName + ", result = " + result);
2953 }
2954 getOutPrintWriter().println(result);
2955 } catch (RemoteException e) {
2956 Log.w(LOG_TAG,
2957 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2958 errPw.println("Exception: " + e.getMessage());
2959 return -1;
2960 }
2961 return 0;
2962 }
2963
2964 private int handleRadioGetModemServiceCommand() {
2965 PrintWriter errPw = getErrPrintWriter();
2966 String result;
2967
2968 try {
2969 result = mInterface.getModemService();
2970 getOutPrintWriter().println(result);
2971 } catch (RemoteException e) {
2972 errPw.println("Exception: " + e.getMessage());
2973 return -1;
2974 }
2975 if (VDBG) {
2976 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2977 }
2978 return 0;
2979 }
2980
2981 private int handleRadioCommand() {
2982 String arg = getNextArg();
2983 if (arg == null) {
2984 onHelpRadio();
2985 return 0;
2986 }
2987
2988 switch (arg) {
2989 case RADIO_SET_MODEM_SERVICE:
2990 return handleRadioSetModemServiceCommand();
2991
2992 case RADIO_GET_MODEM_SERVICE:
2993 return handleRadioGetModemServiceCommand();
2994 }
2995
2996 return -1;
2997 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07002998}