blob: 2c1306098b6a2c1148c9f3a32f281b049e3ed8c7 [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Hall Liuaa4211e2021-01-20 15:43:39 -080024import android.Manifest;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010025import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080027import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010028import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070030import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000031import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070032import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070033import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010034import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070035import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070036import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000037import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070038import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080039import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000040import android.telephony.ims.ImsException;
41import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080042import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080043import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000044import android.util.ArrayMap;
45import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070046import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070047import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070048
Brad Ebinger14d467f2021-02-12 06:18:28 +000049import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080051import com.android.internal.telephony.Phone;
52import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080053import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080054import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080055import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080056import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080057import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070058
Allen Xuee00f0e2022-03-14 21:04:49 +000059import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070060import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080061import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000062import java.util.Arrays;
63import java.util.Collections;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010064import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080065import java.util.List;
Grant Menke567d48f2022-08-18 20:19:10 +000066import java.util.Locale;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010067import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000068import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010069import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080070import java.util.UUID;
71import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070072
73/**
74 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
75 * permission checks have been done before onCommand was called. Make sure any commands processed
76 * here also contain the appropriate permissions checks.
77 */
78
Hall Liua1548bd2019-12-24 14:14:12 -080079public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81 private static final String LOG_TAG = "TelephonyShellCommand";
82 // Don't commit with this true.
83 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070084 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070085
Hall Liuaa4211e2021-01-20 15:43:39 -080086 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080088 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080089 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080090 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070091 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000092 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000093 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010094 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080095 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080096 private static final String ENABLE = "enable";
97 private static final String DISABLE = "disable";
98 private static final String QUERY = "query";
99
Hall Liu7135e502021-02-04 16:58:17 -0800100 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800101 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800102 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800103
Brad Ebinger999d3302020-11-25 14:31:39 -0800104 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
105 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
106 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700107 // Used to disable or enable processing of conference event package data from the network.
108 // This is handy for testing scenarios where CEP data does not exist on a network which does
109 // support CEP data.
110 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700111
Hall Liud892bec2018-11-30 14:51:45 -0800112 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800113 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800114
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100115 private static final String CC_GET_VALUE = "get-value";
116 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000117 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100118 private static final String CC_CLEAR_VALUES = "clear-values";
119
Hui Wang641e81c2020-10-12 12:14:23 -0700120 private static final String GBA_SUBCOMMAND = "gba";
121 private static final String GBA_SET_SERVICE = "set-service";
122 private static final String GBA_GET_SERVICE = "get-service";
123 private static final String GBA_SET_RELEASE_TIME = "set-release";
124 private static final String GBA_GET_RELEASE_TIME = "get-release";
125
Hui Wang761a6682020-10-31 05:12:53 +0000126 private static final String SINGLE_REGISTATION_CONFIG = "src";
127 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
128 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
129 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
130 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800131 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
132 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800133 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
134 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000135
Tyler Gunn92479152021-01-20 16:30:10 -0800136 private static final String D2D_SUBCOMMAND = "d2d";
137 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800138 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700139 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800140
Nazanin014f41e2021-05-06 17:26:31 -0700141 private static final String BARRING_SUBCOMMAND = "barring";
142 private static final String BARRING_SEND_INFO = "send";
143
James.cf Linbcdf8b32021-01-14 16:44:13 +0800144 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800145 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800146 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800147 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800148 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
149 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000150 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
151 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800152 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
153 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800154 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
155 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800156
jimsun3b9ccac2021-10-26 15:01:23 +0800157 private static final String RADIO_SUBCOMMAND = "radio";
158 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
159 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
160
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800161 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
162 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
163
Jordan Liu0ccee222021-04-27 11:55:13 -0700164 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
165 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
166
Jack Nudelman644b91a2021-03-12 14:09:48 -0800167 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
168 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
169 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
170
Grant Menke567d48f2022-08-18 20:19:10 +0000171 private static final String INVALID_ENTRY_ERROR = "An emergency number (only allow '0'-'9', "
172 + "'*', '#' or '+') needs to be specified after -a in the command ";
173
174 private static final int[] ROUTING_TYPES = {EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN,
175 EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY,
176 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL};
177
SongFerngWang98dd5992021-05-13 17:50:00 +0800178 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
179 "get-allowed-network-types-for-users";
180 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
181 "set-allowed-network-types-for-users";
Jack Yuf745f972022-08-15 19:53:50 +0000182 // Check if telephony new data stack is enabled.
183 private static final String GET_DATA_MODE = "get-data-mode";
Ling Ma4fbab492022-01-25 22:36:16 +0000184 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000185 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700186 // Take advantage of existing methods that already contain permissions checks when possible.
187 private final ITelephony mInterface;
188
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100189 private SubscriptionManager mSubscriptionManager;
190 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700191 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700192 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100193
194 private enum CcType {
195 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000196 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100197 }
198
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100199 private class CcOptionParseResult {
200 public int mSubId;
201 public boolean mPersistent;
202 }
203
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100204 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
205 // keys by looking at the end of the string which usually tells the type.
206 // For instance: "xxxx_string", "xxxx_string_array", etc.
207 // The carrier config keys in this map does not follow this convention. It is therefore not
208 // possible to infer the type for these keys by looking at the string.
209 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
210 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
211 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
212 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
213 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
214 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
215 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
216 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
217 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
218 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
219 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
220 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
221 CcType.STRING);
222 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
223 CcType.STRING_ARRAY);
224 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
225 CcType.STRING_ARRAY);
226 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
227 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
228 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
229 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
230 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
231 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
232 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
233 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
234 }
235 };
236
Brad Ebinger14d467f2021-02-12 06:18:28 +0000237 /**
238 * Map from a shorthand string to the feature tags required in registration required in order
239 * for the RCS feature to be considered "capable".
240 */
241 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
242 static {
243 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
244 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
245 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
246 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
247 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
248 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
249 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
250 FeatureTags.FEATURE_TAG_VIDEO)));
251 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
252 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
253 map.put("call_comp",
254 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
255 map.put("call_comp_mmtel",
256 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
257 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
258 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
259 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
260 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
261 // version
262 map.put("chatbot", new ArraySet<>(Arrays.asList(
263 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
264 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
265 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
266 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000267 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000268 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
269 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
270 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
271 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
272 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000273 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000274 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
275 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
276 }
277
278
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100279 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700280 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100281 mCarrierConfigManager =
282 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
283 mSubscriptionManager = (SubscriptionManager)
284 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700285 mTelephonyRegistryManager = (TelephonyRegistryManager)
286 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700287 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700288 }
289
290 @Override
291 public int onCommand(String cmd) {
292 if (cmd == null) {
293 return handleDefaultCommands(null);
294 }
295
296 switch (cmd) {
297 case IMS_SUBCOMMAND: {
298 return handleImsCommand();
299 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800300 case RCS_UCE_COMMAND:
301 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800302 case NUMBER_VERIFICATION_SUBCOMMAND:
303 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800304 case EMERGENCY_CALLBACK_MODE:
305 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800306 case EMERGENCY_NUMBER_TEST_MODE:
307 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100308 case CARRIER_CONFIG_SUBCOMMAND: {
309 return handleCcCommand();
310 }
Shuo Qianf5125122019-12-16 17:03:07 -0800311 case DATA_TEST_MODE:
312 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700313 case END_BLOCK_SUPPRESSION:
314 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700315 case GBA_SUBCOMMAND:
316 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800317 case D2D_SUBCOMMAND:
318 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700319 case BARRING_SUBCOMMAND:
320 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000321 case SINGLE_REGISTATION_CONFIG:
322 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000323 case RESTART_MODEM:
324 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800325 case CALL_COMPOSER_SUBCOMMAND:
326 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000327 case UNATTENDED_REBOOT:
328 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800329 case HAS_CARRIER_PRIVILEGES_COMMAND:
330 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800331 case THERMAL_MITIGATION_COMMAND:
332 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700333 case DISABLE_PHYSICAL_SUBSCRIPTION:
334 return handleEnablePhysicalSubscription(false);
335 case ENABLE_PHYSICAL_SUBSCRIPTION:
336 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800337 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
338 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
339 return handleAllowedNetworkTypesCommand(cmd);
Jack Yuf745f972022-08-15 19:53:50 +0000340 case GET_DATA_MODE:
341 return handleGetDataMode();
Ling Ma4fbab492022-01-25 22:36:16 +0000342 case GET_IMEI:
343 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000344 case GET_SIM_SLOTS_MAPPING:
345 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800346 case RADIO_SUBCOMMAND:
347 return handleRadioCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700348 default: {
349 return handleDefaultCommands(cmd);
350 }
351 }
352 }
353
354 @Override
355 public void onHelp() {
356 PrintWriter pw = getOutPrintWriter();
357 pw.println("Telephony Commands:");
358 pw.println(" help");
359 pw.println(" Print this help text.");
360 pw.println(" ims");
361 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800362 pw.println(" uce");
363 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800364 pw.println(" emergency-number-test-mode");
365 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700366 pw.println(" end-block-suppression");
367 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800368 pw.println(" data");
369 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100370 pw.println(" cc");
371 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700372 pw.println(" gba");
373 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000374 pw.println(" src");
375 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000376 pw.println(" restart-modem");
377 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000378 pw.println(" unattended-reboot");
379 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800380 pw.println(" has-carrier-privileges [package]");
381 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800382 pw.println(" get-allowed-network-types-for-users");
383 pw.println(" Get the Allowed Network Types.");
384 pw.println(" set-allowed-network-types-for-users");
385 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800386 pw.println(" radio");
387 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700388 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800389 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800390 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700391 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800392 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100393 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700394 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000395 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800396 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700397 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800398 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800399 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000400 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800401 }
402
403 private void onHelpD2D() {
404 PrintWriter pw = getOutPrintWriter();
405 pw.println("D2D Comms Commands:");
406 pw.println(" d2d send TYPE VALUE");
407 pw.println(" Sends a D2D message of specified type and value.");
408 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
409 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
410 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
411 MESSAGE_CALL_AUDIO_CODEC));
412 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
413 + Communicator.messageToString(
414 MESSAGE_DEVICE_BATTERY_STATE));
415 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
416 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800417 pw.println(" d2d transport TYPE");
418 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
419 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700420 pw.println(" d2d set-device-support true/default");
421 pw.println(" true - forces device support to be enabled for D2D.");
422 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
423 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700424 }
425
Nazanin014f41e2021-05-06 17:26:31 -0700426 private void onHelpBarring() {
427 PrintWriter pw = getOutPrintWriter();
428 pw.println("Barring Commands:");
429 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
430 + " -t CONDITIONAL_BARRING_TIME_SECS");
431 pw.println(" Notifies of a barring info change for the specified slot id.");
432 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
433 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
434 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
435 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
436 }
437
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700438 private void onHelpIms() {
439 PrintWriter pw = getOutPrintWriter();
440 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800441 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700442 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
443 pw.println(" ImsService. Options are:");
444 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
445 pw.println(" is specified, it will choose the default voice SIM slot.");
446 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
447 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800448 pw.println(" -f: Set the feature that this override if for, if no option is");
449 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700450 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
451 pw.println(" Gets the package name of the currently defined ImsService.");
452 pw.println(" Options are:");
453 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
454 pw.println(" is specified, it will choose the default voice SIM slot.");
455 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000456 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800457 pw.println(" -f: The feature type that the query will be requested for. If none is");
458 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800459 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
460 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
461 pw.println(" configuration overrides. Options are:");
462 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
463 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700464 pw.println(" ims enable [-s SLOT_ID]");
465 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
466 pw.println(" if none is specified.");
467 pw.println(" ims disable [-s SLOT_ID]");
468 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
469 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700470 pw.println(" ims conference-event-package [enable/disable]");
471 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700472 }
473
James.cf Linbcdf8b32021-01-14 16:44:13 +0800474 private void onHelpUce() {
475 PrintWriter pw = getOutPrintWriter();
476 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800477 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
478 pw.println(" Get the EAB contacts from the EAB database.");
479 pw.println(" Options are:");
480 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
481 pw.println(" Expected output format :");
482 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800483 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
484 pw.println(" Remove the EAB contacts from the EAB database.");
485 pw.println(" Options are:");
486 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
487 pw.println(" is specified, it will choose the default voice SIM slot.");
488 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800489 pw.println(" uce get-device-enabled");
490 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
491 pw.println(" uce set-device-enabled true|false");
492 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
493 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000494 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
495 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
496 pw.println(" Options are:");
497 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
498 pw.println(" is specified, it will choose the default voice SIM slot.");
499 pw.println(" add [CAPABILITY]: add a new capability");
500 pw.println(" remove [CAPABILITY]: remove a capability");
501 pw.println(" clear: clear all capability overrides");
502 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
503 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
504 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
505 pw.println(" chatbot_sa, chatbot_role] as well as full length");
506 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
507 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
508 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
509 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800510 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
511 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800512 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
513 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800514 }
515
Hall Liud892bec2018-11-30 14:51:45 -0800516 private void onHelpNumberVerification() {
517 PrintWriter pw = getOutPrintWriter();
518 pw.println("Number verification commands");
519 pw.println(" numverify override-package PACKAGE_NAME;");
520 pw.println(" Set the authorized package for number verification.");
521 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800522 pw.println(" numverify fake-call NUMBER;");
523 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
524 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800525 }
526
Jack Nudelman644b91a2021-03-12 14:09:48 -0800527 private void onHelpThermalMitigation() {
528 PrintWriter pw = getOutPrintWriter();
529 pw.println("Thermal mitigation commands");
530 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
531 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
532 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
533 pw.println(" Remove the package from one of the authorized packages for thermal "
534 + "mitigation.");
535 }
536
Jordan Liu0ccee222021-04-27 11:55:13 -0700537 private void onHelpDisableOrEnablePhysicalSubscription() {
538 PrintWriter pw = getOutPrintWriter();
539 pw.println("Disable or enable a physical subscription");
540 pw.println(" disable-physical-subscription SUB_ID");
541 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
542 pw.println(" enable-physical-subscription SUB_ID");
543 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
544 }
545
Shuo Qianf5125122019-12-16 17:03:07 -0800546 private void onHelpDataTestMode() {
547 PrintWriter pw = getOutPrintWriter();
548 pw.println("Mobile Data Test Mode Commands:");
549 pw.println(" data enable: enable mobile data connectivity");
550 pw.println(" data disable: disable mobile data connectivity");
551 }
552
sqian9d4df8b2019-01-15 18:32:07 -0800553 private void onHelpEmergencyNumber() {
554 PrintWriter pw = getOutPrintWriter();
555 pw.println("Emergency Number Test Mode Commands:");
556 pw.println(" emergency-number-test-mode ");
557 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
558 + " the test mode");
559 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700560 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800561 pw.println(" -c: clear the emergency number list in the test mode.");
562 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700563 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800564 pw.println(" -p: get the full emergency number list in the test mode.");
565 }
566
Shuo Qian489d9282020-07-09 11:30:03 -0700567 private void onHelpEndBlockSupperssion() {
568 PrintWriter pw = getOutPrintWriter();
569 pw.println("End Block Suppression command:");
570 pw.println(" end-block-suppression: disable suppressing blocking by contact");
571 pw.println(" with emergency services.");
572 }
573
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100574 private void onHelpCc() {
575 PrintWriter pw = getOutPrintWriter();
576 pw.println("Carrier Config Commands:");
577 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
578 pw.println(" Print carrier config values.");
579 pw.println(" Options are:");
580 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
581 pw.println(" is specified, it will choose the default voice SIM slot.");
582 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
583 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100584 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100585 pw.println(" Set carrier config KEY to NEW_VALUE.");
586 pw.println(" Options are:");
587 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
588 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100589 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100590 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
591 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
592 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
593 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000594 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
595 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
596 pw.println(" provided through standard input and follow CarrierConfig XML format.");
597 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
598 pw.println(" Options are:");
599 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
600 pw.println(" is specified, it will choose the default voice SIM slot.");
601 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100602 pw.println(" cc clear-values [-s SLOT_ID]");
603 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000604 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100605 pw.println(" Options are:");
606 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
607 pw.println(" is specified, it will choose the default voice SIM slot.");
608 }
609
Hui Wang641e81c2020-10-12 12:14:23 -0700610 private void onHelpGba() {
611 PrintWriter pw = getOutPrintWriter();
612 pw.println("Gba Commands:");
613 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
614 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
615 pw.println(" Options are:");
616 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
617 pw.println(" is specified, it will choose the default voice SIM slot.");
618 pw.println(" gba get-service [-s SLOT_ID]");
619 pw.println(" Gets the package name of the currently defined GbaService.");
620 pw.println(" Options are:");
621 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
622 pw.println(" is specified, it will choose the default voice SIM slot.");
623 pw.println(" gba set-release [-s SLOT_ID] n");
624 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
625 pw.println(" Do not release/unbind if n is -1.");
626 pw.println(" Options are:");
627 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
628 pw.println(" is specified, it will choose the default voice SIM slot.");
629 pw.println(" gba get-release [-s SLOT_ID]");
630 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
631 pw.println(" Options are:");
632 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
633 pw.println(" is specified, it will choose the default voice SIM slot.");
634 }
635
Hui Wang761a6682020-10-31 05:12:53 +0000636 private void onHelpSrc() {
637 PrintWriter pw = getOutPrintWriter();
638 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800639 pw.println(" src set-test-enabled true|false");
640 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
641 pw.println(" The value could be true, false, or null(undefined).");
642 pw.println(" src get-test-enabled");
643 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000644 pw.println(" src set-device-enabled true|false|null");
645 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
646 pw.println(" The value could be true, false, or null(undefined).");
647 pw.println(" src get-device-enabled");
648 pw.println(" Gets the device config for RCS VoLTE single registration.");
649 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
650 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
651 pw.println(" The value could be true, false, or null(undefined).");
652 pw.println(" Options are:");
653 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
654 pw.println(" is specified, it will choose the default voice SIM slot.");
655 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
656 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
657 pw.println(" Options are:");
658 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
659 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800660 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
661 pw.println(" Sets ims feature validation result.");
662 pw.println(" The value could be true, false, or null(undefined).");
663 pw.println(" Options are:");
664 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
665 pw.println(" is specified, it will choose the default voice SIM slot.");
666 pw.println(" src get-feature-validation [-s SLOT_ID]");
667 pw.println(" Gets ims feature validation override value.");
668 pw.println(" Options are:");
669 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
670 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000671 }
672
SongFerngWang98dd5992021-05-13 17:50:00 +0800673 private void onHelpAllowedNetworkTypes() {
674 PrintWriter pw = getOutPrintWriter();
675 pw.println("Allowed Network Types Commands:");
676 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
677 pw.println(" Print allowed network types value.");
678 pw.println(" Options are:");
679 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
680 pw.println(" option is specified, it will choose the default voice SIM slot.");
681 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
682 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
683 pw.println(" Options are:");
684 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
685 pw.println(" option is specified, it will choose the default voice SIM slot.");
686 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
687 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
688 pw.println(" at TelephonyManager.java");
689 pw.println(" For example:");
690 pw.println(" NR only : 10000000000000000000");
691 pw.println(" NR|LTE : 11000001000000000000");
692 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
693 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
694 pw.println(" LTE only : 01000001000000000000");
695 }
696
jimsun3b9ccac2021-10-26 15:01:23 +0800697 private void onHelpRadio() {
698 PrintWriter pw = getOutPrintWriter();
699 pw.println("Radio Commands:");
700 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
701 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
702 pw.println(" to be the bound. Options are:");
703 pw.println(" -s: the service name that the modem service should be bound for.");
704 pw.println(" If no option is specified, it will bind to the default.");
705 pw.println(" radio get-modem-service");
706 pw.println(" Gets the service name of the currently defined modem service.");
707 pw.println(" If it is binding to default, 'default' returns.");
708 pw.println(" If it doesn't bind to any modem service for some reasons,");
709 pw.println(" the result would be 'unknown'.");
710 }
711
Ling Ma4fbab492022-01-25 22:36:16 +0000712 private void onHelpImei() {
713 PrintWriter pw = getOutPrintWriter();
714 pw.println("IMEI Commands:");
715 pw.println(" get-imei [-s SLOT_ID]");
716 pw.println(" Gets the device IMEI. Options are:");
717 pw.println(" -s: the slot ID to get the IMEI. If no option");
718 pw.println(" is specified, it will choose the default voice SIM slot.");
719 }
720
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700721 private int handleImsCommand() {
722 String arg = getNextArg();
723 if (arg == null) {
724 onHelpIms();
725 return 0;
726 }
727
728 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800729 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700730 return handleImsSetServiceCommand();
731 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800732 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700733 return handleImsGetServiceCommand();
734 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800735 case IMS_CLEAR_SERVICE_OVERRIDE: {
736 return handleImsClearCarrierServiceCommand();
737 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800738 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700739 return handleEnableIms();
740 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800741 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700742 return handleDisableIms();
743 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700744 case IMS_CEP: {
745 return handleCepChange();
746 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700747 }
748
749 return -1;
750 }
751
Shuo Qianf5125122019-12-16 17:03:07 -0800752 private int handleDataTestModeCommand() {
753 PrintWriter errPw = getErrPrintWriter();
754 String arg = getNextArgRequired();
755 if (arg == null) {
756 onHelpDataTestMode();
757 return 0;
758 }
759 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800760 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800761 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700762 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800763 } catch (RemoteException ex) {
764 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
765 errPw.println("Exception: " + ex.getMessage());
766 return -1;
767 }
768 break;
769 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800770 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800771 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700772 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800773 } catch (RemoteException ex) {
774 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
775 errPw.println("Exception: " + ex.getMessage());
776 return -1;
777 }
778 break;
779 }
780 default:
781 onHelpDataTestMode();
782 break;
783 }
784 return 0;
785 }
786
Shuo Qianccbaf742021-02-22 18:32:21 -0800787 private int handleEmergencyCallbackModeCommand() {
788 PrintWriter errPw = getErrPrintWriter();
789 try {
790 mInterface.startEmergencyCallbackMode();
791 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
792 } catch (RemoteException ex) {
793 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
794 errPw.println("Exception: " + ex.getMessage());
795 return -1;
796 }
797 return 0;
798 }
799
Grant Menke567d48f2022-08-18 20:19:10 +0000800 private void removeEmergencyNumberTestMode(String emergencyNumber) {
801 PrintWriter errPw = getErrPrintWriter();
802 for (int routingType : ROUTING_TYPES) {
803 try {
804 mInterface.updateEmergencyNumberListTestMode(
805 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
806 new EmergencyNumber(emergencyNumber, "", "",
807 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
808 new ArrayList<String>(),
809 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
810 routingType));
811 } catch (RemoteException ex) {
812 Log.w(LOG_TAG, "emergency-number-test-mode " + "error " + ex.getMessage());
813 errPw.println("Exception: " + ex.getMessage());
814 }
815 }
816 }
817
sqian9d4df8b2019-01-15 18:32:07 -0800818 private int handleEmergencyNumberTestModeCommand() {
819 PrintWriter errPw = getErrPrintWriter();
820 String opt = getNextOption();
821 if (opt == null) {
822 onHelpEmergencyNumber();
823 return 0;
824 }
sqian9d4df8b2019-01-15 18:32:07 -0800825 switch (opt) {
826 case "-a": {
827 String emergencyNumberCmd = getNextArgRequired();
Grant Menke567d48f2022-08-18 20:19:10 +0000828 if (emergencyNumberCmd == null){
829 errPw.println(INVALID_ENTRY_ERROR);
sqian9d4df8b2019-01-15 18:32:07 -0800830 return -1;
831 }
Grant Menke567d48f2022-08-18 20:19:10 +0000832 String[] params = emergencyNumberCmd.split(":");
833 String emergencyNumber;
834 if (params[0] == null ||
835 !EmergencyNumber.validateEmergencyNumberAddress(params[0])){
836 errPw.println(INVALID_ENTRY_ERROR);
837 return -1;
838 } else {
839 emergencyNumber = params[0];
840 }
841 removeEmergencyNumberTestMode(emergencyNumber);
842 int emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN;
843 if (params.length > 1) {
844 switch (params[1].toLowerCase(Locale.ROOT)) {
845 case "emergency":
846 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY;
847 break;
848 case "normal":
849 emergencyCallRouting = EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL;
850 break;
851 case "unknown":
852 break;
853 default:
854 errPw.println("\"" + params[1] + "\" is not a valid specification for "
855 + "emergency call routing. Please enter either \"normal\", "
856 + "\"unknown\", or \"emergency\" for call routing. "
857 + "(-a 1234:normal)");
858 return -1;
859 }
860 }
sqian9d4df8b2019-01-15 18:32:07 -0800861 try {
862 mInterface.updateEmergencyNumberListTestMode(
863 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
Grant Menke567d48f2022-08-18 20:19:10 +0000864 new EmergencyNumber(emergencyNumber, "", "",
sqian9d4df8b2019-01-15 18:32:07 -0800865 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
866 new ArrayList<String>(),
867 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
Grant Menke567d48f2022-08-18 20:19:10 +0000868 emergencyCallRouting));
sqian9d4df8b2019-01-15 18:32:07 -0800869 } catch (RemoteException ex) {
Grant Menke567d48f2022-08-18 20:19:10 +0000870 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumber
sqian9d4df8b2019-01-15 18:32:07 -0800871 + ", error " + ex.getMessage());
872 errPw.println("Exception: " + ex.getMessage());
873 return -1;
874 }
875 break;
876 }
877 case "-c": {
878 try {
879 mInterface.updateEmergencyNumberListTestMode(
880 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
881 } catch (RemoteException ex) {
882 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
883 errPw.println("Exception: " + ex.getMessage());
884 return -1;
885 }
886 break;
887 }
888 case "-r": {
889 String emergencyNumberCmd = getNextArgRequired();
890 if (emergencyNumberCmd == null
891 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700892 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800893 + " to be specified after -r in the command ");
894 return -1;
895 }
Grant Menke567d48f2022-08-18 20:19:10 +0000896 removeEmergencyNumberTestMode(emergencyNumberCmd);
sqian9d4df8b2019-01-15 18:32:07 -0800897 break;
898 }
899 case "-p": {
900 try {
901 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
902 } catch (RemoteException ex) {
903 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
904 errPw.println("Exception: " + ex.getMessage());
905 return -1;
906 }
907 break;
908 }
909 default:
910 onHelpEmergencyNumber();
911 break;
912 }
913 return 0;
914 }
915
Hall Liud892bec2018-11-30 14:51:45 -0800916 private int handleNumberVerificationCommand() {
917 String arg = getNextArg();
918 if (arg == null) {
919 onHelpNumberVerification();
920 return 0;
921 }
922
Hall Liuca5af3a2018-12-04 16:58:23 -0800923 if (!checkShellUid()) {
924 return -1;
925 }
926
Hall Liud892bec2018-11-30 14:51:45 -0800927 switch (arg) {
928 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800929 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
930 return 0;
931 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800932 case NUMBER_VERIFICATION_FAKE_CALL: {
933 boolean val = NumberVerificationManager.getInstance()
934 .checkIncomingCall(getNextArg());
935 getOutPrintWriter().println(val ? "1" : "0");
936 return 0;
937 }
Hall Liud892bec2018-11-30 14:51:45 -0800938 }
939
940 return -1;
941 }
942
Jordan Liu0ccee222021-04-27 11:55:13 -0700943 private boolean subIsEsim(int subId) {
944 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
945 if (info != null) {
946 return info.isEmbedded();
947 }
948 return false;
949 }
950
951 private int handleEnablePhysicalSubscription(boolean enable) {
952 PrintWriter errPw = getErrPrintWriter();
953 int subId = 0;
954 try {
955 subId = Integer.parseInt(getNextArgRequired());
956 } catch (NumberFormatException e) {
957 errPw.println((enable ? "enable" : "disable")
958 + "-physical-subscription requires an integer as a subId.");
959 return -1;
960 }
961 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
962 // non user build.
963 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
964 errPw.println("cc: Permission denied.");
965 return -1;
966 }
967 // Verify that the subId represents a physical sub
968 if (subIsEsim(subId)) {
969 errPw.println("SubId " + subId + " is not for a physical subscription");
970 return -1;
971 }
972 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
973 + " physical subscription with subId=" + subId);
974 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
975 return 0;
976 }
977
Jack Nudelman644b91a2021-03-12 14:09:48 -0800978 private int handleThermalMitigationCommand() {
979 String arg = getNextArg();
980 String packageName = getNextArg();
981 if (arg == null || packageName == null) {
982 onHelpThermalMitigation();
983 return 0;
984 }
985
986 if (!checkShellUid()) {
987 return -1;
988 }
989
990 switch (arg) {
991 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
992 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
993 return 0;
994 }
995 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
996 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
997 mContext);
998 return 0;
999 }
1000 default:
1001 onHelpThermalMitigation();
1002 }
1003
1004 return -1;
1005
1006 }
1007
Tyler Gunn92479152021-01-20 16:30:10 -08001008 private int handleD2dCommand() {
1009 String arg = getNextArg();
1010 if (arg == null) {
1011 onHelpD2D();
1012 return 0;
1013 }
1014
1015 switch (arg) {
1016 case D2D_SEND: {
1017 return handleD2dSendCommand();
1018 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001019 case D2D_TRANSPORT: {
1020 return handleD2dTransportCommand();
1021 }
Tyler Gunnd4575212021-05-03 14:46:49 -07001022 case D2D_SET_DEVICE_SUPPORT: {
1023 return handleD2dDeviceSupportedCommand();
1024 }
Tyler Gunn92479152021-01-20 16:30:10 -08001025 }
1026
1027 return -1;
1028 }
1029
1030 private int handleD2dSendCommand() {
1031 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -08001032 int messageType = -1;
1033 int messageValue = -1;
1034
Tyler Gunn92479152021-01-20 16:30:10 -08001035 String arg = getNextArg();
1036 if (arg == null) {
1037 onHelpD2D();
1038 return 0;
1039 }
1040 try {
1041 messageType = Integer.parseInt(arg);
1042 } catch (NumberFormatException e) {
1043 errPw.println("message type must be a valid integer");
1044 return -1;
1045 }
1046
1047 arg = getNextArg();
1048 if (arg == null) {
1049 onHelpD2D();
1050 return 0;
1051 }
1052 try {
1053 messageValue = Integer.parseInt(arg);
1054 } catch (NumberFormatException e) {
1055 errPw.println("message value must be a valid integer");
1056 return -1;
1057 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001058
Tyler Gunn92479152021-01-20 16:30:10 -08001059 try {
1060 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1061 } catch (RemoteException e) {
1062 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1063 errPw.println("Exception: " + e.getMessage());
1064 return -1;
1065 }
1066
1067 return 0;
1068 }
1069
Tyler Gunnbabbda02021-02-10 11:05:02 -08001070 private int handleD2dTransportCommand() {
1071 PrintWriter errPw = getErrPrintWriter();
1072
1073 String arg = getNextArg();
1074 if (arg == null) {
1075 onHelpD2D();
1076 return 0;
1077 }
1078
1079 try {
1080 mInterface.setActiveDeviceToDeviceTransport(arg);
1081 } catch (RemoteException e) {
1082 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1083 errPw.println("Exception: " + e.getMessage());
1084 return -1;
1085 }
1086 return 0;
1087 }
Nazanin014f41e2021-05-06 17:26:31 -07001088 private int handleBarringCommand() {
1089 String arg = getNextArg();
1090 if (arg == null) {
1091 onHelpBarring();
1092 return 0;
1093 }
1094
1095 switch (arg) {
1096 case BARRING_SEND_INFO: {
1097 return handleBarringSendCommand();
1098 }
1099 }
1100 return -1;
1101 }
1102
1103 private int handleBarringSendCommand() {
1104 PrintWriter errPw = getErrPrintWriter();
1105 int slotId = getDefaultSlot();
1106 int subId = SubscriptionManager.getSubId(slotId)[0];
1107 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1108 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1109 boolean isConditionallyBarred = false;
1110 int conditionalBarringTimeSeconds = 0;
1111
1112 String opt;
1113 while ((opt = getNextOption()) != null) {
1114 switch (opt) {
1115 case "-s": {
1116 try {
1117 slotId = Integer.parseInt(getNextArgRequired());
1118 subId = SubscriptionManager.getSubId(slotId)[0];
1119 } catch (NumberFormatException e) {
1120 errPw.println("barring send requires an integer as a SLOT_ID.");
1121 return -1;
1122 }
1123 break;
1124 }
1125 case "-b": {
1126 try {
1127 barringType = Integer.parseInt(getNextArgRequired());
1128 if (barringType < -1 || barringType > 2) {
1129 throw new NumberFormatException();
1130 }
1131
1132 } catch (NumberFormatException e) {
1133 errPw.println("barring send requires an integer in range [-1,2] as "
1134 + "a BARRING_TYPE.");
1135 return -1;
1136 }
1137 break;
1138 }
1139 case "-c": {
1140 try {
1141 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1142 } catch (Exception e) {
1143 errPw.println("barring send requires a boolean after -c indicating"
1144 + " conditional barring");
1145 return -1;
1146 }
1147 break;
1148 }
1149 case "-t": {
1150 try {
1151 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1152 } catch (NumberFormatException e) {
1153 errPw.println("barring send requires an integer for time of barring"
1154 + " in seconds after -t for conditional barring");
1155 return -1;
1156 }
1157 break;
1158 }
1159 }
1160 }
1161 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1162 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1163 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1164 barringServiceInfos.append(0, bsi);
1165 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1166 try {
1167 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1168 } catch (Exception e) {
1169 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1170 errPw.println("Exception: " + e.getMessage());
1171 return -1;
1172 }
1173 return 0;
1174 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001175
Tyler Gunnd4575212021-05-03 14:46:49 -07001176 private int handleD2dDeviceSupportedCommand() {
1177 PrintWriter errPw = getErrPrintWriter();
1178
1179 String arg = getNextArg();
1180 if (arg == null) {
1181 onHelpD2D();
1182 return 0;
1183 }
1184
1185 boolean isEnabled = "true".equals(arg.toLowerCase());
1186 try {
1187 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1188 } catch (RemoteException e) {
1189 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1190 errPw.println("Exception: " + e.getMessage());
1191 return -1;
1192 }
1193 return 0;
1194 }
1195
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001196 // ims set-ims-service
1197 private int handleImsSetServiceCommand() {
1198 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001199 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001200 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001201 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001202
1203 String opt;
1204 while ((opt = getNextOption()) != null) {
1205 switch (opt) {
1206 case "-s": {
1207 try {
1208 slotId = Integer.parseInt(getNextArgRequired());
1209 } catch (NumberFormatException e) {
1210 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1211 return -1;
1212 }
1213 break;
1214 }
1215 case "-c": {
1216 isCarrierService = true;
1217 break;
1218 }
1219 case "-d": {
1220 isCarrierService = false;
1221 break;
1222 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001223 case "-f": {
1224 String featureString = getNextArgRequired();
1225 String[] features = featureString.split(",");
1226 for (int i = 0; i < features.length; i++) {
1227 try {
1228 Integer result = Integer.parseInt(features[i]);
1229 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1230 || result >= ImsFeature.FEATURE_MAX) {
1231 errPw.println("ims set-ims-service -f " + result
1232 + " is an invalid feature.");
1233 return -1;
1234 }
1235 featuresList.add(result);
1236 } catch (NumberFormatException e) {
1237 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1238 + " as an integer.");
1239 return -1;
1240 }
1241 }
1242 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001243 }
1244 }
1245 // Mandatory param, either -c or -d
1246 if (isCarrierService == null) {
1247 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1248 return -1;
1249 }
1250
1251 String packageName = getNextArg();
1252
1253 try {
1254 if (packageName == null) {
1255 packageName = "";
1256 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001257 int[] featureArray = new int[featuresList.size()];
1258 for (int i = 0; i < featuresList.size(); i++) {
1259 featureArray[i] = featuresList.get(i);
1260 }
1261 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1262 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001263 if (VDBG) {
1264 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001265 + (isCarrierService ? "-c " : "-d ")
1266 + "-f " + featuresList + " "
1267 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001268 }
1269 getOutPrintWriter().println(result);
1270 } catch (RemoteException e) {
1271 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001272 + (isCarrierService ? "-c " : "-d ")
1273 + "-f " + featuresList + " "
1274 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001275 errPw.println("Exception: " + e.getMessage());
1276 return -1;
1277 }
1278 return 0;
1279 }
1280
Brad Ebinger999d3302020-11-25 14:31:39 -08001281 // ims clear-ims-service-override
1282 private int handleImsClearCarrierServiceCommand() {
1283 PrintWriter errPw = getErrPrintWriter();
1284 int slotId = getDefaultSlot();
1285
1286 String opt;
1287 while ((opt = getNextOption()) != null) {
1288 switch (opt) {
1289 case "-s": {
1290 try {
1291 slotId = Integer.parseInt(getNextArgRequired());
1292 } catch (NumberFormatException e) {
1293 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1294 return -1;
1295 }
1296 break;
1297 }
1298 }
1299 }
1300
1301 try {
1302 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1303 if (VDBG) {
1304 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1305 + ", result=" + result);
1306 }
1307 getOutPrintWriter().println(result);
1308 } catch (RemoteException e) {
1309 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1310 + ", error" + e.getMessage());
1311 errPw.println("Exception: " + e.getMessage());
1312 return -1;
1313 }
1314 return 0;
1315 }
1316
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001317 // ims get-ims-service
1318 private int handleImsGetServiceCommand() {
1319 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001320 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001321 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001322 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001323
1324 String opt;
1325 while ((opt = getNextOption()) != null) {
1326 switch (opt) {
1327 case "-s": {
1328 try {
1329 slotId = Integer.parseInt(getNextArgRequired());
1330 } catch (NumberFormatException e) {
1331 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1332 return -1;
1333 }
1334 break;
1335 }
1336 case "-c": {
1337 isCarrierService = true;
1338 break;
1339 }
1340 case "-d": {
1341 isCarrierService = false;
1342 break;
1343 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001344 case "-f": {
1345 try {
1346 featureType = Integer.parseInt(getNextArg());
1347 } catch (NumberFormatException e) {
1348 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1349 return -1;
1350 }
1351 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1352 || featureType >= ImsFeature.FEATURE_MAX) {
1353 errPw.println("ims get-ims-service -f invalid feature.");
1354 return -1;
1355 }
1356 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001357 }
1358 }
1359 // Mandatory param, either -c or -d
1360 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001361 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001362 return -1;
1363 }
1364
1365 String result;
1366 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001367 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001368 } catch (RemoteException e) {
1369 return -1;
1370 }
1371 if (VDBG) {
1372 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001373 + (isCarrierService ? "-c " : "-d ")
1374 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1375 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001376 }
1377 getOutPrintWriter().println(result);
1378 return 0;
1379 }
1380
1381 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001382 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001383 String opt;
1384 while ((opt = getNextOption()) != null) {
1385 switch (opt) {
1386 case "-s": {
1387 try {
1388 slotId = Integer.parseInt(getNextArgRequired());
1389 } catch (NumberFormatException e) {
1390 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1391 return -1;
1392 }
1393 break;
1394 }
1395 }
1396 }
1397 try {
1398 mInterface.enableIms(slotId);
1399 } catch (RemoteException e) {
1400 return -1;
1401 }
1402 if (VDBG) {
1403 Log.v(LOG_TAG, "ims enable -s " + slotId);
1404 }
1405 return 0;
1406 }
1407
1408 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001409 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001410 String opt;
1411 while ((opt = getNextOption()) != null) {
1412 switch (opt) {
1413 case "-s": {
1414 try {
1415 slotId = Integer.parseInt(getNextArgRequired());
1416 } catch (NumberFormatException e) {
1417 getErrPrintWriter().println(
1418 "ims disable requires an integer as a SLOT_ID.");
1419 return -1;
1420 }
1421 break;
1422 }
1423 }
1424 }
1425 try {
1426 mInterface.disableIms(slotId);
1427 } catch (RemoteException e) {
1428 return -1;
1429 }
1430 if (VDBG) {
1431 Log.v(LOG_TAG, "ims disable -s " + slotId);
1432 }
1433 return 0;
1434 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001435
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001436 private int handleCepChange() {
1437 Log.i(LOG_TAG, "handleCepChange");
1438 String opt = getNextArg();
1439 if (opt == null) {
1440 return -1;
1441 }
1442 boolean isCepEnabled = opt.equals("enable");
1443
1444 try {
1445 mInterface.setCepEnabled(isCepEnabled);
1446 } catch (RemoteException e) {
1447 return -1;
1448 }
1449 return 0;
1450 }
1451
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001452 private int getDefaultSlot() {
1453 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1454 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1455 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1456 // If there is no default, default to slot 0.
1457 slotId = DEFAULT_PHONE_ID;
1458 }
1459 return slotId;
1460 }
sqian2fff4a32018-11-05 14:18:37 -08001461
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001462 // Parse options related to Carrier Config Commands.
1463 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001464 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001465 CcOptionParseResult result = new CcOptionParseResult();
1466 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1467 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001468
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001469 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001470 while ((opt = getNextOption()) != null) {
1471 switch (opt) {
1472 case "-s": {
1473 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001474 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1475 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1476 errPw.println(tag + "No valid subscription found.");
1477 return null;
1478 }
1479
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001480 } catch (IllegalArgumentException e) {
1481 // Missing slot id
1482 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001483 return null;
1484 }
1485 break;
1486 }
1487 case "-p": {
1488 if (allowOptionPersistent) {
1489 result.mPersistent = true;
1490 } else {
1491 errPw.println(tag + "Unexpected option " + opt);
1492 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001493 }
1494 break;
1495 }
1496 default: {
1497 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001498 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001499 }
1500 }
1501 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001502 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001503 }
1504
1505 private int slotStringToSubId(String tag, String slotString) {
1506 int slotId = -1;
1507 try {
1508 slotId = Integer.parseInt(slotString);
1509 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001510 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1511 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1512 }
1513
1514 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001515 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1516 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1517 }
1518
Qiong Liuf25799b2020-09-10 10:13:46 +08001519 Phone phone = PhoneFactory.getPhone(slotId);
1520 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001521 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1522 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1523 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001524 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001525 }
1526
Hall Liud892bec2018-11-30 14:51:45 -08001527 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001528 // adb can run as root or as shell, depending on whether the device is rooted.
1529 return Binder.getCallingUid() == Process.SHELL_UID
1530 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001531 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001532
1533 private int handleCcCommand() {
1534 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1535 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001536 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001537 getErrPrintWriter().println("cc: Permission denied.");
1538 return -1;
1539 }
1540
1541 String arg = getNextArg();
1542 if (arg == null) {
1543 onHelpCc();
1544 return 0;
1545 }
1546
1547 switch (arg) {
1548 case CC_GET_VALUE: {
1549 return handleCcGetValue();
1550 }
1551 case CC_SET_VALUE: {
1552 return handleCcSetValue();
1553 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001554 case CC_SET_VALUES_FROM_XML: {
1555 return handleCcSetValuesFromXml();
1556 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001557 case CC_CLEAR_VALUES: {
1558 return handleCcClearValues();
1559 }
1560 default: {
1561 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1562 }
1563 }
1564 return -1;
1565 }
1566
1567 // cc get-value
1568 private int handleCcGetValue() {
1569 PrintWriter errPw = getErrPrintWriter();
1570 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1571 String key = null;
1572
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001573 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001574 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001575 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001576 return -1;
1577 }
1578
1579 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001580 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001581 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001582 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001583 return -1;
1584 }
1585
1586 // Get the key.
1587 key = getNextArg();
1588 if (key != null) {
1589 // A key was provided. Verify if it is a valid key
1590 if (!bundle.containsKey(key)) {
1591 errPw.println(tag + key + " is not a valid key.");
1592 return -1;
1593 }
1594
1595 // Print the carrier config value for key.
1596 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1597 } else {
1598 // No key provided. Show all values.
1599 // Iterate over a sorted list of all carrier config keys and print them.
1600 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1601 for (String k : sortedSet) {
1602 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1603 }
1604 }
1605 return 0;
1606 }
1607
1608 // cc set-value
1609 private int handleCcSetValue() {
1610 PrintWriter errPw = getErrPrintWriter();
1611 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1612
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001613 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001614 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001615 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001616 return -1;
1617 }
1618
1619 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001620 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001621 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001622 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001623 return -1;
1624 }
1625
1626 // Get the key.
1627 String key = getNextArg();
1628 if (key == null || key.equals("")) {
1629 errPw.println(tag + "KEY is missing");
1630 return -1;
1631 }
1632
1633 // Verify if the key is valid
1634 if (!originalValues.containsKey(key)) {
1635 errPw.println(tag + key + " is not a valid key.");
1636 return -1;
1637 }
1638
1639 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1640 ArrayList<String> valueList = new ArrayList<String>();
1641 while (peekNextArg() != null) {
1642 valueList.add(getNextArg());
1643 }
1644
1645 // Find the type of the carrier config value
1646 CcType type = getType(tag, key, originalValues);
1647 if (type == CcType.UNKNOWN) {
1648 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1649 return -1;
1650 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001651 if (type == CcType.PERSISTABLE_BUNDLE) {
1652 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1653 + "Use set-values-from-xml instead.");
1654 return -1;
1655 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001656
1657 // Create an override bundle containing the key and value that should be overriden.
1658 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1659 if (overrideBundle == null) {
1660 return -1;
1661 }
1662
1663 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001664 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001665
1666 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001667 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001668 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001669 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001670 return -1;
1671 }
1672
1673 // Print the original and new value.
1674 String originalValueString = ccValueToString(key, type, originalValues);
1675 String newValueString = ccValueToString(key, type, newValues);
1676 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1677 getOutPrintWriter().println("New value: \n" + newValueString);
1678
1679 return 0;
1680 }
1681
Allen Xuee00f0e2022-03-14 21:04:49 +00001682 // cc set-values-from-xml
1683 private int handleCcSetValuesFromXml() {
1684 PrintWriter errPw = getErrPrintWriter();
1685 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1686
1687 // Parse all options
Allen Xuaafea2e2022-05-20 22:26:42 +00001688 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001689 if (options == null) {
1690 return -1;
1691 }
1692
1693 // Get bundle containing all current carrier configuration values.
1694 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1695 if (originalValues == null) {
1696 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1697 return -1;
1698 }
1699
1700 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1701 if (overrideBundle == null) {
1702 return -1;
1703 }
1704
1705 // Verify all values are valid types
1706 for (String key : overrideBundle.keySet()) {
1707 CcType type = getType(tag, key, originalValues);
1708 if (type == CcType.UNKNOWN) {
1709 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1710 return -1;
1711 }
1712 }
1713
1714 // Override the value
1715 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1716
1717 // Find bundle containing all new carrier configuration values after the override.
1718 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1719 if (newValues == null) {
1720 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1721 return -1;
1722 }
1723
1724 // Print the original and new values
1725 overrideBundle.keySet().forEach(key -> {
1726 CcType type = getType(tag, key, originalValues);
1727 String originalValueString = ccValueToString(key, type, originalValues);
1728 String newValueString = ccValueToString(key, type, newValues);
1729 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1730 getOutPrintWriter().println("New value: \n" + newValueString);
1731 });
1732
1733 return 0;
1734 }
1735
1736 private PersistableBundle readPersistableBundleFromXml(String tag) {
1737 PersistableBundle subIdBundles;
1738 try {
1739 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1740 } catch (IOException | RuntimeException e) {
1741 PrintWriter errPw = getErrPrintWriter();
1742 errPw.println(tag + e);
1743 return null;
1744 }
1745
1746 return subIdBundles;
1747 }
1748
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001749 // cc clear-values
1750 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001751 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1752
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001753 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001754 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001755 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001756 return -1;
1757 }
1758
1759 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001760 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001761 getOutPrintWriter()
1762 .println("All previously set carrier config override values has been cleared");
1763 return 0;
1764 }
1765
1766 private CcType getType(String tag, String key, PersistableBundle bundle) {
1767 // Find the type by checking the type of the current value stored in the bundle.
1768 Object value = bundle.get(key);
1769
1770 if (CC_TYPE_MAP.containsKey(key)) {
1771 return CC_TYPE_MAP.get(key);
1772 } else if (value != null) {
1773 if (value instanceof Boolean) {
1774 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001775 }
1776 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001777 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001778 }
1779 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001780 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001781 }
1782 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001783 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001784 }
1785 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001786 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001787 }
1788 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001789 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001790 }
1791 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001792 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001793 }
1794 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001795 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001796 }
1797 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001798 return CcType.STRING_ARRAY;
1799 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001800 if (value instanceof PersistableBundle) {
1801 return CcType.PERSISTABLE_BUNDLE;
1802 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001803 } else {
1804 // Current value was null and can therefore not be used in order to find the type.
1805 // Check the name of the key to infer the type. This check is not needed for primitive
1806 // data types (boolean, double, int and long), since they can not be null.
1807 if (key.endsWith("double_array")) {
1808 return CcType.DOUBLE_ARRAY;
1809 }
1810 if (key.endsWith("int_array")) {
1811 return CcType.INT_ARRAY;
1812 }
1813 if (key.endsWith("long_array")) {
1814 return CcType.LONG_ARRAY;
1815 }
1816 if (key.endsWith("string")) {
1817 return CcType.STRING;
1818 }
1819 if (key.endsWith("string_array") || key.endsWith("strings")) {
1820 return CcType.STRING_ARRAY;
1821 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001822 if (key.endsWith("bundle")) {
1823 return CcType.PERSISTABLE_BUNDLE;
1824 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001825 }
1826
1827 // Not possible to infer the type by looking at the current value or the key.
1828 PrintWriter errPw = getErrPrintWriter();
1829 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1830 return CcType.UNKNOWN;
1831 }
1832
1833 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1834 String result;
1835 StringBuilder valueString = new StringBuilder();
1836 String typeString = type.toString();
1837 Object value = bundle.get(key);
1838
1839 if (value == null) {
1840 valueString.append("null");
1841 } else {
1842 switch (type) {
1843 case DOUBLE_ARRAY: {
1844 // Format the string representation of the int array as value1 value2......
1845 double[] valueArray = (double[]) value;
1846 for (int i = 0; i < valueArray.length; i++) {
1847 if (i != 0) {
1848 valueString.append(" ");
1849 }
1850 valueString.append(valueArray[i]);
1851 }
1852 break;
1853 }
1854 case INT_ARRAY: {
1855 // Format the string representation of the int array as value1 value2......
1856 int[] valueArray = (int[]) value;
1857 for (int i = 0; i < valueArray.length; i++) {
1858 if (i != 0) {
1859 valueString.append(" ");
1860 }
1861 valueString.append(valueArray[i]);
1862 }
1863 break;
1864 }
1865 case LONG_ARRAY: {
1866 // Format the string representation of the int array as value1 value2......
1867 long[] valueArray = (long[]) value;
1868 for (int i = 0; i < valueArray.length; i++) {
1869 if (i != 0) {
1870 valueString.append(" ");
1871 }
1872 valueString.append(valueArray[i]);
1873 }
1874 break;
1875 }
1876 case STRING: {
1877 valueString.append("\"" + value.toString() + "\"");
1878 break;
1879 }
1880 case STRING_ARRAY: {
1881 // Format the string representation of the string array as "value1" "value2"....
1882 String[] valueArray = (String[]) value;
1883 for (int i = 0; i < valueArray.length; i++) {
1884 if (i != 0) {
1885 valueString.append(" ");
1886 }
1887 if (valueArray[i] != null) {
1888 valueString.append("\"" + valueArray[i] + "\"");
1889 } else {
1890 valueString.append("null");
1891 }
1892 }
1893 break;
1894 }
1895 default: {
1896 valueString.append(value.toString());
1897 }
1898 }
1899 }
1900 return String.format("%-70s %-15s %s", key, typeString, valueString);
1901 }
1902
1903 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1904 ArrayList<String> valueList) {
1905 PrintWriter errPw = getErrPrintWriter();
1906 PersistableBundle bundle = new PersistableBundle();
1907
1908 // First verify that a valid number of values has been provided for the type.
1909 switch (type) {
1910 case BOOLEAN:
1911 case DOUBLE:
1912 case INT:
1913 case LONG: {
1914 if (valueList.size() != 1) {
1915 errPw.println(tag + "Expected 1 value for type " + type
1916 + ". Found: " + valueList.size());
1917 return null;
1918 }
1919 break;
1920 }
1921 case STRING: {
1922 if (valueList.size() > 1) {
1923 errPw.println(tag + "Expected 0 or 1 values for type " + type
1924 + ". Found: " + valueList.size());
1925 return null;
1926 }
1927 break;
1928 }
1929 }
1930
1931 // Parse the value according to type and add it to the Bundle.
1932 switch (type) {
1933 case BOOLEAN: {
1934 if ("true".equalsIgnoreCase(valueList.get(0))) {
1935 bundle.putBoolean(key, true);
1936 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1937 bundle.putBoolean(key, false);
1938 } else {
1939 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1940 return null;
1941 }
1942 break;
1943 }
1944 case DOUBLE: {
1945 try {
1946 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1947 } catch (NumberFormatException nfe) {
1948 // Not a valid double
1949 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1950 return null;
1951 }
1952 break;
1953 }
1954 case DOUBLE_ARRAY: {
1955 double[] valueDoubleArray = null;
1956 if (valueList.size() > 0) {
1957 valueDoubleArray = new double[valueList.size()];
1958 for (int i = 0; i < valueList.size(); i++) {
1959 try {
1960 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1961 } catch (NumberFormatException nfe) {
1962 // Not a valid double
1963 errPw.println(
1964 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1965 return null;
1966 }
1967 }
1968 }
1969 bundle.putDoubleArray(key, valueDoubleArray);
1970 break;
1971 }
1972 case INT: {
1973 try {
1974 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1975 } catch (NumberFormatException nfe) {
1976 // Not a valid integer
1977 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1978 return null;
1979 }
1980 break;
1981 }
1982 case INT_ARRAY: {
1983 int[] valueIntArray = null;
1984 if (valueList.size() > 0) {
1985 valueIntArray = new int[valueList.size()];
1986 for (int i = 0; i < valueList.size(); i++) {
1987 try {
1988 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1989 } catch (NumberFormatException nfe) {
1990 // Not a valid integer
1991 errPw.println(tag
1992 + "Unable to parse " + valueList.get(i) + " as an integer.");
1993 return null;
1994 }
1995 }
1996 }
1997 bundle.putIntArray(key, valueIntArray);
1998 break;
1999 }
2000 case LONG: {
2001 try {
2002 bundle.putLong(key, Long.parseLong(valueList.get(0)));
2003 } catch (NumberFormatException nfe) {
2004 // Not a valid long
2005 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
2006 return null;
2007 }
2008 break;
2009 }
2010 case LONG_ARRAY: {
2011 long[] valueLongArray = null;
2012 if (valueList.size() > 0) {
2013 valueLongArray = new long[valueList.size()];
2014 for (int i = 0; i < valueList.size(); i++) {
2015 try {
2016 valueLongArray[i] = Long.parseLong(valueList.get(i));
2017 } catch (NumberFormatException nfe) {
2018 // Not a valid long
2019 errPw.println(
2020 tag + "Unable to parse " + valueList.get(i) + " as a long");
2021 return null;
2022 }
2023 }
2024 }
2025 bundle.putLongArray(key, valueLongArray);
2026 break;
2027 }
2028 case STRING: {
2029 String value = null;
2030 if (valueList.size() > 0) {
2031 value = valueList.get(0);
2032 }
2033 bundle.putString(key, value);
2034 break;
2035 }
2036 case STRING_ARRAY: {
2037 String[] valueStringArray = null;
2038 if (valueList.size() > 0) {
2039 valueStringArray = new String[valueList.size()];
2040 valueList.toArray(valueStringArray);
2041 }
2042 bundle.putStringArray(key, valueStringArray);
2043 break;
2044 }
2045 }
2046 return bundle;
2047 }
Shuo Qian489d9282020-07-09 11:30:03 -07002048
2049 private int handleEndBlockSuppressionCommand() {
2050 if (!checkShellUid()) {
2051 return -1;
2052 }
2053
2054 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2055 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2056 }
2057 return 0;
2058 }
Hui Wang641e81c2020-10-12 12:14:23 -07002059
Michele Berionne54af4632020-12-28 20:23:16 +00002060 private int handleRestartModemCommand() {
2061 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2062 // non user build.
2063 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2064 getErrPrintWriter().println("RestartModem: Permission denied.");
2065 return -1;
2066 }
2067
2068 boolean result = TelephonyManager.getDefault().rebootRadio();
2069 getOutPrintWriter().println(result);
2070
2071 return result ? 0 : -1;
2072 }
2073
Ling Ma4fbab492022-01-25 22:36:16 +00002074 private int handleGetImei() {
2075 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2076 // non user build.
2077 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2078 getErrPrintWriter().println("Device IMEI: Permission denied.");
2079 return -1;
2080 }
2081
2082 final long identity = Binder.clearCallingIdentity();
2083
2084 String imei = null;
2085 String arg = getNextArg();
2086 if (arg != null) {
2087 try {
2088 int specifiedSlotIndex = Integer.parseInt(arg);
2089 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2090 } catch (NumberFormatException exception) {
2091 PrintWriter errPw = getErrPrintWriter();
2092 errPw.println("-s requires an integer as slot index.");
2093 return -1;
2094 }
2095
2096 } else {
2097 imei = TelephonyManager.from(mContext).getImei();
2098 }
2099 getOutPrintWriter().println("Device IMEI: " + imei);
2100
2101 Binder.restoreCallingIdentity(identity);
2102 return 0;
2103 }
2104
Michele Berionne5e411512020-11-13 02:36:59 +00002105 private int handleUnattendedReboot() {
2106 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2107 // non user build.
2108 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2109 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2110 return -1;
2111 }
2112
2113 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2114 getOutPrintWriter().println("result: " + result);
2115
2116 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2117 }
2118
Aman Gupta07124872022-02-09 08:02:14 +00002119 private int handleGetSimSlotsMapping() {
2120 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2121 // non user build.
2122 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2123 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2124 return -1;
2125 }
2126 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2127 String result = telephonyManager.getSimSlotMapping().toString();
2128 getOutPrintWriter().println("simSlotsMapping: " + result);
2129
2130 return 0;
2131 }
2132
Hui Wang641e81c2020-10-12 12:14:23 -07002133 private int handleGbaCommand() {
2134 String arg = getNextArg();
2135 if (arg == null) {
2136 onHelpGba();
2137 return 0;
2138 }
2139
2140 switch (arg) {
2141 case GBA_SET_SERVICE: {
2142 return handleGbaSetServiceCommand();
2143 }
2144 case GBA_GET_SERVICE: {
2145 return handleGbaGetServiceCommand();
2146 }
2147 case GBA_SET_RELEASE_TIME: {
2148 return handleGbaSetReleaseCommand();
2149 }
2150 case GBA_GET_RELEASE_TIME: {
2151 return handleGbaGetReleaseCommand();
2152 }
2153 }
2154
2155 return -1;
2156 }
2157
2158 private int getSubId(String cmd) {
2159 int slotId = getDefaultSlot();
2160 String opt = getNextOption();
2161 if (opt != null && opt.equals("-s")) {
2162 try {
2163 slotId = Integer.parseInt(getNextArgRequired());
2164 } catch (NumberFormatException e) {
2165 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2166 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2167 }
2168 }
2169 int[] subIds = SubscriptionManager.getSubId(slotId);
2170 return subIds[0];
2171 }
2172
2173 private int handleGbaSetServiceCommand() {
2174 int subId = getSubId("gba set-service");
2175 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2176 return -1;
2177 }
2178
2179 String packageName = getNextArg();
2180 try {
2181 if (packageName == null) {
2182 packageName = "";
2183 }
2184 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2185 if (VDBG) {
2186 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2187 + packageName + ", result=" + result);
2188 }
2189 getOutPrintWriter().println(result);
2190 } catch (RemoteException e) {
2191 Log.w(LOG_TAG, "gba set-service " + subId + " "
2192 + packageName + ", error" + e.getMessage());
2193 getErrPrintWriter().println("Exception: " + e.getMessage());
2194 return -1;
2195 }
2196 return 0;
2197 }
2198
2199 private int handleGbaGetServiceCommand() {
2200 String result;
2201
2202 int subId = getSubId("gba get-service");
2203 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2204 return -1;
2205 }
2206
2207 try {
2208 result = mInterface.getBoundGbaService(subId);
2209 } catch (RemoteException e) {
2210 return -1;
2211 }
2212 if (VDBG) {
2213 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2214 }
2215 getOutPrintWriter().println(result);
2216 return 0;
2217 }
2218
2219 private int handleGbaSetReleaseCommand() {
2220 //the release time value could be -1
2221 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2222 : SubscriptionManager.getDefaultSubscriptionId();
2223 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2224 return -1;
2225 }
2226
2227 String intervalStr = getNextArg();
2228 if (intervalStr == null) {
2229 return -1;
2230 }
2231
2232 try {
2233 int interval = Integer.parseInt(intervalStr);
2234 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2235 if (VDBG) {
2236 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2237 + intervalStr + ", result=" + result);
2238 }
2239 getOutPrintWriter().println(result);
2240 } catch (NumberFormatException | RemoteException e) {
2241 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2242 + intervalStr + ", error" + e.getMessage());
2243 getErrPrintWriter().println("Exception: " + e.getMessage());
2244 return -1;
2245 }
2246 return 0;
2247 }
2248
2249 private int handleGbaGetReleaseCommand() {
2250 int subId = getSubId("gba get-release");
2251 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2252 return -1;
2253 }
2254
2255 int result = 0;
2256 try {
2257 result = mInterface.getGbaReleaseTime(subId);
2258 } catch (RemoteException e) {
2259 return -1;
2260 }
2261 if (VDBG) {
2262 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2263 }
2264 getOutPrintWriter().println(result);
2265 return 0;
2266 }
Hui Wang761a6682020-10-31 05:12:53 +00002267
2268 private int handleSingleRegistrationConfigCommand() {
2269 String arg = getNextArg();
2270 if (arg == null) {
2271 onHelpSrc();
2272 return 0;
2273 }
2274
2275 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002276 case SRC_SET_TEST_ENABLED: {
2277 return handleSrcSetTestEnabledCommand();
2278 }
2279 case SRC_GET_TEST_ENABLED: {
2280 return handleSrcGetTestEnabledCommand();
2281 }
Hui Wang761a6682020-10-31 05:12:53 +00002282 case SRC_SET_DEVICE_ENABLED: {
2283 return handleSrcSetDeviceEnabledCommand();
2284 }
2285 case SRC_GET_DEVICE_ENABLED: {
2286 return handleSrcGetDeviceEnabledCommand();
2287 }
2288 case SRC_SET_CARRIER_ENABLED: {
2289 return handleSrcSetCarrierEnabledCommand();
2290 }
2291 case SRC_GET_CARRIER_ENABLED: {
2292 return handleSrcGetCarrierEnabledCommand();
2293 }
Hui Wangb647abe2021-02-26 09:33:38 -08002294 case SRC_SET_FEATURE_ENABLED: {
2295 return handleSrcSetFeatureValidationCommand();
2296 }
2297 case SRC_GET_FEATURE_ENABLED: {
2298 return handleSrcGetFeatureValidationCommand();
2299 }
Hui Wang761a6682020-10-31 05:12:53 +00002300 }
2301
2302 return -1;
2303 }
2304
James.cf Linbcdf8b32021-01-14 16:44:13 +08002305 private int handleRcsUceCommand() {
2306 String arg = getNextArg();
2307 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002308 onHelpUce();
2309 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002310 }
2311
2312 switch (arg) {
2313 case UCE_REMOVE_EAB_CONTACT:
2314 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002315 case UCE_GET_EAB_CONTACT:
2316 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002317 case UCE_GET_EAB_CAPABILITY:
2318 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002319 case UCE_GET_DEVICE_ENABLED:
2320 return handleUceGetDeviceEnabledCommand();
2321 case UCE_SET_DEVICE_ENABLED:
2322 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002323 case UCE_OVERRIDE_PUBLISH_CAPS:
2324 return handleUceOverridePublishCaps();
2325 case UCE_GET_LAST_PIDF_XML:
2326 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002327 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2328 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002329 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2330 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002331 }
2332 return -1;
2333 }
2334
2335 private int handleRemovingEabContactCommand() {
2336 int subId = getSubId("uce remove-eab-contact");
2337 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2338 return -1;
2339 }
2340
2341 String phoneNumber = getNextArgRequired();
2342 if (TextUtils.isEmpty(phoneNumber)) {
2343 return -1;
2344 }
2345 int result = 0;
2346 try {
2347 result = mInterface.removeContactFromEab(subId, phoneNumber);
2348 } catch (RemoteException e) {
2349 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2350 getErrPrintWriter().println("Exception: " + e.getMessage());
2351 return -1;
2352 }
2353
2354 if (VDBG) {
2355 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2356 }
calvinpan293ea1b2021-02-04 17:52:13 +08002357 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002358 }
2359
calvinpane4a8a1d2021-01-25 13:51:18 +08002360 private int handleGettingEabContactCommand() {
2361 String phoneNumber = getNextArgRequired();
2362 if (TextUtils.isEmpty(phoneNumber)) {
2363 return -1;
2364 }
2365 String result = "";
2366 try {
2367 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002368 } catch (RemoteException e) {
2369 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2370 getErrPrintWriter().println("Exception: " + e.getMessage());
2371 return -1;
2372 }
2373
2374 if (VDBG) {
2375 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2376 }
calvinpan293ea1b2021-02-04 17:52:13 +08002377 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002378 return 0;
2379 }
2380
Calvin Pana1434322021-07-01 19:27:01 +08002381 private int handleGettingEabCapabilityCommand() {
2382 String phoneNumber = getNextArgRequired();
2383 if (TextUtils.isEmpty(phoneNumber)) {
2384 return -1;
2385 }
2386 String result = "";
2387 try {
2388 result = mInterface.getCapabilityFromEab(phoneNumber);
2389 } catch (RemoteException e) {
2390 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2391 getErrPrintWriter().println("Exception: " + e.getMessage());
2392 return -1;
2393 }
2394
2395 if (VDBG) {
2396 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2397 }
2398 getOutPrintWriter().println(result);
2399 return 0;
2400 }
2401
James.cf Lin4b784aa2021-01-31 03:25:15 +08002402 private int handleUceGetDeviceEnabledCommand() {
2403 boolean result = false;
2404 try {
2405 result = mInterface.getDeviceUceEnabled();
2406 } catch (RemoteException e) {
2407 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2408 return -1;
2409 }
2410 if (VDBG) {
2411 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2412 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002413 getOutPrintWriter().println(result);
2414 return 0;
2415 }
2416
James.cf Lin4b784aa2021-01-31 03:25:15 +08002417 private int handleUceSetDeviceEnabledCommand() {
2418 String enabledStr = getNextArg();
2419 if (TextUtils.isEmpty(enabledStr)) {
2420 return -1;
2421 }
2422
2423 try {
2424 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2425 mInterface.setDeviceUceEnabled(isEnabled);
2426 if (VDBG) {
2427 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2428 }
2429 } catch (NumberFormatException | RemoteException e) {
2430 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2431 getErrPrintWriter().println("Exception: " + e.getMessage());
2432 return -1;
2433 }
2434 return 0;
2435 }
2436
James.cf Line8713a42021-04-29 16:04:26 +08002437 private int handleUceRemoveRequestDisallowedStatus() {
2438 int subId = getSubId("uce remove-request-disallowed-status");
2439 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2440 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2441 return -1;
2442 }
2443 boolean result;
2444 try {
2445 result = mInterface.removeUceRequestDisallowedStatus(subId);
2446 } catch (RemoteException e) {
2447 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2448 return -1;
2449 }
2450 if (VDBG) {
2451 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2452 }
2453 getOutPrintWriter().println(result);
2454 return 0;
2455 }
2456
James.cf Lin0fc71b02021-05-25 01:37:38 +08002457 private int handleUceSetCapRequestTimeout() {
2458 int subId = getSubId("uce set-capabilities-request-timeout");
2459 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2460 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2461 return -1;
2462 }
2463 long timeoutAfterMs = Long.valueOf(getNextArg());
2464 boolean result;
2465 try {
2466 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2467 } catch (RemoteException e) {
2468 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2469 return -1;
2470 }
2471 if (VDBG) {
2472 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2473 }
2474 getOutPrintWriter().println(result);
2475 return 0;
2476 }
2477
Hui Wangbaaee6a2021-02-19 20:45:36 -08002478 private int handleSrcSetTestEnabledCommand() {
2479 String enabledStr = getNextArg();
2480 if (enabledStr == null) {
2481 return -1;
2482 }
2483
2484 try {
2485 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2486 if (VDBG) {
2487 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2488 }
2489 getOutPrintWriter().println("Done");
2490 } catch (NumberFormatException | RemoteException e) {
2491 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2492 getErrPrintWriter().println("Exception: " + e.getMessage());
2493 return -1;
2494 }
2495 return 0;
2496 }
2497
2498 private int handleSrcGetTestEnabledCommand() {
2499 boolean result = false;
2500 try {
2501 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2502 } catch (RemoteException e) {
2503 return -1;
2504 }
2505 if (VDBG) {
2506 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2507 }
2508 getOutPrintWriter().println(result);
2509 return 0;
2510 }
2511
Brad Ebinger14d467f2021-02-12 06:18:28 +00002512 private int handleUceOverridePublishCaps() {
2513 int subId = getSubId("uce override-published-caps");
2514 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2515 return -1;
2516 }
2517 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2518 String operation = getNextArgRequired();
2519 String caps = getNextArg();
2520 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2521 && !"list".equals(operation)) {
2522 getErrPrintWriter().println("Invalid operation: " + operation);
2523 return -1;
2524 }
2525
2526 // add/remove requires capabilities to be specified.
2527 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2528 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2529 + "specified");
2530 return -1;
2531 }
2532
2533 ArraySet<String> capSet = new ArraySet<>();
2534 if (!TextUtils.isEmpty(caps)) {
2535 String[] capArray = caps.split(":");
2536 for (String cap : capArray) {
2537 // Allow unknown tags to be passed in as well.
2538 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2539 }
2540 }
2541
2542 RcsContactUceCapability result = null;
2543 try {
2544 switch (operation) {
2545 case "add":
2546 result = mInterface.addUceRegistrationOverrideShell(subId,
2547 new ArrayList<>(capSet));
2548 break;
2549 case "remove":
2550 result = mInterface.removeUceRegistrationOverrideShell(subId,
2551 new ArrayList<>(capSet));
2552 break;
2553 case "clear":
2554 result = mInterface.clearUceRegistrationOverrideShell(subId);
2555 break;
2556 case "list":
2557 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2558 break;
2559 }
2560 } catch (RemoteException e) {
2561 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2562 getErrPrintWriter().println("Exception: " + e.getMessage());
2563 return -1;
2564 } catch (ServiceSpecificException sse) {
2565 // Reconstruct ImsException
2566 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2567 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2568 getErrPrintWriter().println("Exception: " + imsException);
2569 return -1;
2570 }
2571 if (result == null) {
2572 getErrPrintWriter().println("Service not available");
2573 return -1;
2574 }
2575 getOutPrintWriter().println(result);
2576 return 0;
2577 }
2578
2579 private int handleUceGetPidfXml() {
2580 int subId = getSubId("uce get-last-publish-pidf");
2581 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2582 return -1;
2583 }
2584
2585 String result;
2586 try {
2587 result = mInterface.getLastUcePidfXmlShell(subId);
2588 } catch (RemoteException e) {
2589 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2590 getErrPrintWriter().println("Exception: " + e.getMessage());
2591 return -1;
2592 } catch (ServiceSpecificException sse) {
2593 // Reconstruct ImsException
2594 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2595 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2596 getErrPrintWriter().println("Exception: " + imsException);
2597 return -1;
2598 }
2599 if (result == null) {
2600 getErrPrintWriter().println("Service not available");
2601 return -1;
2602 }
2603 getOutPrintWriter().println(result);
2604 return 0;
2605 }
2606
Hui Wang761a6682020-10-31 05:12:53 +00002607 private int handleSrcSetDeviceEnabledCommand() {
2608 String enabledStr = getNextArg();
2609 if (enabledStr == null) {
2610 return -1;
2611 }
2612
2613 try {
2614 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2615 if (VDBG) {
2616 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2617 }
2618 getOutPrintWriter().println("Done");
2619 } catch (NumberFormatException | RemoteException e) {
2620 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2621 getErrPrintWriter().println("Exception: " + e.getMessage());
2622 return -1;
2623 }
2624 return 0;
2625 }
2626
2627 private int handleSrcGetDeviceEnabledCommand() {
2628 boolean result = false;
2629 try {
2630 result = mInterface.getDeviceSingleRegistrationEnabled();
2631 } catch (RemoteException e) {
2632 return -1;
2633 }
2634 if (VDBG) {
2635 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2636 }
2637 getOutPrintWriter().println(result);
2638 return 0;
2639 }
2640
2641 private int handleSrcSetCarrierEnabledCommand() {
2642 //the release time value could be -1
2643 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2644 : SubscriptionManager.getDefaultSubscriptionId();
2645 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2646 return -1;
2647 }
2648
2649 String enabledStr = getNextArg();
2650 if (enabledStr == null) {
2651 return -1;
2652 }
2653
2654 try {
2655 boolean result =
2656 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2657 if (VDBG) {
2658 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2659 + enabledStr + ", result=" + result);
2660 }
2661 getOutPrintWriter().println(result);
2662 } catch (NumberFormatException | RemoteException e) {
2663 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2664 + enabledStr + ", error" + e.getMessage());
2665 getErrPrintWriter().println("Exception: " + e.getMessage());
2666 return -1;
2667 }
2668 return 0;
2669 }
2670
2671 private int handleSrcGetCarrierEnabledCommand() {
2672 int subId = getSubId("src get-carrier-enabled");
2673 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2674 return -1;
2675 }
2676
2677 boolean result = false;
2678 try {
2679 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2680 } catch (RemoteException e) {
2681 return -1;
2682 }
2683 if (VDBG) {
2684 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2685 }
2686 getOutPrintWriter().println(result);
2687 return 0;
2688 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002689
Hui Wangb647abe2021-02-26 09:33:38 -08002690 private int handleSrcSetFeatureValidationCommand() {
2691 //the release time value could be -1
2692 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2693 : SubscriptionManager.getDefaultSubscriptionId();
2694 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2695 return -1;
2696 }
2697
2698 String enabledStr = getNextArg();
2699 if (enabledStr == null) {
2700 return -1;
2701 }
2702
2703 try {
2704 boolean result =
2705 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2706 if (VDBG) {
2707 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2708 + enabledStr + ", result=" + result);
2709 }
2710 getOutPrintWriter().println(result);
2711 } catch (NumberFormatException | RemoteException e) {
2712 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2713 + enabledStr + ", error" + e.getMessage());
2714 getErrPrintWriter().println("Exception: " + e.getMessage());
2715 return -1;
2716 }
2717 return 0;
2718 }
2719
2720 private int handleSrcGetFeatureValidationCommand() {
2721 int subId = getSubId("src get-feature-validation");
2722 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2723 return -1;
2724 }
2725
2726 Boolean result = false;
2727 try {
2728 result = mInterface.getImsFeatureValidationOverride(subId);
2729 } catch (RemoteException e) {
2730 return -1;
2731 }
2732 if (VDBG) {
2733 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2734 }
2735 getOutPrintWriter().println(result);
2736 return 0;
2737 }
2738
2739
Hall Liuaa4211e2021-01-20 15:43:39 -08002740 private void onHelpCallComposer() {
2741 PrintWriter pw = getOutPrintWriter();
2742 pw.println("Call composer commands");
2743 pw.println(" callcomposer test-mode enable|disable|query");
2744 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2745 pw.println(" upload/download from carrier servers is disabled, and operations are");
2746 pw.println(" performed using emulated local files instead.");
2747 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2748 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2749 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002750 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2751 pw.println(" Enables or disables the user setting for call composer, as set by");
2752 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002753 }
2754
2755 private int handleCallComposerCommand() {
2756 String arg = getNextArg();
2757 if (arg == null) {
2758 onHelpCallComposer();
2759 return 0;
2760 }
2761
2762 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2763 "MODIFY_PHONE_STATE required for call composer shell cmds");
2764 switch (arg) {
2765 case CALL_COMPOSER_TEST_MODE: {
2766 String enabledStr = getNextArg();
2767 if (ENABLE.equals(enabledStr)) {
2768 CallComposerPictureManager.sTestMode = true;
2769 } else if (DISABLE.equals(enabledStr)) {
2770 CallComposerPictureManager.sTestMode = false;
2771 } else if (QUERY.equals(enabledStr)) {
2772 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2773 } else {
2774 onHelpCallComposer();
2775 return 1;
2776 }
2777 break;
2778 }
2779 case CALL_COMPOSER_SIMULATE_CALL: {
2780 int subscriptionId = Integer.valueOf(getNextArg());
2781 String uuidString = getNextArg();
2782 UUID uuid = UUID.fromString(uuidString);
2783 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2784 Binder.withCleanCallingIdentity(() -> {
2785 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2786 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2787 });
2788 try {
2789 Uri uri = storageUriFuture.get();
2790 getOutPrintWriter().println(String.valueOf(uri));
2791 } catch (Exception e) {
2792 throw new RuntimeException(e);
2793 }
2794 break;
2795 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002796 case CALL_COMPOSER_USER_SETTING: {
2797 try {
2798 int subscriptionId = Integer.valueOf(getNextArg());
2799 String enabledStr = getNextArg();
2800 if (ENABLE.equals(enabledStr)) {
2801 mInterface.setCallComposerStatus(subscriptionId,
2802 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2803 } else if (DISABLE.equals(enabledStr)) {
2804 mInterface.setCallComposerStatus(subscriptionId,
2805 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2806 } else if (QUERY.equals(enabledStr)) {
2807 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2808 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2809 } else {
2810 onHelpCallComposer();
2811 return 1;
2812 }
2813 } catch (RemoteException e) {
2814 e.printStackTrace(getOutPrintWriter());
2815 return 1;
2816 }
2817 break;
2818 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002819 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002820 return 0;
2821 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002822
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002823 private int handleHasCarrierPrivilegesCommand() {
2824 String packageName = getNextArgRequired();
2825
2826 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002827 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002828 try {
2829 hasCarrierPrivileges =
2830 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2831 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2832 } catch (RemoteException e) {
2833 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2834 getErrPrintWriter().println("Exception: " + e.getMessage());
2835 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002836 } finally {
2837 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002838 }
2839
2840 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002841 return 0;
2842 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002843
2844 private int handleAllowedNetworkTypesCommand(String command) {
2845 if (!checkShellUid()) {
2846 return -1;
2847 }
2848
2849 PrintWriter errPw = getErrPrintWriter();
2850 String tag = command + ": ";
2851 String opt;
2852 int subId = -1;
2853 Log.v(LOG_TAG, command + " start");
2854
2855 while ((opt = getNextOption()) != null) {
2856 if (opt.equals("-s")) {
2857 try {
2858 subId = slotStringToSubId(tag, getNextArgRequired());
2859 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2860 errPw.println(tag + "No valid subscription found.");
2861 return -1;
2862 }
2863 } catch (IllegalArgumentException e) {
2864 // Missing slot id
2865 errPw.println(tag + "SLOT_ID expected after -s.");
2866 return -1;
2867 }
2868 } else {
2869 errPw.println(tag + "Unknown option " + opt);
2870 return -1;
2871 }
2872 }
2873
2874 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2875 return handleGetAllowedNetworkTypesCommand(subId);
2876 }
2877 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2878 return handleSetAllowedNetworkTypesCommand(subId);
2879 }
2880 return -1;
2881 }
2882
2883 private int handleGetAllowedNetworkTypesCommand(int subId) {
2884 PrintWriter errPw = getErrPrintWriter();
2885
2886 long result = -1;
2887 try {
2888 if (mInterface != null) {
2889 result = mInterface.getAllowedNetworkTypesForReason(subId,
2890 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2891 } else {
2892 throw new IllegalStateException("telephony service is null.");
2893 }
2894 } catch (RemoteException e) {
2895 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2896 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2897 return -1;
2898 }
2899
2900 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2901 return 0;
2902 }
2903
2904 private int handleSetAllowedNetworkTypesCommand(int subId) {
2905 PrintWriter errPw = getErrPrintWriter();
2906
2907 String bitmaskString = getNextArg();
2908 if (TextUtils.isEmpty(bitmaskString)) {
2909 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2910 return -1;
2911 }
2912 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2913 if (allowedNetworkTypes < 0) {
2914 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2915 return -1;
2916 }
2917 boolean result = false;
2918 try {
2919 if (mInterface != null) {
2920 result = mInterface.setAllowedNetworkTypesForReason(subId,
2921 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2922 } else {
2923 throw new IllegalStateException("telephony service is null.");
2924 }
2925 } catch (RemoteException e) {
2926 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2927 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2928 return -1;
2929 }
2930
2931 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2932 if (result) {
2933 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2934 }
2935 getOutPrintWriter().println(resultMessage);
2936 return 0;
2937 }
2938
2939 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2940 if (TextUtils.isEmpty(bitmaskString)) {
2941 return -1;
2942 }
2943 if (VDBG) {
2944 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2945 + ", length: " + bitmaskString.length());
2946 }
2947 try {
2948 return Long.parseLong(bitmaskString, 2);
2949 } catch (NumberFormatException e) {
2950 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2951 return -1;
2952 }
2953 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002954
Jack Yuf745f972022-08-15 19:53:50 +00002955 private int handleGetDataMode() {
2956 if (!checkShellUid()) {
2957 return -1;
2958 }
2959
2960 boolean newDataStackEnabled = false;
2961 try {
2962 newDataStackEnabled = mInterface.isUsingNewDataStack();
2963 } catch (RemoteException e) {
2964 getOutPrintWriter().println("Something went wrong. " + e);
2965 return -1;
2966 }
2967
2968 getOutPrintWriter().println("Telephony is running with the "
2969 + (newDataStackEnabled ? "new" : "old") + " data stack.");
2970 return 0;
2971 }
2972
jimsun3b9ccac2021-10-26 15:01:23 +08002973 private int handleRadioSetModemServiceCommand() {
2974 PrintWriter errPw = getErrPrintWriter();
2975 String serviceName = null;
2976
2977 String opt;
2978 while ((opt = getNextOption()) != null) {
2979 switch (opt) {
2980 case "-s": {
2981 serviceName = getNextArgRequired();
2982 break;
2983 }
2984 }
2985 }
2986
2987 try {
2988 boolean result = mInterface.setModemService(serviceName);
2989 if (VDBG) {
2990 Log.v(LOG_TAG,
2991 "RadioSetModemService " + serviceName + ", result = " + result);
2992 }
2993 getOutPrintWriter().println(result);
2994 } catch (RemoteException e) {
2995 Log.w(LOG_TAG,
2996 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2997 errPw.println("Exception: " + e.getMessage());
2998 return -1;
2999 }
3000 return 0;
3001 }
3002
3003 private int handleRadioGetModemServiceCommand() {
3004 PrintWriter errPw = getErrPrintWriter();
3005 String result;
3006
3007 try {
3008 result = mInterface.getModemService();
3009 getOutPrintWriter().println(result);
3010 } catch (RemoteException e) {
3011 errPw.println("Exception: " + e.getMessage());
3012 return -1;
3013 }
3014 if (VDBG) {
3015 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
3016 }
3017 return 0;
3018 }
3019
3020 private int handleRadioCommand() {
3021 String arg = getNextArg();
3022 if (arg == null) {
3023 onHelpRadio();
3024 return 0;
3025 }
3026
3027 switch (arg) {
3028 case RADIO_SET_MODEM_SERVICE:
3029 return handleRadioSetModemServiceCommand();
3030
3031 case RADIO_GET_MODEM_SERVICE:
3032 return handleRadioGetModemServiceCommand();
3033 }
3034
3035 return -1;
3036 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003037}