blob: fdaf1bb7914be1986932d43445c96d1a7b3f351d [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();
Jack Yu00ece8c2022-11-19 22:29:12 -08001102 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001103 @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());
Jack Yu00ece8c2022-11-19 22:29:12 -08001114 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001115 } 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 }
Jack Yu00ece8c2022-11-19 22:29:12 -08002165 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002166 }
2167
2168 private int handleGbaSetServiceCommand() {
2169 int subId = getSubId("gba set-service");
2170 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2171 return -1;
2172 }
2173
2174 String packageName = getNextArg();
2175 try {
2176 if (packageName == null) {
2177 packageName = "";
2178 }
2179 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2180 if (VDBG) {
2181 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2182 + packageName + ", result=" + result);
2183 }
2184 getOutPrintWriter().println(result);
2185 } catch (RemoteException e) {
2186 Log.w(LOG_TAG, "gba set-service " + subId + " "
2187 + packageName + ", error" + e.getMessage());
2188 getErrPrintWriter().println("Exception: " + e.getMessage());
2189 return -1;
2190 }
2191 return 0;
2192 }
2193
2194 private int handleGbaGetServiceCommand() {
2195 String result;
2196
2197 int subId = getSubId("gba get-service");
2198 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2199 return -1;
2200 }
2201
2202 try {
2203 result = mInterface.getBoundGbaService(subId);
2204 } catch (RemoteException e) {
2205 return -1;
2206 }
2207 if (VDBG) {
2208 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2209 }
2210 getOutPrintWriter().println(result);
2211 return 0;
2212 }
2213
2214 private int handleGbaSetReleaseCommand() {
2215 //the release time value could be -1
2216 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2217 : SubscriptionManager.getDefaultSubscriptionId();
2218 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2219 return -1;
2220 }
2221
2222 String intervalStr = getNextArg();
2223 if (intervalStr == null) {
2224 return -1;
2225 }
2226
2227 try {
2228 int interval = Integer.parseInt(intervalStr);
2229 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2230 if (VDBG) {
2231 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2232 + intervalStr + ", result=" + result);
2233 }
2234 getOutPrintWriter().println(result);
2235 } catch (NumberFormatException | RemoteException e) {
2236 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2237 + intervalStr + ", error" + e.getMessage());
2238 getErrPrintWriter().println("Exception: " + e.getMessage());
2239 return -1;
2240 }
2241 return 0;
2242 }
2243
2244 private int handleGbaGetReleaseCommand() {
2245 int subId = getSubId("gba get-release");
2246 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2247 return -1;
2248 }
2249
2250 int result = 0;
2251 try {
2252 result = mInterface.getGbaReleaseTime(subId);
2253 } catch (RemoteException e) {
2254 return -1;
2255 }
2256 if (VDBG) {
2257 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2258 }
2259 getOutPrintWriter().println(result);
2260 return 0;
2261 }
Hui Wang761a6682020-10-31 05:12:53 +00002262
2263 private int handleSingleRegistrationConfigCommand() {
2264 String arg = getNextArg();
2265 if (arg == null) {
2266 onHelpSrc();
2267 return 0;
2268 }
2269
2270 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002271 case SRC_SET_TEST_ENABLED: {
2272 return handleSrcSetTestEnabledCommand();
2273 }
2274 case SRC_GET_TEST_ENABLED: {
2275 return handleSrcGetTestEnabledCommand();
2276 }
Hui Wang761a6682020-10-31 05:12:53 +00002277 case SRC_SET_DEVICE_ENABLED: {
2278 return handleSrcSetDeviceEnabledCommand();
2279 }
2280 case SRC_GET_DEVICE_ENABLED: {
2281 return handleSrcGetDeviceEnabledCommand();
2282 }
2283 case SRC_SET_CARRIER_ENABLED: {
2284 return handleSrcSetCarrierEnabledCommand();
2285 }
2286 case SRC_GET_CARRIER_ENABLED: {
2287 return handleSrcGetCarrierEnabledCommand();
2288 }
Hui Wangb647abe2021-02-26 09:33:38 -08002289 case SRC_SET_FEATURE_ENABLED: {
2290 return handleSrcSetFeatureValidationCommand();
2291 }
2292 case SRC_GET_FEATURE_ENABLED: {
2293 return handleSrcGetFeatureValidationCommand();
2294 }
Hui Wang761a6682020-10-31 05:12:53 +00002295 }
2296
2297 return -1;
2298 }
2299
James.cf Linbcdf8b32021-01-14 16:44:13 +08002300 private int handleRcsUceCommand() {
2301 String arg = getNextArg();
2302 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002303 onHelpUce();
2304 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002305 }
2306
2307 switch (arg) {
2308 case UCE_REMOVE_EAB_CONTACT:
2309 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002310 case UCE_GET_EAB_CONTACT:
2311 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002312 case UCE_GET_EAB_CAPABILITY:
2313 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002314 case UCE_GET_DEVICE_ENABLED:
2315 return handleUceGetDeviceEnabledCommand();
2316 case UCE_SET_DEVICE_ENABLED:
2317 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002318 case UCE_OVERRIDE_PUBLISH_CAPS:
2319 return handleUceOverridePublishCaps();
2320 case UCE_GET_LAST_PIDF_XML:
2321 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002322 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2323 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002324 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2325 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002326 }
2327 return -1;
2328 }
2329
2330 private int handleRemovingEabContactCommand() {
2331 int subId = getSubId("uce remove-eab-contact");
2332 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2333 return -1;
2334 }
2335
2336 String phoneNumber = getNextArgRequired();
2337 if (TextUtils.isEmpty(phoneNumber)) {
2338 return -1;
2339 }
2340 int result = 0;
2341 try {
2342 result = mInterface.removeContactFromEab(subId, phoneNumber);
2343 } catch (RemoteException e) {
2344 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2345 getErrPrintWriter().println("Exception: " + e.getMessage());
2346 return -1;
2347 }
2348
2349 if (VDBG) {
2350 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2351 }
calvinpan293ea1b2021-02-04 17:52:13 +08002352 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002353 }
2354
calvinpane4a8a1d2021-01-25 13:51:18 +08002355 private int handleGettingEabContactCommand() {
2356 String phoneNumber = getNextArgRequired();
2357 if (TextUtils.isEmpty(phoneNumber)) {
2358 return -1;
2359 }
2360 String result = "";
2361 try {
2362 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002363 } catch (RemoteException e) {
2364 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2365 getErrPrintWriter().println("Exception: " + e.getMessage());
2366 return -1;
2367 }
2368
2369 if (VDBG) {
2370 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2371 }
calvinpan293ea1b2021-02-04 17:52:13 +08002372 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002373 return 0;
2374 }
2375
Calvin Pana1434322021-07-01 19:27:01 +08002376 private int handleGettingEabCapabilityCommand() {
2377 String phoneNumber = getNextArgRequired();
2378 if (TextUtils.isEmpty(phoneNumber)) {
2379 return -1;
2380 }
2381 String result = "";
2382 try {
2383 result = mInterface.getCapabilityFromEab(phoneNumber);
2384 } catch (RemoteException e) {
2385 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2386 getErrPrintWriter().println("Exception: " + e.getMessage());
2387 return -1;
2388 }
2389
2390 if (VDBG) {
2391 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2392 }
2393 getOutPrintWriter().println(result);
2394 return 0;
2395 }
2396
James.cf Lin4b784aa2021-01-31 03:25:15 +08002397 private int handleUceGetDeviceEnabledCommand() {
2398 boolean result = false;
2399 try {
2400 result = mInterface.getDeviceUceEnabled();
2401 } catch (RemoteException e) {
2402 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2403 return -1;
2404 }
2405 if (VDBG) {
2406 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2407 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002408 getOutPrintWriter().println(result);
2409 return 0;
2410 }
2411
James.cf Lin4b784aa2021-01-31 03:25:15 +08002412 private int handleUceSetDeviceEnabledCommand() {
2413 String enabledStr = getNextArg();
2414 if (TextUtils.isEmpty(enabledStr)) {
2415 return -1;
2416 }
2417
2418 try {
2419 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2420 mInterface.setDeviceUceEnabled(isEnabled);
2421 if (VDBG) {
2422 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2423 }
2424 } catch (NumberFormatException | RemoteException e) {
2425 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2426 getErrPrintWriter().println("Exception: " + e.getMessage());
2427 return -1;
2428 }
2429 return 0;
2430 }
2431
James.cf Line8713a42021-04-29 16:04:26 +08002432 private int handleUceRemoveRequestDisallowedStatus() {
2433 int subId = getSubId("uce remove-request-disallowed-status");
2434 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2435 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2436 return -1;
2437 }
2438 boolean result;
2439 try {
2440 result = mInterface.removeUceRequestDisallowedStatus(subId);
2441 } catch (RemoteException e) {
2442 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2443 return -1;
2444 }
2445 if (VDBG) {
2446 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2447 }
2448 getOutPrintWriter().println(result);
2449 return 0;
2450 }
2451
James.cf Lin0fc71b02021-05-25 01:37:38 +08002452 private int handleUceSetCapRequestTimeout() {
2453 int subId = getSubId("uce set-capabilities-request-timeout");
2454 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2455 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2456 return -1;
2457 }
2458 long timeoutAfterMs = Long.valueOf(getNextArg());
2459 boolean result;
2460 try {
2461 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2462 } catch (RemoteException e) {
2463 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2464 return -1;
2465 }
2466 if (VDBG) {
2467 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2468 }
2469 getOutPrintWriter().println(result);
2470 return 0;
2471 }
2472
Hui Wangbaaee6a2021-02-19 20:45:36 -08002473 private int handleSrcSetTestEnabledCommand() {
2474 String enabledStr = getNextArg();
2475 if (enabledStr == null) {
2476 return -1;
2477 }
2478
2479 try {
2480 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2481 if (VDBG) {
2482 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2483 }
2484 getOutPrintWriter().println("Done");
2485 } catch (NumberFormatException | RemoteException e) {
2486 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2487 getErrPrintWriter().println("Exception: " + e.getMessage());
2488 return -1;
2489 }
2490 return 0;
2491 }
2492
2493 private int handleSrcGetTestEnabledCommand() {
2494 boolean result = false;
2495 try {
2496 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2497 } catch (RemoteException e) {
2498 return -1;
2499 }
2500 if (VDBG) {
2501 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2502 }
2503 getOutPrintWriter().println(result);
2504 return 0;
2505 }
2506
Brad Ebinger14d467f2021-02-12 06:18:28 +00002507 private int handleUceOverridePublishCaps() {
2508 int subId = getSubId("uce override-published-caps");
2509 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2510 return -1;
2511 }
2512 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2513 String operation = getNextArgRequired();
2514 String caps = getNextArg();
2515 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2516 && !"list".equals(operation)) {
2517 getErrPrintWriter().println("Invalid operation: " + operation);
2518 return -1;
2519 }
2520
2521 // add/remove requires capabilities to be specified.
2522 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2523 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2524 + "specified");
2525 return -1;
2526 }
2527
2528 ArraySet<String> capSet = new ArraySet<>();
2529 if (!TextUtils.isEmpty(caps)) {
2530 String[] capArray = caps.split(":");
2531 for (String cap : capArray) {
2532 // Allow unknown tags to be passed in as well.
2533 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2534 }
2535 }
2536
2537 RcsContactUceCapability result = null;
2538 try {
2539 switch (operation) {
2540 case "add":
2541 result = mInterface.addUceRegistrationOverrideShell(subId,
2542 new ArrayList<>(capSet));
2543 break;
2544 case "remove":
2545 result = mInterface.removeUceRegistrationOverrideShell(subId,
2546 new ArrayList<>(capSet));
2547 break;
2548 case "clear":
2549 result = mInterface.clearUceRegistrationOverrideShell(subId);
2550 break;
2551 case "list":
2552 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2553 break;
2554 }
2555 } catch (RemoteException e) {
2556 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2557 getErrPrintWriter().println("Exception: " + e.getMessage());
2558 return -1;
2559 } catch (ServiceSpecificException sse) {
2560 // Reconstruct ImsException
2561 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2562 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2563 getErrPrintWriter().println("Exception: " + imsException);
2564 return -1;
2565 }
2566 if (result == null) {
2567 getErrPrintWriter().println("Service not available");
2568 return -1;
2569 }
2570 getOutPrintWriter().println(result);
2571 return 0;
2572 }
2573
2574 private int handleUceGetPidfXml() {
2575 int subId = getSubId("uce get-last-publish-pidf");
2576 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2577 return -1;
2578 }
2579
2580 String result;
2581 try {
2582 result = mInterface.getLastUcePidfXmlShell(subId);
2583 } catch (RemoteException e) {
2584 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2585 getErrPrintWriter().println("Exception: " + e.getMessage());
2586 return -1;
2587 } catch (ServiceSpecificException sse) {
2588 // Reconstruct ImsException
2589 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2590 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2591 getErrPrintWriter().println("Exception: " + imsException);
2592 return -1;
2593 }
2594 if (result == null) {
2595 getErrPrintWriter().println("Service not available");
2596 return -1;
2597 }
2598 getOutPrintWriter().println(result);
2599 return 0;
2600 }
2601
Hui Wang761a6682020-10-31 05:12:53 +00002602 private int handleSrcSetDeviceEnabledCommand() {
2603 String enabledStr = getNextArg();
2604 if (enabledStr == null) {
2605 return -1;
2606 }
2607
2608 try {
2609 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2610 if (VDBG) {
2611 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2612 }
2613 getOutPrintWriter().println("Done");
2614 } catch (NumberFormatException | RemoteException e) {
2615 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2616 getErrPrintWriter().println("Exception: " + e.getMessage());
2617 return -1;
2618 }
2619 return 0;
2620 }
2621
2622 private int handleSrcGetDeviceEnabledCommand() {
2623 boolean result = false;
2624 try {
2625 result = mInterface.getDeviceSingleRegistrationEnabled();
2626 } catch (RemoteException e) {
2627 return -1;
2628 }
2629 if (VDBG) {
2630 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2631 }
2632 getOutPrintWriter().println(result);
2633 return 0;
2634 }
2635
2636 private int handleSrcSetCarrierEnabledCommand() {
2637 //the release time value could be -1
2638 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2639 : SubscriptionManager.getDefaultSubscriptionId();
2640 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2641 return -1;
2642 }
2643
2644 String enabledStr = getNextArg();
2645 if (enabledStr == null) {
2646 return -1;
2647 }
2648
2649 try {
2650 boolean result =
2651 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2652 if (VDBG) {
2653 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2654 + enabledStr + ", result=" + result);
2655 }
2656 getOutPrintWriter().println(result);
2657 } catch (NumberFormatException | RemoteException e) {
2658 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2659 + enabledStr + ", error" + e.getMessage());
2660 getErrPrintWriter().println("Exception: " + e.getMessage());
2661 return -1;
2662 }
2663 return 0;
2664 }
2665
2666 private int handleSrcGetCarrierEnabledCommand() {
2667 int subId = getSubId("src get-carrier-enabled");
2668 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2669 return -1;
2670 }
2671
2672 boolean result = false;
2673 try {
2674 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2675 } catch (RemoteException e) {
2676 return -1;
2677 }
2678 if (VDBG) {
2679 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2680 }
2681 getOutPrintWriter().println(result);
2682 return 0;
2683 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002684
Hui Wangb647abe2021-02-26 09:33:38 -08002685 private int handleSrcSetFeatureValidationCommand() {
2686 //the release time value could be -1
2687 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2688 : SubscriptionManager.getDefaultSubscriptionId();
2689 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2690 return -1;
2691 }
2692
2693 String enabledStr = getNextArg();
2694 if (enabledStr == null) {
2695 return -1;
2696 }
2697
2698 try {
2699 boolean result =
2700 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2701 if (VDBG) {
2702 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2703 + enabledStr + ", result=" + result);
2704 }
2705 getOutPrintWriter().println(result);
2706 } catch (NumberFormatException | RemoteException e) {
2707 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2708 + enabledStr + ", error" + e.getMessage());
2709 getErrPrintWriter().println("Exception: " + e.getMessage());
2710 return -1;
2711 }
2712 return 0;
2713 }
2714
2715 private int handleSrcGetFeatureValidationCommand() {
2716 int subId = getSubId("src get-feature-validation");
2717 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2718 return -1;
2719 }
2720
2721 Boolean result = false;
2722 try {
2723 result = mInterface.getImsFeatureValidationOverride(subId);
2724 } catch (RemoteException e) {
2725 return -1;
2726 }
2727 if (VDBG) {
2728 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2729 }
2730 getOutPrintWriter().println(result);
2731 return 0;
2732 }
2733
2734
Hall Liuaa4211e2021-01-20 15:43:39 -08002735 private void onHelpCallComposer() {
2736 PrintWriter pw = getOutPrintWriter();
2737 pw.println("Call composer commands");
2738 pw.println(" callcomposer test-mode enable|disable|query");
2739 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2740 pw.println(" upload/download from carrier servers is disabled, and operations are");
2741 pw.println(" performed using emulated local files instead.");
2742 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2743 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2744 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002745 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2746 pw.println(" Enables or disables the user setting for call composer, as set by");
2747 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002748 }
2749
2750 private int handleCallComposerCommand() {
2751 String arg = getNextArg();
2752 if (arg == null) {
2753 onHelpCallComposer();
2754 return 0;
2755 }
2756
2757 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2758 "MODIFY_PHONE_STATE required for call composer shell cmds");
2759 switch (arg) {
2760 case CALL_COMPOSER_TEST_MODE: {
2761 String enabledStr = getNextArg();
2762 if (ENABLE.equals(enabledStr)) {
2763 CallComposerPictureManager.sTestMode = true;
2764 } else if (DISABLE.equals(enabledStr)) {
2765 CallComposerPictureManager.sTestMode = false;
2766 } else if (QUERY.equals(enabledStr)) {
2767 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2768 } else {
2769 onHelpCallComposer();
2770 return 1;
2771 }
2772 break;
2773 }
2774 case CALL_COMPOSER_SIMULATE_CALL: {
2775 int subscriptionId = Integer.valueOf(getNextArg());
2776 String uuidString = getNextArg();
2777 UUID uuid = UUID.fromString(uuidString);
2778 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2779 Binder.withCleanCallingIdentity(() -> {
2780 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2781 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2782 });
2783 try {
2784 Uri uri = storageUriFuture.get();
2785 getOutPrintWriter().println(String.valueOf(uri));
2786 } catch (Exception e) {
2787 throw new RuntimeException(e);
2788 }
2789 break;
2790 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002791 case CALL_COMPOSER_USER_SETTING: {
2792 try {
2793 int subscriptionId = Integer.valueOf(getNextArg());
2794 String enabledStr = getNextArg();
2795 if (ENABLE.equals(enabledStr)) {
2796 mInterface.setCallComposerStatus(subscriptionId,
2797 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2798 } else if (DISABLE.equals(enabledStr)) {
2799 mInterface.setCallComposerStatus(subscriptionId,
2800 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2801 } else if (QUERY.equals(enabledStr)) {
2802 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2803 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2804 } else {
2805 onHelpCallComposer();
2806 return 1;
2807 }
2808 } catch (RemoteException e) {
2809 e.printStackTrace(getOutPrintWriter());
2810 return 1;
2811 }
2812 break;
2813 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002814 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002815 return 0;
2816 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002817
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002818 private int handleHasCarrierPrivilegesCommand() {
2819 String packageName = getNextArgRequired();
2820
2821 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002822 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002823 try {
2824 hasCarrierPrivileges =
2825 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2826 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2827 } catch (RemoteException e) {
2828 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2829 getErrPrintWriter().println("Exception: " + e.getMessage());
2830 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002831 } finally {
2832 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002833 }
2834
2835 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002836 return 0;
2837 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002838
2839 private int handleAllowedNetworkTypesCommand(String command) {
2840 if (!checkShellUid()) {
2841 return -1;
2842 }
2843
2844 PrintWriter errPw = getErrPrintWriter();
2845 String tag = command + ": ";
2846 String opt;
2847 int subId = -1;
2848 Log.v(LOG_TAG, command + " start");
2849
2850 while ((opt = getNextOption()) != null) {
2851 if (opt.equals("-s")) {
2852 try {
2853 subId = slotStringToSubId(tag, getNextArgRequired());
2854 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2855 errPw.println(tag + "No valid subscription found.");
2856 return -1;
2857 }
2858 } catch (IllegalArgumentException e) {
2859 // Missing slot id
2860 errPw.println(tag + "SLOT_ID expected after -s.");
2861 return -1;
2862 }
2863 } else {
2864 errPw.println(tag + "Unknown option " + opt);
2865 return -1;
2866 }
2867 }
2868
2869 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2870 return handleGetAllowedNetworkTypesCommand(subId);
2871 }
2872 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2873 return handleSetAllowedNetworkTypesCommand(subId);
2874 }
2875 return -1;
2876 }
2877
2878 private int handleGetAllowedNetworkTypesCommand(int subId) {
2879 PrintWriter errPw = getErrPrintWriter();
2880
2881 long result = -1;
2882 try {
2883 if (mInterface != null) {
2884 result = mInterface.getAllowedNetworkTypesForReason(subId,
2885 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2886 } else {
2887 throw new IllegalStateException("telephony service is null.");
2888 }
2889 } catch (RemoteException e) {
2890 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2891 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2892 return -1;
2893 }
2894
2895 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2896 return 0;
2897 }
2898
2899 private int handleSetAllowedNetworkTypesCommand(int subId) {
2900 PrintWriter errPw = getErrPrintWriter();
2901
2902 String bitmaskString = getNextArg();
2903 if (TextUtils.isEmpty(bitmaskString)) {
2904 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2905 return -1;
2906 }
2907 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2908 if (allowedNetworkTypes < 0) {
2909 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2910 return -1;
2911 }
2912 boolean result = false;
2913 try {
2914 if (mInterface != null) {
2915 result = mInterface.setAllowedNetworkTypesForReason(subId,
2916 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2917 } else {
2918 throw new IllegalStateException("telephony service is null.");
2919 }
2920 } catch (RemoteException e) {
2921 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2922 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2923 return -1;
2924 }
2925
2926 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2927 if (result) {
2928 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2929 }
2930 getOutPrintWriter().println(resultMessage);
2931 return 0;
2932 }
2933
2934 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2935 if (TextUtils.isEmpty(bitmaskString)) {
2936 return -1;
2937 }
2938 if (VDBG) {
2939 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2940 + ", length: " + bitmaskString.length());
2941 }
2942 try {
2943 return Long.parseLong(bitmaskString, 2);
2944 } catch (NumberFormatException e) {
2945 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2946 return -1;
2947 }
2948 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002949
jimsun3b9ccac2021-10-26 15:01:23 +08002950 private int handleRadioSetModemServiceCommand() {
2951 PrintWriter errPw = getErrPrintWriter();
2952 String serviceName = null;
2953
2954 String opt;
2955 while ((opt = getNextOption()) != null) {
2956 switch (opt) {
2957 case "-s": {
2958 serviceName = getNextArgRequired();
2959 break;
2960 }
2961 }
2962 }
2963
2964 try {
2965 boolean result = mInterface.setModemService(serviceName);
2966 if (VDBG) {
2967 Log.v(LOG_TAG,
2968 "RadioSetModemService " + serviceName + ", result = " + result);
2969 }
2970 getOutPrintWriter().println(result);
2971 } catch (RemoteException e) {
2972 Log.w(LOG_TAG,
2973 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2974 errPw.println("Exception: " + e.getMessage());
2975 return -1;
2976 }
2977 return 0;
2978 }
2979
2980 private int handleRadioGetModemServiceCommand() {
2981 PrintWriter errPw = getErrPrintWriter();
2982 String result;
2983
2984 try {
2985 result = mInterface.getModemService();
2986 getOutPrintWriter().println(result);
2987 } catch (RemoteException e) {
2988 errPw.println("Exception: " + e.getMessage());
2989 return -1;
2990 }
2991 if (VDBG) {
2992 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2993 }
2994 return 0;
2995 }
2996
2997 private int handleRadioCommand() {
2998 String arg = getNextArg();
2999 if (arg == null) {
3000 onHelpRadio();
3001 return 0;
3002 }
3003
3004 switch (arg) {
3005 case RADIO_SET_MODEM_SERVICE:
3006 return handleRadioSetModemServiceCommand();
3007
3008 case RADIO_GET_MODEM_SERVICE:
3009 return handleRadioGetModemServiceCommand();
3010 }
3011
3012 return -1;
3013 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003014}