blob: e7548f6ca0a810e838be4215183725851d7082ae [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Hall Liuaa4211e2021-01-20 15:43:39 -080024import android.Manifest;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010025import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080027import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010028import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070030import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000031import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070032import android.provider.BlockedNumberContract;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010033import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070034import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070035import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000036import android.telephony.TelephonyManager;
sqian9d4df8b2019-01-15 18:32:07 -080037import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000038import android.telephony.ims.ImsException;
39import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080040import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080041import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000042import android.util.ArrayMap;
43import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070044import android.util.Log;
45
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070047import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080048import com.android.internal.telephony.Phone;
49import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080050import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080051import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080052import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080053import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080054import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070055
56import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080057import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000058import java.util.Arrays;
59import java.util.Collections;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010060import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080061import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010062import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000063import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010064import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080065import java.util.UUID;
66import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070067
68/**
69 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
70 * permission checks have been done before onCommand was called. Make sure any commands processed
71 * here also contain the appropriate permissions checks.
72 */
73
Hall Liua1548bd2019-12-24 14:14:12 -080074public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070075
76 private static final String LOG_TAG = "TelephonyShellCommand";
77 // Don't commit with this true.
78 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070079 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
Hall Liuaa4211e2021-01-20 15:43:39 -080081 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070082 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080083 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080084 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080085 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070086 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000087 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000088 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010089 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080090 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080091 private static final String ENABLE = "enable";
92 private static final String DISABLE = "disable";
93 private static final String QUERY = "query";
94
Hall Liu7135e502021-02-04 16:58:17 -080095 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -080096 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -080097 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -080098
Brad Ebinger999d3302020-11-25 14:31:39 -080099 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
100 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
101 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700102 // Used to disable or enable processing of conference event package data from the network.
103 // This is handy for testing scenarios where CEP data does not exist on a network which does
104 // support CEP data.
105 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700106
Hall Liud892bec2018-11-30 14:51:45 -0800107 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800108 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800109
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100110 private static final String CC_GET_VALUE = "get-value";
111 private static final String CC_SET_VALUE = "set-value";
112 private static final String CC_CLEAR_VALUES = "clear-values";
113
Hui Wang641e81c2020-10-12 12:14:23 -0700114 private static final String GBA_SUBCOMMAND = "gba";
115 private static final String GBA_SET_SERVICE = "set-service";
116 private static final String GBA_GET_SERVICE = "get-service";
117 private static final String GBA_SET_RELEASE_TIME = "set-release";
118 private static final String GBA_GET_RELEASE_TIME = "get-release";
119
Hui Wang761a6682020-10-31 05:12:53 +0000120 private static final String SINGLE_REGISTATION_CONFIG = "src";
121 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
122 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
123 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
124 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800125 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
126 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800127 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
128 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000129
Tyler Gunn92479152021-01-20 16:30:10 -0800130 private static final String D2D_SUBCOMMAND = "d2d";
131 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800132 private static final String D2D_TRANSPORT = "transport";
Tyler Gunn92479152021-01-20 16:30:10 -0800133
James.cf Linbcdf8b32021-01-14 16:44:13 +0800134 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800135 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800136 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800137 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
138 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000139 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
140 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800141
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800142 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
143 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
144
Jordan Liu0ccee222021-04-27 11:55:13 -0700145 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
146 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
147
Jack Nudelman644b91a2021-03-12 14:09:48 -0800148 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
149 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
150 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
151
SongFerngWang98dd5992021-05-13 17:50:00 +0800152 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
153 "get-allowed-network-types-for-users";
154 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
155 "set-allowed-network-types-for-users";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700156 // Take advantage of existing methods that already contain permissions checks when possible.
157 private final ITelephony mInterface;
158
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100159 private SubscriptionManager mSubscriptionManager;
160 private CarrierConfigManager mCarrierConfigManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700161 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100162
163 private enum CcType {
164 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
165 STRING_ARRAY, UNKNOWN
166 }
167
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100168 private class CcOptionParseResult {
169 public int mSubId;
170 public boolean mPersistent;
171 }
172
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100173 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
174 // keys by looking at the end of the string which usually tells the type.
175 // For instance: "xxxx_string", "xxxx_string_array", etc.
176 // The carrier config keys in this map does not follow this convention. It is therefore not
177 // possible to infer the type for these keys by looking at the string.
178 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
179 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
180 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
181 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
182 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
183 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
184 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
185 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
186 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
187 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
188 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
189 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
190 CcType.STRING);
191 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
192 CcType.STRING_ARRAY);
193 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
194 CcType.STRING_ARRAY);
195 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
196 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
197 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
198 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
199 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
200 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
201 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
202 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
203 }
204 };
205
Brad Ebinger14d467f2021-02-12 06:18:28 +0000206 /**
207 * Map from a shorthand string to the feature tags required in registration required in order
208 * for the RCS feature to be considered "capable".
209 */
210 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
211 static {
212 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
213 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
214 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
215 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
216 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
217 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
218 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
219 FeatureTags.FEATURE_TAG_VIDEO)));
220 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
221 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
222 map.put("call_comp",
223 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
224 map.put("call_comp_mmtel",
225 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
226 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
227 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
228 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
229 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
230 // version
231 map.put("chatbot", new ArraySet<>(Arrays.asList(
232 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
233 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
234 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
235 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
236 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
237 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
238 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
239 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
240 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
241 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
242 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
243 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
244 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
245 }
246
247
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100248 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700249 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100250 mCarrierConfigManager =
251 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
252 mSubscriptionManager = (SubscriptionManager)
253 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700254 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700255 }
256
257 @Override
258 public int onCommand(String cmd) {
259 if (cmd == null) {
260 return handleDefaultCommands(null);
261 }
262
263 switch (cmd) {
264 case IMS_SUBCOMMAND: {
265 return handleImsCommand();
266 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800267 case RCS_UCE_COMMAND:
268 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800269 case NUMBER_VERIFICATION_SUBCOMMAND:
270 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800271 case EMERGENCY_CALLBACK_MODE:
272 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800273 case EMERGENCY_NUMBER_TEST_MODE:
274 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100275 case CARRIER_CONFIG_SUBCOMMAND: {
276 return handleCcCommand();
277 }
Shuo Qianf5125122019-12-16 17:03:07 -0800278 case DATA_TEST_MODE:
279 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700280 case END_BLOCK_SUPPRESSION:
281 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700282 case GBA_SUBCOMMAND:
283 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800284 case D2D_SUBCOMMAND:
285 return handleD2dCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000286 case SINGLE_REGISTATION_CONFIG:
287 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000288 case RESTART_MODEM:
289 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800290 case CALL_COMPOSER_SUBCOMMAND:
291 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000292 case UNATTENDED_REBOOT:
293 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800294 case HAS_CARRIER_PRIVILEGES_COMMAND:
295 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800296 case THERMAL_MITIGATION_COMMAND:
297 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700298 case DISABLE_PHYSICAL_SUBSCRIPTION:
299 return handleEnablePhysicalSubscription(false);
300 case ENABLE_PHYSICAL_SUBSCRIPTION:
301 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800302 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
303 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
304 return handleAllowedNetworkTypesCommand(cmd);
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700305 default: {
306 return handleDefaultCommands(cmd);
307 }
308 }
309 }
310
311 @Override
312 public void onHelp() {
313 PrintWriter pw = getOutPrintWriter();
314 pw.println("Telephony Commands:");
315 pw.println(" help");
316 pw.println(" Print this help text.");
317 pw.println(" ims");
318 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800319 pw.println(" uce");
320 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800321 pw.println(" emergency-number-test-mode");
322 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700323 pw.println(" end-block-suppression");
324 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800325 pw.println(" data");
326 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100327 pw.println(" cc");
328 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700329 pw.println(" gba");
330 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000331 pw.println(" src");
332 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000333 pw.println(" restart-modem");
334 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000335 pw.println(" unattended-reboot");
336 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800337 pw.println(" has-carrier-privileges [package]");
338 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800339 pw.println(" get-allowed-network-types-for-users");
340 pw.println(" Get the Allowed Network Types.");
341 pw.println(" set-allowed-network-types-for-users");
342 pw.println(" Set the Allowed Network Types.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700343 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800344 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800345 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700346 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800347 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100348 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700349 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000350 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800351 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700352 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800353 onHelpAllowedNetworkTypes();
Tyler Gunn92479152021-01-20 16:30:10 -0800354 }
355
356 private void onHelpD2D() {
357 PrintWriter pw = getOutPrintWriter();
358 pw.println("D2D Comms Commands:");
359 pw.println(" d2d send TYPE VALUE");
360 pw.println(" Sends a D2D message of specified type and value.");
361 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
362 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
363 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
364 MESSAGE_CALL_AUDIO_CODEC));
365 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
366 + Communicator.messageToString(
367 MESSAGE_DEVICE_BATTERY_STATE));
368 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
369 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800370 pw.println(" d2d transport TYPE");
371 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
372 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700373 }
374
375 private void onHelpIms() {
376 PrintWriter pw = getOutPrintWriter();
377 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800378 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700379 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
380 pw.println(" ImsService. Options are:");
381 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
382 pw.println(" is specified, it will choose the default voice SIM slot.");
383 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
384 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800385 pw.println(" -f: Set the feature that this override if for, if no option is");
386 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700387 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
388 pw.println(" Gets the package name of the currently defined ImsService.");
389 pw.println(" Options are:");
390 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
391 pw.println(" is specified, it will choose the default voice SIM slot.");
392 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000393 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800394 pw.println(" -f: The feature type that the query will be requested for. If none is");
395 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800396 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
397 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
398 pw.println(" configuration overrides. Options are:");
399 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
400 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700401 pw.println(" ims enable [-s SLOT_ID]");
402 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
403 pw.println(" if none is specified.");
404 pw.println(" ims disable [-s SLOT_ID]");
405 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
406 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700407 pw.println(" ims conference-event-package [enable/disable]");
408 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700409 }
410
James.cf Linbcdf8b32021-01-14 16:44:13 +0800411 private void onHelpUce() {
412 PrintWriter pw = getOutPrintWriter();
413 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800414 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
415 pw.println(" Get the EAB contacts from the EAB database.");
416 pw.println(" Options are:");
417 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
418 pw.println(" Expected output format :");
419 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800420 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
421 pw.println(" Remove the EAB contacts from the EAB database.");
422 pw.println(" Options are:");
423 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
424 pw.println(" is specified, it will choose the default voice SIM slot.");
425 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800426 pw.println(" uce get-device-enabled");
427 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
428 pw.println(" uce set-device-enabled true|false");
429 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
430 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000431 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
432 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
433 pw.println(" Options are:");
434 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
435 pw.println(" is specified, it will choose the default voice SIM slot.");
436 pw.println(" add [CAPABILITY]: add a new capability");
437 pw.println(" remove [CAPABILITY]: remove a capability");
438 pw.println(" clear: clear all capability overrides");
439 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
440 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
441 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
442 pw.println(" chatbot_sa, chatbot_role] as well as full length");
443 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
444 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
445 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
446 pw.println(" PUBLISH is active");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800447 }
448
Hall Liud892bec2018-11-30 14:51:45 -0800449 private void onHelpNumberVerification() {
450 PrintWriter pw = getOutPrintWriter();
451 pw.println("Number verification commands");
452 pw.println(" numverify override-package PACKAGE_NAME;");
453 pw.println(" Set the authorized package for number verification.");
454 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800455 pw.println(" numverify fake-call NUMBER;");
456 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
457 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800458 }
459
Jack Nudelman644b91a2021-03-12 14:09:48 -0800460 private void onHelpThermalMitigation() {
461 PrintWriter pw = getOutPrintWriter();
462 pw.println("Thermal mitigation commands");
463 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
464 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
465 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
466 pw.println(" Remove the package from one of the authorized packages for thermal "
467 + "mitigation.");
468 }
469
Jordan Liu0ccee222021-04-27 11:55:13 -0700470 private void onHelpDisableOrEnablePhysicalSubscription() {
471 PrintWriter pw = getOutPrintWriter();
472 pw.println("Disable or enable a physical subscription");
473 pw.println(" disable-physical-subscription SUB_ID");
474 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
475 pw.println(" enable-physical-subscription SUB_ID");
476 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
477 }
478
Shuo Qianf5125122019-12-16 17:03:07 -0800479 private void onHelpDataTestMode() {
480 PrintWriter pw = getOutPrintWriter();
481 pw.println("Mobile Data Test Mode Commands:");
482 pw.println(" data enable: enable mobile data connectivity");
483 pw.println(" data disable: disable mobile data connectivity");
484 }
485
sqian9d4df8b2019-01-15 18:32:07 -0800486 private void onHelpEmergencyNumber() {
487 PrintWriter pw = getOutPrintWriter();
488 pw.println("Emergency Number Test Mode Commands:");
489 pw.println(" emergency-number-test-mode ");
490 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
491 + " the test mode");
492 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700493 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800494 pw.println(" -c: clear the emergency number list in the test mode.");
495 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700496 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800497 pw.println(" -p: get the full emergency number list in the test mode.");
498 }
499
Shuo Qian489d9282020-07-09 11:30:03 -0700500 private void onHelpEndBlockSupperssion() {
501 PrintWriter pw = getOutPrintWriter();
502 pw.println("End Block Suppression command:");
503 pw.println(" end-block-suppression: disable suppressing blocking by contact");
504 pw.println(" with emergency services.");
505 }
506
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100507 private void onHelpCc() {
508 PrintWriter pw = getOutPrintWriter();
509 pw.println("Carrier Config Commands:");
510 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
511 pw.println(" Print carrier config values.");
512 pw.println(" Options are:");
513 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
514 pw.println(" is specified, it will choose the default voice SIM slot.");
515 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
516 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100517 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100518 pw.println(" Set carrier config KEY to NEW_VALUE.");
519 pw.println(" Options are:");
520 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
521 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100522 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100523 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
524 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
525 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
526 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
527 pw.println(" cc clear-values [-s SLOT_ID]");
528 pw.println(" Clear all carrier override values that has previously been set");
529 pw.println(" with set-value");
530 pw.println(" Options are:");
531 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
532 pw.println(" is specified, it will choose the default voice SIM slot.");
533 }
534
Hui Wang641e81c2020-10-12 12:14:23 -0700535 private void onHelpGba() {
536 PrintWriter pw = getOutPrintWriter();
537 pw.println("Gba Commands:");
538 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
539 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
540 pw.println(" Options are:");
541 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
542 pw.println(" is specified, it will choose the default voice SIM slot.");
543 pw.println(" gba get-service [-s SLOT_ID]");
544 pw.println(" Gets the package name of the currently defined GbaService.");
545 pw.println(" Options are:");
546 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
547 pw.println(" is specified, it will choose the default voice SIM slot.");
548 pw.println(" gba set-release [-s SLOT_ID] n");
549 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
550 pw.println(" Do not release/unbind if n is -1.");
551 pw.println(" Options are:");
552 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
553 pw.println(" is specified, it will choose the default voice SIM slot.");
554 pw.println(" gba get-release [-s SLOT_ID]");
555 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
556 pw.println(" Options are:");
557 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
558 pw.println(" is specified, it will choose the default voice SIM slot.");
559 }
560
Hui Wang761a6682020-10-31 05:12:53 +0000561 private void onHelpSrc() {
562 PrintWriter pw = getOutPrintWriter();
563 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800564 pw.println(" src set-test-enabled true|false");
565 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
566 pw.println(" The value could be true, false, or null(undefined).");
567 pw.println(" src get-test-enabled");
568 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000569 pw.println(" src set-device-enabled true|false|null");
570 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
571 pw.println(" The value could be true, false, or null(undefined).");
572 pw.println(" src get-device-enabled");
573 pw.println(" Gets the device config for RCS VoLTE single registration.");
574 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
575 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
576 pw.println(" The value could be true, false, or null(undefined).");
577 pw.println(" Options are:");
578 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
579 pw.println(" is specified, it will choose the default voice SIM slot.");
580 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
581 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
582 pw.println(" Options are:");
583 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
584 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800585 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
586 pw.println(" Sets ims feature validation result.");
587 pw.println(" The value could be true, false, or null(undefined).");
588 pw.println(" Options are:");
589 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
590 pw.println(" is specified, it will choose the default voice SIM slot.");
591 pw.println(" src get-feature-validation [-s SLOT_ID]");
592 pw.println(" Gets ims feature validation override value.");
593 pw.println(" Options are:");
594 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
595 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000596 }
597
SongFerngWang98dd5992021-05-13 17:50:00 +0800598 private void onHelpAllowedNetworkTypes() {
599 PrintWriter pw = getOutPrintWriter();
600 pw.println("Allowed Network Types Commands:");
601 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
602 pw.println(" Print allowed network types value.");
603 pw.println(" Options are:");
604 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
605 pw.println(" option is specified, it will choose the default voice SIM slot.");
606 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
607 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
608 pw.println(" Options are:");
609 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
610 pw.println(" option is specified, it will choose the default voice SIM slot.");
611 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
612 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
613 pw.println(" at TelephonyManager.java");
614 pw.println(" For example:");
615 pw.println(" NR only : 10000000000000000000");
616 pw.println(" NR|LTE : 11000001000000000000");
617 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
618 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
619 pw.println(" LTE only : 01000001000000000000");
620 }
621
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700622 private int handleImsCommand() {
623 String arg = getNextArg();
624 if (arg == null) {
625 onHelpIms();
626 return 0;
627 }
628
629 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800630 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700631 return handleImsSetServiceCommand();
632 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800633 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700634 return handleImsGetServiceCommand();
635 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800636 case IMS_CLEAR_SERVICE_OVERRIDE: {
637 return handleImsClearCarrierServiceCommand();
638 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800639 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700640 return handleEnableIms();
641 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800642 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700643 return handleDisableIms();
644 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700645 case IMS_CEP: {
646 return handleCepChange();
647 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700648 }
649
650 return -1;
651 }
652
Shuo Qianf5125122019-12-16 17:03:07 -0800653 private int handleDataTestModeCommand() {
654 PrintWriter errPw = getErrPrintWriter();
655 String arg = getNextArgRequired();
656 if (arg == null) {
657 onHelpDataTestMode();
658 return 0;
659 }
660 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800661 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800662 try {
663 mInterface.enableDataConnectivity();
664 } catch (RemoteException ex) {
665 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
666 errPw.println("Exception: " + ex.getMessage());
667 return -1;
668 }
669 break;
670 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800671 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800672 try {
673 mInterface.disableDataConnectivity();
674 } catch (RemoteException ex) {
675 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
676 errPw.println("Exception: " + ex.getMessage());
677 return -1;
678 }
679 break;
680 }
681 default:
682 onHelpDataTestMode();
683 break;
684 }
685 return 0;
686 }
687
Shuo Qianccbaf742021-02-22 18:32:21 -0800688 private int handleEmergencyCallbackModeCommand() {
689 PrintWriter errPw = getErrPrintWriter();
690 try {
691 mInterface.startEmergencyCallbackMode();
692 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
693 } catch (RemoteException ex) {
694 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
695 errPw.println("Exception: " + ex.getMessage());
696 return -1;
697 }
698 return 0;
699 }
700
sqian9d4df8b2019-01-15 18:32:07 -0800701 private int handleEmergencyNumberTestModeCommand() {
702 PrintWriter errPw = getErrPrintWriter();
703 String opt = getNextOption();
704 if (opt == null) {
705 onHelpEmergencyNumber();
706 return 0;
707 }
708
709 switch (opt) {
710 case "-a": {
711 String emergencyNumberCmd = getNextArgRequired();
712 if (emergencyNumberCmd == null
713 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700714 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800715 + " to be specified after -a in the command ");
716 return -1;
717 }
718 try {
719 mInterface.updateEmergencyNumberListTestMode(
720 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
721 new EmergencyNumber(emergencyNumberCmd, "", "",
722 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
723 new ArrayList<String>(),
724 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
725 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
726 } catch (RemoteException ex) {
727 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
728 + ", error " + ex.getMessage());
729 errPw.println("Exception: " + ex.getMessage());
730 return -1;
731 }
732 break;
733 }
734 case "-c": {
735 try {
736 mInterface.updateEmergencyNumberListTestMode(
737 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
738 } catch (RemoteException ex) {
739 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
740 errPw.println("Exception: " + ex.getMessage());
741 return -1;
742 }
743 break;
744 }
745 case "-r": {
746 String emergencyNumberCmd = getNextArgRequired();
747 if (emergencyNumberCmd == null
748 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700749 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800750 + " to be specified after -r in the command ");
751 return -1;
752 }
753 try {
754 mInterface.updateEmergencyNumberListTestMode(
755 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
756 new EmergencyNumber(emergencyNumberCmd, "", "",
757 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
758 new ArrayList<String>(),
759 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
760 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
761 } catch (RemoteException ex) {
762 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
763 + ", error " + ex.getMessage());
764 errPw.println("Exception: " + ex.getMessage());
765 return -1;
766 }
767 break;
768 }
769 case "-p": {
770 try {
771 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
772 } catch (RemoteException ex) {
773 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
774 errPw.println("Exception: " + ex.getMessage());
775 return -1;
776 }
777 break;
778 }
779 default:
780 onHelpEmergencyNumber();
781 break;
782 }
783 return 0;
784 }
785
Hall Liud892bec2018-11-30 14:51:45 -0800786 private int handleNumberVerificationCommand() {
787 String arg = getNextArg();
788 if (arg == null) {
789 onHelpNumberVerification();
790 return 0;
791 }
792
Hall Liuca5af3a2018-12-04 16:58:23 -0800793 if (!checkShellUid()) {
794 return -1;
795 }
796
Hall Liud892bec2018-11-30 14:51:45 -0800797 switch (arg) {
798 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800799 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
800 return 0;
801 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800802 case NUMBER_VERIFICATION_FAKE_CALL: {
803 boolean val = NumberVerificationManager.getInstance()
804 .checkIncomingCall(getNextArg());
805 getOutPrintWriter().println(val ? "1" : "0");
806 return 0;
807 }
Hall Liud892bec2018-11-30 14:51:45 -0800808 }
809
810 return -1;
811 }
812
Jordan Liu0ccee222021-04-27 11:55:13 -0700813 private boolean subIsEsim(int subId) {
814 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
815 if (info != null) {
816 return info.isEmbedded();
817 }
818 return false;
819 }
820
821 private int handleEnablePhysicalSubscription(boolean enable) {
822 PrintWriter errPw = getErrPrintWriter();
823 int subId = 0;
824 try {
825 subId = Integer.parseInt(getNextArgRequired());
826 } catch (NumberFormatException e) {
827 errPw.println((enable ? "enable" : "disable")
828 + "-physical-subscription requires an integer as a subId.");
829 return -1;
830 }
831 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
832 // non user build.
833 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
834 errPw.println("cc: Permission denied.");
835 return -1;
836 }
837 // Verify that the subId represents a physical sub
838 if (subIsEsim(subId)) {
839 errPw.println("SubId " + subId + " is not for a physical subscription");
840 return -1;
841 }
842 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
843 + " physical subscription with subId=" + subId);
844 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
845 return 0;
846 }
847
Jack Nudelman644b91a2021-03-12 14:09:48 -0800848 private int handleThermalMitigationCommand() {
849 String arg = getNextArg();
850 String packageName = getNextArg();
851 if (arg == null || packageName == null) {
852 onHelpThermalMitigation();
853 return 0;
854 }
855
856 if (!checkShellUid()) {
857 return -1;
858 }
859
860 switch (arg) {
861 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
862 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
863 return 0;
864 }
865 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
866 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
867 mContext);
868 return 0;
869 }
870 default:
871 onHelpThermalMitigation();
872 }
873
874 return -1;
875
876 }
877
Tyler Gunn92479152021-01-20 16:30:10 -0800878 private int handleD2dCommand() {
879 String arg = getNextArg();
880 if (arg == null) {
881 onHelpD2D();
882 return 0;
883 }
884
885 switch (arg) {
886 case D2D_SEND: {
887 return handleD2dSendCommand();
888 }
Tyler Gunnbabbda02021-02-10 11:05:02 -0800889 case D2D_TRANSPORT: {
890 return handleD2dTransportCommand();
891 }
Tyler Gunn92479152021-01-20 16:30:10 -0800892 }
893
894 return -1;
895 }
896
897 private int handleD2dSendCommand() {
898 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -0800899 int messageType = -1;
900 int messageValue = -1;
901
Tyler Gunn92479152021-01-20 16:30:10 -0800902 String arg = getNextArg();
903 if (arg == null) {
904 onHelpD2D();
905 return 0;
906 }
907 try {
908 messageType = Integer.parseInt(arg);
909 } catch (NumberFormatException e) {
910 errPw.println("message type must be a valid integer");
911 return -1;
912 }
913
914 arg = getNextArg();
915 if (arg == null) {
916 onHelpD2D();
917 return 0;
918 }
919 try {
920 messageValue = Integer.parseInt(arg);
921 } catch (NumberFormatException e) {
922 errPw.println("message value must be a valid integer");
923 return -1;
924 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800925
Tyler Gunn92479152021-01-20 16:30:10 -0800926 try {
927 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
928 } catch (RemoteException e) {
929 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
930 errPw.println("Exception: " + e.getMessage());
931 return -1;
932 }
933
934 return 0;
935 }
936
Tyler Gunnbabbda02021-02-10 11:05:02 -0800937 private int handleD2dTransportCommand() {
938 PrintWriter errPw = getErrPrintWriter();
939
940 String arg = getNextArg();
941 if (arg == null) {
942 onHelpD2D();
943 return 0;
944 }
945
946 try {
947 mInterface.setActiveDeviceToDeviceTransport(arg);
948 } catch (RemoteException e) {
949 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
950 errPw.println("Exception: " + e.getMessage());
951 return -1;
952 }
953 return 0;
954 }
955
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700956 // ims set-ims-service
957 private int handleImsSetServiceCommand() {
958 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700959 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700960 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -0800961 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700962
963 String opt;
964 while ((opt = getNextOption()) != null) {
965 switch (opt) {
966 case "-s": {
967 try {
968 slotId = Integer.parseInt(getNextArgRequired());
969 } catch (NumberFormatException e) {
970 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
971 return -1;
972 }
973 break;
974 }
975 case "-c": {
976 isCarrierService = true;
977 break;
978 }
979 case "-d": {
980 isCarrierService = false;
981 break;
982 }
Brad Ebinger24c29992019-12-05 13:03:21 -0800983 case "-f": {
984 String featureString = getNextArgRequired();
985 String[] features = featureString.split(",");
986 for (int i = 0; i < features.length; i++) {
987 try {
988 Integer result = Integer.parseInt(features[i]);
989 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
990 || result >= ImsFeature.FEATURE_MAX) {
991 errPw.println("ims set-ims-service -f " + result
992 + " is an invalid feature.");
993 return -1;
994 }
995 featuresList.add(result);
996 } catch (NumberFormatException e) {
997 errPw.println("ims set-ims-service -f tried to parse " + features[i]
998 + " as an integer.");
999 return -1;
1000 }
1001 }
1002 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001003 }
1004 }
1005 // Mandatory param, either -c or -d
1006 if (isCarrierService == null) {
1007 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1008 return -1;
1009 }
1010
1011 String packageName = getNextArg();
1012
1013 try {
1014 if (packageName == null) {
1015 packageName = "";
1016 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001017 int[] featureArray = new int[featuresList.size()];
1018 for (int i = 0; i < featuresList.size(); i++) {
1019 featureArray[i] = featuresList.get(i);
1020 }
1021 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1022 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001023 if (VDBG) {
1024 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001025 + (isCarrierService ? "-c " : "-d ")
1026 + "-f " + featuresList + " "
1027 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001028 }
1029 getOutPrintWriter().println(result);
1030 } catch (RemoteException e) {
1031 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001032 + (isCarrierService ? "-c " : "-d ")
1033 + "-f " + featuresList + " "
1034 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001035 errPw.println("Exception: " + e.getMessage());
1036 return -1;
1037 }
1038 return 0;
1039 }
1040
Brad Ebinger999d3302020-11-25 14:31:39 -08001041 // ims clear-ims-service-override
1042 private int handleImsClearCarrierServiceCommand() {
1043 PrintWriter errPw = getErrPrintWriter();
1044 int slotId = getDefaultSlot();
1045
1046 String opt;
1047 while ((opt = getNextOption()) != null) {
1048 switch (opt) {
1049 case "-s": {
1050 try {
1051 slotId = Integer.parseInt(getNextArgRequired());
1052 } catch (NumberFormatException e) {
1053 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1054 return -1;
1055 }
1056 break;
1057 }
1058 }
1059 }
1060
1061 try {
1062 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1063 if (VDBG) {
1064 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1065 + ", result=" + result);
1066 }
1067 getOutPrintWriter().println(result);
1068 } catch (RemoteException e) {
1069 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1070 + ", error" + e.getMessage());
1071 errPw.println("Exception: " + e.getMessage());
1072 return -1;
1073 }
1074 return 0;
1075 }
1076
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001077 // ims get-ims-service
1078 private int handleImsGetServiceCommand() {
1079 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001080 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001081 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001082 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001083
1084 String opt;
1085 while ((opt = getNextOption()) != null) {
1086 switch (opt) {
1087 case "-s": {
1088 try {
1089 slotId = Integer.parseInt(getNextArgRequired());
1090 } catch (NumberFormatException e) {
1091 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1092 return -1;
1093 }
1094 break;
1095 }
1096 case "-c": {
1097 isCarrierService = true;
1098 break;
1099 }
1100 case "-d": {
1101 isCarrierService = false;
1102 break;
1103 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001104 case "-f": {
1105 try {
1106 featureType = Integer.parseInt(getNextArg());
1107 } catch (NumberFormatException e) {
1108 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1109 return -1;
1110 }
1111 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1112 || featureType >= ImsFeature.FEATURE_MAX) {
1113 errPw.println("ims get-ims-service -f invalid feature.");
1114 return -1;
1115 }
1116 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001117 }
1118 }
1119 // Mandatory param, either -c or -d
1120 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001121 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001122 return -1;
1123 }
1124
1125 String result;
1126 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001127 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001128 } catch (RemoteException e) {
1129 return -1;
1130 }
1131 if (VDBG) {
1132 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001133 + (isCarrierService ? "-c " : "-d ")
1134 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1135 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001136 }
1137 getOutPrintWriter().println(result);
1138 return 0;
1139 }
1140
1141 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001142 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001143 String opt;
1144 while ((opt = getNextOption()) != null) {
1145 switch (opt) {
1146 case "-s": {
1147 try {
1148 slotId = Integer.parseInt(getNextArgRequired());
1149 } catch (NumberFormatException e) {
1150 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1151 return -1;
1152 }
1153 break;
1154 }
1155 }
1156 }
1157 try {
1158 mInterface.enableIms(slotId);
1159 } catch (RemoteException e) {
1160 return -1;
1161 }
1162 if (VDBG) {
1163 Log.v(LOG_TAG, "ims enable -s " + slotId);
1164 }
1165 return 0;
1166 }
1167
1168 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001169 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001170 String opt;
1171 while ((opt = getNextOption()) != null) {
1172 switch (opt) {
1173 case "-s": {
1174 try {
1175 slotId = Integer.parseInt(getNextArgRequired());
1176 } catch (NumberFormatException e) {
1177 getErrPrintWriter().println(
1178 "ims disable requires an integer as a SLOT_ID.");
1179 return -1;
1180 }
1181 break;
1182 }
1183 }
1184 }
1185 try {
1186 mInterface.disableIms(slotId);
1187 } catch (RemoteException e) {
1188 return -1;
1189 }
1190 if (VDBG) {
1191 Log.v(LOG_TAG, "ims disable -s " + slotId);
1192 }
1193 return 0;
1194 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001195
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001196 private int handleCepChange() {
1197 Log.i(LOG_TAG, "handleCepChange");
1198 String opt = getNextArg();
1199 if (opt == null) {
1200 return -1;
1201 }
1202 boolean isCepEnabled = opt.equals("enable");
1203
1204 try {
1205 mInterface.setCepEnabled(isCepEnabled);
1206 } catch (RemoteException e) {
1207 return -1;
1208 }
1209 return 0;
1210 }
1211
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001212 private int getDefaultSlot() {
1213 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1214 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1215 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1216 // If there is no default, default to slot 0.
1217 slotId = DEFAULT_PHONE_ID;
1218 }
1219 return slotId;
1220 }
sqian2fff4a32018-11-05 14:18:37 -08001221
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001222 // Parse options related to Carrier Config Commands.
1223 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001224 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001225 CcOptionParseResult result = new CcOptionParseResult();
1226 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1227 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001228
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001229 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001230 while ((opt = getNextOption()) != null) {
1231 switch (opt) {
1232 case "-s": {
1233 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001234 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1235 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1236 errPw.println(tag + "No valid subscription found.");
1237 return null;
1238 }
1239
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001240 } catch (IllegalArgumentException e) {
1241 // Missing slot id
1242 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001243 return null;
1244 }
1245 break;
1246 }
1247 case "-p": {
1248 if (allowOptionPersistent) {
1249 result.mPersistent = true;
1250 } else {
1251 errPw.println(tag + "Unexpected option " + opt);
1252 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001253 }
1254 break;
1255 }
1256 default: {
1257 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001258 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001259 }
1260 }
1261 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001262 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001263 }
1264
1265 private int slotStringToSubId(String tag, String slotString) {
1266 int slotId = -1;
1267 try {
1268 slotId = Integer.parseInt(slotString);
1269 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001270 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1271 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1272 }
1273
1274 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001275 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1276 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1277 }
1278
Qiong Liuf25799b2020-09-10 10:13:46 +08001279 Phone phone = PhoneFactory.getPhone(slotId);
1280 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001281 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1282 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1283 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001284 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001285 }
1286
Hall Liud892bec2018-11-30 14:51:45 -08001287 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001288 // adb can run as root or as shell, depending on whether the device is rooted.
1289 return Binder.getCallingUid() == Process.SHELL_UID
1290 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001291 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001292
1293 private int handleCcCommand() {
1294 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1295 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001296 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001297 getErrPrintWriter().println("cc: Permission denied.");
1298 return -1;
1299 }
1300
1301 String arg = getNextArg();
1302 if (arg == null) {
1303 onHelpCc();
1304 return 0;
1305 }
1306
1307 switch (arg) {
1308 case CC_GET_VALUE: {
1309 return handleCcGetValue();
1310 }
1311 case CC_SET_VALUE: {
1312 return handleCcSetValue();
1313 }
1314 case CC_CLEAR_VALUES: {
1315 return handleCcClearValues();
1316 }
1317 default: {
1318 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1319 }
1320 }
1321 return -1;
1322 }
1323
1324 // cc get-value
1325 private int handleCcGetValue() {
1326 PrintWriter errPw = getErrPrintWriter();
1327 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1328 String key = null;
1329
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001330 // Parse all options
1331 CcOptionParseResult options = parseCcOptions(tag, false);
1332 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001333 return -1;
1334 }
1335
1336 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001337 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001338 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001339 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001340 return -1;
1341 }
1342
1343 // Get the key.
1344 key = getNextArg();
1345 if (key != null) {
1346 // A key was provided. Verify if it is a valid key
1347 if (!bundle.containsKey(key)) {
1348 errPw.println(tag + key + " is not a valid key.");
1349 return -1;
1350 }
1351
1352 // Print the carrier config value for key.
1353 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1354 } else {
1355 // No key provided. Show all values.
1356 // Iterate over a sorted list of all carrier config keys and print them.
1357 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1358 for (String k : sortedSet) {
1359 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1360 }
1361 }
1362 return 0;
1363 }
1364
1365 // cc set-value
1366 private int handleCcSetValue() {
1367 PrintWriter errPw = getErrPrintWriter();
1368 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1369
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001370 // Parse all options
1371 CcOptionParseResult options = parseCcOptions(tag, true);
1372 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001373 return -1;
1374 }
1375
1376 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001377 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001378 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001379 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001380 return -1;
1381 }
1382
1383 // Get the key.
1384 String key = getNextArg();
1385 if (key == null || key.equals("")) {
1386 errPw.println(tag + "KEY is missing");
1387 return -1;
1388 }
1389
1390 // Verify if the key is valid
1391 if (!originalValues.containsKey(key)) {
1392 errPw.println(tag + key + " is not a valid key.");
1393 return -1;
1394 }
1395
1396 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1397 ArrayList<String> valueList = new ArrayList<String>();
1398 while (peekNextArg() != null) {
1399 valueList.add(getNextArg());
1400 }
1401
1402 // Find the type of the carrier config value
1403 CcType type = getType(tag, key, originalValues);
1404 if (type == CcType.UNKNOWN) {
1405 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1406 return -1;
1407 }
1408
1409 // Create an override bundle containing the key and value that should be overriden.
1410 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1411 if (overrideBundle == null) {
1412 return -1;
1413 }
1414
1415 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001416 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001417
1418 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001419 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001420 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001421 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001422 return -1;
1423 }
1424
1425 // Print the original and new value.
1426 String originalValueString = ccValueToString(key, type, originalValues);
1427 String newValueString = ccValueToString(key, type, newValues);
1428 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1429 getOutPrintWriter().println("New value: \n" + newValueString);
1430
1431 return 0;
1432 }
1433
1434 // cc clear-values
1435 private int handleCcClearValues() {
1436 PrintWriter errPw = getErrPrintWriter();
1437 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1438
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001439 // Parse all options
1440 CcOptionParseResult options = parseCcOptions(tag, false);
1441 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001442 return -1;
1443 }
1444
1445 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001446 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001447 getOutPrintWriter()
1448 .println("All previously set carrier config override values has been cleared");
1449 return 0;
1450 }
1451
1452 private CcType getType(String tag, String key, PersistableBundle bundle) {
1453 // Find the type by checking the type of the current value stored in the bundle.
1454 Object value = bundle.get(key);
1455
1456 if (CC_TYPE_MAP.containsKey(key)) {
1457 return CC_TYPE_MAP.get(key);
1458 } else if (value != null) {
1459 if (value instanceof Boolean) {
1460 return CcType.BOOLEAN;
1461 } else if (value instanceof Double) {
1462 return CcType.DOUBLE;
1463 } else if (value instanceof double[]) {
1464 return CcType.DOUBLE_ARRAY;
1465 } else if (value instanceof Integer) {
1466 return CcType.INT;
1467 } else if (value instanceof int[]) {
1468 return CcType.INT_ARRAY;
1469 } else if (value instanceof Long) {
1470 return CcType.LONG;
1471 } else if (value instanceof long[]) {
1472 return CcType.LONG_ARRAY;
1473 } else if (value instanceof String) {
1474 return CcType.STRING;
1475 } else if (value instanceof String[]) {
1476 return CcType.STRING_ARRAY;
1477 }
1478 } else {
1479 // Current value was null and can therefore not be used in order to find the type.
1480 // Check the name of the key to infer the type. This check is not needed for primitive
1481 // data types (boolean, double, int and long), since they can not be null.
1482 if (key.endsWith("double_array")) {
1483 return CcType.DOUBLE_ARRAY;
1484 }
1485 if (key.endsWith("int_array")) {
1486 return CcType.INT_ARRAY;
1487 }
1488 if (key.endsWith("long_array")) {
1489 return CcType.LONG_ARRAY;
1490 }
1491 if (key.endsWith("string")) {
1492 return CcType.STRING;
1493 }
1494 if (key.endsWith("string_array") || key.endsWith("strings")) {
1495 return CcType.STRING_ARRAY;
1496 }
1497 }
1498
1499 // Not possible to infer the type by looking at the current value or the key.
1500 PrintWriter errPw = getErrPrintWriter();
1501 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1502 return CcType.UNKNOWN;
1503 }
1504
1505 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1506 String result;
1507 StringBuilder valueString = new StringBuilder();
1508 String typeString = type.toString();
1509 Object value = bundle.get(key);
1510
1511 if (value == null) {
1512 valueString.append("null");
1513 } else {
1514 switch (type) {
1515 case DOUBLE_ARRAY: {
1516 // Format the string representation of the int array as value1 value2......
1517 double[] valueArray = (double[]) value;
1518 for (int i = 0; i < valueArray.length; i++) {
1519 if (i != 0) {
1520 valueString.append(" ");
1521 }
1522 valueString.append(valueArray[i]);
1523 }
1524 break;
1525 }
1526 case INT_ARRAY: {
1527 // Format the string representation of the int array as value1 value2......
1528 int[] valueArray = (int[]) value;
1529 for (int i = 0; i < valueArray.length; i++) {
1530 if (i != 0) {
1531 valueString.append(" ");
1532 }
1533 valueString.append(valueArray[i]);
1534 }
1535 break;
1536 }
1537 case LONG_ARRAY: {
1538 // Format the string representation of the int array as value1 value2......
1539 long[] valueArray = (long[]) value;
1540 for (int i = 0; i < valueArray.length; i++) {
1541 if (i != 0) {
1542 valueString.append(" ");
1543 }
1544 valueString.append(valueArray[i]);
1545 }
1546 break;
1547 }
1548 case STRING: {
1549 valueString.append("\"" + value.toString() + "\"");
1550 break;
1551 }
1552 case STRING_ARRAY: {
1553 // Format the string representation of the string array as "value1" "value2"....
1554 String[] valueArray = (String[]) value;
1555 for (int i = 0; i < valueArray.length; i++) {
1556 if (i != 0) {
1557 valueString.append(" ");
1558 }
1559 if (valueArray[i] != null) {
1560 valueString.append("\"" + valueArray[i] + "\"");
1561 } else {
1562 valueString.append("null");
1563 }
1564 }
1565 break;
1566 }
1567 default: {
1568 valueString.append(value.toString());
1569 }
1570 }
1571 }
1572 return String.format("%-70s %-15s %s", key, typeString, valueString);
1573 }
1574
1575 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1576 ArrayList<String> valueList) {
1577 PrintWriter errPw = getErrPrintWriter();
1578 PersistableBundle bundle = new PersistableBundle();
1579
1580 // First verify that a valid number of values has been provided for the type.
1581 switch (type) {
1582 case BOOLEAN:
1583 case DOUBLE:
1584 case INT:
1585 case LONG: {
1586 if (valueList.size() != 1) {
1587 errPw.println(tag + "Expected 1 value for type " + type
1588 + ". Found: " + valueList.size());
1589 return null;
1590 }
1591 break;
1592 }
1593 case STRING: {
1594 if (valueList.size() > 1) {
1595 errPw.println(tag + "Expected 0 or 1 values for type " + type
1596 + ". Found: " + valueList.size());
1597 return null;
1598 }
1599 break;
1600 }
1601 }
1602
1603 // Parse the value according to type and add it to the Bundle.
1604 switch (type) {
1605 case BOOLEAN: {
1606 if ("true".equalsIgnoreCase(valueList.get(0))) {
1607 bundle.putBoolean(key, true);
1608 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1609 bundle.putBoolean(key, false);
1610 } else {
1611 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1612 return null;
1613 }
1614 break;
1615 }
1616 case DOUBLE: {
1617 try {
1618 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1619 } catch (NumberFormatException nfe) {
1620 // Not a valid double
1621 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1622 return null;
1623 }
1624 break;
1625 }
1626 case DOUBLE_ARRAY: {
1627 double[] valueDoubleArray = null;
1628 if (valueList.size() > 0) {
1629 valueDoubleArray = new double[valueList.size()];
1630 for (int i = 0; i < valueList.size(); i++) {
1631 try {
1632 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1633 } catch (NumberFormatException nfe) {
1634 // Not a valid double
1635 errPw.println(
1636 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1637 return null;
1638 }
1639 }
1640 }
1641 bundle.putDoubleArray(key, valueDoubleArray);
1642 break;
1643 }
1644 case INT: {
1645 try {
1646 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1647 } catch (NumberFormatException nfe) {
1648 // Not a valid integer
1649 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1650 return null;
1651 }
1652 break;
1653 }
1654 case INT_ARRAY: {
1655 int[] valueIntArray = null;
1656 if (valueList.size() > 0) {
1657 valueIntArray = new int[valueList.size()];
1658 for (int i = 0; i < valueList.size(); i++) {
1659 try {
1660 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1661 } catch (NumberFormatException nfe) {
1662 // Not a valid integer
1663 errPw.println(tag
1664 + "Unable to parse " + valueList.get(i) + " as an integer.");
1665 return null;
1666 }
1667 }
1668 }
1669 bundle.putIntArray(key, valueIntArray);
1670 break;
1671 }
1672 case LONG: {
1673 try {
1674 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1675 } catch (NumberFormatException nfe) {
1676 // Not a valid long
1677 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1678 return null;
1679 }
1680 break;
1681 }
1682 case LONG_ARRAY: {
1683 long[] valueLongArray = null;
1684 if (valueList.size() > 0) {
1685 valueLongArray = new long[valueList.size()];
1686 for (int i = 0; i < valueList.size(); i++) {
1687 try {
1688 valueLongArray[i] = Long.parseLong(valueList.get(i));
1689 } catch (NumberFormatException nfe) {
1690 // Not a valid long
1691 errPw.println(
1692 tag + "Unable to parse " + valueList.get(i) + " as a long");
1693 return null;
1694 }
1695 }
1696 }
1697 bundle.putLongArray(key, valueLongArray);
1698 break;
1699 }
1700 case STRING: {
1701 String value = null;
1702 if (valueList.size() > 0) {
1703 value = valueList.get(0);
1704 }
1705 bundle.putString(key, value);
1706 break;
1707 }
1708 case STRING_ARRAY: {
1709 String[] valueStringArray = null;
1710 if (valueList.size() > 0) {
1711 valueStringArray = new String[valueList.size()];
1712 valueList.toArray(valueStringArray);
1713 }
1714 bundle.putStringArray(key, valueStringArray);
1715 break;
1716 }
1717 }
1718 return bundle;
1719 }
Shuo Qian489d9282020-07-09 11:30:03 -07001720
1721 private int handleEndBlockSuppressionCommand() {
1722 if (!checkShellUid()) {
1723 return -1;
1724 }
1725
1726 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
1727 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
1728 }
1729 return 0;
1730 }
Hui Wang641e81c2020-10-12 12:14:23 -07001731
Michele Berionne54af4632020-12-28 20:23:16 +00001732 private int handleRestartModemCommand() {
1733 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1734 // non user build.
1735 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1736 getErrPrintWriter().println("RestartModem: Permission denied.");
1737 return -1;
1738 }
1739
1740 boolean result = TelephonyManager.getDefault().rebootRadio();
1741 getOutPrintWriter().println(result);
1742
1743 return result ? 0 : -1;
1744 }
1745
Michele Berionne5e411512020-11-13 02:36:59 +00001746 private int handleUnattendedReboot() {
1747 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1748 // non user build.
1749 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
1750 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
1751 return -1;
1752 }
1753
1754 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
1755 getOutPrintWriter().println("result: " + result);
1756
1757 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
1758 }
1759
Hui Wang641e81c2020-10-12 12:14:23 -07001760 private int handleGbaCommand() {
1761 String arg = getNextArg();
1762 if (arg == null) {
1763 onHelpGba();
1764 return 0;
1765 }
1766
1767 switch (arg) {
1768 case GBA_SET_SERVICE: {
1769 return handleGbaSetServiceCommand();
1770 }
1771 case GBA_GET_SERVICE: {
1772 return handleGbaGetServiceCommand();
1773 }
1774 case GBA_SET_RELEASE_TIME: {
1775 return handleGbaSetReleaseCommand();
1776 }
1777 case GBA_GET_RELEASE_TIME: {
1778 return handleGbaGetReleaseCommand();
1779 }
1780 }
1781
1782 return -1;
1783 }
1784
1785 private int getSubId(String cmd) {
1786 int slotId = getDefaultSlot();
1787 String opt = getNextOption();
1788 if (opt != null && opt.equals("-s")) {
1789 try {
1790 slotId = Integer.parseInt(getNextArgRequired());
1791 } catch (NumberFormatException e) {
1792 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
1793 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1794 }
1795 }
1796 int[] subIds = SubscriptionManager.getSubId(slotId);
1797 return subIds[0];
1798 }
1799
1800 private int handleGbaSetServiceCommand() {
1801 int subId = getSubId("gba set-service");
1802 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1803 return -1;
1804 }
1805
1806 String packageName = getNextArg();
1807 try {
1808 if (packageName == null) {
1809 packageName = "";
1810 }
1811 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
1812 if (VDBG) {
1813 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
1814 + packageName + ", result=" + result);
1815 }
1816 getOutPrintWriter().println(result);
1817 } catch (RemoteException e) {
1818 Log.w(LOG_TAG, "gba set-service " + subId + " "
1819 + packageName + ", error" + e.getMessage());
1820 getErrPrintWriter().println("Exception: " + e.getMessage());
1821 return -1;
1822 }
1823 return 0;
1824 }
1825
1826 private int handleGbaGetServiceCommand() {
1827 String result;
1828
1829 int subId = getSubId("gba get-service");
1830 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1831 return -1;
1832 }
1833
1834 try {
1835 result = mInterface.getBoundGbaService(subId);
1836 } catch (RemoteException e) {
1837 return -1;
1838 }
1839 if (VDBG) {
1840 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
1841 }
1842 getOutPrintWriter().println(result);
1843 return 0;
1844 }
1845
1846 private int handleGbaSetReleaseCommand() {
1847 //the release time value could be -1
1848 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
1849 : SubscriptionManager.getDefaultSubscriptionId();
1850 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1851 return -1;
1852 }
1853
1854 String intervalStr = getNextArg();
1855 if (intervalStr == null) {
1856 return -1;
1857 }
1858
1859 try {
1860 int interval = Integer.parseInt(intervalStr);
1861 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
1862 if (VDBG) {
1863 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
1864 + intervalStr + ", result=" + result);
1865 }
1866 getOutPrintWriter().println(result);
1867 } catch (NumberFormatException | RemoteException e) {
1868 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
1869 + intervalStr + ", error" + e.getMessage());
1870 getErrPrintWriter().println("Exception: " + e.getMessage());
1871 return -1;
1872 }
1873 return 0;
1874 }
1875
1876 private int handleGbaGetReleaseCommand() {
1877 int subId = getSubId("gba get-release");
1878 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1879 return -1;
1880 }
1881
1882 int result = 0;
1883 try {
1884 result = mInterface.getGbaReleaseTime(subId);
1885 } catch (RemoteException e) {
1886 return -1;
1887 }
1888 if (VDBG) {
1889 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
1890 }
1891 getOutPrintWriter().println(result);
1892 return 0;
1893 }
Hui Wang761a6682020-10-31 05:12:53 +00001894
1895 private int handleSingleRegistrationConfigCommand() {
1896 String arg = getNextArg();
1897 if (arg == null) {
1898 onHelpSrc();
1899 return 0;
1900 }
1901
1902 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08001903 case SRC_SET_TEST_ENABLED: {
1904 return handleSrcSetTestEnabledCommand();
1905 }
1906 case SRC_GET_TEST_ENABLED: {
1907 return handleSrcGetTestEnabledCommand();
1908 }
Hui Wang761a6682020-10-31 05:12:53 +00001909 case SRC_SET_DEVICE_ENABLED: {
1910 return handleSrcSetDeviceEnabledCommand();
1911 }
1912 case SRC_GET_DEVICE_ENABLED: {
1913 return handleSrcGetDeviceEnabledCommand();
1914 }
1915 case SRC_SET_CARRIER_ENABLED: {
1916 return handleSrcSetCarrierEnabledCommand();
1917 }
1918 case SRC_GET_CARRIER_ENABLED: {
1919 return handleSrcGetCarrierEnabledCommand();
1920 }
Hui Wangb647abe2021-02-26 09:33:38 -08001921 case SRC_SET_FEATURE_ENABLED: {
1922 return handleSrcSetFeatureValidationCommand();
1923 }
1924 case SRC_GET_FEATURE_ENABLED: {
1925 return handleSrcGetFeatureValidationCommand();
1926 }
Hui Wang761a6682020-10-31 05:12:53 +00001927 }
1928
1929 return -1;
1930 }
1931
James.cf Linbcdf8b32021-01-14 16:44:13 +08001932 private int handleRcsUceCommand() {
1933 String arg = getNextArg();
1934 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00001935 onHelpUce();
1936 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001937 }
1938
1939 switch (arg) {
1940 case UCE_REMOVE_EAB_CONTACT:
1941 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08001942 case UCE_GET_EAB_CONTACT:
1943 return handleGettingEabContactCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08001944 case UCE_GET_DEVICE_ENABLED:
1945 return handleUceGetDeviceEnabledCommand();
1946 case UCE_SET_DEVICE_ENABLED:
1947 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00001948 case UCE_OVERRIDE_PUBLISH_CAPS:
1949 return handleUceOverridePublishCaps();
1950 case UCE_GET_LAST_PIDF_XML:
1951 return handleUceGetPidfXml();
James.cf Linbcdf8b32021-01-14 16:44:13 +08001952 }
1953 return -1;
1954 }
1955
1956 private int handleRemovingEabContactCommand() {
1957 int subId = getSubId("uce remove-eab-contact");
1958 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
1959 return -1;
1960 }
1961
1962 String phoneNumber = getNextArgRequired();
1963 if (TextUtils.isEmpty(phoneNumber)) {
1964 return -1;
1965 }
1966 int result = 0;
1967 try {
1968 result = mInterface.removeContactFromEab(subId, phoneNumber);
1969 } catch (RemoteException e) {
1970 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
1971 getErrPrintWriter().println("Exception: " + e.getMessage());
1972 return -1;
1973 }
1974
1975 if (VDBG) {
1976 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
1977 }
calvinpan293ea1b2021-02-04 17:52:13 +08001978 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08001979 }
1980
calvinpane4a8a1d2021-01-25 13:51:18 +08001981 private int handleGettingEabContactCommand() {
1982 String phoneNumber = getNextArgRequired();
1983 if (TextUtils.isEmpty(phoneNumber)) {
1984 return -1;
1985 }
1986 String result = "";
1987 try {
1988 result = mInterface.getContactFromEab(phoneNumber);
1989
1990 } catch (RemoteException e) {
1991 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
1992 getErrPrintWriter().println("Exception: " + e.getMessage());
1993 return -1;
1994 }
1995
1996 if (VDBG) {
1997 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
1998 }
calvinpan293ea1b2021-02-04 17:52:13 +08001999 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002000 return 0;
2001 }
2002
2003 private int handleUceGetDeviceEnabledCommand() {
2004 boolean result = false;
2005 try {
2006 result = mInterface.getDeviceUceEnabled();
2007 } catch (RemoteException e) {
2008 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2009 return -1;
2010 }
2011 if (VDBG) {
2012 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2013 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002014 getOutPrintWriter().println(result);
2015 return 0;
2016 }
2017
James.cf Lin4b784aa2021-01-31 03:25:15 +08002018 private int handleUceSetDeviceEnabledCommand() {
2019 String enabledStr = getNextArg();
2020 if (TextUtils.isEmpty(enabledStr)) {
2021 return -1;
2022 }
2023
2024 try {
2025 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2026 mInterface.setDeviceUceEnabled(isEnabled);
2027 if (VDBG) {
2028 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2029 }
2030 } catch (NumberFormatException | RemoteException e) {
2031 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2032 getErrPrintWriter().println("Exception: " + e.getMessage());
2033 return -1;
2034 }
2035 return 0;
2036 }
2037
Hui Wangbaaee6a2021-02-19 20:45:36 -08002038 private int handleSrcSetTestEnabledCommand() {
2039 String enabledStr = getNextArg();
2040 if (enabledStr == null) {
2041 return -1;
2042 }
2043
2044 try {
2045 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2046 if (VDBG) {
2047 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2048 }
2049 getOutPrintWriter().println("Done");
2050 } catch (NumberFormatException | RemoteException e) {
2051 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2052 getErrPrintWriter().println("Exception: " + e.getMessage());
2053 return -1;
2054 }
2055 return 0;
2056 }
2057
2058 private int handleSrcGetTestEnabledCommand() {
2059 boolean result = false;
2060 try {
2061 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2062 } catch (RemoteException e) {
2063 return -1;
2064 }
2065 if (VDBG) {
2066 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2067 }
2068 getOutPrintWriter().println(result);
2069 return 0;
2070 }
2071
Brad Ebinger14d467f2021-02-12 06:18:28 +00002072 private int handleUceOverridePublishCaps() {
2073 int subId = getSubId("uce override-published-caps");
2074 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2075 return -1;
2076 }
2077 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2078 String operation = getNextArgRequired();
2079 String caps = getNextArg();
2080 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2081 && !"list".equals(operation)) {
2082 getErrPrintWriter().println("Invalid operation: " + operation);
2083 return -1;
2084 }
2085
2086 // add/remove requires capabilities to be specified.
2087 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2088 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2089 + "specified");
2090 return -1;
2091 }
2092
2093 ArraySet<String> capSet = new ArraySet<>();
2094 if (!TextUtils.isEmpty(caps)) {
2095 String[] capArray = caps.split(":");
2096 for (String cap : capArray) {
2097 // Allow unknown tags to be passed in as well.
2098 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2099 }
2100 }
2101
2102 RcsContactUceCapability result = null;
2103 try {
2104 switch (operation) {
2105 case "add":
2106 result = mInterface.addUceRegistrationOverrideShell(subId,
2107 new ArrayList<>(capSet));
2108 break;
2109 case "remove":
2110 result = mInterface.removeUceRegistrationOverrideShell(subId,
2111 new ArrayList<>(capSet));
2112 break;
2113 case "clear":
2114 result = mInterface.clearUceRegistrationOverrideShell(subId);
2115 break;
2116 case "list":
2117 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2118 break;
2119 }
2120 } catch (RemoteException e) {
2121 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2122 getErrPrintWriter().println("Exception: " + e.getMessage());
2123 return -1;
2124 } catch (ServiceSpecificException sse) {
2125 // Reconstruct ImsException
2126 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2127 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2128 getErrPrintWriter().println("Exception: " + imsException);
2129 return -1;
2130 }
2131 if (result == null) {
2132 getErrPrintWriter().println("Service not available");
2133 return -1;
2134 }
2135 getOutPrintWriter().println(result);
2136 return 0;
2137 }
2138
2139 private int handleUceGetPidfXml() {
2140 int subId = getSubId("uce get-last-publish-pidf");
2141 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2142 return -1;
2143 }
2144
2145 String result;
2146 try {
2147 result = mInterface.getLastUcePidfXmlShell(subId);
2148 } catch (RemoteException e) {
2149 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2150 getErrPrintWriter().println("Exception: " + e.getMessage());
2151 return -1;
2152 } catch (ServiceSpecificException sse) {
2153 // Reconstruct ImsException
2154 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2155 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2156 getErrPrintWriter().println("Exception: " + imsException);
2157 return -1;
2158 }
2159 if (result == null) {
2160 getErrPrintWriter().println("Service not available");
2161 return -1;
2162 }
2163 getOutPrintWriter().println(result);
2164 return 0;
2165 }
2166
Hui Wang761a6682020-10-31 05:12:53 +00002167 private int handleSrcSetDeviceEnabledCommand() {
2168 String enabledStr = getNextArg();
2169 if (enabledStr == null) {
2170 return -1;
2171 }
2172
2173 try {
2174 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2175 if (VDBG) {
2176 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2177 }
2178 getOutPrintWriter().println("Done");
2179 } catch (NumberFormatException | RemoteException e) {
2180 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2181 getErrPrintWriter().println("Exception: " + e.getMessage());
2182 return -1;
2183 }
2184 return 0;
2185 }
2186
2187 private int handleSrcGetDeviceEnabledCommand() {
2188 boolean result = false;
2189 try {
2190 result = mInterface.getDeviceSingleRegistrationEnabled();
2191 } catch (RemoteException e) {
2192 return -1;
2193 }
2194 if (VDBG) {
2195 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2196 }
2197 getOutPrintWriter().println(result);
2198 return 0;
2199 }
2200
2201 private int handleSrcSetCarrierEnabledCommand() {
2202 //the release time value could be -1
2203 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2204 : SubscriptionManager.getDefaultSubscriptionId();
2205 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2206 return -1;
2207 }
2208
2209 String enabledStr = getNextArg();
2210 if (enabledStr == null) {
2211 return -1;
2212 }
2213
2214 try {
2215 boolean result =
2216 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2217 if (VDBG) {
2218 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2219 + enabledStr + ", result=" + result);
2220 }
2221 getOutPrintWriter().println(result);
2222 } catch (NumberFormatException | RemoteException e) {
2223 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2224 + enabledStr + ", error" + e.getMessage());
2225 getErrPrintWriter().println("Exception: " + e.getMessage());
2226 return -1;
2227 }
2228 return 0;
2229 }
2230
2231 private int handleSrcGetCarrierEnabledCommand() {
2232 int subId = getSubId("src get-carrier-enabled");
2233 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2234 return -1;
2235 }
2236
2237 boolean result = false;
2238 try {
2239 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2240 } catch (RemoteException e) {
2241 return -1;
2242 }
2243 if (VDBG) {
2244 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2245 }
2246 getOutPrintWriter().println(result);
2247 return 0;
2248 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002249
Hui Wangb647abe2021-02-26 09:33:38 -08002250 private int handleSrcSetFeatureValidationCommand() {
2251 //the release time value could be -1
2252 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2253 : SubscriptionManager.getDefaultSubscriptionId();
2254 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2255 return -1;
2256 }
2257
2258 String enabledStr = getNextArg();
2259 if (enabledStr == null) {
2260 return -1;
2261 }
2262
2263 try {
2264 boolean result =
2265 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2266 if (VDBG) {
2267 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2268 + enabledStr + ", result=" + result);
2269 }
2270 getOutPrintWriter().println(result);
2271 } catch (NumberFormatException | RemoteException e) {
2272 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2273 + enabledStr + ", error" + e.getMessage());
2274 getErrPrintWriter().println("Exception: " + e.getMessage());
2275 return -1;
2276 }
2277 return 0;
2278 }
2279
2280 private int handleSrcGetFeatureValidationCommand() {
2281 int subId = getSubId("src get-feature-validation");
2282 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2283 return -1;
2284 }
2285
2286 Boolean result = false;
2287 try {
2288 result = mInterface.getImsFeatureValidationOverride(subId);
2289 } catch (RemoteException e) {
2290 return -1;
2291 }
2292 if (VDBG) {
2293 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2294 }
2295 getOutPrintWriter().println(result);
2296 return 0;
2297 }
2298
2299
Hall Liuaa4211e2021-01-20 15:43:39 -08002300 private void onHelpCallComposer() {
2301 PrintWriter pw = getOutPrintWriter();
2302 pw.println("Call composer commands");
2303 pw.println(" callcomposer test-mode enable|disable|query");
2304 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2305 pw.println(" upload/download from carrier servers is disabled, and operations are");
2306 pw.println(" performed using emulated local files instead.");
2307 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2308 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2309 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002310 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2311 pw.println(" Enables or disables the user setting for call composer, as set by");
2312 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002313 }
2314
2315 private int handleCallComposerCommand() {
2316 String arg = getNextArg();
2317 if (arg == null) {
2318 onHelpCallComposer();
2319 return 0;
2320 }
2321
2322 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2323 "MODIFY_PHONE_STATE required for call composer shell cmds");
2324 switch (arg) {
2325 case CALL_COMPOSER_TEST_MODE: {
2326 String enabledStr = getNextArg();
2327 if (ENABLE.equals(enabledStr)) {
2328 CallComposerPictureManager.sTestMode = true;
2329 } else if (DISABLE.equals(enabledStr)) {
2330 CallComposerPictureManager.sTestMode = false;
2331 } else if (QUERY.equals(enabledStr)) {
2332 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2333 } else {
2334 onHelpCallComposer();
2335 return 1;
2336 }
2337 break;
2338 }
2339 case CALL_COMPOSER_SIMULATE_CALL: {
2340 int subscriptionId = Integer.valueOf(getNextArg());
2341 String uuidString = getNextArg();
2342 UUID uuid = UUID.fromString(uuidString);
2343 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2344 Binder.withCleanCallingIdentity(() -> {
2345 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2346 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2347 });
2348 try {
2349 Uri uri = storageUriFuture.get();
2350 getOutPrintWriter().println(String.valueOf(uri));
2351 } catch (Exception e) {
2352 throw new RuntimeException(e);
2353 }
2354 break;
2355 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002356 case CALL_COMPOSER_USER_SETTING: {
2357 try {
2358 int subscriptionId = Integer.valueOf(getNextArg());
2359 String enabledStr = getNextArg();
2360 if (ENABLE.equals(enabledStr)) {
2361 mInterface.setCallComposerStatus(subscriptionId,
2362 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2363 } else if (DISABLE.equals(enabledStr)) {
2364 mInterface.setCallComposerStatus(subscriptionId,
2365 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2366 } else if (QUERY.equals(enabledStr)) {
2367 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2368 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2369 } else {
2370 onHelpCallComposer();
2371 return 1;
2372 }
2373 } catch (RemoteException e) {
2374 e.printStackTrace(getOutPrintWriter());
2375 return 1;
2376 }
2377 break;
2378 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002379 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002380 return 0;
2381 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002382
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002383 private int handleHasCarrierPrivilegesCommand() {
2384 String packageName = getNextArgRequired();
2385
2386 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002387 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002388 try {
2389 hasCarrierPrivileges =
2390 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2391 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2392 } catch (RemoteException e) {
2393 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2394 getErrPrintWriter().println("Exception: " + e.getMessage());
2395 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002396 } finally {
2397 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002398 }
2399
2400 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002401 return 0;
2402 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002403
2404 private int handleAllowedNetworkTypesCommand(String command) {
2405 if (!checkShellUid()) {
2406 return -1;
2407 }
2408
2409 PrintWriter errPw = getErrPrintWriter();
2410 String tag = command + ": ";
2411 String opt;
2412 int subId = -1;
2413 Log.v(LOG_TAG, command + " start");
2414
2415 while ((opt = getNextOption()) != null) {
2416 if (opt.equals("-s")) {
2417 try {
2418 subId = slotStringToSubId(tag, getNextArgRequired());
2419 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2420 errPw.println(tag + "No valid subscription found.");
2421 return -1;
2422 }
2423 } catch (IllegalArgumentException e) {
2424 // Missing slot id
2425 errPw.println(tag + "SLOT_ID expected after -s.");
2426 return -1;
2427 }
2428 } else {
2429 errPw.println(tag + "Unknown option " + opt);
2430 return -1;
2431 }
2432 }
2433
2434 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2435 return handleGetAllowedNetworkTypesCommand(subId);
2436 }
2437 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2438 return handleSetAllowedNetworkTypesCommand(subId);
2439 }
2440 return -1;
2441 }
2442
2443 private int handleGetAllowedNetworkTypesCommand(int subId) {
2444 PrintWriter errPw = getErrPrintWriter();
2445
2446 long result = -1;
2447 try {
2448 if (mInterface != null) {
2449 result = mInterface.getAllowedNetworkTypesForReason(subId,
2450 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2451 } else {
2452 throw new IllegalStateException("telephony service is null.");
2453 }
2454 } catch (RemoteException e) {
2455 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2456 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2457 return -1;
2458 }
2459
2460 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2461 return 0;
2462 }
2463
2464 private int handleSetAllowedNetworkTypesCommand(int subId) {
2465 PrintWriter errPw = getErrPrintWriter();
2466
2467 String bitmaskString = getNextArg();
2468 if (TextUtils.isEmpty(bitmaskString)) {
2469 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2470 return -1;
2471 }
2472 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2473 if (allowedNetworkTypes < 0) {
2474 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2475 return -1;
2476 }
2477 boolean result = false;
2478 try {
2479 if (mInterface != null) {
2480 result = mInterface.setAllowedNetworkTypesForReason(subId,
2481 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2482 } else {
2483 throw new IllegalStateException("telephony service is null.");
2484 }
2485 } catch (RemoteException e) {
2486 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2487 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2488 return -1;
2489 }
2490
2491 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2492 if (result) {
2493 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2494 }
2495 getOutPrintWriter().println(resultMessage);
2496 return 0;
2497 }
2498
2499 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2500 if (TextUtils.isEmpty(bitmaskString)) {
2501 return -1;
2502 }
2503 if (VDBG) {
2504 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2505 + ", length: " + bitmaskString.length());
2506 }
2507 try {
2508 return Long.parseLong(bitmaskString, 2);
2509 } catch (NumberFormatException e) {
2510 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2511 return -1;
2512 }
2513 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07002514}