blob: 9f86c241cffbcc1c6707286767ab02f65085c2f1 [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;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010067import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000068import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010069import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080070import java.util.UUID;
71import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070072
73/**
74 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
75 * permission checks have been done before onCommand was called. Make sure any commands processed
76 * here also contain the appropriate permissions checks.
77 */
78
Hall Liua1548bd2019-12-24 14:14:12 -080079public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81 private static final String LOG_TAG = "TelephonyShellCommand";
82 // Don't commit with this true.
83 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070084 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070085
Hall Liuaa4211e2021-01-20 15:43:39 -080086 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080088 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080089 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080090 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070091 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000092 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000093 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010094 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080095 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080096 private static final String ENABLE = "enable";
97 private static final String DISABLE = "disable";
98 private static final String QUERY = "query";
99
Hall Liu7135e502021-02-04 16:58:17 -0800100 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800101 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800102 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800103
Brad Ebinger999d3302020-11-25 14:31:39 -0800104 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
105 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
106 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700107 // Used to disable or enable processing of conference event package data from the network.
108 // This is handy for testing scenarios where CEP data does not exist on a network which does
109 // support CEP data.
110 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700111
Hall Liud892bec2018-11-30 14:51:45 -0800112 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800113 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800114
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100115 private static final String CC_GET_VALUE = "get-value";
116 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000117 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100118 private static final String CC_CLEAR_VALUES = "clear-values";
119
Hui Wang641e81c2020-10-12 12:14:23 -0700120 private static final String GBA_SUBCOMMAND = "gba";
121 private static final String GBA_SET_SERVICE = "set-service";
122 private static final String GBA_GET_SERVICE = "get-service";
123 private static final String GBA_SET_RELEASE_TIME = "set-release";
124 private static final String GBA_GET_RELEASE_TIME = "get-release";
125
Hui Wang761a6682020-10-31 05:12:53 +0000126 private static final String SINGLE_REGISTATION_CONFIG = "src";
127 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
128 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
129 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
130 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800131 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
132 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800133 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
134 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000135
Tyler Gunn92479152021-01-20 16:30:10 -0800136 private static final String D2D_SUBCOMMAND = "d2d";
137 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800138 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700139 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800140
Nazanin014f41e2021-05-06 17:26:31 -0700141 private static final String BARRING_SUBCOMMAND = "barring";
142 private static final String BARRING_SEND_INFO = "send";
143
James.cf Linbcdf8b32021-01-14 16:44:13 +0800144 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800145 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800146 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800147 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800148 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
149 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000150 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
151 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800152 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
153 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800154 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
155 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800156
jimsun3b9ccac2021-10-26 15:01:23 +0800157 private static final String RADIO_SUBCOMMAND = "radio";
158 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
159 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
160
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800161 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
162 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
163
Jordan Liu0ccee222021-04-27 11:55:13 -0700164 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
165 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
166
Jack Nudelman644b91a2021-03-12 14:09:48 -0800167 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
168 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
169 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
170
SongFerngWang98dd5992021-05-13 17:50:00 +0800171 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
172 "get-allowed-network-types-for-users";
173 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
174 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000175 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000176 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700177 // Take advantage of existing methods that already contain permissions checks when possible.
178 private final ITelephony mInterface;
179
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100180 private SubscriptionManager mSubscriptionManager;
181 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700182 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700183 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100184
185 private enum CcType {
186 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000187 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100188 }
189
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100190 private class CcOptionParseResult {
191 public int mSubId;
192 public boolean mPersistent;
193 }
194
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100195 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
196 // keys by looking at the end of the string which usually tells the type.
197 // For instance: "xxxx_string", "xxxx_string_array", etc.
198 // The carrier config keys in this map does not follow this convention. It is therefore not
199 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700200 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
201 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
202 CcType.STRING),
203 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
204 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
205 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
206 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
207 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
208 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
209 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
210 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
211 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
212 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
213 CcType.STRING),
214 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
215 CcType.STRING_ARRAY),
216 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
217 CcType.STRING_ARRAY),
218 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
219 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
220 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
221 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
222 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
223 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
224 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
225 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100226
Brad Ebinger14d467f2021-02-12 06:18:28 +0000227 /**
228 * Map from a shorthand string to the feature tags required in registration required in order
229 * for the RCS feature to be considered "capable".
230 */
231 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
232 static {
233 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
234 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
235 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
236 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
237 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
238 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
239 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
240 FeatureTags.FEATURE_TAG_VIDEO)));
241 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
242 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
243 map.put("call_comp",
244 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
245 map.put("call_comp_mmtel",
246 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
247 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
248 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
249 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
250 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
251 // version
252 map.put("chatbot", new ArraySet<>(Arrays.asList(
253 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
254 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
255 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
256 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000257 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000258 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
259 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
260 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
261 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
262 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000263 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000264 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
265 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
266 }
267
268
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100269 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700270 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100271 mCarrierConfigManager =
272 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
273 mSubscriptionManager = (SubscriptionManager)
274 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700275 mTelephonyRegistryManager = (TelephonyRegistryManager)
276 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700277 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700278 }
279
280 @Override
281 public int onCommand(String cmd) {
282 if (cmd == null) {
283 return handleDefaultCommands(null);
284 }
285
286 switch (cmd) {
287 case IMS_SUBCOMMAND: {
288 return handleImsCommand();
289 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800290 case RCS_UCE_COMMAND:
291 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800292 case NUMBER_VERIFICATION_SUBCOMMAND:
293 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800294 case EMERGENCY_CALLBACK_MODE:
295 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800296 case EMERGENCY_NUMBER_TEST_MODE:
297 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100298 case CARRIER_CONFIG_SUBCOMMAND: {
299 return handleCcCommand();
300 }
Shuo Qianf5125122019-12-16 17:03:07 -0800301 case DATA_TEST_MODE:
302 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700303 case END_BLOCK_SUPPRESSION:
304 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700305 case GBA_SUBCOMMAND:
306 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800307 case D2D_SUBCOMMAND:
308 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700309 case BARRING_SUBCOMMAND:
310 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000311 case SINGLE_REGISTATION_CONFIG:
312 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000313 case RESTART_MODEM:
314 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800315 case CALL_COMPOSER_SUBCOMMAND:
316 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000317 case UNATTENDED_REBOOT:
318 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800319 case HAS_CARRIER_PRIVILEGES_COMMAND:
320 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800321 case THERMAL_MITIGATION_COMMAND:
322 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700323 case DISABLE_PHYSICAL_SUBSCRIPTION:
324 return handleEnablePhysicalSubscription(false);
325 case ENABLE_PHYSICAL_SUBSCRIPTION:
326 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800327 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
328 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
329 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000330 case GET_IMEI:
331 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000332 case GET_SIM_SLOTS_MAPPING:
333 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800334 case RADIO_SUBCOMMAND:
335 return handleRadioCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700336 default: {
337 return handleDefaultCommands(cmd);
338 }
339 }
340 }
341
342 @Override
343 public void onHelp() {
344 PrintWriter pw = getOutPrintWriter();
345 pw.println("Telephony Commands:");
346 pw.println(" help");
347 pw.println(" Print this help text.");
348 pw.println(" ims");
349 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800350 pw.println(" uce");
351 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800352 pw.println(" emergency-number-test-mode");
353 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700354 pw.println(" end-block-suppression");
355 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800356 pw.println(" data");
357 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100358 pw.println(" cc");
359 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700360 pw.println(" gba");
361 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000362 pw.println(" src");
363 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000364 pw.println(" restart-modem");
365 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000366 pw.println(" unattended-reboot");
367 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800368 pw.println(" has-carrier-privileges [package]");
369 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800370 pw.println(" get-allowed-network-types-for-users");
371 pw.println(" Get the Allowed Network Types.");
372 pw.println(" set-allowed-network-types-for-users");
373 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800374 pw.println(" radio");
375 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700376 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800377 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800378 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700379 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800380 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100381 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700382 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000383 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800384 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700385 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800386 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800387 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000388 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800389 }
390
391 private void onHelpD2D() {
392 PrintWriter pw = getOutPrintWriter();
393 pw.println("D2D Comms Commands:");
394 pw.println(" d2d send TYPE VALUE");
395 pw.println(" Sends a D2D message of specified type and value.");
396 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
397 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
398 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
399 MESSAGE_CALL_AUDIO_CODEC));
400 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
401 + Communicator.messageToString(
402 MESSAGE_DEVICE_BATTERY_STATE));
403 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
404 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800405 pw.println(" d2d transport TYPE");
406 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
407 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700408 pw.println(" d2d set-device-support true/default");
409 pw.println(" true - forces device support to be enabled for D2D.");
410 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
411 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700412 }
413
Nazanin014f41e2021-05-06 17:26:31 -0700414 private void onHelpBarring() {
415 PrintWriter pw = getOutPrintWriter();
416 pw.println("Barring Commands:");
417 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
418 + " -t CONDITIONAL_BARRING_TIME_SECS");
419 pw.println(" Notifies of a barring info change for the specified slot id.");
420 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
421 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
422 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
423 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
424 }
425
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700426 private void onHelpIms() {
427 PrintWriter pw = getOutPrintWriter();
428 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800429 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700430 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
431 pw.println(" ImsService. Options are:");
432 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
433 pw.println(" is specified, it will choose the default voice SIM slot.");
434 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
435 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800436 pw.println(" -f: Set the feature that this override if for, if no option is");
437 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700438 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
439 pw.println(" Gets the package name of the currently defined ImsService.");
440 pw.println(" Options are:");
441 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
442 pw.println(" is specified, it will choose the default voice SIM slot.");
443 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000444 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800445 pw.println(" -f: The feature type that the query will be requested for. If none is");
446 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800447 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
448 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
449 pw.println(" configuration overrides. Options are:");
450 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
451 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700452 pw.println(" ims enable [-s SLOT_ID]");
453 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
454 pw.println(" if none is specified.");
455 pw.println(" ims disable [-s SLOT_ID]");
456 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
457 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700458 pw.println(" ims conference-event-package [enable/disable]");
459 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700460 }
461
James.cf Linbcdf8b32021-01-14 16:44:13 +0800462 private void onHelpUce() {
463 PrintWriter pw = getOutPrintWriter();
464 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800465 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
466 pw.println(" Get the EAB contacts from the EAB database.");
467 pw.println(" Options are:");
468 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
469 pw.println(" Expected output format :");
470 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800471 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
472 pw.println(" Remove the EAB contacts from the EAB database.");
473 pw.println(" Options are:");
474 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
475 pw.println(" is specified, it will choose the default voice SIM slot.");
476 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800477 pw.println(" uce get-device-enabled");
478 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
479 pw.println(" uce set-device-enabled true|false");
480 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
481 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000482 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
483 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
484 pw.println(" Options are:");
485 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
486 pw.println(" is specified, it will choose the default voice SIM slot.");
487 pw.println(" add [CAPABILITY]: add a new capability");
488 pw.println(" remove [CAPABILITY]: remove a capability");
489 pw.println(" clear: clear all capability overrides");
490 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
491 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
492 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
493 pw.println(" chatbot_sa, chatbot_role] as well as full length");
494 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
495 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
496 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
497 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800498 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
499 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800500 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
501 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800502 }
503
Hall Liud892bec2018-11-30 14:51:45 -0800504 private void onHelpNumberVerification() {
505 PrintWriter pw = getOutPrintWriter();
506 pw.println("Number verification commands");
507 pw.println(" numverify override-package PACKAGE_NAME;");
508 pw.println(" Set the authorized package for number verification.");
509 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800510 pw.println(" numverify fake-call NUMBER;");
511 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
512 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800513 }
514
Jack Nudelman644b91a2021-03-12 14:09:48 -0800515 private void onHelpThermalMitigation() {
516 PrintWriter pw = getOutPrintWriter();
517 pw.println("Thermal mitigation commands");
518 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
519 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
520 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
521 pw.println(" Remove the package from one of the authorized packages for thermal "
522 + "mitigation.");
523 }
524
Jordan Liu0ccee222021-04-27 11:55:13 -0700525 private void onHelpDisableOrEnablePhysicalSubscription() {
526 PrintWriter pw = getOutPrintWriter();
527 pw.println("Disable or enable a physical subscription");
528 pw.println(" disable-physical-subscription SUB_ID");
529 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
530 pw.println(" enable-physical-subscription SUB_ID");
531 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
532 }
533
Shuo Qianf5125122019-12-16 17:03:07 -0800534 private void onHelpDataTestMode() {
535 PrintWriter pw = getOutPrintWriter();
536 pw.println("Mobile Data Test Mode Commands:");
537 pw.println(" data enable: enable mobile data connectivity");
538 pw.println(" data disable: disable mobile data connectivity");
539 }
540
sqian9d4df8b2019-01-15 18:32:07 -0800541 private void onHelpEmergencyNumber() {
542 PrintWriter pw = getOutPrintWriter();
543 pw.println("Emergency Number Test Mode Commands:");
544 pw.println(" emergency-number-test-mode ");
545 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
546 + " the test mode");
547 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700548 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800549 pw.println(" -c: clear the emergency number list in the test mode.");
550 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700551 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800552 pw.println(" -p: get the full emergency number list in the test mode.");
553 }
554
Shuo Qian489d9282020-07-09 11:30:03 -0700555 private void onHelpEndBlockSupperssion() {
556 PrintWriter pw = getOutPrintWriter();
557 pw.println("End Block Suppression command:");
558 pw.println(" end-block-suppression: disable suppressing blocking by contact");
559 pw.println(" with emergency services.");
560 }
561
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100562 private void onHelpCc() {
563 PrintWriter pw = getOutPrintWriter();
564 pw.println("Carrier Config Commands:");
565 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
566 pw.println(" Print carrier config values.");
567 pw.println(" Options are:");
568 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
569 pw.println(" is specified, it will choose the default voice SIM slot.");
570 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
571 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100572 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100573 pw.println(" Set carrier config KEY to NEW_VALUE.");
574 pw.println(" Options are:");
575 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
576 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100577 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100578 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
579 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
580 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
581 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000582 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
583 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
584 pw.println(" provided through standard input and follow CarrierConfig XML format.");
585 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
586 pw.println(" Options are:");
587 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
588 pw.println(" is specified, it will choose the default voice SIM slot.");
589 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100590 pw.println(" cc clear-values [-s SLOT_ID]");
591 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000592 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100593 pw.println(" Options are:");
594 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
595 pw.println(" is specified, it will choose the default voice SIM slot.");
596 }
597
Hui Wang641e81c2020-10-12 12:14:23 -0700598 private void onHelpGba() {
599 PrintWriter pw = getOutPrintWriter();
600 pw.println("Gba Commands:");
601 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
602 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
603 pw.println(" Options are:");
604 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
605 pw.println(" is specified, it will choose the default voice SIM slot.");
606 pw.println(" gba get-service [-s SLOT_ID]");
607 pw.println(" Gets the package name of the currently defined GbaService.");
608 pw.println(" Options are:");
609 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
610 pw.println(" is specified, it will choose the default voice SIM slot.");
611 pw.println(" gba set-release [-s SLOT_ID] n");
612 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
613 pw.println(" Do not release/unbind if n is -1.");
614 pw.println(" Options are:");
615 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
616 pw.println(" is specified, it will choose the default voice SIM slot.");
617 pw.println(" gba get-release [-s SLOT_ID]");
618 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
619 pw.println(" Options are:");
620 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
621 pw.println(" is specified, it will choose the default voice SIM slot.");
622 }
623
Hui Wang761a6682020-10-31 05:12:53 +0000624 private void onHelpSrc() {
625 PrintWriter pw = getOutPrintWriter();
626 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800627 pw.println(" src set-test-enabled true|false");
628 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
629 pw.println(" The value could be true, false, or null(undefined).");
630 pw.println(" src get-test-enabled");
631 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000632 pw.println(" src set-device-enabled true|false|null");
633 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
634 pw.println(" The value could be true, false, or null(undefined).");
635 pw.println(" src get-device-enabled");
636 pw.println(" Gets the device config for RCS VoLTE single registration.");
637 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
638 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
639 pw.println(" The value could be true, false, or null(undefined).");
640 pw.println(" Options are:");
641 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
642 pw.println(" is specified, it will choose the default voice SIM slot.");
643 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
644 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
645 pw.println(" Options are:");
646 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
647 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800648 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
649 pw.println(" Sets ims feature validation result.");
650 pw.println(" The value could be true, false, or null(undefined).");
651 pw.println(" Options are:");
652 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
653 pw.println(" is specified, it will choose the default voice SIM slot.");
654 pw.println(" src get-feature-validation [-s SLOT_ID]");
655 pw.println(" Gets ims feature validation override value.");
656 pw.println(" Options are:");
657 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
658 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000659 }
660
SongFerngWang98dd5992021-05-13 17:50:00 +0800661 private void onHelpAllowedNetworkTypes() {
662 PrintWriter pw = getOutPrintWriter();
663 pw.println("Allowed Network Types Commands:");
664 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
665 pw.println(" Print allowed network types value.");
666 pw.println(" Options are:");
667 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
668 pw.println(" option is specified, it will choose the default voice SIM slot.");
669 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
670 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
671 pw.println(" Options are:");
672 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
673 pw.println(" option is specified, it will choose the default voice SIM slot.");
674 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
675 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
676 pw.println(" at TelephonyManager.java");
677 pw.println(" For example:");
678 pw.println(" NR only : 10000000000000000000");
679 pw.println(" NR|LTE : 11000001000000000000");
680 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
681 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
682 pw.println(" LTE only : 01000001000000000000");
683 }
684
jimsun3b9ccac2021-10-26 15:01:23 +0800685 private void onHelpRadio() {
686 PrintWriter pw = getOutPrintWriter();
687 pw.println("Radio Commands:");
688 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
689 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
690 pw.println(" to be the bound. Options are:");
691 pw.println(" -s: the service name that the modem service should be bound for.");
692 pw.println(" If no option is specified, it will bind to the default.");
693 pw.println(" radio get-modem-service");
694 pw.println(" Gets the service name of the currently defined modem service.");
695 pw.println(" If it is binding to default, 'default' returns.");
696 pw.println(" If it doesn't bind to any modem service for some reasons,");
697 pw.println(" the result would be 'unknown'.");
698 }
699
Ling Ma4fbab492022-01-25 22:36:16 +0000700 private void onHelpImei() {
701 PrintWriter pw = getOutPrintWriter();
702 pw.println("IMEI Commands:");
703 pw.println(" get-imei [-s SLOT_ID]");
704 pw.println(" Gets the device IMEI. Options are:");
705 pw.println(" -s: the slot ID to get the IMEI. If no option");
706 pw.println(" is specified, it will choose the default voice SIM slot.");
707 }
708
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700709 private int handleImsCommand() {
710 String arg = getNextArg();
711 if (arg == null) {
712 onHelpIms();
713 return 0;
714 }
715
716 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800717 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700718 return handleImsSetServiceCommand();
719 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800720 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700721 return handleImsGetServiceCommand();
722 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800723 case IMS_CLEAR_SERVICE_OVERRIDE: {
724 return handleImsClearCarrierServiceCommand();
725 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800726 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700727 return handleEnableIms();
728 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800729 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700730 return handleDisableIms();
731 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700732 case IMS_CEP: {
733 return handleCepChange();
734 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700735 }
736
737 return -1;
738 }
739
Shuo Qianf5125122019-12-16 17:03:07 -0800740 private int handleDataTestModeCommand() {
741 PrintWriter errPw = getErrPrintWriter();
742 String arg = getNextArgRequired();
743 if (arg == null) {
744 onHelpDataTestMode();
745 return 0;
746 }
747 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800748 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800749 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700750 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800751 } catch (RemoteException ex) {
752 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
753 errPw.println("Exception: " + ex.getMessage());
754 return -1;
755 }
756 break;
757 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800758 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800759 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700760 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800761 } catch (RemoteException ex) {
762 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
763 errPw.println("Exception: " + ex.getMessage());
764 return -1;
765 }
766 break;
767 }
768 default:
769 onHelpDataTestMode();
770 break;
771 }
772 return 0;
773 }
774
Shuo Qianccbaf742021-02-22 18:32:21 -0800775 private int handleEmergencyCallbackModeCommand() {
776 PrintWriter errPw = getErrPrintWriter();
777 try {
778 mInterface.startEmergencyCallbackMode();
779 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
780 } catch (RemoteException ex) {
781 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
782 errPw.println("Exception: " + ex.getMessage());
783 return -1;
784 }
785 return 0;
786 }
787
sqian9d4df8b2019-01-15 18:32:07 -0800788 private int handleEmergencyNumberTestModeCommand() {
789 PrintWriter errPw = getErrPrintWriter();
790 String opt = getNextOption();
791 if (opt == null) {
792 onHelpEmergencyNumber();
793 return 0;
794 }
795
796 switch (opt) {
797 case "-a": {
798 String emergencyNumberCmd = getNextArgRequired();
799 if (emergencyNumberCmd == null
800 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700801 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800802 + " to be specified after -a in the command ");
803 return -1;
804 }
805 try {
806 mInterface.updateEmergencyNumberListTestMode(
807 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
808 new EmergencyNumber(emergencyNumberCmd, "", "",
809 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
810 new ArrayList<String>(),
811 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
812 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
813 } catch (RemoteException ex) {
814 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
815 + ", error " + ex.getMessage());
816 errPw.println("Exception: " + ex.getMessage());
817 return -1;
818 }
819 break;
820 }
821 case "-c": {
822 try {
823 mInterface.updateEmergencyNumberListTestMode(
824 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
825 } catch (RemoteException ex) {
826 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
827 errPw.println("Exception: " + ex.getMessage());
828 return -1;
829 }
830 break;
831 }
832 case "-r": {
833 String emergencyNumberCmd = getNextArgRequired();
834 if (emergencyNumberCmd == null
835 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700836 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800837 + " to be specified after -r in the command ");
838 return -1;
839 }
840 try {
841 mInterface.updateEmergencyNumberListTestMode(
842 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
843 new EmergencyNumber(emergencyNumberCmd, "", "",
844 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
845 new ArrayList<String>(),
846 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
847 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
848 } catch (RemoteException ex) {
849 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
850 + ", error " + ex.getMessage());
851 errPw.println("Exception: " + ex.getMessage());
852 return -1;
853 }
854 break;
855 }
856 case "-p": {
857 try {
858 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
859 } catch (RemoteException ex) {
860 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
861 errPw.println("Exception: " + ex.getMessage());
862 return -1;
863 }
864 break;
865 }
866 default:
867 onHelpEmergencyNumber();
868 break;
869 }
870 return 0;
871 }
872
Hall Liud892bec2018-11-30 14:51:45 -0800873 private int handleNumberVerificationCommand() {
874 String arg = getNextArg();
875 if (arg == null) {
876 onHelpNumberVerification();
877 return 0;
878 }
879
Hall Liuca5af3a2018-12-04 16:58:23 -0800880 if (!checkShellUid()) {
881 return -1;
882 }
883
Hall Liud892bec2018-11-30 14:51:45 -0800884 switch (arg) {
885 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800886 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
887 return 0;
888 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800889 case NUMBER_VERIFICATION_FAKE_CALL: {
890 boolean val = NumberVerificationManager.getInstance()
891 .checkIncomingCall(getNextArg());
892 getOutPrintWriter().println(val ? "1" : "0");
893 return 0;
894 }
Hall Liud892bec2018-11-30 14:51:45 -0800895 }
896
897 return -1;
898 }
899
Jordan Liu0ccee222021-04-27 11:55:13 -0700900 private boolean subIsEsim(int subId) {
901 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
902 if (info != null) {
903 return info.isEmbedded();
904 }
905 return false;
906 }
907
908 private int handleEnablePhysicalSubscription(boolean enable) {
909 PrintWriter errPw = getErrPrintWriter();
910 int subId = 0;
911 try {
912 subId = Integer.parseInt(getNextArgRequired());
913 } catch (NumberFormatException e) {
914 errPw.println((enable ? "enable" : "disable")
915 + "-physical-subscription requires an integer as a subId.");
916 return -1;
917 }
918 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
919 // non user build.
920 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
921 errPw.println("cc: Permission denied.");
922 return -1;
923 }
924 // Verify that the subId represents a physical sub
925 if (subIsEsim(subId)) {
926 errPw.println("SubId " + subId + " is not for a physical subscription");
927 return -1;
928 }
929 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
930 + " physical subscription with subId=" + subId);
931 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
932 return 0;
933 }
934
Jack Nudelman644b91a2021-03-12 14:09:48 -0800935 private int handleThermalMitigationCommand() {
936 String arg = getNextArg();
937 String packageName = getNextArg();
938 if (arg == null || packageName == null) {
939 onHelpThermalMitigation();
940 return 0;
941 }
942
943 if (!checkShellUid()) {
944 return -1;
945 }
946
947 switch (arg) {
948 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
949 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
950 return 0;
951 }
952 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
953 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
954 mContext);
955 return 0;
956 }
957 default:
958 onHelpThermalMitigation();
959 }
960
961 return -1;
962
963 }
964
Tyler Gunn92479152021-01-20 16:30:10 -0800965 private int handleD2dCommand() {
966 String arg = getNextArg();
967 if (arg == null) {
968 onHelpD2D();
969 return 0;
970 }
971
972 switch (arg) {
973 case D2D_SEND: {
974 return handleD2dSendCommand();
975 }
Tyler Gunnbabbda02021-02-10 11:05:02 -0800976 case D2D_TRANSPORT: {
977 return handleD2dTransportCommand();
978 }
Tyler Gunnd4575212021-05-03 14:46:49 -0700979 case D2D_SET_DEVICE_SUPPORT: {
980 return handleD2dDeviceSupportedCommand();
981 }
Tyler Gunn92479152021-01-20 16:30:10 -0800982 }
983
984 return -1;
985 }
986
987 private int handleD2dSendCommand() {
988 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -0800989 int messageType = -1;
990 int messageValue = -1;
991
Tyler Gunn92479152021-01-20 16:30:10 -0800992 String arg = getNextArg();
993 if (arg == null) {
994 onHelpD2D();
995 return 0;
996 }
997 try {
998 messageType = Integer.parseInt(arg);
999 } catch (NumberFormatException e) {
1000 errPw.println("message type must be a valid integer");
1001 return -1;
1002 }
1003
1004 arg = getNextArg();
1005 if (arg == null) {
1006 onHelpD2D();
1007 return 0;
1008 }
1009 try {
1010 messageValue = Integer.parseInt(arg);
1011 } catch (NumberFormatException e) {
1012 errPw.println("message value must be a valid integer");
1013 return -1;
1014 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001015
Tyler Gunn92479152021-01-20 16:30:10 -08001016 try {
1017 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1018 } catch (RemoteException e) {
1019 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1020 errPw.println("Exception: " + e.getMessage());
1021 return -1;
1022 }
1023
1024 return 0;
1025 }
1026
Tyler Gunnbabbda02021-02-10 11:05:02 -08001027 private int handleD2dTransportCommand() {
1028 PrintWriter errPw = getErrPrintWriter();
1029
1030 String arg = getNextArg();
1031 if (arg == null) {
1032 onHelpD2D();
1033 return 0;
1034 }
1035
1036 try {
1037 mInterface.setActiveDeviceToDeviceTransport(arg);
1038 } catch (RemoteException e) {
1039 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1040 errPw.println("Exception: " + e.getMessage());
1041 return -1;
1042 }
1043 return 0;
1044 }
Nazanin014f41e2021-05-06 17:26:31 -07001045 private int handleBarringCommand() {
1046 String arg = getNextArg();
1047 if (arg == null) {
1048 onHelpBarring();
1049 return 0;
1050 }
1051
1052 switch (arg) {
1053 case BARRING_SEND_INFO: {
1054 return handleBarringSendCommand();
1055 }
1056 }
1057 return -1;
1058 }
1059
1060 private int handleBarringSendCommand() {
1061 PrintWriter errPw = getErrPrintWriter();
1062 int slotId = getDefaultSlot();
Jack Yude40a3f2022-11-19 22:29:12 -08001063 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001064 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1065 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1066 boolean isConditionallyBarred = false;
1067 int conditionalBarringTimeSeconds = 0;
1068
1069 String opt;
1070 while ((opt = getNextOption()) != null) {
1071 switch (opt) {
1072 case "-s": {
1073 try {
1074 slotId = Integer.parseInt(getNextArgRequired());
Jack Yude40a3f2022-11-19 22:29:12 -08001075 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001076 } catch (NumberFormatException e) {
1077 errPw.println("barring send requires an integer as a SLOT_ID.");
1078 return -1;
1079 }
1080 break;
1081 }
1082 case "-b": {
1083 try {
1084 barringType = Integer.parseInt(getNextArgRequired());
1085 if (barringType < -1 || barringType > 2) {
1086 throw new NumberFormatException();
1087 }
1088
1089 } catch (NumberFormatException e) {
1090 errPw.println("barring send requires an integer in range [-1,2] as "
1091 + "a BARRING_TYPE.");
1092 return -1;
1093 }
1094 break;
1095 }
1096 case "-c": {
1097 try {
1098 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1099 } catch (Exception e) {
1100 errPw.println("barring send requires a boolean after -c indicating"
1101 + " conditional barring");
1102 return -1;
1103 }
1104 break;
1105 }
1106 case "-t": {
1107 try {
1108 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1109 } catch (NumberFormatException e) {
1110 errPw.println("barring send requires an integer for time of barring"
1111 + " in seconds after -t for conditional barring");
1112 return -1;
1113 }
1114 break;
1115 }
1116 }
1117 }
1118 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1119 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1120 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1121 barringServiceInfos.append(0, bsi);
1122 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1123 try {
1124 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1125 } catch (Exception e) {
1126 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1127 errPw.println("Exception: " + e.getMessage());
1128 return -1;
1129 }
1130 return 0;
1131 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001132
Tyler Gunnd4575212021-05-03 14:46:49 -07001133 private int handleD2dDeviceSupportedCommand() {
1134 PrintWriter errPw = getErrPrintWriter();
1135
1136 String arg = getNextArg();
1137 if (arg == null) {
1138 onHelpD2D();
1139 return 0;
1140 }
1141
1142 boolean isEnabled = "true".equals(arg.toLowerCase());
1143 try {
1144 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1145 } catch (RemoteException e) {
1146 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1147 errPw.println("Exception: " + e.getMessage());
1148 return -1;
1149 }
1150 return 0;
1151 }
1152
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001153 // ims set-ims-service
1154 private int handleImsSetServiceCommand() {
1155 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001156 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001157 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001158 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001159
1160 String opt;
1161 while ((opt = getNextOption()) != null) {
1162 switch (opt) {
1163 case "-s": {
1164 try {
1165 slotId = Integer.parseInt(getNextArgRequired());
1166 } catch (NumberFormatException e) {
1167 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1168 return -1;
1169 }
1170 break;
1171 }
1172 case "-c": {
1173 isCarrierService = true;
1174 break;
1175 }
1176 case "-d": {
1177 isCarrierService = false;
1178 break;
1179 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001180 case "-f": {
1181 String featureString = getNextArgRequired();
1182 String[] features = featureString.split(",");
1183 for (int i = 0; i < features.length; i++) {
1184 try {
1185 Integer result = Integer.parseInt(features[i]);
1186 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1187 || result >= ImsFeature.FEATURE_MAX) {
1188 errPw.println("ims set-ims-service -f " + result
1189 + " is an invalid feature.");
1190 return -1;
1191 }
1192 featuresList.add(result);
1193 } catch (NumberFormatException e) {
1194 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1195 + " as an integer.");
1196 return -1;
1197 }
1198 }
1199 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001200 }
1201 }
1202 // Mandatory param, either -c or -d
1203 if (isCarrierService == null) {
1204 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1205 return -1;
1206 }
1207
1208 String packageName = getNextArg();
1209
1210 try {
1211 if (packageName == null) {
1212 packageName = "";
1213 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001214 int[] featureArray = new int[featuresList.size()];
1215 for (int i = 0; i < featuresList.size(); i++) {
1216 featureArray[i] = featuresList.get(i);
1217 }
1218 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1219 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001220 if (VDBG) {
1221 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001222 + (isCarrierService ? "-c " : "-d ")
1223 + "-f " + featuresList + " "
1224 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001225 }
1226 getOutPrintWriter().println(result);
1227 } catch (RemoteException e) {
1228 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001229 + (isCarrierService ? "-c " : "-d ")
1230 + "-f " + featuresList + " "
1231 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001232 errPw.println("Exception: " + e.getMessage());
1233 return -1;
1234 }
1235 return 0;
1236 }
1237
Brad Ebinger999d3302020-11-25 14:31:39 -08001238 // ims clear-ims-service-override
1239 private int handleImsClearCarrierServiceCommand() {
1240 PrintWriter errPw = getErrPrintWriter();
1241 int slotId = getDefaultSlot();
1242
1243 String opt;
1244 while ((opt = getNextOption()) != null) {
1245 switch (opt) {
1246 case "-s": {
1247 try {
1248 slotId = Integer.parseInt(getNextArgRequired());
1249 } catch (NumberFormatException e) {
1250 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1251 return -1;
1252 }
1253 break;
1254 }
1255 }
1256 }
1257
1258 try {
1259 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1260 if (VDBG) {
1261 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1262 + ", result=" + result);
1263 }
1264 getOutPrintWriter().println(result);
1265 } catch (RemoteException e) {
1266 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1267 + ", error" + e.getMessage());
1268 errPw.println("Exception: " + e.getMessage());
1269 return -1;
1270 }
1271 return 0;
1272 }
1273
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001274 // ims get-ims-service
1275 private int handleImsGetServiceCommand() {
1276 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001277 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001278 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001279 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001280
1281 String opt;
1282 while ((opt = getNextOption()) != null) {
1283 switch (opt) {
1284 case "-s": {
1285 try {
1286 slotId = Integer.parseInt(getNextArgRequired());
1287 } catch (NumberFormatException e) {
1288 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1289 return -1;
1290 }
1291 break;
1292 }
1293 case "-c": {
1294 isCarrierService = true;
1295 break;
1296 }
1297 case "-d": {
1298 isCarrierService = false;
1299 break;
1300 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001301 case "-f": {
1302 try {
1303 featureType = Integer.parseInt(getNextArg());
1304 } catch (NumberFormatException e) {
1305 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1306 return -1;
1307 }
1308 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1309 || featureType >= ImsFeature.FEATURE_MAX) {
1310 errPw.println("ims get-ims-service -f invalid feature.");
1311 return -1;
1312 }
1313 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001314 }
1315 }
1316 // Mandatory param, either -c or -d
1317 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001318 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001319 return -1;
1320 }
1321
1322 String result;
1323 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001324 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001325 } catch (RemoteException e) {
1326 return -1;
1327 }
1328 if (VDBG) {
1329 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001330 + (isCarrierService ? "-c " : "-d ")
1331 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1332 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001333 }
1334 getOutPrintWriter().println(result);
1335 return 0;
1336 }
1337
1338 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001339 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001340 String opt;
1341 while ((opt = getNextOption()) != null) {
1342 switch (opt) {
1343 case "-s": {
1344 try {
1345 slotId = Integer.parseInt(getNextArgRequired());
1346 } catch (NumberFormatException e) {
1347 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1348 return -1;
1349 }
1350 break;
1351 }
1352 }
1353 }
1354 try {
1355 mInterface.enableIms(slotId);
1356 } catch (RemoteException e) {
1357 return -1;
1358 }
1359 if (VDBG) {
1360 Log.v(LOG_TAG, "ims enable -s " + slotId);
1361 }
1362 return 0;
1363 }
1364
1365 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001366 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001367 String opt;
1368 while ((opt = getNextOption()) != null) {
1369 switch (opt) {
1370 case "-s": {
1371 try {
1372 slotId = Integer.parseInt(getNextArgRequired());
1373 } catch (NumberFormatException e) {
1374 getErrPrintWriter().println(
1375 "ims disable requires an integer as a SLOT_ID.");
1376 return -1;
1377 }
1378 break;
1379 }
1380 }
1381 }
1382 try {
1383 mInterface.disableIms(slotId);
1384 } catch (RemoteException e) {
1385 return -1;
1386 }
1387 if (VDBG) {
1388 Log.v(LOG_TAG, "ims disable -s " + slotId);
1389 }
1390 return 0;
1391 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001392
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001393 private int handleCepChange() {
1394 Log.i(LOG_TAG, "handleCepChange");
1395 String opt = getNextArg();
1396 if (opt == null) {
1397 return -1;
1398 }
1399 boolean isCepEnabled = opt.equals("enable");
1400
1401 try {
1402 mInterface.setCepEnabled(isCepEnabled);
1403 } catch (RemoteException e) {
1404 return -1;
1405 }
1406 return 0;
1407 }
1408
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001409 private int getDefaultSlot() {
1410 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1411 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1412 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1413 // If there is no default, default to slot 0.
1414 slotId = DEFAULT_PHONE_ID;
1415 }
1416 return slotId;
1417 }
sqian2fff4a32018-11-05 14:18:37 -08001418
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001419 // Parse options related to Carrier Config Commands.
1420 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001421 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001422 CcOptionParseResult result = new CcOptionParseResult();
1423 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1424 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001425
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001426 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001427 while ((opt = getNextOption()) != null) {
1428 switch (opt) {
1429 case "-s": {
1430 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001431 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1432 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1433 errPw.println(tag + "No valid subscription found.");
1434 return null;
1435 }
1436
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001437 } catch (IllegalArgumentException e) {
1438 // Missing slot id
1439 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001440 return null;
1441 }
1442 break;
1443 }
1444 case "-p": {
1445 if (allowOptionPersistent) {
1446 result.mPersistent = true;
1447 } else {
1448 errPw.println(tag + "Unexpected option " + opt);
1449 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001450 }
1451 break;
1452 }
1453 default: {
1454 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001455 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001456 }
1457 }
1458 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001459 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001460 }
1461
1462 private int slotStringToSubId(String tag, String slotString) {
1463 int slotId = -1;
1464 try {
1465 slotId = Integer.parseInt(slotString);
1466 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001467 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1468 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1469 }
1470
1471 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001472 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1473 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1474 }
1475
Qiong Liuf25799b2020-09-10 10:13:46 +08001476 Phone phone = PhoneFactory.getPhone(slotId);
1477 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001478 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1479 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1480 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001481 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001482 }
1483
Hall Liud892bec2018-11-30 14:51:45 -08001484 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001485 // adb can run as root or as shell, depending on whether the device is rooted.
1486 return Binder.getCallingUid() == Process.SHELL_UID
1487 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001488 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001489
1490 private int handleCcCommand() {
1491 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1492 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001493 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001494 getErrPrintWriter().println("cc: Permission denied.");
1495 return -1;
1496 }
1497
1498 String arg = getNextArg();
1499 if (arg == null) {
1500 onHelpCc();
1501 return 0;
1502 }
1503
1504 switch (arg) {
1505 case CC_GET_VALUE: {
1506 return handleCcGetValue();
1507 }
1508 case CC_SET_VALUE: {
1509 return handleCcSetValue();
1510 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001511 case CC_SET_VALUES_FROM_XML: {
1512 return handleCcSetValuesFromXml();
1513 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001514 case CC_CLEAR_VALUES: {
1515 return handleCcClearValues();
1516 }
1517 default: {
1518 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1519 }
1520 }
1521 return -1;
1522 }
1523
1524 // cc get-value
1525 private int handleCcGetValue() {
1526 PrintWriter errPw = getErrPrintWriter();
1527 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1528 String key = null;
1529
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001530 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001531 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001532 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001533 return -1;
1534 }
1535
1536 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001537 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001538 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001539 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001540 return -1;
1541 }
1542
1543 // Get the key.
1544 key = getNextArg();
1545 if (key != null) {
1546 // A key was provided. Verify if it is a valid key
1547 if (!bundle.containsKey(key)) {
1548 errPw.println(tag + key + " is not a valid key.");
1549 return -1;
1550 }
1551
1552 // Print the carrier config value for key.
1553 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1554 } else {
1555 // No key provided. Show all values.
1556 // Iterate over a sorted list of all carrier config keys and print them.
1557 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1558 for (String k : sortedSet) {
1559 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1560 }
1561 }
1562 return 0;
1563 }
1564
1565 // cc set-value
1566 private int handleCcSetValue() {
1567 PrintWriter errPw = getErrPrintWriter();
1568 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1569
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001570 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001571 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001572 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001573 return -1;
1574 }
1575
1576 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001577 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001578 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001579 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001580 return -1;
1581 }
1582
1583 // Get the key.
1584 String key = getNextArg();
1585 if (key == null || key.equals("")) {
1586 errPw.println(tag + "KEY is missing");
1587 return -1;
1588 }
1589
1590 // Verify if the key is valid
1591 if (!originalValues.containsKey(key)) {
1592 errPw.println(tag + key + " is not a valid key.");
1593 return -1;
1594 }
1595
1596 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1597 ArrayList<String> valueList = new ArrayList<String>();
1598 while (peekNextArg() != null) {
1599 valueList.add(getNextArg());
1600 }
1601
1602 // Find the type of the carrier config value
1603 CcType type = getType(tag, key, originalValues);
1604 if (type == CcType.UNKNOWN) {
1605 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1606 return -1;
1607 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001608 if (type == CcType.PERSISTABLE_BUNDLE) {
1609 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1610 + "Use set-values-from-xml instead.");
1611 return -1;
1612 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001613
1614 // Create an override bundle containing the key and value that should be overriden.
1615 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1616 if (overrideBundle == null) {
1617 return -1;
1618 }
1619
1620 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001621 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001622
1623 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001624 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001625 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001626 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001627 return -1;
1628 }
1629
1630 // Print the original and new value.
1631 String originalValueString = ccValueToString(key, type, originalValues);
1632 String newValueString = ccValueToString(key, type, newValues);
1633 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1634 getOutPrintWriter().println("New value: \n" + newValueString);
1635
1636 return 0;
1637 }
1638
Allen Xuee00f0e2022-03-14 21:04:49 +00001639 // cc set-values-from-xml
1640 private int handleCcSetValuesFromXml() {
1641 PrintWriter errPw = getErrPrintWriter();
1642 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1643
1644 // Parse all options
Allen Xud8db8332022-05-20 22:26:42 +00001645 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001646 if (options == null) {
1647 return -1;
1648 }
1649
1650 // Get bundle containing all current carrier configuration values.
1651 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1652 if (originalValues == null) {
1653 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1654 return -1;
1655 }
1656
1657 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1658 if (overrideBundle == null) {
1659 return -1;
1660 }
1661
1662 // Verify all values are valid types
1663 for (String key : overrideBundle.keySet()) {
1664 CcType type = getType(tag, key, originalValues);
1665 if (type == CcType.UNKNOWN) {
1666 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1667 return -1;
1668 }
1669 }
1670
1671 // Override the value
1672 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1673
1674 // Find bundle containing all new carrier configuration values after the override.
1675 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1676 if (newValues == null) {
1677 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1678 return -1;
1679 }
1680
1681 // Print the original and new values
1682 overrideBundle.keySet().forEach(key -> {
1683 CcType type = getType(tag, key, originalValues);
1684 String originalValueString = ccValueToString(key, type, originalValues);
1685 String newValueString = ccValueToString(key, type, newValues);
1686 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1687 getOutPrintWriter().println("New value: \n" + newValueString);
1688 });
1689
1690 return 0;
1691 }
1692
1693 private PersistableBundle readPersistableBundleFromXml(String tag) {
1694 PersistableBundle subIdBundles;
1695 try {
1696 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1697 } catch (IOException | RuntimeException e) {
1698 PrintWriter errPw = getErrPrintWriter();
1699 errPw.println(tag + e);
1700 return null;
1701 }
1702
1703 return subIdBundles;
1704 }
1705
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001706 // cc clear-values
1707 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001708 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1709
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001710 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001711 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001712 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001713 return -1;
1714 }
1715
1716 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001717 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001718 getOutPrintWriter()
1719 .println("All previously set carrier config override values has been cleared");
1720 return 0;
1721 }
1722
1723 private CcType getType(String tag, String key, PersistableBundle bundle) {
1724 // Find the type by checking the type of the current value stored in the bundle.
1725 Object value = bundle.get(key);
1726
1727 if (CC_TYPE_MAP.containsKey(key)) {
1728 return CC_TYPE_MAP.get(key);
1729 } else if (value != null) {
1730 if (value instanceof Boolean) {
1731 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001732 }
1733 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001734 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001735 }
1736 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001737 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001738 }
1739 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001740 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001741 }
1742 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001743 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001744 }
1745 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001746 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001747 }
1748 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001749 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001750 }
1751 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001752 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001753 }
1754 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001755 return CcType.STRING_ARRAY;
1756 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001757 if (value instanceof PersistableBundle) {
1758 return CcType.PERSISTABLE_BUNDLE;
1759 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001760 } else {
1761 // Current value was null and can therefore not be used in order to find the type.
1762 // Check the name of the key to infer the type. This check is not needed for primitive
1763 // data types (boolean, double, int and long), since they can not be null.
1764 if (key.endsWith("double_array")) {
1765 return CcType.DOUBLE_ARRAY;
1766 }
1767 if (key.endsWith("int_array")) {
1768 return CcType.INT_ARRAY;
1769 }
1770 if (key.endsWith("long_array")) {
1771 return CcType.LONG_ARRAY;
1772 }
1773 if (key.endsWith("string")) {
1774 return CcType.STRING;
1775 }
1776 if (key.endsWith("string_array") || key.endsWith("strings")) {
1777 return CcType.STRING_ARRAY;
1778 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001779 if (key.endsWith("bundle")) {
1780 return CcType.PERSISTABLE_BUNDLE;
1781 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001782 }
1783
1784 // Not possible to infer the type by looking at the current value or the key.
1785 PrintWriter errPw = getErrPrintWriter();
1786 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1787 return CcType.UNKNOWN;
1788 }
1789
1790 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1791 String result;
1792 StringBuilder valueString = new StringBuilder();
1793 String typeString = type.toString();
1794 Object value = bundle.get(key);
1795
1796 if (value == null) {
1797 valueString.append("null");
1798 } else {
1799 switch (type) {
1800 case DOUBLE_ARRAY: {
1801 // Format the string representation of the int array as value1 value2......
1802 double[] valueArray = (double[]) value;
1803 for (int i = 0; i < valueArray.length; i++) {
1804 if (i != 0) {
1805 valueString.append(" ");
1806 }
1807 valueString.append(valueArray[i]);
1808 }
1809 break;
1810 }
1811 case INT_ARRAY: {
1812 // Format the string representation of the int array as value1 value2......
1813 int[] valueArray = (int[]) value;
1814 for (int i = 0; i < valueArray.length; i++) {
1815 if (i != 0) {
1816 valueString.append(" ");
1817 }
1818 valueString.append(valueArray[i]);
1819 }
1820 break;
1821 }
1822 case LONG_ARRAY: {
1823 // Format the string representation of the int array as value1 value2......
1824 long[] valueArray = (long[]) value;
1825 for (int i = 0; i < valueArray.length; i++) {
1826 if (i != 0) {
1827 valueString.append(" ");
1828 }
1829 valueString.append(valueArray[i]);
1830 }
1831 break;
1832 }
1833 case STRING: {
1834 valueString.append("\"" + value.toString() + "\"");
1835 break;
1836 }
1837 case STRING_ARRAY: {
1838 // Format the string representation of the string array as "value1" "value2"....
1839 String[] valueArray = (String[]) value;
1840 for (int i = 0; i < valueArray.length; i++) {
1841 if (i != 0) {
1842 valueString.append(" ");
1843 }
1844 if (valueArray[i] != null) {
1845 valueString.append("\"" + valueArray[i] + "\"");
1846 } else {
1847 valueString.append("null");
1848 }
1849 }
1850 break;
1851 }
1852 default: {
1853 valueString.append(value.toString());
1854 }
1855 }
1856 }
1857 return String.format("%-70s %-15s %s", key, typeString, valueString);
1858 }
1859
1860 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1861 ArrayList<String> valueList) {
1862 PrintWriter errPw = getErrPrintWriter();
1863 PersistableBundle bundle = new PersistableBundle();
1864
1865 // First verify that a valid number of values has been provided for the type.
1866 switch (type) {
1867 case BOOLEAN:
1868 case DOUBLE:
1869 case INT:
1870 case LONG: {
1871 if (valueList.size() != 1) {
1872 errPw.println(tag + "Expected 1 value for type " + type
1873 + ". Found: " + valueList.size());
1874 return null;
1875 }
1876 break;
1877 }
1878 case STRING: {
1879 if (valueList.size() > 1) {
1880 errPw.println(tag + "Expected 0 or 1 values for type " + type
1881 + ". Found: " + valueList.size());
1882 return null;
1883 }
1884 break;
1885 }
1886 }
1887
1888 // Parse the value according to type and add it to the Bundle.
1889 switch (type) {
1890 case BOOLEAN: {
1891 if ("true".equalsIgnoreCase(valueList.get(0))) {
1892 bundle.putBoolean(key, true);
1893 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1894 bundle.putBoolean(key, false);
1895 } else {
1896 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1897 return null;
1898 }
1899 break;
1900 }
1901 case DOUBLE: {
1902 try {
1903 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1904 } catch (NumberFormatException nfe) {
1905 // Not a valid double
1906 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1907 return null;
1908 }
1909 break;
1910 }
1911 case DOUBLE_ARRAY: {
1912 double[] valueDoubleArray = null;
1913 if (valueList.size() > 0) {
1914 valueDoubleArray = new double[valueList.size()];
1915 for (int i = 0; i < valueList.size(); i++) {
1916 try {
1917 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1918 } catch (NumberFormatException nfe) {
1919 // Not a valid double
1920 errPw.println(
1921 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1922 return null;
1923 }
1924 }
1925 }
1926 bundle.putDoubleArray(key, valueDoubleArray);
1927 break;
1928 }
1929 case INT: {
1930 try {
1931 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1932 } catch (NumberFormatException nfe) {
1933 // Not a valid integer
1934 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1935 return null;
1936 }
1937 break;
1938 }
1939 case INT_ARRAY: {
1940 int[] valueIntArray = null;
1941 if (valueList.size() > 0) {
1942 valueIntArray = new int[valueList.size()];
1943 for (int i = 0; i < valueList.size(); i++) {
1944 try {
1945 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1946 } catch (NumberFormatException nfe) {
1947 // Not a valid integer
1948 errPw.println(tag
1949 + "Unable to parse " + valueList.get(i) + " as an integer.");
1950 return null;
1951 }
1952 }
1953 }
1954 bundle.putIntArray(key, valueIntArray);
1955 break;
1956 }
1957 case LONG: {
1958 try {
1959 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1960 } catch (NumberFormatException nfe) {
1961 // Not a valid long
1962 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1963 return null;
1964 }
1965 break;
1966 }
1967 case LONG_ARRAY: {
1968 long[] valueLongArray = null;
1969 if (valueList.size() > 0) {
1970 valueLongArray = new long[valueList.size()];
1971 for (int i = 0; i < valueList.size(); i++) {
1972 try {
1973 valueLongArray[i] = Long.parseLong(valueList.get(i));
1974 } catch (NumberFormatException nfe) {
1975 // Not a valid long
1976 errPw.println(
1977 tag + "Unable to parse " + valueList.get(i) + " as a long");
1978 return null;
1979 }
1980 }
1981 }
1982 bundle.putLongArray(key, valueLongArray);
1983 break;
1984 }
1985 case STRING: {
1986 String value = null;
1987 if (valueList.size() > 0) {
1988 value = valueList.get(0);
1989 }
1990 bundle.putString(key, value);
1991 break;
1992 }
1993 case STRING_ARRAY: {
1994 String[] valueStringArray = null;
1995 if (valueList.size() > 0) {
1996 valueStringArray = new String[valueList.size()];
1997 valueList.toArray(valueStringArray);
1998 }
1999 bundle.putStringArray(key, valueStringArray);
2000 break;
2001 }
2002 }
2003 return bundle;
2004 }
Shuo Qian489d9282020-07-09 11:30:03 -07002005
2006 private int handleEndBlockSuppressionCommand() {
2007 if (!checkShellUid()) {
2008 return -1;
2009 }
2010
2011 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2012 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2013 }
2014 return 0;
2015 }
Hui Wang641e81c2020-10-12 12:14:23 -07002016
Michele Berionne54af4632020-12-28 20:23:16 +00002017 private int handleRestartModemCommand() {
2018 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2019 // non user build.
2020 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2021 getErrPrintWriter().println("RestartModem: Permission denied.");
2022 return -1;
2023 }
2024
2025 boolean result = TelephonyManager.getDefault().rebootRadio();
2026 getOutPrintWriter().println(result);
2027
2028 return result ? 0 : -1;
2029 }
2030
Ling Ma4fbab492022-01-25 22:36:16 +00002031 private int handleGetImei() {
2032 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2033 // non user build.
2034 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2035 getErrPrintWriter().println("Device IMEI: Permission denied.");
2036 return -1;
2037 }
2038
2039 final long identity = Binder.clearCallingIdentity();
2040
2041 String imei = null;
2042 String arg = getNextArg();
2043 if (arg != null) {
2044 try {
2045 int specifiedSlotIndex = Integer.parseInt(arg);
2046 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2047 } catch (NumberFormatException exception) {
2048 PrintWriter errPw = getErrPrintWriter();
2049 errPw.println("-s requires an integer as slot index.");
2050 return -1;
2051 }
2052
2053 } else {
2054 imei = TelephonyManager.from(mContext).getImei();
2055 }
2056 getOutPrintWriter().println("Device IMEI: " + imei);
2057
2058 Binder.restoreCallingIdentity(identity);
2059 return 0;
2060 }
2061
Michele Berionne5e411512020-11-13 02:36:59 +00002062 private int handleUnattendedReboot() {
2063 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2064 // non user build.
2065 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2066 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2067 return -1;
2068 }
2069
2070 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2071 getOutPrintWriter().println("result: " + result);
2072
2073 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2074 }
2075
Aman Gupta07124872022-02-09 08:02:14 +00002076 private int handleGetSimSlotsMapping() {
2077 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2078 // non user build.
2079 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2080 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2081 return -1;
2082 }
2083 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2084 String result = telephonyManager.getSimSlotMapping().toString();
2085 getOutPrintWriter().println("simSlotsMapping: " + result);
2086
2087 return 0;
2088 }
2089
Hui Wang641e81c2020-10-12 12:14:23 -07002090 private int handleGbaCommand() {
2091 String arg = getNextArg();
2092 if (arg == null) {
2093 onHelpGba();
2094 return 0;
2095 }
2096
2097 switch (arg) {
2098 case GBA_SET_SERVICE: {
2099 return handleGbaSetServiceCommand();
2100 }
2101 case GBA_GET_SERVICE: {
2102 return handleGbaGetServiceCommand();
2103 }
2104 case GBA_SET_RELEASE_TIME: {
2105 return handleGbaSetReleaseCommand();
2106 }
2107 case GBA_GET_RELEASE_TIME: {
2108 return handleGbaGetReleaseCommand();
2109 }
2110 }
2111
2112 return -1;
2113 }
2114
2115 private int getSubId(String cmd) {
2116 int slotId = getDefaultSlot();
2117 String opt = getNextOption();
2118 if (opt != null && opt.equals("-s")) {
2119 try {
2120 slotId = Integer.parseInt(getNextArgRequired());
2121 } catch (NumberFormatException e) {
2122 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2123 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2124 }
2125 }
Jack Yude40a3f2022-11-19 22:29:12 -08002126 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002127 }
2128
2129 private int handleGbaSetServiceCommand() {
2130 int subId = getSubId("gba set-service");
2131 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2132 return -1;
2133 }
2134
2135 String packageName = getNextArg();
2136 try {
2137 if (packageName == null) {
2138 packageName = "";
2139 }
2140 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2141 if (VDBG) {
2142 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2143 + packageName + ", result=" + result);
2144 }
2145 getOutPrintWriter().println(result);
2146 } catch (RemoteException e) {
2147 Log.w(LOG_TAG, "gba set-service " + subId + " "
2148 + packageName + ", error" + e.getMessage());
2149 getErrPrintWriter().println("Exception: " + e.getMessage());
2150 return -1;
2151 }
2152 return 0;
2153 }
2154
2155 private int handleGbaGetServiceCommand() {
2156 String result;
2157
2158 int subId = getSubId("gba get-service");
2159 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2160 return -1;
2161 }
2162
2163 try {
2164 result = mInterface.getBoundGbaService(subId);
2165 } catch (RemoteException e) {
2166 return -1;
2167 }
2168 if (VDBG) {
2169 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2170 }
2171 getOutPrintWriter().println(result);
2172 return 0;
2173 }
2174
2175 private int handleGbaSetReleaseCommand() {
2176 //the release time value could be -1
2177 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2178 : SubscriptionManager.getDefaultSubscriptionId();
2179 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2180 return -1;
2181 }
2182
2183 String intervalStr = getNextArg();
2184 if (intervalStr == null) {
2185 return -1;
2186 }
2187
2188 try {
2189 int interval = Integer.parseInt(intervalStr);
2190 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2191 if (VDBG) {
2192 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2193 + intervalStr + ", result=" + result);
2194 }
2195 getOutPrintWriter().println(result);
2196 } catch (NumberFormatException | RemoteException e) {
2197 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2198 + intervalStr + ", error" + e.getMessage());
2199 getErrPrintWriter().println("Exception: " + e.getMessage());
2200 return -1;
2201 }
2202 return 0;
2203 }
2204
2205 private int handleGbaGetReleaseCommand() {
2206 int subId = getSubId("gba get-release");
2207 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2208 return -1;
2209 }
2210
2211 int result = 0;
2212 try {
2213 result = mInterface.getGbaReleaseTime(subId);
2214 } catch (RemoteException e) {
2215 return -1;
2216 }
2217 if (VDBG) {
2218 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2219 }
2220 getOutPrintWriter().println(result);
2221 return 0;
2222 }
Hui Wang761a6682020-10-31 05:12:53 +00002223
2224 private int handleSingleRegistrationConfigCommand() {
2225 String arg = getNextArg();
2226 if (arg == null) {
2227 onHelpSrc();
2228 return 0;
2229 }
2230
2231 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002232 case SRC_SET_TEST_ENABLED: {
2233 return handleSrcSetTestEnabledCommand();
2234 }
2235 case SRC_GET_TEST_ENABLED: {
2236 return handleSrcGetTestEnabledCommand();
2237 }
Hui Wang761a6682020-10-31 05:12:53 +00002238 case SRC_SET_DEVICE_ENABLED: {
2239 return handleSrcSetDeviceEnabledCommand();
2240 }
2241 case SRC_GET_DEVICE_ENABLED: {
2242 return handleSrcGetDeviceEnabledCommand();
2243 }
2244 case SRC_SET_CARRIER_ENABLED: {
2245 return handleSrcSetCarrierEnabledCommand();
2246 }
2247 case SRC_GET_CARRIER_ENABLED: {
2248 return handleSrcGetCarrierEnabledCommand();
2249 }
Hui Wangb647abe2021-02-26 09:33:38 -08002250 case SRC_SET_FEATURE_ENABLED: {
2251 return handleSrcSetFeatureValidationCommand();
2252 }
2253 case SRC_GET_FEATURE_ENABLED: {
2254 return handleSrcGetFeatureValidationCommand();
2255 }
Hui Wang761a6682020-10-31 05:12:53 +00002256 }
2257
2258 return -1;
2259 }
2260
James.cf Linbcdf8b32021-01-14 16:44:13 +08002261 private int handleRcsUceCommand() {
2262 String arg = getNextArg();
2263 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002264 onHelpUce();
2265 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002266 }
2267
2268 switch (arg) {
2269 case UCE_REMOVE_EAB_CONTACT:
2270 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002271 case UCE_GET_EAB_CONTACT:
2272 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002273 case UCE_GET_EAB_CAPABILITY:
2274 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002275 case UCE_GET_DEVICE_ENABLED:
2276 return handleUceGetDeviceEnabledCommand();
2277 case UCE_SET_DEVICE_ENABLED:
2278 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002279 case UCE_OVERRIDE_PUBLISH_CAPS:
2280 return handleUceOverridePublishCaps();
2281 case UCE_GET_LAST_PIDF_XML:
2282 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002283 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2284 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002285 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2286 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002287 }
2288 return -1;
2289 }
2290
2291 private int handleRemovingEabContactCommand() {
2292 int subId = getSubId("uce remove-eab-contact");
2293 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2294 return -1;
2295 }
2296
2297 String phoneNumber = getNextArgRequired();
2298 if (TextUtils.isEmpty(phoneNumber)) {
2299 return -1;
2300 }
2301 int result = 0;
2302 try {
2303 result = mInterface.removeContactFromEab(subId, phoneNumber);
2304 } catch (RemoteException e) {
2305 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2306 getErrPrintWriter().println("Exception: " + e.getMessage());
2307 return -1;
2308 }
2309
2310 if (VDBG) {
2311 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2312 }
calvinpan293ea1b2021-02-04 17:52:13 +08002313 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002314 }
2315
calvinpane4a8a1d2021-01-25 13:51:18 +08002316 private int handleGettingEabContactCommand() {
2317 String phoneNumber = getNextArgRequired();
2318 if (TextUtils.isEmpty(phoneNumber)) {
2319 return -1;
2320 }
2321 String result = "";
2322 try {
2323 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002324 } catch (RemoteException e) {
2325 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2326 getErrPrintWriter().println("Exception: " + e.getMessage());
2327 return -1;
2328 }
2329
2330 if (VDBG) {
2331 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2332 }
calvinpan293ea1b2021-02-04 17:52:13 +08002333 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002334 return 0;
2335 }
2336
Calvin Pana1434322021-07-01 19:27:01 +08002337 private int handleGettingEabCapabilityCommand() {
2338 String phoneNumber = getNextArgRequired();
2339 if (TextUtils.isEmpty(phoneNumber)) {
2340 return -1;
2341 }
2342 String result = "";
2343 try {
2344 result = mInterface.getCapabilityFromEab(phoneNumber);
2345 } catch (RemoteException e) {
2346 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2347 getErrPrintWriter().println("Exception: " + e.getMessage());
2348 return -1;
2349 }
2350
2351 if (VDBG) {
2352 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2353 }
2354 getOutPrintWriter().println(result);
2355 return 0;
2356 }
2357
James.cf Lin4b784aa2021-01-31 03:25:15 +08002358 private int handleUceGetDeviceEnabledCommand() {
2359 boolean result = false;
2360 try {
2361 result = mInterface.getDeviceUceEnabled();
2362 } catch (RemoteException e) {
2363 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2364 return -1;
2365 }
2366 if (VDBG) {
2367 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2368 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002369 getOutPrintWriter().println(result);
2370 return 0;
2371 }
2372
James.cf Lin4b784aa2021-01-31 03:25:15 +08002373 private int handleUceSetDeviceEnabledCommand() {
2374 String enabledStr = getNextArg();
2375 if (TextUtils.isEmpty(enabledStr)) {
2376 return -1;
2377 }
2378
2379 try {
2380 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2381 mInterface.setDeviceUceEnabled(isEnabled);
2382 if (VDBG) {
2383 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2384 }
2385 } catch (NumberFormatException | RemoteException e) {
2386 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2387 getErrPrintWriter().println("Exception: " + e.getMessage());
2388 return -1;
2389 }
2390 return 0;
2391 }
2392
James.cf Line8713a42021-04-29 16:04:26 +08002393 private int handleUceRemoveRequestDisallowedStatus() {
2394 int subId = getSubId("uce remove-request-disallowed-status");
2395 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2396 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2397 return -1;
2398 }
2399 boolean result;
2400 try {
2401 result = mInterface.removeUceRequestDisallowedStatus(subId);
2402 } catch (RemoteException e) {
2403 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2404 return -1;
2405 }
2406 if (VDBG) {
2407 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2408 }
2409 getOutPrintWriter().println(result);
2410 return 0;
2411 }
2412
James.cf Lin0fc71b02021-05-25 01:37:38 +08002413 private int handleUceSetCapRequestTimeout() {
2414 int subId = getSubId("uce set-capabilities-request-timeout");
2415 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2416 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2417 return -1;
2418 }
2419 long timeoutAfterMs = Long.valueOf(getNextArg());
2420 boolean result;
2421 try {
2422 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2423 } catch (RemoteException e) {
2424 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2425 return -1;
2426 }
2427 if (VDBG) {
2428 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2429 }
2430 getOutPrintWriter().println(result);
2431 return 0;
2432 }
2433
Hui Wangbaaee6a2021-02-19 20:45:36 -08002434 private int handleSrcSetTestEnabledCommand() {
2435 String enabledStr = getNextArg();
2436 if (enabledStr == null) {
2437 return -1;
2438 }
2439
2440 try {
2441 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2442 if (VDBG) {
2443 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2444 }
2445 getOutPrintWriter().println("Done");
2446 } catch (NumberFormatException | RemoteException e) {
2447 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2448 getErrPrintWriter().println("Exception: " + e.getMessage());
2449 return -1;
2450 }
2451 return 0;
2452 }
2453
2454 private int handleSrcGetTestEnabledCommand() {
2455 boolean result = false;
2456 try {
2457 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2458 } catch (RemoteException e) {
2459 return -1;
2460 }
2461 if (VDBG) {
2462 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2463 }
2464 getOutPrintWriter().println(result);
2465 return 0;
2466 }
2467
Brad Ebinger14d467f2021-02-12 06:18:28 +00002468 private int handleUceOverridePublishCaps() {
2469 int subId = getSubId("uce override-published-caps");
2470 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2471 return -1;
2472 }
2473 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2474 String operation = getNextArgRequired();
2475 String caps = getNextArg();
2476 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2477 && !"list".equals(operation)) {
2478 getErrPrintWriter().println("Invalid operation: " + operation);
2479 return -1;
2480 }
2481
2482 // add/remove requires capabilities to be specified.
2483 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2484 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2485 + "specified");
2486 return -1;
2487 }
2488
2489 ArraySet<String> capSet = new ArraySet<>();
2490 if (!TextUtils.isEmpty(caps)) {
2491 String[] capArray = caps.split(":");
2492 for (String cap : capArray) {
2493 // Allow unknown tags to be passed in as well.
2494 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2495 }
2496 }
2497
2498 RcsContactUceCapability result = null;
2499 try {
2500 switch (operation) {
2501 case "add":
2502 result = mInterface.addUceRegistrationOverrideShell(subId,
2503 new ArrayList<>(capSet));
2504 break;
2505 case "remove":
2506 result = mInterface.removeUceRegistrationOverrideShell(subId,
2507 new ArrayList<>(capSet));
2508 break;
2509 case "clear":
2510 result = mInterface.clearUceRegistrationOverrideShell(subId);
2511 break;
2512 case "list":
2513 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2514 break;
2515 }
2516 } catch (RemoteException e) {
2517 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2518 getErrPrintWriter().println("Exception: " + e.getMessage());
2519 return -1;
2520 } catch (ServiceSpecificException sse) {
2521 // Reconstruct ImsException
2522 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2523 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2524 getErrPrintWriter().println("Exception: " + imsException);
2525 return -1;
2526 }
2527 if (result == null) {
2528 getErrPrintWriter().println("Service not available");
2529 return -1;
2530 }
2531 getOutPrintWriter().println(result);
2532 return 0;
2533 }
2534
2535 private int handleUceGetPidfXml() {
2536 int subId = getSubId("uce get-last-publish-pidf");
2537 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2538 return -1;
2539 }
2540
2541 String result;
2542 try {
2543 result = mInterface.getLastUcePidfXmlShell(subId);
2544 } catch (RemoteException e) {
2545 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2546 getErrPrintWriter().println("Exception: " + e.getMessage());
2547 return -1;
2548 } catch (ServiceSpecificException sse) {
2549 // Reconstruct ImsException
2550 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2551 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2552 getErrPrintWriter().println("Exception: " + imsException);
2553 return -1;
2554 }
2555 if (result == null) {
2556 getErrPrintWriter().println("Service not available");
2557 return -1;
2558 }
2559 getOutPrintWriter().println(result);
2560 return 0;
2561 }
2562
Hui Wang761a6682020-10-31 05:12:53 +00002563 private int handleSrcSetDeviceEnabledCommand() {
2564 String enabledStr = getNextArg();
2565 if (enabledStr == null) {
2566 return -1;
2567 }
2568
2569 try {
2570 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2571 if (VDBG) {
2572 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2573 }
2574 getOutPrintWriter().println("Done");
2575 } catch (NumberFormatException | RemoteException e) {
2576 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2577 getErrPrintWriter().println("Exception: " + e.getMessage());
2578 return -1;
2579 }
2580 return 0;
2581 }
2582
2583 private int handleSrcGetDeviceEnabledCommand() {
2584 boolean result = false;
2585 try {
2586 result = mInterface.getDeviceSingleRegistrationEnabled();
2587 } catch (RemoteException e) {
2588 return -1;
2589 }
2590 if (VDBG) {
2591 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2592 }
2593 getOutPrintWriter().println(result);
2594 return 0;
2595 }
2596
2597 private int handleSrcSetCarrierEnabledCommand() {
2598 //the release time value could be -1
2599 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2600 : SubscriptionManager.getDefaultSubscriptionId();
2601 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2602 return -1;
2603 }
2604
2605 String enabledStr = getNextArg();
2606 if (enabledStr == null) {
2607 return -1;
2608 }
2609
2610 try {
2611 boolean result =
2612 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2613 if (VDBG) {
2614 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2615 + enabledStr + ", result=" + result);
2616 }
2617 getOutPrintWriter().println(result);
2618 } catch (NumberFormatException | RemoteException e) {
2619 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2620 + enabledStr + ", error" + e.getMessage());
2621 getErrPrintWriter().println("Exception: " + e.getMessage());
2622 return -1;
2623 }
2624 return 0;
2625 }
2626
2627 private int handleSrcGetCarrierEnabledCommand() {
2628 int subId = getSubId("src get-carrier-enabled");
2629 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2630 return -1;
2631 }
2632
2633 boolean result = false;
2634 try {
2635 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2636 } catch (RemoteException e) {
2637 return -1;
2638 }
2639 if (VDBG) {
2640 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2641 }
2642 getOutPrintWriter().println(result);
2643 return 0;
2644 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002645
Hui Wangb647abe2021-02-26 09:33:38 -08002646 private int handleSrcSetFeatureValidationCommand() {
2647 //the release time value could be -1
2648 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2649 : SubscriptionManager.getDefaultSubscriptionId();
2650 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2651 return -1;
2652 }
2653
2654 String enabledStr = getNextArg();
2655 if (enabledStr == null) {
2656 return -1;
2657 }
2658
2659 try {
2660 boolean result =
2661 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2662 if (VDBG) {
2663 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2664 + enabledStr + ", result=" + result);
2665 }
2666 getOutPrintWriter().println(result);
2667 } catch (NumberFormatException | RemoteException e) {
2668 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2669 + enabledStr + ", error" + e.getMessage());
2670 getErrPrintWriter().println("Exception: " + e.getMessage());
2671 return -1;
2672 }
2673 return 0;
2674 }
2675
2676 private int handleSrcGetFeatureValidationCommand() {
2677 int subId = getSubId("src get-feature-validation");
2678 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2679 return -1;
2680 }
2681
2682 Boolean result = false;
2683 try {
2684 result = mInterface.getImsFeatureValidationOverride(subId);
2685 } catch (RemoteException e) {
2686 return -1;
2687 }
2688 if (VDBG) {
2689 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2690 }
2691 getOutPrintWriter().println(result);
2692 return 0;
2693 }
2694
2695
Hall Liuaa4211e2021-01-20 15:43:39 -08002696 private void onHelpCallComposer() {
2697 PrintWriter pw = getOutPrintWriter();
2698 pw.println("Call composer commands");
2699 pw.println(" callcomposer test-mode enable|disable|query");
2700 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2701 pw.println(" upload/download from carrier servers is disabled, and operations are");
2702 pw.println(" performed using emulated local files instead.");
2703 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2704 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2705 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002706 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2707 pw.println(" Enables or disables the user setting for call composer, as set by");
2708 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002709 }
2710
2711 private int handleCallComposerCommand() {
2712 String arg = getNextArg();
2713 if (arg == null) {
2714 onHelpCallComposer();
2715 return 0;
2716 }
2717
2718 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2719 "MODIFY_PHONE_STATE required for call composer shell cmds");
2720 switch (arg) {
2721 case CALL_COMPOSER_TEST_MODE: {
2722 String enabledStr = getNextArg();
2723 if (ENABLE.equals(enabledStr)) {
2724 CallComposerPictureManager.sTestMode = true;
2725 } else if (DISABLE.equals(enabledStr)) {
2726 CallComposerPictureManager.sTestMode = false;
2727 } else if (QUERY.equals(enabledStr)) {
2728 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2729 } else {
2730 onHelpCallComposer();
2731 return 1;
2732 }
2733 break;
2734 }
2735 case CALL_COMPOSER_SIMULATE_CALL: {
2736 int subscriptionId = Integer.valueOf(getNextArg());
2737 String uuidString = getNextArg();
2738 UUID uuid = UUID.fromString(uuidString);
2739 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2740 Binder.withCleanCallingIdentity(() -> {
2741 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2742 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2743 });
2744 try {
2745 Uri uri = storageUriFuture.get();
2746 getOutPrintWriter().println(String.valueOf(uri));
2747 } catch (Exception e) {
2748 throw new RuntimeException(e);
2749 }
2750 break;
2751 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002752 case CALL_COMPOSER_USER_SETTING: {
2753 try {
2754 int subscriptionId = Integer.valueOf(getNextArg());
2755 String enabledStr = getNextArg();
2756 if (ENABLE.equals(enabledStr)) {
2757 mInterface.setCallComposerStatus(subscriptionId,
2758 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2759 } else if (DISABLE.equals(enabledStr)) {
2760 mInterface.setCallComposerStatus(subscriptionId,
2761 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2762 } else if (QUERY.equals(enabledStr)) {
2763 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2764 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2765 } else {
2766 onHelpCallComposer();
2767 return 1;
2768 }
2769 } catch (RemoteException e) {
2770 e.printStackTrace(getOutPrintWriter());
2771 return 1;
2772 }
2773 break;
2774 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002775 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002776 return 0;
2777 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002778
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002779 private int handleHasCarrierPrivilegesCommand() {
2780 String packageName = getNextArgRequired();
2781
2782 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002783 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002784 try {
2785 hasCarrierPrivileges =
2786 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2787 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2788 } catch (RemoteException e) {
2789 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2790 getErrPrintWriter().println("Exception: " + e.getMessage());
2791 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002792 } finally {
2793 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002794 }
2795
2796 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002797 return 0;
2798 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002799
2800 private int handleAllowedNetworkTypesCommand(String command) {
2801 if (!checkShellUid()) {
2802 return -1;
2803 }
2804
2805 PrintWriter errPw = getErrPrintWriter();
2806 String tag = command + ": ";
2807 String opt;
2808 int subId = -1;
2809 Log.v(LOG_TAG, command + " start");
2810
2811 while ((opt = getNextOption()) != null) {
2812 if (opt.equals("-s")) {
2813 try {
2814 subId = slotStringToSubId(tag, getNextArgRequired());
2815 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2816 errPw.println(tag + "No valid subscription found.");
2817 return -1;
2818 }
2819 } catch (IllegalArgumentException e) {
2820 // Missing slot id
2821 errPw.println(tag + "SLOT_ID expected after -s.");
2822 return -1;
2823 }
2824 } else {
2825 errPw.println(tag + "Unknown option " + opt);
2826 return -1;
2827 }
2828 }
2829
2830 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2831 return handleGetAllowedNetworkTypesCommand(subId);
2832 }
2833 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2834 return handleSetAllowedNetworkTypesCommand(subId);
2835 }
2836 return -1;
2837 }
2838
2839 private int handleGetAllowedNetworkTypesCommand(int subId) {
2840 PrintWriter errPw = getErrPrintWriter();
2841
2842 long result = -1;
2843 try {
2844 if (mInterface != null) {
2845 result = mInterface.getAllowedNetworkTypesForReason(subId,
2846 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2847 } else {
2848 throw new IllegalStateException("telephony service is null.");
2849 }
2850 } catch (RemoteException e) {
2851 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2852 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2853 return -1;
2854 }
2855
2856 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2857 return 0;
2858 }
2859
2860 private int handleSetAllowedNetworkTypesCommand(int subId) {
2861 PrintWriter errPw = getErrPrintWriter();
2862
2863 String bitmaskString = getNextArg();
2864 if (TextUtils.isEmpty(bitmaskString)) {
2865 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2866 return -1;
2867 }
2868 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2869 if (allowedNetworkTypes < 0) {
2870 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2871 return -1;
2872 }
2873 boolean result = false;
2874 try {
2875 if (mInterface != null) {
2876 result = mInterface.setAllowedNetworkTypesForReason(subId,
2877 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2878 } else {
2879 throw new IllegalStateException("telephony service is null.");
2880 }
2881 } catch (RemoteException e) {
2882 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2883 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2884 return -1;
2885 }
2886
2887 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2888 if (result) {
2889 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2890 }
2891 getOutPrintWriter().println(resultMessage);
2892 return 0;
2893 }
2894
2895 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2896 if (TextUtils.isEmpty(bitmaskString)) {
2897 return -1;
2898 }
2899 if (VDBG) {
2900 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2901 + ", length: " + bitmaskString.length());
2902 }
2903 try {
2904 return Long.parseLong(bitmaskString, 2);
2905 } catch (NumberFormatException e) {
2906 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2907 return -1;
2908 }
2909 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002910
jimsun3b9ccac2021-10-26 15:01:23 +08002911 private int handleRadioSetModemServiceCommand() {
2912 PrintWriter errPw = getErrPrintWriter();
2913 String serviceName = null;
2914
2915 String opt;
2916 while ((opt = getNextOption()) != null) {
2917 switch (opt) {
2918 case "-s": {
2919 serviceName = getNextArgRequired();
2920 break;
2921 }
2922 }
2923 }
2924
2925 try {
2926 boolean result = mInterface.setModemService(serviceName);
2927 if (VDBG) {
2928 Log.v(LOG_TAG,
2929 "RadioSetModemService " + serviceName + ", result = " + result);
2930 }
2931 getOutPrintWriter().println(result);
2932 } catch (RemoteException e) {
2933 Log.w(LOG_TAG,
2934 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2935 errPw.println("Exception: " + e.getMessage());
2936 return -1;
2937 }
2938 return 0;
2939 }
2940
2941 private int handleRadioGetModemServiceCommand() {
2942 PrintWriter errPw = getErrPrintWriter();
2943 String result;
2944
2945 try {
2946 result = mInterface.getModemService();
2947 getOutPrintWriter().println(result);
2948 } catch (RemoteException e) {
2949 errPw.println("Exception: " + e.getMessage());
2950 return -1;
2951 }
2952 if (VDBG) {
2953 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2954 }
2955 return 0;
2956 }
2957
2958 private int handleRadioCommand() {
2959 String arg = getNextArg();
2960 if (arg == null) {
2961 onHelpRadio();
2962 return 0;
2963 }
2964
2965 switch (arg) {
2966 case RADIO_SET_MODEM_SERVICE:
2967 return handleRadioSetModemServiceCommand();
2968
2969 case RADIO_GET_MODEM_SERVICE:
2970 return handleRadioGetModemServiceCommand();
2971 }
2972
2973 return -1;
2974 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07002975}