blob: 0cf120a2f4c3603f36356039ce7d15d1a7dff77c [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010027import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080028import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080031import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070032import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000033import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070034import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070035import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010036import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070037import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070038import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000039import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070040import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080041import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000042import android.telephony.ims.ImsException;
43import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080044import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080045import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import android.util.ArrayMap;
47import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070048import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070049import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050
Brad Ebinger14d467f2021-02-12 06:18:28 +000051import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080053import com.android.internal.telephony.Phone;
54import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080055import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080056import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080057import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080058import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080059import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070060
Allen Xuee00f0e2022-03-14 21:04:49 +000061import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070062import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080063import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000064import java.util.Arrays;
65import java.util.Collections;
Brad Ebinger24c29992019-12-05 13:03:21 -080066import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000067import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010068import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000069import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010070import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080071import java.util.UUID;
72import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070073
74/**
75 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
76 * permission checks have been done before onCommand was called. Make sure any commands processed
77 * here also contain the appropriate permissions checks.
78 */
79
Hall Liua1548bd2019-12-24 14:14:12 -080080public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070081
82 private static final String LOG_TAG = "TelephonyShellCommand";
83 // Don't commit with this true.
84 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070085 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070086
Hall Liuaa4211e2021-01-20 15:43:39 -080087 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070088 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080089 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080090 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080091 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070092 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000093 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000094 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010095 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080096 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080097 private static final String ENABLE = "enable";
98 private static final String DISABLE = "disable";
99 private static final String QUERY = "query";
100
Hall Liu7135e502021-02-04 16:58:17 -0800101 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800102 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800103 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800104
Brad Ebinger999d3302020-11-25 14:31:39 -0800105 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
106 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
107 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700108 // Used to disable or enable processing of conference event package data from the network.
109 // This is handy for testing scenarios where CEP data does not exist on a network which does
110 // support CEP data.
111 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700112
Hall Liud892bec2018-11-30 14:51:45 -0800113 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800114 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800115
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100116 private static final String CC_GET_VALUE = "get-value";
117 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000118 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100119 private static final String CC_CLEAR_VALUES = "clear-values";
120
Hui Wang641e81c2020-10-12 12:14:23 -0700121 private static final String GBA_SUBCOMMAND = "gba";
122 private static final String GBA_SET_SERVICE = "set-service";
123 private static final String GBA_GET_SERVICE = "get-service";
124 private static final String GBA_SET_RELEASE_TIME = "set-release";
125 private static final String GBA_GET_RELEASE_TIME = "get-release";
126
Hui Wang761a6682020-10-31 05:12:53 +0000127 private static final String SINGLE_REGISTATION_CONFIG = "src";
128 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
129 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
130 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
131 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800132 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
133 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800134 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
135 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000136
Tyler Gunn92479152021-01-20 16:30:10 -0800137 private static final String D2D_SUBCOMMAND = "d2d";
138 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800139 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700140 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800141
Nazanin014f41e2021-05-06 17:26:31 -0700142 private static final String BARRING_SUBCOMMAND = "barring";
143 private static final String BARRING_SEND_INFO = "send";
144
James.cf Linbcdf8b32021-01-14 16:44:13 +0800145 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800146 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800147 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800148 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800149 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
150 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000151 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
152 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800153 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
154 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800155 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
156 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800157
jimsun3b9ccac2021-10-26 15:01:23 +0800158 private static final String RADIO_SUBCOMMAND = "radio";
159 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
160 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
161
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800162 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
163 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
164
Jordan Liu0ccee222021-04-27 11:55:13 -0700165 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
166 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
167
Jack Nudelman644b91a2021-03-12 14:09:48 -0800168 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
169 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
170 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
171
Grant Menke567d48f2022-08-18 20:19:10 +0000172 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
173 + "'*', '#' or '+') needs to be specified after -a in the command ";
174
175 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
176 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
177 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
178
SongFerngWang98dd5992021-05-13 17:50:00 +0800179 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
180 "get-allowed-network-types-for-users";
181 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
182 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000183 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000184 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700185 // Take advantage of existing methods that already contain permissions checks when possible.
186 private final ITelephony mInterface;
187
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100188 private SubscriptionManager mSubscriptionManager;
189 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700190 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700191 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100192
193 private enum CcType {
194 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000195 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100196 }
197
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100198 private class CcOptionParseResult {
199 public int mSubId;
200 public boolean mPersistent;
201 }
202
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100203 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
204 // keys by looking at the end of the string which usually tells the type.
205 // For instance: "xxxx_string", "xxxx_string_array", etc.
206 // The carrier config keys in this map does not follow this convention. It is therefore not
207 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700208 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
209 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
210 CcType.STRING),
211 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
212 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
213 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
214 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
215 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
216 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
217 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
218 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
219 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
220 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
221 CcType.STRING),
222 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
223 CcType.STRING_ARRAY),
224 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
225 CcType.STRING_ARRAY),
226 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
227 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
228 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
229 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
230 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
231 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
232 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
233 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100234
Brad Ebinger14d467f2021-02-12 06:18:28 +0000235 /**
236 * Map from a shorthand string to the feature tags required in registration required in order
237 * for the RCS feature to be considered "capable".
238 */
239 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
240 static {
241 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
242 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
243 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
244 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
245 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
246 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
247 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
248 FeatureTags.FEATURE_TAG_VIDEO)));
249 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
250 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
251 map.put("call_comp",
252 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
253 map.put("call_comp_mmtel",
254 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
255 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
256 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
257 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
258 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
259 // version
260 map.put("chatbot", new ArraySet<>(Arrays.asList(
261 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
262 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
263 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
264 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
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_sa", new ArraySet<>(Arrays.asList(
267 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
268 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
269 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
270 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000271 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000272 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
273 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
274 }
275
276
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100277 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700278 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100279 mCarrierConfigManager =
280 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
281 mSubscriptionManager = (SubscriptionManager)
282 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700283 mTelephonyRegistryManager = (TelephonyRegistryManager)
284 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700285 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700286 }
287
288 @Override
289 public int onCommand(String cmd) {
290 if (cmd == null) {
291 return handleDefaultCommands(null);
292 }
293
294 switch (cmd) {
295 case IMS_SUBCOMMAND: {
296 return handleImsCommand();
297 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800298 case RCS_UCE_COMMAND:
299 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800300 case NUMBER_VERIFICATION_SUBCOMMAND:
301 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800302 case EMERGENCY_CALLBACK_MODE:
303 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800304 case EMERGENCY_NUMBER_TEST_MODE:
305 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100306 case CARRIER_CONFIG_SUBCOMMAND: {
307 return handleCcCommand();
308 }
Shuo Qianf5125122019-12-16 17:03:07 -0800309 case DATA_TEST_MODE:
310 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700311 case END_BLOCK_SUPPRESSION:
312 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700313 case GBA_SUBCOMMAND:
314 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800315 case D2D_SUBCOMMAND:
316 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700317 case BARRING_SUBCOMMAND:
318 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000319 case SINGLE_REGISTATION_CONFIG:
320 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000321 case RESTART_MODEM:
322 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800323 case CALL_COMPOSER_SUBCOMMAND:
324 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000325 case UNATTENDED_REBOOT:
326 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800327 case HAS_CARRIER_PRIVILEGES_COMMAND:
328 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800329 case THERMAL_MITIGATION_COMMAND:
330 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700331 case DISABLE_PHYSICAL_SUBSCRIPTION:
332 return handleEnablePhysicalSubscription(false);
333 case ENABLE_PHYSICAL_SUBSCRIPTION:
334 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800335 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
336 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
337 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000338 case GET_IMEI:
339 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000340 case GET_SIM_SLOTS_MAPPING:
341 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800342 case RADIO_SUBCOMMAND:
343 return handleRadioCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700344 default: {
345 return handleDefaultCommands(cmd);
346 }
347 }
348 }
349
350 @Override
351 public void onHelp() {
352 PrintWriter pw = getOutPrintWriter();
353 pw.println("Telephony Commands:");
354 pw.println(" help");
355 pw.println(" Print this help text.");
356 pw.println(" ims");
357 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800358 pw.println(" uce");
359 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800360 pw.println(" emergency-number-test-mode");
361 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700362 pw.println(" end-block-suppression");
363 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800364 pw.println(" data");
365 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100366 pw.println(" cc");
367 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700368 pw.println(" gba");
369 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000370 pw.println(" src");
371 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000372 pw.println(" restart-modem");
373 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000374 pw.println(" unattended-reboot");
375 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800376 pw.println(" has-carrier-privileges [package]");
377 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800378 pw.println(" get-allowed-network-types-for-users");
379 pw.println(" Get the Allowed Network Types.");
380 pw.println(" set-allowed-network-types-for-users");
381 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800382 pw.println(" radio");
383 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700384 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800385 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800386 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700387 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800388 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100389 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700390 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000391 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800392 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700393 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800394 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800395 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000396 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800397 }
398
399 private void onHelpD2D() {
400 PrintWriter pw = getOutPrintWriter();
401 pw.println("D2D Comms Commands:");
402 pw.println(" d2d send TYPE VALUE");
403 pw.println(" Sends a D2D message of specified type and value.");
404 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
405 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
406 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
407 MESSAGE_CALL_AUDIO_CODEC));
408 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
409 + Communicator.messageToString(
410 MESSAGE_DEVICE_BATTERY_STATE));
411 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
412 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800413 pw.println(" d2d transport TYPE");
414 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
415 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700416 pw.println(" d2d set-device-support true/default");
417 pw.println(" true - forces device support to be enabled for D2D.");
418 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
419 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700420 }
421
Nazanin014f41e2021-05-06 17:26:31 -0700422 private void onHelpBarring() {
423 PrintWriter pw = getOutPrintWriter();
424 pw.println("Barring Commands:");
425 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
426 + " -t CONDITIONAL_BARRING_TIME_SECS");
427 pw.println(" Notifies of a barring info change for the specified slot id.");
428 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
429 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
430 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
431 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
432 }
433
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700434 private void onHelpIms() {
435 PrintWriter pw = getOutPrintWriter();
436 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800437 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700438 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
439 pw.println(" ImsService. Options are:");
440 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
441 pw.println(" is specified, it will choose the default voice SIM slot.");
442 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
443 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800444 pw.println(" -f: Set the feature that this override if for, if no option is");
445 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700446 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
447 pw.println(" Gets the package name of the currently defined ImsService.");
448 pw.println(" Options are:");
449 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
450 pw.println(" is specified, it will choose the default voice SIM slot.");
451 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000452 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800453 pw.println(" -f: The feature type that the query will be requested for. If none is");
454 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800455 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
456 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
457 pw.println(" configuration overrides. Options are:");
458 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
459 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700460 pw.println(" ims enable [-s SLOT_ID]");
461 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
462 pw.println(" if none is specified.");
463 pw.println(" ims disable [-s SLOT_ID]");
464 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
465 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700466 pw.println(" ims conference-event-package [enable/disable]");
467 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700468 }
469
James.cf Linbcdf8b32021-01-14 16:44:13 +0800470 private void onHelpUce() {
471 PrintWriter pw = getOutPrintWriter();
472 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800473 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
474 pw.println(" Get the EAB contacts from the EAB database.");
475 pw.println(" Options are:");
476 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
477 pw.println(" Expected output format :");
478 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800479 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
480 pw.println(" Remove the EAB contacts from the EAB database.");
481 pw.println(" Options are:");
482 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
483 pw.println(" is specified, it will choose the default voice SIM slot.");
484 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800485 pw.println(" uce get-device-enabled");
486 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
487 pw.println(" uce set-device-enabled true|false");
488 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
489 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000490 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
491 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
492 pw.println(" Options are:");
493 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
494 pw.println(" is specified, it will choose the default voice SIM slot.");
495 pw.println(" add [CAPABILITY]: add a new capability");
496 pw.println(" remove [CAPABILITY]: remove a capability");
497 pw.println(" clear: clear all capability overrides");
498 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
499 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
500 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
501 pw.println(" chatbot_sa, chatbot_role] as well as full length");
502 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
503 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
504 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
505 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800506 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
507 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800508 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
509 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800510 }
511
Hall Liud892bec2018-11-30 14:51:45 -0800512 private void onHelpNumberVerification() {
513 PrintWriter pw = getOutPrintWriter();
514 pw.println("Number verification commands");
515 pw.println(" numverify override-package PACKAGE_NAME;");
516 pw.println(" Set the authorized package for number verification.");
517 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800518 pw.println(" numverify fake-call NUMBER;");
519 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
520 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800521 }
522
Jack Nudelman644b91a2021-03-12 14:09:48 -0800523 private void onHelpThermalMitigation() {
524 PrintWriter pw = getOutPrintWriter();
525 pw.println("Thermal mitigation commands");
526 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
527 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
528 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
529 pw.println(" Remove the package from one of the authorized packages for thermal "
530 + "mitigation.");
531 }
532
Jordan Liu0ccee222021-04-27 11:55:13 -0700533 private void onHelpDisableOrEnablePhysicalSubscription() {
534 PrintWriter pw = getOutPrintWriter();
535 pw.println("Disable or enable a physical subscription");
536 pw.println(" disable-physical-subscription SUB_ID");
537 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
538 pw.println(" enable-physical-subscription SUB_ID");
539 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
540 }
541
Shuo Qianf5125122019-12-16 17:03:07 -0800542 private void onHelpDataTestMode() {
543 PrintWriter pw = getOutPrintWriter();
544 pw.println("Mobile Data Test Mode Commands:");
545 pw.println(" data enable: enable mobile data connectivity");
546 pw.println(" data disable: disable mobile data connectivity");
547 }
548
sqian9d4df8b2019-01-15 18:32:07 -0800549 private void onHelpEmergencyNumber() {
550 PrintWriter pw = getOutPrintWriter();
551 pw.println("Emergency Number Test Mode Commands:");
552 pw.println(" emergency-number-test-mode ");
553 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
554 + " the test mode");
555 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700556 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800557 pw.println(" -c: clear the emergency number list in the test mode.");
558 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700559 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800560 pw.println(" -p: get the full emergency number list in the test mode.");
561 }
562
Shuo Qian489d9282020-07-09 11:30:03 -0700563 private void onHelpEndBlockSupperssion() {
564 PrintWriter pw = getOutPrintWriter();
565 pw.println("End Block Suppression command:");
566 pw.println(" end-block-suppression: disable suppressing blocking by contact");
567 pw.println(" with emergency services.");
568 }
569
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100570 private void onHelpCc() {
571 PrintWriter pw = getOutPrintWriter();
572 pw.println("Carrier Config Commands:");
573 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
574 pw.println(" Print carrier config values.");
575 pw.println(" Options are:");
576 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
577 pw.println(" is specified, it will choose the default voice SIM slot.");
578 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
579 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100580 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100581 pw.println(" Set carrier config KEY to NEW_VALUE.");
582 pw.println(" Options are:");
583 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
584 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100585 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100586 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
587 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
588 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
589 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000590 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
591 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
592 pw.println(" provided through standard input and follow CarrierConfig XML format.");
593 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
594 pw.println(" Options are:");
595 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
596 pw.println(" is specified, it will choose the default voice SIM slot.");
597 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100598 pw.println(" cc clear-values [-s SLOT_ID]");
599 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000600 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100601 pw.println(" Options are:");
602 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
603 pw.println(" is specified, it will choose the default voice SIM slot.");
604 }
605
Hui Wang641e81c2020-10-12 12:14:23 -0700606 private void onHelpGba() {
607 PrintWriter pw = getOutPrintWriter();
608 pw.println("Gba Commands:");
609 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
610 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
611 pw.println(" Options are:");
612 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
613 pw.println(" is specified, it will choose the default voice SIM slot.");
614 pw.println(" gba get-service [-s SLOT_ID]");
615 pw.println(" Gets the package name of the currently defined GbaService.");
616 pw.println(" Options are:");
617 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
618 pw.println(" is specified, it will choose the default voice SIM slot.");
619 pw.println(" gba set-release [-s SLOT_ID] n");
620 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
621 pw.println(" Do not release/unbind if n is -1.");
622 pw.println(" Options are:");
623 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
624 pw.println(" is specified, it will choose the default voice SIM slot.");
625 pw.println(" gba get-release [-s SLOT_ID]");
626 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
627 pw.println(" Options are:");
628 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
629 pw.println(" is specified, it will choose the default voice SIM slot.");
630 }
631
Hui Wang761a6682020-10-31 05:12:53 +0000632 private void onHelpSrc() {
633 PrintWriter pw = getOutPrintWriter();
634 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800635 pw.println(" src set-test-enabled true|false");
636 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
637 pw.println(" The value could be true, false, or null(undefined).");
638 pw.println(" src get-test-enabled");
639 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000640 pw.println(" src set-device-enabled true|false|null");
641 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
642 pw.println(" The value could be true, false, or null(undefined).");
643 pw.println(" src get-device-enabled");
644 pw.println(" Gets the device config for RCS VoLTE single registration.");
645 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
646 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
647 pw.println(" The value could be true, false, or null(undefined).");
648 pw.println(" Options are:");
649 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
650 pw.println(" is specified, it will choose the default voice SIM slot.");
651 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
652 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
653 pw.println(" Options are:");
654 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
655 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800656 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
657 pw.println(" Sets ims feature validation result.");
658 pw.println(" The value could be true, false, or null(undefined).");
659 pw.println(" Options are:");
660 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
661 pw.println(" is specified, it will choose the default voice SIM slot.");
662 pw.println(" src get-feature-validation [-s SLOT_ID]");
663 pw.println(" Gets ims feature validation override value.");
664 pw.println(" Options are:");
665 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
666 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000667 }
668
SongFerngWang98dd5992021-05-13 17:50:00 +0800669 private void onHelpAllowedNetworkTypes() {
670 PrintWriter pw = getOutPrintWriter();
671 pw.println("Allowed Network Types Commands:");
672 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
673 pw.println(" Print allowed network types value.");
674 pw.println(" Options are:");
675 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
676 pw.println(" option is specified, it will choose the default voice SIM slot.");
677 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
678 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
679 pw.println(" Options are:");
680 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
681 pw.println(" option is specified, it will choose the default voice SIM slot.");
682 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
683 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
684 pw.println(" at TelephonyManager.java");
685 pw.println(" For example:");
686 pw.println(" NR only : 10000000000000000000");
687 pw.println(" NR|LTE : 11000001000000000000");
688 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
689 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
690 pw.println(" LTE only : 01000001000000000000");
691 }
692
jimsun3b9ccac2021-10-26 15:01:23 +0800693 private void onHelpRadio() {
694 PrintWriter pw = getOutPrintWriter();
695 pw.println("Radio Commands:");
696 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
697 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
698 pw.println(" to be the bound. Options are:");
699 pw.println(" -s: the service name that the modem service should be bound for.");
700 pw.println(" If no option is specified, it will bind to the default.");
701 pw.println(" radio get-modem-service");
702 pw.println(" Gets the service name of the currently defined modem service.");
703 pw.println(" If it is binding to default, 'default' returns.");
704 pw.println(" If it doesn't bind to any modem service for some reasons,");
705 pw.println(" the result would be 'unknown'.");
706 }
707
Ling Ma4fbab492022-01-25 22:36:16 +0000708 private void onHelpImei() {
709 PrintWriter pw = getOutPrintWriter();
710 pw.println("IMEI Commands:");
711 pw.println(" get-imei [-s SLOT_ID]");
712 pw.println(" Gets the device IMEI. Options are:");
713 pw.println(" -s: the slot ID to get the IMEI. If no option");
714 pw.println(" is specified, it will choose the default voice SIM slot.");
715 }
716
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700717 private int handleImsCommand() {
718 String arg = getNextArg();
719 if (arg == null) {
720 onHelpIms();
721 return 0;
722 }
723
724 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800725 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700726 return handleImsSetServiceCommand();
727 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800728 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700729 return handleImsGetServiceCommand();
730 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800731 case IMS_CLEAR_SERVICE_OVERRIDE: {
732 return handleImsClearCarrierServiceCommand();
733 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800734 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700735 return handleEnableIms();
736 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800737 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700738 return handleDisableIms();
739 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700740 case IMS_CEP: {
741 return handleCepChange();
742 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700743 }
744
745 return -1;
746 }
747
Shuo Qianf5125122019-12-16 17:03:07 -0800748 private int handleDataTestModeCommand() {
749 PrintWriter errPw = getErrPrintWriter();
750 String arg = getNextArgRequired();
751 if (arg == null) {
752 onHelpDataTestMode();
753 return 0;
754 }
755 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800756 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800757 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700758 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800759 } catch (RemoteException ex) {
760 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
761 errPw.println("Exception: " + ex.getMessage());
762 return -1;
763 }
764 break;
765 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800766 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800767 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700768 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800769 } catch (RemoteException ex) {
770 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
771 errPw.println("Exception: " + ex.getMessage());
772 return -1;
773 }
774 break;
775 }
776 default:
777 onHelpDataTestMode();
778 break;
779 }
780 return 0;
781 }
782
Shuo Qianccbaf742021-02-22 18:32:21 -0800783 private int handleEmergencyCallbackModeCommand() {
784 PrintWriter errPw = getErrPrintWriter();
785 try {
786 mInterface.startEmergencyCallbackMode();
787 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
788 } catch (RemoteException ex) {
789 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
790 errPw.println("Exception: " + ex.getMessage());
791 return -1;
792 }
793 return 0;
794 }
795
Grant Menke567d48f2022-08-18 20:19:10 +0000796 private void removeEmergencyNumberTestMode(String emergencyNumber) {
797 PrintWriter errPw = getErrPrintWriter();
798 for (int routingType : ROUTING_TYPES) {
799 try {
800 mInterface.updateEmergencyNumberListTestMode(
801 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
802 new EmergencyNumber(emergencyNumber, "", "",
803 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
804 new ArrayList<String>(),
805 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
806 routingType));
807 } catch (RemoteException ex) {
808 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
809 errPw.println("Exception: " + ex.getMessage());
810 }
811 }
812 }
813
sqian9d4df8b2019-01-15 18:32:07 -0800814 private int handleEmergencyNumberTestModeCommand() {
815 PrintWriter errPw = getErrPrintWriter();
816 String opt = getNextOption();
817 if (opt == null) {
818 onHelpEmergencyNumber();
819 return 0;
820 }
sqian9d4df8b2019-01-15 18:32:07 -0800821 switch (opt) {
822 case "-a": {
823 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000824 if (emergencyNumberCmd == null){
825 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800826 return -1;
827 }
Grant Menke567d48f2022-08-18 20:19:10 +0000828 String[] params = emergencyNumberCmd.split(":");
829 String emergencyNumber;
830 if (params[0] == null ||
831 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
832 errPw.println(INVALID_ENTRY_ERROR);
833 return -1;
834 } else {
835 emergencyNumber = params[0];
836 }
837 removeEmergencyNumberTestMode(emergencyNumber);
838 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
839 if (params.length > 1) {
840 switch (params[1].toLowerCase(Locale.ROOT)) {
841 case "emergency":
842 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
843 break;
844 case "normal":
845 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
846 break;
847 case "unknown":
848 break;
849 default:
850 errPw.println("\"" + params[1] + "\" is not a valid specification for "
851 + "emergency call routing. Please enter either \"normal\", "
852 + "\"unknown\", or \"emergency\" for call routing. "
853 + "(-a 1234:normal)");
854 return -1;
855 }
856 }
sqian9d4df8b2019-01-15 18:32:07 -0800857 try {
858 mInterface.updateEmergencyNumberListTestMode(
859 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +0000860 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -0800861 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
862 new ArrayList<String>(),
863 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +0000864 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -0800865 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +0000866 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -0800867 + ", error " + ex.getMessage());
868 errPw.println("Exception: " + ex.getMessage());
869 return -1;
870 }
871 break;
872 }
873 case "-c": {
874 try {
875 mInterface.updateEmergencyNumberListTestMode(
876 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
877 } catch (RemoteException ex) {
878 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
879 errPw.println("Exception: " + ex.getMessage());
880 return -1;
881 }
882 break;
883 }
884 case "-r": {
885 String emergencyNumberCmd = getNextArgRequired();
886 if (emergencyNumberCmd == null
887 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700888 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800889 + " to be specified after -r in the command ");
890 return -1;
891 }
Grant Menke567d48f2022-08-18 20:19:10 +0000892 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -0800893 break;
894 }
895 case "-p": {
896 try {
897 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
898 } catch (RemoteException ex) {
899 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
900 errPw.println("Exception: " + ex.getMessage());
901 return -1;
902 }
903 break;
904 }
905 default:
906 onHelpEmergencyNumber();
907 break;
908 }
909 return 0;
910 }
911
Hall Liud892bec2018-11-30 14:51:45 -0800912 private int handleNumberVerificationCommand() {
913 String arg = getNextArg();
914 if (arg == null) {
915 onHelpNumberVerification();
916 return 0;
917 }
918
Hall Liuca5af3a2018-12-04 16:58:23 -0800919 if (!checkShellUid()) {
920 return -1;
921 }
922
Hall Liud892bec2018-11-30 14:51:45 -0800923 switch (arg) {
924 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800925 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
926 return 0;
927 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800928 case NUMBER_VERIFICATION_FAKE_CALL: {
929 boolean val = NumberVerificationManager.getInstance()
930 .checkIncomingCall(getNextArg());
931 getOutPrintWriter().println(val ? "1" : "0");
932 return 0;
933 }
Hall Liud892bec2018-11-30 14:51:45 -0800934 }
935
936 return -1;
937 }
938
Jordan Liu0ccee222021-04-27 11:55:13 -0700939 private boolean subIsEsim(int subId) {
940 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
941 if (info != null) {
942 return info.isEmbedded();
943 }
944 return false;
945 }
946
947 private int handleEnablePhysicalSubscription(boolean enable) {
948 PrintWriter errPw = getErrPrintWriter();
949 int subId = 0;
950 try {
951 subId = Integer.parseInt(getNextArgRequired());
952 } catch (NumberFormatException e) {
953 errPw.println((enable ? "enable" : "disable")
954 + "-physical-subscription requires an integer as a subId.");
955 return -1;
956 }
957 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
958 // non user build.
959 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
960 errPw.println("cc: Permission denied.");
961 return -1;
962 }
963 // Verify that the subId represents a physical sub
964 if (subIsEsim(subId)) {
965 errPw.println("SubId " + subId + " is not for a physical subscription");
966 return -1;
967 }
968 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
969 + " physical subscription with subId=" + subId);
970 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
971 return 0;
972 }
973
Jack Nudelman644b91a2021-03-12 14:09:48 -0800974 private int handleThermalMitigationCommand() {
975 String arg = getNextArg();
976 String packageName = getNextArg();
977 if (arg == null || packageName == null) {
978 onHelpThermalMitigation();
979 return 0;
980 }
981
982 if (!checkShellUid()) {
983 return -1;
984 }
985
986 switch (arg) {
987 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
988 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
989 return 0;
990 }
991 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
992 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
993 mContext);
994 return 0;
995 }
996 default:
997 onHelpThermalMitigation();
998 }
999
1000 return -1;
1001
1002 }
1003
Tyler Gunn92479152021-01-20 16:30:10 -08001004 private int handleD2dCommand() {
1005 String arg = getNextArg();
1006 if (arg == null) {
1007 onHelpD2D();
1008 return 0;
1009 }
1010
1011 switch (arg) {
1012 case D2D_SEND: {
1013 return handleD2dSendCommand();
1014 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001015 case D2D_TRANSPORT: {
1016 return handleD2dTransportCommand();
1017 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001018 case D2D_SET_DEVICE_SUPPORT: {
1019 return handleD2dDeviceSupportedCommand();
1020 }
Tyler Gunn92479152021-01-20 16:30:10 -08001021 }
1022
1023 return -1;
1024 }
1025
1026 private int handleD2dSendCommand() {
1027 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001028 int messageType = -1;
1029 int messageValue = -1;
1030
Tyler Gunn92479152021-01-20 16:30:10 -08001031 String arg = getNextArg();
1032 if (arg == null) {
1033 onHelpD2D();
1034 return 0;
1035 }
1036 try {
1037 messageType = Integer.parseInt(arg);
1038 } catch (NumberFormatException e) {
1039 errPw.println("message type must be a valid integer");
1040 return -1;
1041 }
1042
1043 arg = getNextArg();
1044 if (arg == null) {
1045 onHelpD2D();
1046 return 0;
1047 }
1048 try {
1049 messageValue = Integer.parseInt(arg);
1050 } catch (NumberFormatException e) {
1051 errPw.println("message value must be a valid integer");
1052 return -1;
1053 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001054
Tyler Gunn92479152021-01-20 16:30:10 -08001055 try {
1056 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1057 } catch (RemoteException e) {
1058 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1059 errPw.println("Exception: " + e.getMessage());
1060 return -1;
1061 }
1062
1063 return 0;
1064 }
1065
Tyler Gunnbabbda02021-02-10 11:05:02 -08001066 private int handleD2dTransportCommand() {
1067 PrintWriter errPw = getErrPrintWriter();
1068
1069 String arg = getNextArg();
1070 if (arg == null) {
1071 onHelpD2D();
1072 return 0;
1073 }
1074
1075 try {
1076 mInterface.setActiveDeviceToDeviceTransport(arg);
1077 } catch (RemoteException e) {
1078 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1079 errPw.println("Exception: " + e.getMessage());
1080 return -1;
1081 }
1082 return 0;
1083 }
Nazanin014f41e2021-05-06 17:26:31 -07001084 private int handleBarringCommand() {
1085 String arg = getNextArg();
1086 if (arg == null) {
1087 onHelpBarring();
1088 return 0;
1089 }
1090
1091 switch (arg) {
1092 case BARRING_SEND_INFO: {
1093 return handleBarringSendCommand();
1094 }
1095 }
1096 return -1;
1097 }
1098
1099 private int handleBarringSendCommand() {
1100 PrintWriter errPw = getErrPrintWriter();
1101 int slotId = getDefaultSlot();
1102 int subId = SubscriptionManager.getSubId(slotId)[0];
1103 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1104 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1105 boolean isConditionallyBarred = false;
1106 int conditionalBarringTimeSeconds = 0;
1107
1108 String opt;
1109 while ((opt = getNextOption()) != null) {
1110 switch (opt) {
1111 case "-s": {
1112 try {
1113 slotId = Integer.parseInt(getNextArgRequired());
1114 subId = SubscriptionManager.getSubId(slotId)[0];
1115 } catch (NumberFormatException e) {
1116 errPw.println("barring send requires an integer as a SLOT_ID.");
1117 return -1;
1118 }
1119 break;
1120 }
1121 case "-b": {
1122 try {
1123 barringType = Integer.parseInt(getNextArgRequired());
1124 if (barringType < -1 || barringType > 2) {
1125 throw new NumberFormatException();
1126 }
1127
1128 } catch (NumberFormatException e) {
1129 errPw.println("barring send requires an integer in range [-1,2] as "
1130 + "a BARRING_TYPE.");
1131 return -1;
1132 }
1133 break;
1134 }
1135 case "-c": {
1136 try {
1137 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1138 } catch (Exception e) {
1139 errPw.println("barring send requires a boolean after -c indicating"
1140 + " conditional barring");
1141 return -1;
1142 }
1143 break;
1144 }
1145 case "-t": {
1146 try {
1147 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1148 } catch (NumberFormatException e) {
1149 errPw.println("barring send requires an integer for time of barring"
1150 + " in seconds after -t for conditional barring");
1151 return -1;
1152 }
1153 break;
1154 }
1155 }
1156 }
1157 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1158 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1159 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1160 barringServiceInfos.append(0, bsi);
1161 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1162 try {
1163 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1164 } catch (Exception e) {
1165 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1166 errPw.println("Exception: " + e.getMessage());
1167 return -1;
1168 }
1169 return 0;
1170 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001171
Tyler Gunnd4575212021-05-03 14:46:49 -07001172 private int handleD2dDeviceSupportedCommand() {
1173 PrintWriter errPw = getErrPrintWriter();
1174
1175 String arg = getNextArg();
1176 if (arg == null) {
1177 onHelpD2D();
1178 return 0;
1179 }
1180
Jack Yua533d632022-09-30 13:53:46 -07001181 boolean isEnabled = "true".equals(arg.toLowerCase(Locale.ROOT));
Tyler Gunnd4575212021-05-03 14:46:49 -07001182 try {
1183 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1184 } catch (RemoteException e) {
1185 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1186 errPw.println("Exception: " + e.getMessage());
1187 return -1;
1188 }
1189 return 0;
1190 }
1191
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001192 // ims set-ims-service
1193 private int handleImsSetServiceCommand() {
1194 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001195 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001196 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001197 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001198
1199 String opt;
1200 while ((opt = getNextOption()) != null) {
1201 switch (opt) {
1202 case "-s": {
1203 try {
1204 slotId = Integer.parseInt(getNextArgRequired());
1205 } catch (NumberFormatException e) {
1206 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1207 return -1;
1208 }
1209 break;
1210 }
1211 case "-c": {
1212 isCarrierService = true;
1213 break;
1214 }
1215 case "-d": {
1216 isCarrierService = false;
1217 break;
1218 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001219 case "-f": {
1220 String featureString = getNextArgRequired();
1221 String[] features = featureString.split(",");
1222 for (int i = 0; i < features.length; i++) {
1223 try {
1224 Integer result = Integer.parseInt(features[i]);
1225 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1226 || result >= ImsFeature.FEATURE_MAX) {
1227 errPw.println("ims set-ims-service -f " + result
1228 + " is an invalid feature.");
1229 return -1;
1230 }
1231 featuresList.add(result);
1232 } catch (NumberFormatException e) {
1233 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1234 + " as an integer.");
1235 return -1;
1236 }
1237 }
1238 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001239 }
1240 }
1241 // Mandatory param, either -c or -d
1242 if (isCarrierService == null) {
1243 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1244 return -1;
1245 }
1246
1247 String packageName = getNextArg();
1248
1249 try {
1250 if (packageName == null) {
1251 packageName = "";
1252 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001253 int[] featureArray = new int[featuresList.size()];
1254 for (int i = 0; i < featuresList.size(); i++) {
1255 featureArray[i] = featuresList.get(i);
1256 }
1257 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1258 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001259 if (VDBG) {
1260 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001261 + (isCarrierService ? "-c " : "-d ")
1262 + "-f " + featuresList + " "
1263 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001264 }
1265 getOutPrintWriter().println(result);
1266 } catch (RemoteException e) {
1267 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001268 + (isCarrierService ? "-c " : "-d ")
1269 + "-f " + featuresList + " "
1270 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001271 errPw.println("Exception: " + e.getMessage());
1272 return -1;
1273 }
1274 return 0;
1275 }
1276
Brad Ebinger999d3302020-11-25 14:31:39 -08001277 // ims clear-ims-service-override
1278 private int handleImsClearCarrierServiceCommand() {
1279 PrintWriter errPw = getErrPrintWriter();
1280 int slotId = getDefaultSlot();
1281
1282 String opt;
1283 while ((opt = getNextOption()) != null) {
1284 switch (opt) {
1285 case "-s": {
1286 try {
1287 slotId = Integer.parseInt(getNextArgRequired());
1288 } catch (NumberFormatException e) {
1289 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1290 return -1;
1291 }
1292 break;
1293 }
1294 }
1295 }
1296
1297 try {
1298 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1299 if (VDBG) {
1300 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1301 + ", result=" + result);
1302 }
1303 getOutPrintWriter().println(result);
1304 } catch (RemoteException e) {
1305 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1306 + ", error" + e.getMessage());
1307 errPw.println("Exception: " + e.getMessage());
1308 return -1;
1309 }
1310 return 0;
1311 }
1312
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001313 // ims get-ims-service
1314 private int handleImsGetServiceCommand() {
1315 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001316 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001317 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001318 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001319
1320 String opt;
1321 while ((opt = getNextOption()) != null) {
1322 switch (opt) {
1323 case "-s": {
1324 try {
1325 slotId = Integer.parseInt(getNextArgRequired());
1326 } catch (NumberFormatException e) {
1327 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1328 return -1;
1329 }
1330 break;
1331 }
1332 case "-c": {
1333 isCarrierService = true;
1334 break;
1335 }
1336 case "-d": {
1337 isCarrierService = false;
1338 break;
1339 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001340 case "-f": {
1341 try {
1342 featureType = Integer.parseInt(getNextArg());
1343 } catch (NumberFormatException e) {
1344 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1345 return -1;
1346 }
1347 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1348 || featureType >= ImsFeature.FEATURE_MAX) {
1349 errPw.println("ims get-ims-service -f invalid feature.");
1350 return -1;
1351 }
1352 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001353 }
1354 }
1355 // Mandatory param, either -c or -d
1356 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001357 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001358 return -1;
1359 }
1360
1361 String result;
1362 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001363 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001364 } catch (RemoteException e) {
1365 return -1;
1366 }
1367 if (VDBG) {
1368 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001369 + (isCarrierService ? "-c " : "-d ")
1370 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1371 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001372 }
1373 getOutPrintWriter().println(result);
1374 return 0;
1375 }
1376
1377 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001378 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001379 String opt;
1380 while ((opt = getNextOption()) != null) {
1381 switch (opt) {
1382 case "-s": {
1383 try {
1384 slotId = Integer.parseInt(getNextArgRequired());
1385 } catch (NumberFormatException e) {
1386 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1387 return -1;
1388 }
1389 break;
1390 }
1391 }
1392 }
1393 try {
1394 mInterface.enableIms(slotId);
1395 } catch (RemoteException e) {
1396 return -1;
1397 }
1398 if (VDBG) {
1399 Log.v(LOG_TAG, "ims enable -s " + slotId);
1400 }
1401 return 0;
1402 }
1403
1404 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001405 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001406 String opt;
1407 while ((opt = getNextOption()) != null) {
1408 switch (opt) {
1409 case "-s": {
1410 try {
1411 slotId = Integer.parseInt(getNextArgRequired());
1412 } catch (NumberFormatException e) {
1413 getErrPrintWriter().println(
1414 "ims disable requires an integer as a SLOT_ID.");
1415 return -1;
1416 }
1417 break;
1418 }
1419 }
1420 }
1421 try {
1422 mInterface.disableIms(slotId);
1423 } catch (RemoteException e) {
1424 return -1;
1425 }
1426 if (VDBG) {
1427 Log.v(LOG_TAG, "ims disable -s " + slotId);
1428 }
1429 return 0;
1430 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001431
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001432 private int handleCepChange() {
1433 Log.i(LOG_TAG, "handleCepChange");
1434 String opt = getNextArg();
1435 if (opt == null) {
1436 return -1;
1437 }
1438 boolean isCepEnabled = opt.equals("enable");
1439
1440 try {
1441 mInterface.setCepEnabled(isCepEnabled);
1442 } catch (RemoteException e) {
1443 return -1;
1444 }
1445 return 0;
1446 }
1447
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001448 private int getDefaultSlot() {
1449 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1450 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1451 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1452 // If there is no default, default to slot 0.
1453 slotId = DEFAULT_PHONE_ID;
1454 }
1455 return slotId;
1456 }
sqian2fff4a32018-11-05 14:18:37 -08001457
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001458 // Parse options related to Carrier Config Commands.
1459 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001460 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001461 CcOptionParseResult result = new CcOptionParseResult();
1462 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1463 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001464
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001465 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001466 while ((opt = getNextOption()) != null) {
1467 switch (opt) {
1468 case "-s": {
1469 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001470 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1471 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1472 errPw.println(tag + "No valid subscription found.");
1473 return null;
1474 }
1475
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001476 } catch (IllegalArgumentException e) {
1477 // Missing slot id
1478 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001479 return null;
1480 }
1481 break;
1482 }
1483 case "-p": {
1484 if (allowOptionPersistent) {
1485 result.mPersistent = true;
1486 } else {
1487 errPw.println(tag + "Unexpected option " + opt);
1488 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001489 }
1490 break;
1491 }
1492 default: {
1493 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001494 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001495 }
1496 }
1497 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001498 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001499 }
1500
1501 private int slotStringToSubId(String tag, String slotString) {
1502 int slotId = -1;
1503 try {
1504 slotId = Integer.parseInt(slotString);
1505 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001506 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1507 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1508 }
1509
1510 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001511 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1512 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1513 }
1514
Qiong Liuf25799b2020-09-10 10:13:46 +08001515 Phone phone = PhoneFactory.getPhone(slotId);
1516 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001517 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1518 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1519 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001520 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001521 }
1522
Hall Liud892bec2018-11-30 14:51:45 -08001523 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001524 // adb can run as root or as shell, depending on whether the device is rooted.
1525 return Binder.getCallingUid() == Process.SHELL_UID
1526 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001527 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001528
1529 private int handleCcCommand() {
1530 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1531 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001532 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001533 getErrPrintWriter().println("cc: Permission denied.");
1534 return -1;
1535 }
1536
1537 String arg = getNextArg();
1538 if (arg == null) {
1539 onHelpCc();
1540 return 0;
1541 }
1542
1543 switch (arg) {
1544 case CC_GET_VALUE: {
1545 return handleCcGetValue();
1546 }
1547 case CC_SET_VALUE: {
1548 return handleCcSetValue();
1549 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001550 case CC_SET_VALUES_FROM_XML: {
1551 return handleCcSetValuesFromXml();
1552 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001553 case CC_CLEAR_VALUES: {
1554 return handleCcClearValues();
1555 }
1556 default: {
1557 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1558 }
1559 }
1560 return -1;
1561 }
1562
1563 // cc get-value
1564 private int handleCcGetValue() {
1565 PrintWriter errPw = getErrPrintWriter();
1566 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1567 String key = null;
1568
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001569 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001570 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001571 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001572 return -1;
1573 }
1574
1575 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001576 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001577 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001578 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001579 return -1;
1580 }
1581
1582 // Get the key.
1583 key = getNextArg();
1584 if (key != null) {
1585 // A key was provided. Verify if it is a valid key
1586 if (!bundle.containsKey(key)) {
1587 errPw.println(tag + key + " is not a valid key.");
1588 return -1;
1589 }
1590
1591 // Print the carrier config value for key.
1592 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1593 } else {
1594 // No key provided. Show all values.
1595 // Iterate over a sorted list of all carrier config keys and print them.
1596 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1597 for (String k : sortedSet) {
1598 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1599 }
1600 }
1601 return 0;
1602 }
1603
1604 // cc set-value
1605 private int handleCcSetValue() {
1606 PrintWriter errPw = getErrPrintWriter();
1607 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1608
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001609 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001610 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001611 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001612 return -1;
1613 }
1614
1615 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001616 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001617 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001618 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001619 return -1;
1620 }
1621
1622 // Get the key.
1623 String key = getNextArg();
1624 if (key == null || key.equals("")) {
1625 errPw.println(tag + "KEY is missing");
1626 return -1;
1627 }
1628
1629 // Verify if the key is valid
1630 if (!originalValues.containsKey(key)) {
1631 errPw.println(tag + key + " is not a valid key.");
1632 return -1;
1633 }
1634
1635 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1636 ArrayList<String> valueList = new ArrayList<String>();
1637 while (peekNextArg() != null) {
1638 valueList.add(getNextArg());
1639 }
1640
1641 // Find the type of the carrier config value
1642 CcType type = getType(tag, key, originalValues);
1643 if (type == CcType.UNKNOWN) {
1644 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1645 return -1;
1646 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001647 if (type == CcType.PERSISTABLE_BUNDLE) {
1648 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1649 + "Use set-values-from-xml instead.");
1650 return -1;
1651 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001652
1653 // Create an override bundle containing the key and value that should be overriden.
1654 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1655 if (overrideBundle == null) {
1656 return -1;
1657 }
1658
1659 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001660 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001661
1662 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001663 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001664 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001665 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001666 return -1;
1667 }
1668
1669 // Print the original and new value.
1670 String originalValueString = ccValueToString(key, type, originalValues);
1671 String newValueString = ccValueToString(key, type, newValues);
1672 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1673 getOutPrintWriter().println("New value: \n" + newValueString);
1674
1675 return 0;
1676 }
1677
Allen Xuee00f0e2022-03-14 21:04:49 +00001678 // cc set-values-from-xml
1679 private int handleCcSetValuesFromXml() {
1680 PrintWriter errPw = getErrPrintWriter();
1681 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1682
1683 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001684 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001685 if (options == null) {
1686 return -1;
1687 }
1688
1689 // Get bundle containing all current carrier configuration values.
1690 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1691 if (originalValues == null) {
1692 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1693 return -1;
1694 }
1695
1696 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1697 if (overrideBundle == null) {
1698 return -1;
1699 }
1700
1701 // Verify all values are valid types
1702 for (String key : overrideBundle.keySet()) {
1703 CcType type = getType(tag, key, originalValues);
1704 if (type == CcType.UNKNOWN) {
1705 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1706 return -1;
1707 }
1708 }
1709
1710 // Override the value
1711 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1712
1713 // Find bundle containing all new carrier configuration values after the override.
1714 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1715 if (newValues == null) {
1716 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1717 return -1;
1718 }
1719
1720 // Print the original and new values
1721 overrideBundle.keySet().forEach(key -> {
1722 CcType type = getType(tag, key, originalValues);
1723 String originalValueString = ccValueToString(key, type, originalValues);
1724 String newValueString = ccValueToString(key, type, newValues);
1725 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1726 getOutPrintWriter().println("New value: \n" + newValueString);
1727 });
1728
1729 return 0;
1730 }
1731
1732 private PersistableBundle readPersistableBundleFromXml(String tag) {
1733 PersistableBundle subIdBundles;
1734 try {
1735 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1736 } catch (IOException | RuntimeException e) {
1737 PrintWriter errPw = getErrPrintWriter();
1738 errPw.println(tag + e);
1739 return null;
1740 }
1741
1742 return subIdBundles;
1743 }
1744
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001745 // cc clear-values
1746 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001747 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1748
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001749 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001750 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001751 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001752 return -1;
1753 }
1754
1755 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001756 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001757 getOutPrintWriter()
1758 .println("All previously set carrier config override values has been cleared");
1759 return 0;
1760 }
1761
1762 private CcType getType(String tag, String key, PersistableBundle bundle) {
1763 // Find the type by checking the type of the current value stored in the bundle.
1764 Object value = bundle.get(key);
1765
1766 if (CC_TYPE_MAP.containsKey(key)) {
1767 return CC_TYPE_MAP.get(key);
1768 } else if (value != null) {
1769 if (value instanceof Boolean) {
1770 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001771 }
1772 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001773 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001774 }
1775 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001776 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001777 }
1778 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001779 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001780 }
1781 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001782 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001783 }
1784 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001785 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001786 }
1787 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001788 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001789 }
1790 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001791 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001792 }
1793 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001794 return CcType.STRING_ARRAY;
1795 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001796 if (value instanceof PersistableBundle) {
1797 return CcType.PERSISTABLE_BUNDLE;
1798 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001799 } else {
1800 // Current value was null and can therefore not be used in order to find the type.
1801 // Check the name of the key to infer the type. This check is not needed for primitive
1802 // data types (boolean, double, int and long), since they can not be null.
1803 if (key.endsWith("double_array")) {
1804 return CcType.DOUBLE_ARRAY;
1805 }
1806 if (key.endsWith("int_array")) {
1807 return CcType.INT_ARRAY;
1808 }
1809 if (key.endsWith("long_array")) {
1810 return CcType.LONG_ARRAY;
1811 }
1812 if (key.endsWith("string")) {
1813 return CcType.STRING;
1814 }
1815 if (key.endsWith("string_array") || key.endsWith("strings")) {
1816 return CcType.STRING_ARRAY;
1817 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001818 if (key.endsWith("bundle")) {
1819 return CcType.PERSISTABLE_BUNDLE;
1820 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001821 }
1822
1823 // Not possible to infer the type by looking at the current value or the key.
1824 PrintWriter errPw = getErrPrintWriter();
1825 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1826 return CcType.UNKNOWN;
1827 }
1828
1829 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1830 String result;
1831 StringBuilder valueString = new StringBuilder();
1832 String typeString = type.toString();
1833 Object value = bundle.get(key);
1834
1835 if (value == null) {
1836 valueString.append("null");
1837 } else {
1838 switch (type) {
1839 case DOUBLE_ARRAY: {
1840 // Format the string representation of the int array as value1 value2......
1841 double[] valueArray = (double[]) value;
1842 for (int i = 0; i < valueArray.length; i++) {
1843 if (i != 0) {
1844 valueString.append(" ");
1845 }
1846 valueString.append(valueArray[i]);
1847 }
1848 break;
1849 }
1850 case INT_ARRAY: {
1851 // Format the string representation of the int array as value1 value2......
1852 int[] valueArray = (int[]) value;
1853 for (int i = 0; i < valueArray.length; i++) {
1854 if (i != 0) {
1855 valueString.append(" ");
1856 }
1857 valueString.append(valueArray[i]);
1858 }
1859 break;
1860 }
1861 case LONG_ARRAY: {
1862 // Format the string representation of the int array as value1 value2......
1863 long[] valueArray = (long[]) value;
1864 for (int i = 0; i < valueArray.length; i++) {
1865 if (i != 0) {
1866 valueString.append(" ");
1867 }
1868 valueString.append(valueArray[i]);
1869 }
1870 break;
1871 }
1872 case STRING: {
1873 valueString.append("\"" + value.toString() + "\"");
1874 break;
1875 }
1876 case STRING_ARRAY: {
1877 // Format the string representation of the string array as "value1" "value2"....
1878 String[] valueArray = (String[]) value;
1879 for (int i = 0; i < valueArray.length; i++) {
1880 if (i != 0) {
1881 valueString.append(" ");
1882 }
1883 if (valueArray[i] != null) {
1884 valueString.append("\"" + valueArray[i] + "\"");
1885 } else {
1886 valueString.append("null");
1887 }
1888 }
1889 break;
1890 }
1891 default: {
1892 valueString.append(value.toString());
1893 }
1894 }
1895 }
1896 return String.format("%-70s %-15s %s", key, typeString, valueString);
1897 }
1898
1899 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1900 ArrayList<String> valueList) {
1901 PrintWriter errPw = getErrPrintWriter();
1902 PersistableBundle bundle = new PersistableBundle();
1903
1904 // First verify that a valid number of values has been provided for the type.
1905 switch (type) {
1906 case BOOLEAN:
1907 case DOUBLE:
1908 case INT:
1909 case LONG: {
1910 if (valueList.size() != 1) {
1911 errPw.println(tag + "Expected 1 value for type " + type
1912 + ". Found: " + valueList.size());
1913 return null;
1914 }
1915 break;
1916 }
1917 case STRING: {
1918 if (valueList.size() > 1) {
1919 errPw.println(tag + "Expected 0 or 1 values for type " + type
1920 + ". Found: " + valueList.size());
1921 return null;
1922 }
1923 break;
1924 }
1925 }
1926
1927 // Parse the value according to type and add it to the Bundle.
1928 switch (type) {
1929 case BOOLEAN: {
1930 if ("true".equalsIgnoreCase(valueList.get(0))) {
1931 bundle.putBoolean(key, true);
1932 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1933 bundle.putBoolean(key, false);
1934 } else {
1935 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1936 return null;
1937 }
1938 break;
1939 }
1940 case DOUBLE: {
1941 try {
1942 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1943 } catch (NumberFormatException nfe) {
1944 // Not a valid double
1945 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1946 return null;
1947 }
1948 break;
1949 }
1950 case DOUBLE_ARRAY: {
1951 double[] valueDoubleArray = null;
1952 if (valueList.size() > 0) {
1953 valueDoubleArray = new double[valueList.size()];
1954 for (int i = 0; i < valueList.size(); i++) {
1955 try {
1956 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1957 } catch (NumberFormatException nfe) {
1958 // Not a valid double
1959 errPw.println(
1960 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1961 return null;
1962 }
1963 }
1964 }
1965 bundle.putDoubleArray(key, valueDoubleArray);
1966 break;
1967 }
1968 case INT: {
1969 try {
1970 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1971 } catch (NumberFormatException nfe) {
1972 // Not a valid integer
1973 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1974 return null;
1975 }
1976 break;
1977 }
1978 case INT_ARRAY: {
1979 int[] valueIntArray = null;
1980 if (valueList.size() > 0) {
1981 valueIntArray = new int[valueList.size()];
1982 for (int i = 0; i < valueList.size(); i++) {
1983 try {
1984 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1985 } catch (NumberFormatException nfe) {
1986 // Not a valid integer
1987 errPw.println(tag
1988 + "Unable to parse " + valueList.get(i) + " as an integer.");
1989 return null;
1990 }
1991 }
1992 }
1993 bundle.putIntArray(key, valueIntArray);
1994 break;
1995 }
1996 case LONG: {
1997 try {
1998 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1999 } catch (NumberFormatException nfe) {
2000 // Not a valid long
2001 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2002 return null;
2003 }
2004 break;
2005 }
2006 case LONG_ARRAY: {
2007 long[] valueLongArray = null;
2008 if (valueList.size() > 0) {
2009 valueLongArray = new long[valueList.size()];
2010 for (int i = 0; i < valueList.size(); i++) {
2011 try {
2012 valueLongArray[i] = Long.parseLong(valueList.get(i));
2013 } catch (NumberFormatException nfe) {
2014 // Not a valid long
2015 errPw.println(
2016 tag + "Unable to parse " + valueList.get(i) + " as a long");
2017 return null;
2018 }
2019 }
2020 }
2021 bundle.putLongArray(key, valueLongArray);
2022 break;
2023 }
2024 case STRING: {
2025 String value = null;
2026 if (valueList.size() > 0) {
2027 value = valueList.get(0);
2028 }
2029 bundle.putString(key, value);
2030 break;
2031 }
2032 case STRING_ARRAY: {
2033 String[] valueStringArray = null;
2034 if (valueList.size() > 0) {
2035 valueStringArray = new String[valueList.size()];
2036 valueList.toArray(valueStringArray);
2037 }
2038 bundle.putStringArray(key, valueStringArray);
2039 break;
2040 }
2041 }
2042 return bundle;
2043 }
Shuo Qian489d9282020-07-09 11:30:03 -07002044
2045 private int handleEndBlockSuppressionCommand() {
2046 if (!checkShellUid()) {
2047 return -1;
2048 }
2049
2050 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2051 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2052 }
2053 return 0;
2054 }
Hui Wang641e81c2020-10-12 12:14:23 -07002055
Michele Berionne54af4632020-12-28 20:23:16 +00002056 private int handleRestartModemCommand() {
2057 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2058 // non user build.
2059 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2060 getErrPrintWriter().println("RestartModem: Permission denied.");
2061 return -1;
2062 }
2063
2064 boolean result = TelephonyManager.getDefault().rebootRadio();
2065 getOutPrintWriter().println(result);
2066
2067 return result ? 0 : -1;
2068 }
2069
Ling Ma4fbab492022-01-25 22:36:16 +00002070 private int handleGetImei() {
2071 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2072 // non user build.
2073 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2074 getErrPrintWriter().println("Device IMEI: Permission denied.");
2075 return -1;
2076 }
2077
2078 final long identity = Binder.clearCallingIdentity();
2079
2080 String imei = null;
2081 String arg = getNextArg();
2082 if (arg != null) {
2083 try {
2084 int specifiedSlotIndex = Integer.parseInt(arg);
2085 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2086 } catch (NumberFormatException exception) {
2087 PrintWriter errPw = getErrPrintWriter();
2088 errPw.println("-s requires an integer as slot index.");
2089 return -1;
2090 }
2091
2092 } else {
2093 imei = TelephonyManager.from(mContext).getImei();
2094 }
2095 getOutPrintWriter().println("Device IMEI: " + imei);
2096
2097 Binder.restoreCallingIdentity(identity);
2098 return 0;
2099 }
2100
Michele Berionne5e411512020-11-13 02:36:59 +00002101 private int handleUnattendedReboot() {
2102 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2103 // non user build.
2104 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2105 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2106 return -1;
2107 }
2108
2109 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2110 getOutPrintWriter().println("result: " + result);
2111
2112 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2113 }
2114
Aman Gupta07124872022-02-09 08:02:14 +00002115 private int handleGetSimSlotsMapping() {
2116 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2117 // non user build.
2118 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2119 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2120 return -1;
2121 }
2122 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2123 String result = telephonyManager.getSimSlotMapping().toString();
2124 getOutPrintWriter().println("simSlotsMapping: " + result);
2125
2126 return 0;
2127 }
2128
Hui Wang641e81c2020-10-12 12:14:23 -07002129 private int handleGbaCommand() {
2130 String arg = getNextArg();
2131 if (arg == null) {
2132 onHelpGba();
2133 return 0;
2134 }
2135
2136 switch (arg) {
2137 case GBA_SET_SERVICE: {
2138 return handleGbaSetServiceCommand();
2139 }
2140 case GBA_GET_SERVICE: {
2141 return handleGbaGetServiceCommand();
2142 }
2143 case GBA_SET_RELEASE_TIME: {
2144 return handleGbaSetReleaseCommand();
2145 }
2146 case GBA_GET_RELEASE_TIME: {
2147 return handleGbaGetReleaseCommand();
2148 }
2149 }
2150
2151 return -1;
2152 }
2153
2154 private int getSubId(String cmd) {
2155 int slotId = getDefaultSlot();
2156 String opt = getNextOption();
2157 if (opt != null && opt.equals("-s")) {
2158 try {
2159 slotId = Integer.parseInt(getNextArgRequired());
2160 } catch (NumberFormatException e) {
2161 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2162 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2163 }
2164 }
2165 int[] subIds = SubscriptionManager.getSubId(slotId);
2166 return subIds[0];
2167 }
2168
2169 private int handleGbaSetServiceCommand() {
2170 int subId = getSubId("gba set-service");
2171 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2172 return -1;
2173 }
2174
2175 String packageName = getNextArg();
2176 try {
2177 if (packageName == null) {
2178 packageName = "";
2179 }
2180 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2181 if (VDBG) {
2182 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2183 + packageName + ", result=" + result);
2184 }
2185 getOutPrintWriter().println(result);
2186 } catch (RemoteException e) {
2187 Log.w(LOG_TAG, "gba set-service " + subId + " "
2188 + packageName + ", error" + e.getMessage());
2189 getErrPrintWriter().println("Exception: " + e.getMessage());
2190 return -1;
2191 }
2192 return 0;
2193 }
2194
2195 private int handleGbaGetServiceCommand() {
2196 String result;
2197
2198 int subId = getSubId("gba get-service");
2199 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2200 return -1;
2201 }
2202
2203 try {
2204 result = mInterface.getBoundGbaService(subId);
2205 } catch (RemoteException e) {
2206 return -1;
2207 }
2208 if (VDBG) {
2209 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2210 }
2211 getOutPrintWriter().println(result);
2212 return 0;
2213 }
2214
2215 private int handleGbaSetReleaseCommand() {
2216 //the release time value could be -1
2217 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2218 : SubscriptionManager.getDefaultSubscriptionId();
2219 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2220 return -1;
2221 }
2222
2223 String intervalStr = getNextArg();
2224 if (intervalStr == null) {
2225 return -1;
2226 }
2227
2228 try {
2229 int interval = Integer.parseInt(intervalStr);
2230 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2231 if (VDBG) {
2232 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2233 + intervalStr + ", result=" + result);
2234 }
2235 getOutPrintWriter().println(result);
2236 } catch (NumberFormatException | RemoteException e) {
2237 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2238 + intervalStr + ", error" + e.getMessage());
2239 getErrPrintWriter().println("Exception: " + e.getMessage());
2240 return -1;
2241 }
2242 return 0;
2243 }
2244
2245 private int handleGbaGetReleaseCommand() {
2246 int subId = getSubId("gba get-release");
2247 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2248 return -1;
2249 }
2250
2251 int result = 0;
2252 try {
2253 result = mInterface.getGbaReleaseTime(subId);
2254 } catch (RemoteException e) {
2255 return -1;
2256 }
2257 if (VDBG) {
2258 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2259 }
2260 getOutPrintWriter().println(result);
2261 return 0;
2262 }
Hui Wang761a6682020-10-31 05:12:53 +00002263
2264 private int handleSingleRegistrationConfigCommand() {
2265 String arg = getNextArg();
2266 if (arg == null) {
2267 onHelpSrc();
2268 return 0;
2269 }
2270
2271 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002272 case SRC_SET_TEST_ENABLED: {
2273 return handleSrcSetTestEnabledCommand();
2274 }
2275 case SRC_GET_TEST_ENABLED: {
2276 return handleSrcGetTestEnabledCommand();
2277 }
Hui Wang761a6682020-10-31 05:12:53 +00002278 case SRC_SET_DEVICE_ENABLED: {
2279 return handleSrcSetDeviceEnabledCommand();
2280 }
2281 case SRC_GET_DEVICE_ENABLED: {
2282 return handleSrcGetDeviceEnabledCommand();
2283 }
2284 case SRC_SET_CARRIER_ENABLED: {
2285 return handleSrcSetCarrierEnabledCommand();
2286 }
2287 case SRC_GET_CARRIER_ENABLED: {
2288 return handleSrcGetCarrierEnabledCommand();
2289 }
Hui Wangb647abe2021-02-26 09:33:38 -08002290 case SRC_SET_FEATURE_ENABLED: {
2291 return handleSrcSetFeatureValidationCommand();
2292 }
2293 case SRC_GET_FEATURE_ENABLED: {
2294 return handleSrcGetFeatureValidationCommand();
2295 }
Hui Wang761a6682020-10-31 05:12:53 +00002296 }
2297
2298 return -1;
2299 }
2300
James.cf Linbcdf8b32021-01-14 16:44:13 +08002301 private int handleRcsUceCommand() {
2302 String arg = getNextArg();
2303 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002304 onHelpUce();
2305 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002306 }
2307
2308 switch (arg) {
2309 case UCE_REMOVE_EAB_CONTACT:
2310 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002311 case UCE_GET_EAB_CONTACT:
2312 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002313 case UCE_GET_EAB_CAPABILITY:
2314 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002315 case UCE_GET_DEVICE_ENABLED:
2316 return handleUceGetDeviceEnabledCommand();
2317 case UCE_SET_DEVICE_ENABLED:
2318 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002319 case UCE_OVERRIDE_PUBLISH_CAPS:
2320 return handleUceOverridePublishCaps();
2321 case UCE_GET_LAST_PIDF_XML:
2322 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002323 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2324 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002325 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2326 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002327 }
2328 return -1;
2329 }
2330
2331 private int handleRemovingEabContactCommand() {
2332 int subId = getSubId("uce remove-eab-contact");
2333 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2334 return -1;
2335 }
2336
2337 String phoneNumber = getNextArgRequired();
2338 if (TextUtils.isEmpty(phoneNumber)) {
2339 return -1;
2340 }
2341 int result = 0;
2342 try {
2343 result = mInterface.removeContactFromEab(subId, phoneNumber);
2344 } catch (RemoteException e) {
2345 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2346 getErrPrintWriter().println("Exception: " + e.getMessage());
2347 return -1;
2348 }
2349
2350 if (VDBG) {
2351 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2352 }
calvinpan293ea1b2021-02-04 17:52:13 +08002353 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002354 }
2355
calvinpane4a8a1d2021-01-25 13:51:18 +08002356 private int handleGettingEabContactCommand() {
2357 String phoneNumber = getNextArgRequired();
2358 if (TextUtils.isEmpty(phoneNumber)) {
2359 return -1;
2360 }
2361 String result = "";
2362 try {
2363 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002364 } catch (RemoteException e) {
2365 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2366 getErrPrintWriter().println("Exception: " + e.getMessage());
2367 return -1;
2368 }
2369
2370 if (VDBG) {
2371 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2372 }
calvinpan293ea1b2021-02-04 17:52:13 +08002373 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002374 return 0;
2375 }
2376
Calvin Pana1434322021-07-01 19:27:01 +08002377 private int handleGettingEabCapabilityCommand() {
2378 String phoneNumber = getNextArgRequired();
2379 if (TextUtils.isEmpty(phoneNumber)) {
2380 return -1;
2381 }
2382 String result = "";
2383 try {
2384 result = mInterface.getCapabilityFromEab(phoneNumber);
2385 } catch (RemoteException e) {
2386 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2387 getErrPrintWriter().println("Exception: " + e.getMessage());
2388 return -1;
2389 }
2390
2391 if (VDBG) {
2392 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2393 }
2394 getOutPrintWriter().println(result);
2395 return 0;
2396 }
2397
James.cf Lin4b784aa2021-01-31 03:25:15 +08002398 private int handleUceGetDeviceEnabledCommand() {
2399 boolean result = false;
2400 try {
2401 result = mInterface.getDeviceUceEnabled();
2402 } catch (RemoteException e) {
2403 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2404 return -1;
2405 }
2406 if (VDBG) {
2407 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2408 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002409 getOutPrintWriter().println(result);
2410 return 0;
2411 }
2412
James.cf Lin4b784aa2021-01-31 03:25:15 +08002413 private int handleUceSetDeviceEnabledCommand() {
2414 String enabledStr = getNextArg();
2415 if (TextUtils.isEmpty(enabledStr)) {
2416 return -1;
2417 }
2418
2419 try {
2420 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2421 mInterface.setDeviceUceEnabled(isEnabled);
2422 if (VDBG) {
2423 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2424 }
2425 } catch (NumberFormatException | RemoteException e) {
2426 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2427 getErrPrintWriter().println("Exception: " + e.getMessage());
2428 return -1;
2429 }
2430 return 0;
2431 }
2432
James.cf Line8713a42021-04-29 16:04:26 +08002433 private int handleUceRemoveRequestDisallowedStatus() {
2434 int subId = getSubId("uce remove-request-disallowed-status");
2435 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2436 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2437 return -1;
2438 }
2439 boolean result;
2440 try {
2441 result = mInterface.removeUceRequestDisallowedStatus(subId);
2442 } catch (RemoteException e) {
2443 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2444 return -1;
2445 }
2446 if (VDBG) {
2447 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2448 }
2449 getOutPrintWriter().println(result);
2450 return 0;
2451 }
2452
James.cf Lin0fc71b02021-05-25 01:37:38 +08002453 private int handleUceSetCapRequestTimeout() {
2454 int subId = getSubId("uce set-capabilities-request-timeout");
2455 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2456 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2457 return -1;
2458 }
2459 long timeoutAfterMs = Long.valueOf(getNextArg());
2460 boolean result;
2461 try {
2462 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2463 } catch (RemoteException e) {
2464 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2465 return -1;
2466 }
2467 if (VDBG) {
2468 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2469 }
2470 getOutPrintWriter().println(result);
2471 return 0;
2472 }
2473
Hui Wangbaaee6a2021-02-19 20:45:36 -08002474 private int handleSrcSetTestEnabledCommand() {
2475 String enabledStr = getNextArg();
2476 if (enabledStr == null) {
2477 return -1;
2478 }
2479
2480 try {
2481 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2482 if (VDBG) {
2483 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2484 }
2485 getOutPrintWriter().println("Done");
2486 } catch (NumberFormatException | RemoteException e) {
2487 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2488 getErrPrintWriter().println("Exception: " + e.getMessage());
2489 return -1;
2490 }
2491 return 0;
2492 }
2493
2494 private int handleSrcGetTestEnabledCommand() {
2495 boolean result = false;
2496 try {
2497 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2498 } catch (RemoteException e) {
2499 return -1;
2500 }
2501 if (VDBG) {
2502 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2503 }
2504 getOutPrintWriter().println(result);
2505 return 0;
2506 }
2507
Brad Ebinger14d467f2021-02-12 06:18:28 +00002508 private int handleUceOverridePublishCaps() {
2509 int subId = getSubId("uce override-published-caps");
2510 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2511 return -1;
2512 }
2513 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2514 String operation = getNextArgRequired();
2515 String caps = getNextArg();
2516 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2517 && !"list".equals(operation)) {
2518 getErrPrintWriter().println("Invalid operation: " + operation);
2519 return -1;
2520 }
2521
2522 // add/remove requires capabilities to be specified.
2523 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2524 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2525 + "specified");
2526 return -1;
2527 }
2528
2529 ArraySet<String> capSet = new ArraySet<>();
2530 if (!TextUtils.isEmpty(caps)) {
2531 String[] capArray = caps.split(":");
2532 for (String cap : capArray) {
2533 // Allow unknown tags to be passed in as well.
2534 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2535 }
2536 }
2537
2538 RcsContactUceCapability result = null;
2539 try {
2540 switch (operation) {
2541 case "add":
2542 result = mInterface.addUceRegistrationOverrideShell(subId,
2543 new ArrayList<>(capSet));
2544 break;
2545 case "remove":
2546 result = mInterface.removeUceRegistrationOverrideShell(subId,
2547 new ArrayList<>(capSet));
2548 break;
2549 case "clear":
2550 result = mInterface.clearUceRegistrationOverrideShell(subId);
2551 break;
2552 case "list":
2553 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2554 break;
2555 }
2556 } catch (RemoteException e) {
2557 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2558 getErrPrintWriter().println("Exception: " + e.getMessage());
2559 return -1;
2560 } catch (ServiceSpecificException sse) {
2561 // Reconstruct ImsException
2562 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2563 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2564 getErrPrintWriter().println("Exception: " + imsException);
2565 return -1;
2566 }
2567 if (result == null) {
2568 getErrPrintWriter().println("Service not available");
2569 return -1;
2570 }
2571 getOutPrintWriter().println(result);
2572 return 0;
2573 }
2574
2575 private int handleUceGetPidfXml() {
2576 int subId = getSubId("uce get-last-publish-pidf");
2577 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2578 return -1;
2579 }
2580
2581 String result;
2582 try {
2583 result = mInterface.getLastUcePidfXmlShell(subId);
2584 } catch (RemoteException e) {
2585 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2586 getErrPrintWriter().println("Exception: " + e.getMessage());
2587 return -1;
2588 } catch (ServiceSpecificException sse) {
2589 // Reconstruct ImsException
2590 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2591 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2592 getErrPrintWriter().println("Exception: " + imsException);
2593 return -1;
2594 }
2595 if (result == null) {
2596 getErrPrintWriter().println("Service not available");
2597 return -1;
2598 }
2599 getOutPrintWriter().println(result);
2600 return 0;
2601 }
2602
Hui Wang761a6682020-10-31 05:12:53 +00002603 private int handleSrcSetDeviceEnabledCommand() {
2604 String enabledStr = getNextArg();
2605 if (enabledStr == null) {
2606 return -1;
2607 }
2608
2609 try {
2610 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2611 if (VDBG) {
2612 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2613 }
2614 getOutPrintWriter().println("Done");
2615 } catch (NumberFormatException | RemoteException e) {
2616 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2617 getErrPrintWriter().println("Exception: " + e.getMessage());
2618 return -1;
2619 }
2620 return 0;
2621 }
2622
2623 private int handleSrcGetDeviceEnabledCommand() {
2624 boolean result = false;
2625 try {
2626 result = mInterface.getDeviceSingleRegistrationEnabled();
2627 } catch (RemoteException e) {
2628 return -1;
2629 }
2630 if (VDBG) {
2631 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2632 }
2633 getOutPrintWriter().println(result);
2634 return 0;
2635 }
2636
2637 private int handleSrcSetCarrierEnabledCommand() {
2638 //the release time value could be -1
2639 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2640 : SubscriptionManager.getDefaultSubscriptionId();
2641 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2642 return -1;
2643 }
2644
2645 String enabledStr = getNextArg();
2646 if (enabledStr == null) {
2647 return -1;
2648 }
2649
2650 try {
2651 boolean result =
2652 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2653 if (VDBG) {
2654 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2655 + enabledStr + ", result=" + result);
2656 }
2657 getOutPrintWriter().println(result);
2658 } catch (NumberFormatException | RemoteException e) {
2659 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2660 + enabledStr + ", error" + e.getMessage());
2661 getErrPrintWriter().println("Exception: " + e.getMessage());
2662 return -1;
2663 }
2664 return 0;
2665 }
2666
2667 private int handleSrcGetCarrierEnabledCommand() {
2668 int subId = getSubId("src get-carrier-enabled");
2669 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2670 return -1;
2671 }
2672
2673 boolean result = false;
2674 try {
2675 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2676 } catch (RemoteException e) {
2677 return -1;
2678 }
2679 if (VDBG) {
2680 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2681 }
2682 getOutPrintWriter().println(result);
2683 return 0;
2684 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002685
Hui Wangb647abe2021-02-26 09:33:38 -08002686 private int handleSrcSetFeatureValidationCommand() {
2687 //the release time value could be -1
2688 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2689 : SubscriptionManager.getDefaultSubscriptionId();
2690 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2691 return -1;
2692 }
2693
2694 String enabledStr = getNextArg();
2695 if (enabledStr == null) {
2696 return -1;
2697 }
2698
2699 try {
2700 boolean result =
2701 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2702 if (VDBG) {
2703 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2704 + enabledStr + ", result=" + result);
2705 }
2706 getOutPrintWriter().println(result);
2707 } catch (NumberFormatException | RemoteException e) {
2708 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2709 + enabledStr + ", error" + e.getMessage());
2710 getErrPrintWriter().println("Exception: " + e.getMessage());
2711 return -1;
2712 }
2713 return 0;
2714 }
2715
2716 private int handleSrcGetFeatureValidationCommand() {
2717 int subId = getSubId("src get-feature-validation");
2718 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2719 return -1;
2720 }
2721
2722 Boolean result = false;
2723 try {
2724 result = mInterface.getImsFeatureValidationOverride(subId);
2725 } catch (RemoteException e) {
2726 return -1;
2727 }
2728 if (VDBG) {
2729 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2730 }
2731 getOutPrintWriter().println(result);
2732 return 0;
2733 }
2734
2735
Hall Liuaa4211e2021-01-20 15:43:39 -08002736 private void onHelpCallComposer() {
2737 PrintWriter pw = getOutPrintWriter();
2738 pw.println("Call composer commands");
2739 pw.println(" callcomposer test-mode enable|disable|query");
2740 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2741 pw.println(" upload/download from carrier servers is disabled, and operations are");
2742 pw.println(" performed using emulated local files instead.");
2743 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2744 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2745 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002746 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2747 pw.println(" Enables or disables the user setting for call composer, as set by");
2748 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002749 }
2750
2751 private int handleCallComposerCommand() {
2752 String arg = getNextArg();
2753 if (arg == null) {
2754 onHelpCallComposer();
2755 return 0;
2756 }
2757
2758 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2759 "MODIFY_PHONE_STATE required for call composer shell cmds");
2760 switch (arg) {
2761 case CALL_COMPOSER_TEST_MODE: {
2762 String enabledStr = getNextArg();
2763 if (ENABLE.equals(enabledStr)) {
2764 CallComposerPictureManager.sTestMode = true;
2765 } else if (DISABLE.equals(enabledStr)) {
2766 CallComposerPictureManager.sTestMode = false;
2767 } else if (QUERY.equals(enabledStr)) {
2768 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2769 } else {
2770 onHelpCallComposer();
2771 return 1;
2772 }
2773 break;
2774 }
2775 case CALL_COMPOSER_SIMULATE_CALL: {
2776 int subscriptionId = Integer.valueOf(getNextArg());
2777 String uuidString = getNextArg();
2778 UUID uuid = UUID.fromString(uuidString);
2779 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2780 Binder.withCleanCallingIdentity(() -> {
2781 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2782 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2783 });
2784 try {
2785 Uri uri = storageUriFuture.get();
2786 getOutPrintWriter().println(String.valueOf(uri));
2787 } catch (Exception e) {
2788 throw new RuntimeException(e);
2789 }
2790 break;
2791 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002792 case CALL_COMPOSER_USER_SETTING: {
2793 try {
2794 int subscriptionId = Integer.valueOf(getNextArg());
2795 String enabledStr = getNextArg();
2796 if (ENABLE.equals(enabledStr)) {
2797 mInterface.setCallComposerStatus(subscriptionId,
2798 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2799 } else if (DISABLE.equals(enabledStr)) {
2800 mInterface.setCallComposerStatus(subscriptionId,
2801 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2802 } else if (QUERY.equals(enabledStr)) {
2803 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2804 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2805 } else {
2806 onHelpCallComposer();
2807 return 1;
2808 }
2809 } catch (RemoteException e) {
2810 e.printStackTrace(getOutPrintWriter());
2811 return 1;
2812 }
2813 break;
2814 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002815 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002816 return 0;
2817 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002818
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002819 private int handleHasCarrierPrivilegesCommand() {
2820 String packageName = getNextArgRequired();
2821
2822 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002823 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002824 try {
2825 hasCarrierPrivileges =
2826 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2827 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2828 } catch (RemoteException e) {
2829 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2830 getErrPrintWriter().println("Exception: " + e.getMessage());
2831 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002832 } finally {
2833 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002834 }
2835
2836 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002837 return 0;
2838 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002839
2840 private int handleAllowedNetworkTypesCommand(String command) {
2841 if (!checkShellUid()) {
2842 return -1;
2843 }
2844
2845 PrintWriter errPw = getErrPrintWriter();
2846 String tag = command + ": ";
2847 String opt;
2848 int subId = -1;
2849 Log.v(LOG_TAG, command + " start");
2850
2851 while ((opt = getNextOption()) != null) {
2852 if (opt.equals("-s")) {
2853 try {
2854 subId = slotStringToSubId(tag, getNextArgRequired());
2855 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2856 errPw.println(tag + "No valid subscription found.");
2857 return -1;
2858 }
2859 } catch (IllegalArgumentException e) {
2860 // Missing slot id
2861 errPw.println(tag + "SLOT_ID expected after -s.");
2862 return -1;
2863 }
2864 } else {
2865 errPw.println(tag + "Unknown option " + opt);
2866 return -1;
2867 }
2868 }
2869
2870 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2871 return handleGetAllowedNetworkTypesCommand(subId);
2872 }
2873 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2874 return handleSetAllowedNetworkTypesCommand(subId);
2875 }
2876 return -1;
2877 }
2878
2879 private int handleGetAllowedNetworkTypesCommand(int subId) {
2880 PrintWriter errPw = getErrPrintWriter();
2881
2882 long result = -1;
2883 try {
2884 if (mInterface != null) {
2885 result = mInterface.getAllowedNetworkTypesForReason(subId,
2886 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2887 } else {
2888 throw new IllegalStateException("telephony service is null.");
2889 }
2890 } catch (RemoteException e) {
2891 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2892 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2893 return -1;
2894 }
2895
2896 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2897 return 0;
2898 }
2899
2900 private int handleSetAllowedNetworkTypesCommand(int subId) {
2901 PrintWriter errPw = getErrPrintWriter();
2902
2903 String bitmaskString = getNextArg();
2904 if (TextUtils.isEmpty(bitmaskString)) {
2905 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2906 return -1;
2907 }
2908 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2909 if (allowedNetworkTypes < 0) {
2910 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2911 return -1;
2912 }
2913 boolean result = false;
2914 try {
2915 if (mInterface != null) {
2916 result = mInterface.setAllowedNetworkTypesForReason(subId,
2917 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2918 } else {
2919 throw new IllegalStateException("telephony service is null.");
2920 }
2921 } catch (RemoteException e) {
2922 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2923 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2924 return -1;
2925 }
2926
2927 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2928 if (result) {
2929 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2930 }
2931 getOutPrintWriter().println(resultMessage);
2932 return 0;
2933 }
2934
2935 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2936 if (TextUtils.isEmpty(bitmaskString)) {
2937 return -1;
2938 }
2939 if (VDBG) {
2940 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2941 + ", length: " + bitmaskString.length());
2942 }
2943 try {
2944 return Long.parseLong(bitmaskString, 2);
2945 } catch (NumberFormatException e) {
2946 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2947 return -1;
2948 }
2949 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002950
jimsun3b9ccac2021-10-26 15:01:23 +08002951 private int handleRadioSetModemServiceCommand() {
2952 PrintWriter errPw = getErrPrintWriter();
2953 String serviceName = null;
2954
2955 String opt;
2956 while ((opt = getNextOption()) != null) {
2957 switch (opt) {
2958 case "-s": {
2959 serviceName = getNextArgRequired();
2960 break;
2961 }
2962 }
2963 }
2964
2965 try {
2966 boolean result = mInterface.setModemService(serviceName);
2967 if (VDBG) {
2968 Log.v(LOG_TAG,
2969 "RadioSetModemService " + serviceName + ", result = " + result);
2970 }
2971 getOutPrintWriter().println(result);
2972 } catch (RemoteException e) {
2973 Log.w(LOG_TAG,
2974 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2975 errPw.println("Exception: " + e.getMessage());
2976 return -1;
2977 }
2978 return 0;
2979 }
2980
2981 private int handleRadioGetModemServiceCommand() {
2982 PrintWriter errPw = getErrPrintWriter();
2983 String result;
2984
2985 try {
2986 result = mInterface.getModemService();
2987 getOutPrintWriter().println(result);
2988 } catch (RemoteException e) {
2989 errPw.println("Exception: " + e.getMessage());
2990 return -1;
2991 }
2992 if (VDBG) {
2993 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2994 }
2995 return 0;
2996 }
2997
2998 private int handleRadioCommand() {
2999 String arg = getNextArg();
3000 if (arg == null) {
3001 onHelpRadio();
3002 return 0;
3003 }
3004
3005 switch (arg) {
3006 case RADIO_SET_MODEM_SERVICE:
3007 return handleRadioSetModemServiceCommand();
3008
3009 case RADIO_GET_MODEM_SERVICE:
3010 return handleRadioGetModemServiceCommand();
3011 }
3012
3013 return -1;
3014 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003015}