blob: ceaca252b2336fd6985c1798a4f95011e4e6a66f [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;
Jack Yu4c0a5502021-12-03 23:58:26 -080033import android.provider.DeviceConfig;
Nazanin014f41e2021-05-06 17:26:31 -070034import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010035import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070036import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070037import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000038import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070039import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080040import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000041import android.telephony.ims.ImsException;
42import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080043import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080044import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000045import android.util.ArrayMap;
46import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070047import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070048import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070049
Brad Ebinger14d467f2021-02-12 06:18:28 +000050import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070051import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080052import com.android.internal.telephony.Phone;
53import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080054import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080055import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080056import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080057import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080058import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070059
Allen Xuee00f0e2022-03-14 21:04:49 +000060import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070061import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080062import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000063import java.util.Arrays;
64import java.util.Collections;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010065import java.util.HashMap;
Brad Ebinger24c29992019-12-05 13:03:21 -080066import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010067import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000068import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010069import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080070import java.util.UUID;
71import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070072
73/**
74 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
75 * permission checks have been done before onCommand was called. Make sure any commands processed
76 * here also contain the appropriate permissions checks.
77 */
78
Hall Liua1548bd2019-12-24 14:14:12 -080079public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81 private static final String LOG_TAG = "TelephonyShellCommand";
82 // Don't commit with this true.
83 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070084 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070085
Hall Liuaa4211e2021-01-20 15:43:39 -080086 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080088 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080089 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080090 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070091 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000092 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000093 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010094 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080095 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080096 private static final String ENABLE = "enable";
97 private static final String DISABLE = "disable";
98 private static final String QUERY = "query";
99
Hall Liu7135e502021-02-04 16:58:17 -0800100 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800101 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800102 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800103
Brad Ebinger999d3302020-11-25 14:31:39 -0800104 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
105 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
106 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700107 // Used to disable or enable processing of conference event package data from the network.
108 // This is handy for testing scenarios where CEP data does not exist on a network which does
109 // support CEP data.
110 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700111
Hall Liud892bec2018-11-30 14:51:45 -0800112 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800113 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800114
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100115 private static final String CC_GET_VALUE = "get-value";
116 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000117 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100118 private static final String CC_CLEAR_VALUES = "clear-values";
119
Hui Wang641e81c2020-10-12 12:14:23 -0700120 private static final String GBA_SUBCOMMAND = "gba";
121 private static final String GBA_SET_SERVICE = "set-service";
122 private static final String GBA_GET_SERVICE = "get-service";
123 private static final String GBA_SET_RELEASE_TIME = "set-release";
124 private static final String GBA_GET_RELEASE_TIME = "get-release";
125
Hui Wang761a6682020-10-31 05:12:53 +0000126 private static final String SINGLE_REGISTATION_CONFIG = "src";
127 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
128 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
129 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
130 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800131 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
132 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800133 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
134 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000135
Tyler Gunn92479152021-01-20 16:30:10 -0800136 private static final String D2D_SUBCOMMAND = "d2d";
137 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800138 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700139 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800140
Nazanin014f41e2021-05-06 17:26:31 -0700141 private static final String BARRING_SUBCOMMAND = "barring";
142 private static final String BARRING_SEND_INFO = "send";
143
James.cf Linbcdf8b32021-01-14 16:44:13 +0800144 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800145 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800146 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800147 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800148 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
149 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000150 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
151 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800152 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
153 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800154 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
155 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800156
jimsun3b9ccac2021-10-26 15:01:23 +0800157 private static final String RADIO_SUBCOMMAND = "radio";
158 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
159 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
160
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800161 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
162 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
163
Jordan Liu0ccee222021-04-27 11:55:13 -0700164 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
165 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
166
Jack Nudelman644b91a2021-03-12 14:09:48 -0800167 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
168 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
169 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
170
SongFerngWang98dd5992021-05-13 17:50:00 +0800171 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
172 "get-allowed-network-types-for-users";
173 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
174 "set-allowed-network-types-for-users";
Jack Yu4c0a5502021-12-03 23:58:26 -0800175 // Check if telephony new data stack is enabled.
176 private static final String GET_DATA_MODE = "get-data-mode";
Ling Ma4fbab492022-01-25 22:36:16 +0000177 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000178 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700179 // Take advantage of existing methods that already contain permissions checks when possible.
180 private final ITelephony mInterface;
181
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100182 private SubscriptionManager mSubscriptionManager;
183 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700184 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700185 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100186
187 private enum CcType {
188 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000189 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100190 }
191
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100192 private class CcOptionParseResult {
193 public int mSubId;
194 public boolean mPersistent;
195 }
196
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100197 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
198 // keys by looking at the end of the string which usually tells the type.
199 // For instance: "xxxx_string", "xxxx_string_array", etc.
200 // The carrier config keys in this map does not follow this convention. It is therefore not
201 // possible to infer the type for these keys by looking at the string.
202 private static final Map<String, CcType> CC_TYPE_MAP = new HashMap<String, CcType>() {{
203 put(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING, CcType.STRING);
204 put(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING);
205 put(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING);
206 put(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING);
207 put(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING);
208 put(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING);
209 put(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING);
210 put(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING);
211 put(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING);
212 put(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING);
213 put(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
214 CcType.STRING);
215 put(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
216 CcType.STRING_ARRAY);
217 put(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
218 CcType.STRING_ARRAY);
219 put(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING);
220 put(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING);
221 put(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING);
222 put(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING);
223 put(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING);
224 put(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING);
225 put(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING);
226 put(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY);
227 }
228 };
229
Brad Ebinger14d467f2021-02-12 06:18:28 +0000230 /**
231 * Map from a shorthand string to the feature tags required in registration required in order
232 * for the RCS feature to be considered "capable".
233 */
234 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
235 static {
236 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
237 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
238 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
239 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
240 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
241 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
242 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
243 FeatureTags.FEATURE_TAG_VIDEO)));
244 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
245 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
246 map.put("call_comp",
247 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
248 map.put("call_comp_mmtel",
249 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
250 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
251 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
252 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
253 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
254 // version
255 map.put("chatbot", new ArraySet<>(Arrays.asList(
256 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
257 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
258 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
259 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000260 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000261 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
262 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
263 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
264 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
265 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000266 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000267 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
268 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
269 }
270
271
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100272 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700273 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100274 mCarrierConfigManager =
275 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
276 mSubscriptionManager = (SubscriptionManager)
277 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700278 mTelephonyRegistryManager = (TelephonyRegistryManager)
279 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700280 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700281 }
282
283 @Override
284 public int onCommand(String cmd) {
285 if (cmd == null) {
286 return handleDefaultCommands(null);
287 }
288
289 switch (cmd) {
290 case IMS_SUBCOMMAND: {
291 return handleImsCommand();
292 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800293 case RCS_UCE_COMMAND:
294 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800295 case NUMBER_VERIFICATION_SUBCOMMAND:
296 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800297 case EMERGENCY_CALLBACK_MODE:
298 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800299 case EMERGENCY_NUMBER_TEST_MODE:
300 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100301 case CARRIER_CONFIG_SUBCOMMAND: {
302 return handleCcCommand();
303 }
Shuo Qianf5125122019-12-16 17:03:07 -0800304 case DATA_TEST_MODE:
305 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700306 case END_BLOCK_SUPPRESSION:
307 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700308 case GBA_SUBCOMMAND:
309 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800310 case D2D_SUBCOMMAND:
311 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700312 case BARRING_SUBCOMMAND:
313 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000314 case SINGLE_REGISTATION_CONFIG:
315 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000316 case RESTART_MODEM:
317 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800318 case CALL_COMPOSER_SUBCOMMAND:
319 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000320 case UNATTENDED_REBOOT:
321 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800322 case HAS_CARRIER_PRIVILEGES_COMMAND:
323 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800324 case THERMAL_MITIGATION_COMMAND:
325 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700326 case DISABLE_PHYSICAL_SUBSCRIPTION:
327 return handleEnablePhysicalSubscription(false);
328 case ENABLE_PHYSICAL_SUBSCRIPTION:
329 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800330 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
331 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
332 return handleAllowedNetworkTypesCommand(cmd);
Jack Yu4c0a5502021-12-03 23:58:26 -0800333 case GET_DATA_MODE:
334 return handleGetDataMode();
Ling Ma4fbab492022-01-25 22:36:16 +0000335 case GET_IMEI:
336 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000337 case GET_SIM_SLOTS_MAPPING:
338 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800339 case RADIO_SUBCOMMAND:
340 return handleRadioCommand();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700341 default: {
342 return handleDefaultCommands(cmd);
343 }
344 }
345 }
346
347 @Override
348 public void onHelp() {
349 PrintWriter pw = getOutPrintWriter();
350 pw.println("Telephony Commands:");
351 pw.println(" help");
352 pw.println(" Print this help text.");
353 pw.println(" ims");
354 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800355 pw.println(" uce");
356 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800357 pw.println(" emergency-number-test-mode");
358 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700359 pw.println(" end-block-suppression");
360 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800361 pw.println(" data");
362 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100363 pw.println(" cc");
364 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700365 pw.println(" gba");
366 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000367 pw.println(" src");
368 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000369 pw.println(" restart-modem");
370 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000371 pw.println(" unattended-reboot");
372 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800373 pw.println(" has-carrier-privileges [package]");
374 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800375 pw.println(" get-allowed-network-types-for-users");
376 pw.println(" Get the Allowed Network Types.");
377 pw.println(" set-allowed-network-types-for-users");
378 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800379 pw.println(" radio");
380 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700381 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800382 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800383 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700384 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800385 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100386 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700387 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000388 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800389 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700390 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800391 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800392 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000393 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800394 }
395
396 private void onHelpD2D() {
397 PrintWriter pw = getOutPrintWriter();
398 pw.println("D2D Comms Commands:");
399 pw.println(" d2d send TYPE VALUE");
400 pw.println(" Sends a D2D message of specified type and value.");
401 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
402 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
403 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
404 MESSAGE_CALL_AUDIO_CODEC));
405 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
406 + Communicator.messageToString(
407 MESSAGE_DEVICE_BATTERY_STATE));
408 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
409 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800410 pw.println(" d2d transport TYPE");
411 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
412 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700413 pw.println(" d2d set-device-support true/default");
414 pw.println(" true - forces device support to be enabled for D2D.");
415 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
416 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700417 }
418
Nazanin014f41e2021-05-06 17:26:31 -0700419 private void onHelpBarring() {
420 PrintWriter pw = getOutPrintWriter();
421 pw.println("Barring Commands:");
422 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
423 + " -t CONDITIONAL_BARRING_TIME_SECS");
424 pw.println(" Notifies of a barring info change for the specified slot id.");
425 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
426 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
427 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
428 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
429 }
430
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700431 private void onHelpIms() {
432 PrintWriter pw = getOutPrintWriter();
433 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800434 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700435 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
436 pw.println(" ImsService. Options are:");
437 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
438 pw.println(" is specified, it will choose the default voice SIM slot.");
439 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
440 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800441 pw.println(" -f: Set the feature that this override if for, if no option is");
442 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700443 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
444 pw.println(" Gets the package name of the currently defined ImsService.");
445 pw.println(" Options are:");
446 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
447 pw.println(" is specified, it will choose the default voice SIM slot.");
448 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000449 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800450 pw.println(" -f: The feature type that the query will be requested for. If none is");
451 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800452 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
453 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
454 pw.println(" configuration overrides. Options are:");
455 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
456 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700457 pw.println(" ims enable [-s SLOT_ID]");
458 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
459 pw.println(" if none is specified.");
460 pw.println(" ims disable [-s SLOT_ID]");
461 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
462 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700463 pw.println(" ims conference-event-package [enable/disable]");
464 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700465 }
466
James.cf Linbcdf8b32021-01-14 16:44:13 +0800467 private void onHelpUce() {
468 PrintWriter pw = getOutPrintWriter();
469 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800470 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
471 pw.println(" Get the EAB contacts from the EAB database.");
472 pw.println(" Options are:");
473 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
474 pw.println(" Expected output format :");
475 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800476 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
477 pw.println(" Remove the EAB contacts from the EAB database.");
478 pw.println(" Options are:");
479 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
480 pw.println(" is specified, it will choose the default voice SIM slot.");
481 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800482 pw.println(" uce get-device-enabled");
483 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
484 pw.println(" uce set-device-enabled true|false");
485 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
486 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000487 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
488 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
489 pw.println(" Options are:");
490 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
491 pw.println(" is specified, it will choose the default voice SIM slot.");
492 pw.println(" add [CAPABILITY]: add a new capability");
493 pw.println(" remove [CAPABILITY]: remove a capability");
494 pw.println(" clear: clear all capability overrides");
495 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
496 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
497 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
498 pw.println(" chatbot_sa, chatbot_role] as well as full length");
499 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
500 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
501 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
502 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800503 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
504 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800505 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
506 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800507 }
508
Hall Liud892bec2018-11-30 14:51:45 -0800509 private void onHelpNumberVerification() {
510 PrintWriter pw = getOutPrintWriter();
511 pw.println("Number verification commands");
512 pw.println(" numverify override-package PACKAGE_NAME;");
513 pw.println(" Set the authorized package for number verification.");
514 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800515 pw.println(" numverify fake-call NUMBER;");
516 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
517 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800518 }
519
Jack Nudelman644b91a2021-03-12 14:09:48 -0800520 private void onHelpThermalMitigation() {
521 PrintWriter pw = getOutPrintWriter();
522 pw.println("Thermal mitigation commands");
523 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
524 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
525 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
526 pw.println(" Remove the package from one of the authorized packages for thermal "
527 + "mitigation.");
528 }
529
Jordan Liu0ccee222021-04-27 11:55:13 -0700530 private void onHelpDisableOrEnablePhysicalSubscription() {
531 PrintWriter pw = getOutPrintWriter();
532 pw.println("Disable or enable a physical subscription");
533 pw.println(" disable-physical-subscription SUB_ID");
534 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
535 pw.println(" enable-physical-subscription SUB_ID");
536 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
537 }
538
Shuo Qianf5125122019-12-16 17:03:07 -0800539 private void onHelpDataTestMode() {
540 PrintWriter pw = getOutPrintWriter();
541 pw.println("Mobile Data Test Mode Commands:");
542 pw.println(" data enable: enable mobile data connectivity");
543 pw.println(" data disable: disable mobile data connectivity");
544 }
545
sqian9d4df8b2019-01-15 18:32:07 -0800546 private void onHelpEmergencyNumber() {
547 PrintWriter pw = getOutPrintWriter();
548 pw.println("Emergency Number Test Mode Commands:");
549 pw.println(" emergency-number-test-mode ");
550 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
551 + " the test mode");
552 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700553 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800554 pw.println(" -c: clear the emergency number list in the test mode.");
555 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700556 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800557 pw.println(" -p: get the full emergency number list in the test mode.");
558 }
559
Shuo Qian489d9282020-07-09 11:30:03 -0700560 private void onHelpEndBlockSupperssion() {
561 PrintWriter pw = getOutPrintWriter();
562 pw.println("End Block Suppression command:");
563 pw.println(" end-block-suppression: disable suppressing blocking by contact");
564 pw.println(" with emergency services.");
565 }
566
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100567 private void onHelpCc() {
568 PrintWriter pw = getOutPrintWriter();
569 pw.println("Carrier Config Commands:");
570 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
571 pw.println(" Print carrier config values.");
572 pw.println(" Options are:");
573 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
574 pw.println(" is specified, it will choose the default voice SIM slot.");
575 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
576 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100577 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100578 pw.println(" Set carrier config KEY to NEW_VALUE.");
579 pw.println(" Options are:");
580 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
581 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100582 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100583 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
584 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
585 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
586 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000587 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
588 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
589 pw.println(" provided through standard input and follow CarrierConfig XML format.");
590 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
591 pw.println(" Options are:");
592 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
593 pw.println(" is specified, it will choose the default voice SIM slot.");
594 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100595 pw.println(" cc clear-values [-s SLOT_ID]");
596 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000597 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100598 pw.println(" Options are:");
599 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
600 pw.println(" is specified, it will choose the default voice SIM slot.");
601 }
602
Hui Wang641e81c2020-10-12 12:14:23 -0700603 private void onHelpGba() {
604 PrintWriter pw = getOutPrintWriter();
605 pw.println("Gba Commands:");
606 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
607 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
608 pw.println(" Options are:");
609 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
610 pw.println(" is specified, it will choose the default voice SIM slot.");
611 pw.println(" gba get-service [-s SLOT_ID]");
612 pw.println(" Gets the package name of the currently defined GbaService.");
613 pw.println(" Options are:");
614 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
615 pw.println(" is specified, it will choose the default voice SIM slot.");
616 pw.println(" gba set-release [-s SLOT_ID] n");
617 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
618 pw.println(" Do not release/unbind if n is -1.");
619 pw.println(" Options are:");
620 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
621 pw.println(" is specified, it will choose the default voice SIM slot.");
622 pw.println(" gba get-release [-s SLOT_ID]");
623 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
624 pw.println(" Options are:");
625 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
626 pw.println(" is specified, it will choose the default voice SIM slot.");
627 }
628
Hui Wang761a6682020-10-31 05:12:53 +0000629 private void onHelpSrc() {
630 PrintWriter pw = getOutPrintWriter();
631 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800632 pw.println(" src set-test-enabled true|false");
633 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
634 pw.println(" The value could be true, false, or null(undefined).");
635 pw.println(" src get-test-enabled");
636 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000637 pw.println(" src set-device-enabled true|false|null");
638 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
639 pw.println(" The value could be true, false, or null(undefined).");
640 pw.println(" src get-device-enabled");
641 pw.println(" Gets the device config for RCS VoLTE single registration.");
642 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
643 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
644 pw.println(" The value could be true, false, or null(undefined).");
645 pw.println(" Options are:");
646 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
647 pw.println(" is specified, it will choose the default voice SIM slot.");
648 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
649 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
650 pw.println(" Options are:");
651 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
652 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800653 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
654 pw.println(" Sets ims feature validation result.");
655 pw.println(" The value could be true, false, or null(undefined).");
656 pw.println(" Options are:");
657 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
658 pw.println(" is specified, it will choose the default voice SIM slot.");
659 pw.println(" src get-feature-validation [-s SLOT_ID]");
660 pw.println(" Gets ims feature validation override value.");
661 pw.println(" Options are:");
662 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
663 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000664 }
665
SongFerngWang98dd5992021-05-13 17:50:00 +0800666 private void onHelpAllowedNetworkTypes() {
667 PrintWriter pw = getOutPrintWriter();
668 pw.println("Allowed Network Types Commands:");
669 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
670 pw.println(" Print allowed network types value.");
671 pw.println(" Options are:");
672 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
673 pw.println(" option is specified, it will choose the default voice SIM slot.");
674 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
675 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
676 pw.println(" Options are:");
677 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
678 pw.println(" option is specified, it will choose the default voice SIM slot.");
679 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
680 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
681 pw.println(" at TelephonyManager.java");
682 pw.println(" For example:");
683 pw.println(" NR only : 10000000000000000000");
684 pw.println(" NR|LTE : 11000001000000000000");
685 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
686 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
687 pw.println(" LTE only : 01000001000000000000");
688 }
689
jimsun3b9ccac2021-10-26 15:01:23 +0800690 private void onHelpRadio() {
691 PrintWriter pw = getOutPrintWriter();
692 pw.println("Radio Commands:");
693 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
694 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
695 pw.println(" to be the bound. Options are:");
696 pw.println(" -s: the service name that the modem service should be bound for.");
697 pw.println(" If no option is specified, it will bind to the default.");
698 pw.println(" radio get-modem-service");
699 pw.println(" Gets the service name of the currently defined modem service.");
700 pw.println(" If it is binding to default, 'default' returns.");
701 pw.println(" If it doesn't bind to any modem service for some reasons,");
702 pw.println(" the result would be 'unknown'.");
703 }
704
Ling Ma4fbab492022-01-25 22:36:16 +0000705 private void onHelpImei() {
706 PrintWriter pw = getOutPrintWriter();
707 pw.println("IMEI Commands:");
708 pw.println(" get-imei [-s SLOT_ID]");
709 pw.println(" Gets the device IMEI. Options are:");
710 pw.println(" -s: the slot ID to get the IMEI. If no option");
711 pw.println(" is specified, it will choose the default voice SIM slot.");
712 }
713
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700714 private int handleImsCommand() {
715 String arg = getNextArg();
716 if (arg == null) {
717 onHelpIms();
718 return 0;
719 }
720
721 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800722 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700723 return handleImsSetServiceCommand();
724 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800725 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700726 return handleImsGetServiceCommand();
727 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800728 case IMS_CLEAR_SERVICE_OVERRIDE: {
729 return handleImsClearCarrierServiceCommand();
730 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800731 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700732 return handleEnableIms();
733 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800734 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700735 return handleDisableIms();
736 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700737 case IMS_CEP: {
738 return handleCepChange();
739 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700740 }
741
742 return -1;
743 }
744
Shuo Qianf5125122019-12-16 17:03:07 -0800745 private int handleDataTestModeCommand() {
746 PrintWriter errPw = getErrPrintWriter();
747 String arg = getNextArgRequired();
748 if (arg == null) {
749 onHelpDataTestMode();
750 return 0;
751 }
752 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800753 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800754 try {
755 mInterface.enableDataConnectivity();
756 } catch (RemoteException ex) {
757 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
758 errPw.println("Exception: " + ex.getMessage());
759 return -1;
760 }
761 break;
762 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800763 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800764 try {
765 mInterface.disableDataConnectivity();
766 } catch (RemoteException ex) {
767 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
768 errPw.println("Exception: " + ex.getMessage());
769 return -1;
770 }
771 break;
772 }
773 default:
774 onHelpDataTestMode();
775 break;
776 }
777 return 0;
778 }
779
Shuo Qianccbaf742021-02-22 18:32:21 -0800780 private int handleEmergencyCallbackModeCommand() {
781 PrintWriter errPw = getErrPrintWriter();
782 try {
783 mInterface.startEmergencyCallbackMode();
784 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
785 } catch (RemoteException ex) {
786 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
787 errPw.println("Exception: " + ex.getMessage());
788 return -1;
789 }
790 return 0;
791 }
792
sqian9d4df8b2019-01-15 18:32:07 -0800793 private int handleEmergencyNumberTestModeCommand() {
794 PrintWriter errPw = getErrPrintWriter();
795 String opt = getNextOption();
796 if (opt == null) {
797 onHelpEmergencyNumber();
798 return 0;
799 }
800
801 switch (opt) {
802 case "-a": {
803 String emergencyNumberCmd = getNextArgRequired();
804 if (emergencyNumberCmd == null
805 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700806 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800807 + " to be specified after -a in the command ");
808 return -1;
809 }
810 try {
811 mInterface.updateEmergencyNumberListTestMode(
812 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
813 new EmergencyNumber(emergencyNumberCmd, "", "",
814 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
815 new ArrayList<String>(),
816 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
817 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
818 } catch (RemoteException ex) {
819 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
820 + ", error " + ex.getMessage());
821 errPw.println("Exception: " + ex.getMessage());
822 return -1;
823 }
824 break;
825 }
826 case "-c": {
827 try {
828 mInterface.updateEmergencyNumberListTestMode(
829 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
830 } catch (RemoteException ex) {
831 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
832 errPw.println("Exception: " + ex.getMessage());
833 return -1;
834 }
835 break;
836 }
837 case "-r": {
838 String emergencyNumberCmd = getNextArgRequired();
839 if (emergencyNumberCmd == null
840 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700841 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800842 + " to be specified after -r in the command ");
843 return -1;
844 }
845 try {
846 mInterface.updateEmergencyNumberListTestMode(
847 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
848 new EmergencyNumber(emergencyNumberCmd, "", "",
849 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
850 new ArrayList<String>(),
851 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
852 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
853 } catch (RemoteException ex) {
854 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
855 + ", error " + ex.getMessage());
856 errPw.println("Exception: " + ex.getMessage());
857 return -1;
858 }
859 break;
860 }
861 case "-p": {
862 try {
863 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
864 } catch (RemoteException ex) {
865 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
866 errPw.println("Exception: " + ex.getMessage());
867 return -1;
868 }
869 break;
870 }
871 default:
872 onHelpEmergencyNumber();
873 break;
874 }
875 return 0;
876 }
877
Hall Liud892bec2018-11-30 14:51:45 -0800878 private int handleNumberVerificationCommand() {
879 String arg = getNextArg();
880 if (arg == null) {
881 onHelpNumberVerification();
882 return 0;
883 }
884
Hall Liuca5af3a2018-12-04 16:58:23 -0800885 if (!checkShellUid()) {
886 return -1;
887 }
888
Hall Liud892bec2018-11-30 14:51:45 -0800889 switch (arg) {
890 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800891 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
892 return 0;
893 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800894 case NUMBER_VERIFICATION_FAKE_CALL: {
895 boolean val = NumberVerificationManager.getInstance()
896 .checkIncomingCall(getNextArg());
897 getOutPrintWriter().println(val ? "1" : "0");
898 return 0;
899 }
Hall Liud892bec2018-11-30 14:51:45 -0800900 }
901
902 return -1;
903 }
904
Jordan Liu0ccee222021-04-27 11:55:13 -0700905 private boolean subIsEsim(int subId) {
906 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
907 if (info != null) {
908 return info.isEmbedded();
909 }
910 return false;
911 }
912
913 private int handleEnablePhysicalSubscription(boolean enable) {
914 PrintWriter errPw = getErrPrintWriter();
915 int subId = 0;
916 try {
917 subId = Integer.parseInt(getNextArgRequired());
918 } catch (NumberFormatException e) {
919 errPw.println((enable ? "enable" : "disable")
920 + "-physical-subscription requires an integer as a subId.");
921 return -1;
922 }
923 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
924 // non user build.
925 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
926 errPw.println("cc: Permission denied.");
927 return -1;
928 }
929 // Verify that the subId represents a physical sub
930 if (subIsEsim(subId)) {
931 errPw.println("SubId " + subId + " is not for a physical subscription");
932 return -1;
933 }
934 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
935 + " physical subscription with subId=" + subId);
936 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
937 return 0;
938 }
939
Jack Nudelman644b91a2021-03-12 14:09:48 -0800940 private int handleThermalMitigationCommand() {
941 String arg = getNextArg();
942 String packageName = getNextArg();
943 if (arg == null || packageName == null) {
944 onHelpThermalMitigation();
945 return 0;
946 }
947
948 if (!checkShellUid()) {
949 return -1;
950 }
951
952 switch (arg) {
953 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
954 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
955 return 0;
956 }
957 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
958 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
959 mContext);
960 return 0;
961 }
962 default:
963 onHelpThermalMitigation();
964 }
965
966 return -1;
967
968 }
969
Tyler Gunn92479152021-01-20 16:30:10 -0800970 private int handleD2dCommand() {
971 String arg = getNextArg();
972 if (arg == null) {
973 onHelpD2D();
974 return 0;
975 }
976
977 switch (arg) {
978 case D2D_SEND: {
979 return handleD2dSendCommand();
980 }
Tyler Gunnbabbda02021-02-10 11:05:02 -0800981 case D2D_TRANSPORT: {
982 return handleD2dTransportCommand();
983 }
Tyler Gunnd4575212021-05-03 14:46:49 -0700984 case D2D_SET_DEVICE_SUPPORT: {
985 return handleD2dDeviceSupportedCommand();
986 }
Tyler Gunn92479152021-01-20 16:30:10 -0800987 }
988
989 return -1;
990 }
991
992 private int handleD2dSendCommand() {
993 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -0800994 int messageType = -1;
995 int messageValue = -1;
996
Tyler Gunn92479152021-01-20 16:30:10 -0800997 String arg = getNextArg();
998 if (arg == null) {
999 onHelpD2D();
1000 return 0;
1001 }
1002 try {
1003 messageType = Integer.parseInt(arg);
1004 } catch (NumberFormatException e) {
1005 errPw.println("message type must be a valid integer");
1006 return -1;
1007 }
1008
1009 arg = getNextArg();
1010 if (arg == null) {
1011 onHelpD2D();
1012 return 0;
1013 }
1014 try {
1015 messageValue = Integer.parseInt(arg);
1016 } catch (NumberFormatException e) {
1017 errPw.println("message value must be a valid integer");
1018 return -1;
1019 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001020
Tyler Gunn92479152021-01-20 16:30:10 -08001021 try {
1022 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1023 } catch (RemoteException e) {
1024 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1025 errPw.println("Exception: " + e.getMessage());
1026 return -1;
1027 }
1028
1029 return 0;
1030 }
1031
Tyler Gunnbabbda02021-02-10 11:05:02 -08001032 private int handleD2dTransportCommand() {
1033 PrintWriter errPw = getErrPrintWriter();
1034
1035 String arg = getNextArg();
1036 if (arg == null) {
1037 onHelpD2D();
1038 return 0;
1039 }
1040
1041 try {
1042 mInterface.setActiveDeviceToDeviceTransport(arg);
1043 } catch (RemoteException e) {
1044 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1045 errPw.println("Exception: " + e.getMessage());
1046 return -1;
1047 }
1048 return 0;
1049 }
Nazanin014f41e2021-05-06 17:26:31 -07001050 private int handleBarringCommand() {
1051 String arg = getNextArg();
1052 if (arg == null) {
1053 onHelpBarring();
1054 return 0;
1055 }
1056
1057 switch (arg) {
1058 case BARRING_SEND_INFO: {
1059 return handleBarringSendCommand();
1060 }
1061 }
1062 return -1;
1063 }
1064
1065 private int handleBarringSendCommand() {
1066 PrintWriter errPw = getErrPrintWriter();
1067 int slotId = getDefaultSlot();
1068 int subId = SubscriptionManager.getSubId(slotId)[0];
1069 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1070 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1071 boolean isConditionallyBarred = false;
1072 int conditionalBarringTimeSeconds = 0;
1073
1074 String opt;
1075 while ((opt = getNextOption()) != null) {
1076 switch (opt) {
1077 case "-s": {
1078 try {
1079 slotId = Integer.parseInt(getNextArgRequired());
1080 subId = SubscriptionManager.getSubId(slotId)[0];
1081 } catch (NumberFormatException e) {
1082 errPw.println("barring send requires an integer as a SLOT_ID.");
1083 return -1;
1084 }
1085 break;
1086 }
1087 case "-b": {
1088 try {
1089 barringType = Integer.parseInt(getNextArgRequired());
1090 if (barringType < -1 || barringType > 2) {
1091 throw new NumberFormatException();
1092 }
1093
1094 } catch (NumberFormatException e) {
1095 errPw.println("barring send requires an integer in range [-1,2] as "
1096 + "a BARRING_TYPE.");
1097 return -1;
1098 }
1099 break;
1100 }
1101 case "-c": {
1102 try {
1103 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1104 } catch (Exception e) {
1105 errPw.println("barring send requires a boolean after -c indicating"
1106 + " conditional barring");
1107 return -1;
1108 }
1109 break;
1110 }
1111 case "-t": {
1112 try {
1113 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1114 } catch (NumberFormatException e) {
1115 errPw.println("barring send requires an integer for time of barring"
1116 + " in seconds after -t for conditional barring");
1117 return -1;
1118 }
1119 break;
1120 }
1121 }
1122 }
1123 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1124 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1125 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1126 barringServiceInfos.append(0, bsi);
1127 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1128 try {
1129 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1130 } catch (Exception e) {
1131 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1132 errPw.println("Exception: " + e.getMessage());
1133 return -1;
1134 }
1135 return 0;
1136 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001137
Tyler Gunnd4575212021-05-03 14:46:49 -07001138 private int handleD2dDeviceSupportedCommand() {
1139 PrintWriter errPw = getErrPrintWriter();
1140
1141 String arg = getNextArg();
1142 if (arg == null) {
1143 onHelpD2D();
1144 return 0;
1145 }
1146
1147 boolean isEnabled = "true".equals(arg.toLowerCase());
1148 try {
1149 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1150 } catch (RemoteException e) {
1151 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1152 errPw.println("Exception: " + e.getMessage());
1153 return -1;
1154 }
1155 return 0;
1156 }
1157
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001158 // ims set-ims-service
1159 private int handleImsSetServiceCommand() {
1160 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001161 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001162 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001163 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001164
1165 String opt;
1166 while ((opt = getNextOption()) != null) {
1167 switch (opt) {
1168 case "-s": {
1169 try {
1170 slotId = Integer.parseInt(getNextArgRequired());
1171 } catch (NumberFormatException e) {
1172 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1173 return -1;
1174 }
1175 break;
1176 }
1177 case "-c": {
1178 isCarrierService = true;
1179 break;
1180 }
1181 case "-d": {
1182 isCarrierService = false;
1183 break;
1184 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001185 case "-f": {
1186 String featureString = getNextArgRequired();
1187 String[] features = featureString.split(",");
1188 for (int i = 0; i < features.length; i++) {
1189 try {
1190 Integer result = Integer.parseInt(features[i]);
1191 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1192 || result >= ImsFeature.FEATURE_MAX) {
1193 errPw.println("ims set-ims-service -f " + result
1194 + " is an invalid feature.");
1195 return -1;
1196 }
1197 featuresList.add(result);
1198 } catch (NumberFormatException e) {
1199 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1200 + " as an integer.");
1201 return -1;
1202 }
1203 }
1204 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001205 }
1206 }
1207 // Mandatory param, either -c or -d
1208 if (isCarrierService == null) {
1209 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1210 return -1;
1211 }
1212
1213 String packageName = getNextArg();
1214
1215 try {
1216 if (packageName == null) {
1217 packageName = "";
1218 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001219 int[] featureArray = new int[featuresList.size()];
1220 for (int i = 0; i < featuresList.size(); i++) {
1221 featureArray[i] = featuresList.get(i);
1222 }
1223 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1224 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001225 if (VDBG) {
1226 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001227 + (isCarrierService ? "-c " : "-d ")
1228 + "-f " + featuresList + " "
1229 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001230 }
1231 getOutPrintWriter().println(result);
1232 } catch (RemoteException e) {
1233 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001234 + (isCarrierService ? "-c " : "-d ")
1235 + "-f " + featuresList + " "
1236 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001237 errPw.println("Exception: " + e.getMessage());
1238 return -1;
1239 }
1240 return 0;
1241 }
1242
Brad Ebinger999d3302020-11-25 14:31:39 -08001243 // ims clear-ims-service-override
1244 private int handleImsClearCarrierServiceCommand() {
1245 PrintWriter errPw = getErrPrintWriter();
1246 int slotId = getDefaultSlot();
1247
1248 String opt;
1249 while ((opt = getNextOption()) != null) {
1250 switch (opt) {
1251 case "-s": {
1252 try {
1253 slotId = Integer.parseInt(getNextArgRequired());
1254 } catch (NumberFormatException e) {
1255 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1256 return -1;
1257 }
1258 break;
1259 }
1260 }
1261 }
1262
1263 try {
1264 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1265 if (VDBG) {
1266 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1267 + ", result=" + result);
1268 }
1269 getOutPrintWriter().println(result);
1270 } catch (RemoteException e) {
1271 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1272 + ", error" + e.getMessage());
1273 errPw.println("Exception: " + e.getMessage());
1274 return -1;
1275 }
1276 return 0;
1277 }
1278
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001279 // ims get-ims-service
1280 private int handleImsGetServiceCommand() {
1281 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001282 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001283 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001284 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001285
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 case "-c": {
1299 isCarrierService = true;
1300 break;
1301 }
1302 case "-d": {
1303 isCarrierService = false;
1304 break;
1305 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001306 case "-f": {
1307 try {
1308 featureType = Integer.parseInt(getNextArg());
1309 } catch (NumberFormatException e) {
1310 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1311 return -1;
1312 }
1313 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1314 || featureType >= ImsFeature.FEATURE_MAX) {
1315 errPw.println("ims get-ims-service -f invalid feature.");
1316 return -1;
1317 }
1318 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001319 }
1320 }
1321 // Mandatory param, either -c or -d
1322 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001323 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001324 return -1;
1325 }
1326
1327 String result;
1328 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001329 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001330 } catch (RemoteException e) {
1331 return -1;
1332 }
1333 if (VDBG) {
1334 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001335 + (isCarrierService ? "-c " : "-d ")
1336 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1337 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001338 }
1339 getOutPrintWriter().println(result);
1340 return 0;
1341 }
1342
1343 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001344 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001345 String opt;
1346 while ((opt = getNextOption()) != null) {
1347 switch (opt) {
1348 case "-s": {
1349 try {
1350 slotId = Integer.parseInt(getNextArgRequired());
1351 } catch (NumberFormatException e) {
1352 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1353 return -1;
1354 }
1355 break;
1356 }
1357 }
1358 }
1359 try {
1360 mInterface.enableIms(slotId);
1361 } catch (RemoteException e) {
1362 return -1;
1363 }
1364 if (VDBG) {
1365 Log.v(LOG_TAG, "ims enable -s " + slotId);
1366 }
1367 return 0;
1368 }
1369
1370 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001371 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001372 String opt;
1373 while ((opt = getNextOption()) != null) {
1374 switch (opt) {
1375 case "-s": {
1376 try {
1377 slotId = Integer.parseInt(getNextArgRequired());
1378 } catch (NumberFormatException e) {
1379 getErrPrintWriter().println(
1380 "ims disable requires an integer as a SLOT_ID.");
1381 return -1;
1382 }
1383 break;
1384 }
1385 }
1386 }
1387 try {
1388 mInterface.disableIms(slotId);
1389 } catch (RemoteException e) {
1390 return -1;
1391 }
1392 if (VDBG) {
1393 Log.v(LOG_TAG, "ims disable -s " + slotId);
1394 }
1395 return 0;
1396 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001397
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001398 private int handleCepChange() {
1399 Log.i(LOG_TAG, "handleCepChange");
1400 String opt = getNextArg();
1401 if (opt == null) {
1402 return -1;
1403 }
1404 boolean isCepEnabled = opt.equals("enable");
1405
1406 try {
1407 mInterface.setCepEnabled(isCepEnabled);
1408 } catch (RemoteException e) {
1409 return -1;
1410 }
1411 return 0;
1412 }
1413
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001414 private int getDefaultSlot() {
1415 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1416 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1417 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1418 // If there is no default, default to slot 0.
1419 slotId = DEFAULT_PHONE_ID;
1420 }
1421 return slotId;
1422 }
sqian2fff4a32018-11-05 14:18:37 -08001423
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001424 // Parse options related to Carrier Config Commands.
1425 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001426 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001427 CcOptionParseResult result = new CcOptionParseResult();
1428 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1429 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001430
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001431 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001432 while ((opt = getNextOption()) != null) {
1433 switch (opt) {
1434 case "-s": {
1435 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001436 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1437 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1438 errPw.println(tag + "No valid subscription found.");
1439 return null;
1440 }
1441
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001442 } catch (IllegalArgumentException e) {
1443 // Missing slot id
1444 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001445 return null;
1446 }
1447 break;
1448 }
1449 case "-p": {
1450 if (allowOptionPersistent) {
1451 result.mPersistent = true;
1452 } else {
1453 errPw.println(tag + "Unexpected option " + opt);
1454 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001455 }
1456 break;
1457 }
1458 default: {
1459 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001460 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001461 }
1462 }
1463 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001464 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001465 }
1466
1467 private int slotStringToSubId(String tag, String slotString) {
1468 int slotId = -1;
1469 try {
1470 slotId = Integer.parseInt(slotString);
1471 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001472 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1473 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1474 }
1475
1476 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001477 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1478 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1479 }
1480
Qiong Liuf25799b2020-09-10 10:13:46 +08001481 Phone phone = PhoneFactory.getPhone(slotId);
1482 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001483 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1484 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1485 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001486 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001487 }
1488
Hall Liud892bec2018-11-30 14:51:45 -08001489 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001490 // adb can run as root or as shell, depending on whether the device is rooted.
1491 return Binder.getCallingUid() == Process.SHELL_UID
1492 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001493 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001494
1495 private int handleCcCommand() {
1496 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1497 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001498 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001499 getErrPrintWriter().println("cc: Permission denied.");
1500 return -1;
1501 }
1502
1503 String arg = getNextArg();
1504 if (arg == null) {
1505 onHelpCc();
1506 return 0;
1507 }
1508
1509 switch (arg) {
1510 case CC_GET_VALUE: {
1511 return handleCcGetValue();
1512 }
1513 case CC_SET_VALUE: {
1514 return handleCcSetValue();
1515 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001516 case CC_SET_VALUES_FROM_XML: {
1517 return handleCcSetValuesFromXml();
1518 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001519 case CC_CLEAR_VALUES: {
1520 return handleCcClearValues();
1521 }
1522 default: {
1523 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1524 }
1525 }
1526 return -1;
1527 }
1528
1529 // cc get-value
1530 private int handleCcGetValue() {
1531 PrintWriter errPw = getErrPrintWriter();
1532 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1533 String key = null;
1534
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001535 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001536 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001537 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001538 return -1;
1539 }
1540
1541 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001542 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001543 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001544 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001545 return -1;
1546 }
1547
1548 // Get the key.
1549 key = getNextArg();
1550 if (key != null) {
1551 // A key was provided. Verify if it is a valid key
1552 if (!bundle.containsKey(key)) {
1553 errPw.println(tag + key + " is not a valid key.");
1554 return -1;
1555 }
1556
1557 // Print the carrier config value for key.
1558 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1559 } else {
1560 // No key provided. Show all values.
1561 // Iterate over a sorted list of all carrier config keys and print them.
1562 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1563 for (String k : sortedSet) {
1564 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1565 }
1566 }
1567 return 0;
1568 }
1569
1570 // cc set-value
1571 private int handleCcSetValue() {
1572 PrintWriter errPw = getErrPrintWriter();
1573 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1574
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001575 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001576 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001577 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001578 return -1;
1579 }
1580
1581 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001582 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001583 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001584 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001585 return -1;
1586 }
1587
1588 // Get the key.
1589 String key = getNextArg();
1590 if (key == null || key.equals("")) {
1591 errPw.println(tag + "KEY is missing");
1592 return -1;
1593 }
1594
1595 // Verify if the key is valid
1596 if (!originalValues.containsKey(key)) {
1597 errPw.println(tag + key + " is not a valid key.");
1598 return -1;
1599 }
1600
1601 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1602 ArrayList<String> valueList = new ArrayList<String>();
1603 while (peekNextArg() != null) {
1604 valueList.add(getNextArg());
1605 }
1606
1607 // Find the type of the carrier config value
1608 CcType type = getType(tag, key, originalValues);
1609 if (type == CcType.UNKNOWN) {
1610 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1611 return -1;
1612 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001613 if (type == CcType.PERSISTABLE_BUNDLE) {
1614 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1615 + "Use set-values-from-xml instead.");
1616 return -1;
1617 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001618
1619 // Create an override bundle containing the key and value that should be overriden.
1620 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1621 if (overrideBundle == null) {
1622 return -1;
1623 }
1624
1625 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001626 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001627
1628 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001629 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001630 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001631 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001632 return -1;
1633 }
1634
1635 // Print the original and new value.
1636 String originalValueString = ccValueToString(key, type, originalValues);
1637 String newValueString = ccValueToString(key, type, newValues);
1638 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1639 getOutPrintWriter().println("New value: \n" + newValueString);
1640
1641 return 0;
1642 }
1643
Allen Xuee00f0e2022-03-14 21:04:49 +00001644 // cc set-values-from-xml
1645 private int handleCcSetValuesFromXml() {
1646 PrintWriter errPw = getErrPrintWriter();
1647 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1648
1649 // Parse all options
1650 CcOptionParseResult options = parseCcOptions(tag, false);
1651 if (options == null) {
1652 return -1;
1653 }
1654
1655 // Get bundle containing all current carrier configuration values.
1656 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1657 if (originalValues == null) {
1658 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1659 return -1;
1660 }
1661
1662 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1663 if (overrideBundle == null) {
1664 return -1;
1665 }
1666
1667 // Verify all values are valid types
1668 for (String key : overrideBundle.keySet()) {
1669 CcType type = getType(tag, key, originalValues);
1670 if (type == CcType.UNKNOWN) {
1671 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1672 return -1;
1673 }
1674 }
1675
1676 // Override the value
1677 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1678
1679 // Find bundle containing all new carrier configuration values after the override.
1680 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1681 if (newValues == null) {
1682 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1683 return -1;
1684 }
1685
1686 // Print the original and new values
1687 overrideBundle.keySet().forEach(key -> {
1688 CcType type = getType(tag, key, originalValues);
1689 String originalValueString = ccValueToString(key, type, originalValues);
1690 String newValueString = ccValueToString(key, type, newValues);
1691 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1692 getOutPrintWriter().println("New value: \n" + newValueString);
1693 });
1694
1695 return 0;
1696 }
1697
1698 private PersistableBundle readPersistableBundleFromXml(String tag) {
1699 PersistableBundle subIdBundles;
1700 try {
1701 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1702 } catch (IOException | RuntimeException e) {
1703 PrintWriter errPw = getErrPrintWriter();
1704 errPw.println(tag + e);
1705 return null;
1706 }
1707
1708 return subIdBundles;
1709 }
1710
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001711 // cc clear-values
1712 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001713 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1714
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001715 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001716 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001717 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001718 return -1;
1719 }
1720
1721 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001722 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001723 getOutPrintWriter()
1724 .println("All previously set carrier config override values has been cleared");
1725 return 0;
1726 }
1727
1728 private CcType getType(String tag, String key, PersistableBundle bundle) {
1729 // Find the type by checking the type of the current value stored in the bundle.
1730 Object value = bundle.get(key);
1731
1732 if (CC_TYPE_MAP.containsKey(key)) {
1733 return CC_TYPE_MAP.get(key);
1734 } else if (value != null) {
1735 if (value instanceof Boolean) {
1736 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001737 }
1738 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001739 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001740 }
1741 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001742 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001743 }
1744 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001745 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001746 }
1747 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001748 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001749 }
1750 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001751 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001752 }
1753 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001754 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001755 }
1756 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001757 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001758 }
1759 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001760 return CcType.STRING_ARRAY;
1761 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001762 if (value instanceof PersistableBundle) {
1763 return CcType.PERSISTABLE_BUNDLE;
1764 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001765 } else {
1766 // Current value was null and can therefore not be used in order to find the type.
1767 // Check the name of the key to infer the type. This check is not needed for primitive
1768 // data types (boolean, double, int and long), since they can not be null.
1769 if (key.endsWith("double_array")) {
1770 return CcType.DOUBLE_ARRAY;
1771 }
1772 if (key.endsWith("int_array")) {
1773 return CcType.INT_ARRAY;
1774 }
1775 if (key.endsWith("long_array")) {
1776 return CcType.LONG_ARRAY;
1777 }
1778 if (key.endsWith("string")) {
1779 return CcType.STRING;
1780 }
1781 if (key.endsWith("string_array") || key.endsWith("strings")) {
1782 return CcType.STRING_ARRAY;
1783 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001784 if (key.endsWith("bundle")) {
1785 return CcType.PERSISTABLE_BUNDLE;
1786 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001787 }
1788
1789 // Not possible to infer the type by looking at the current value or the key.
1790 PrintWriter errPw = getErrPrintWriter();
1791 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1792 return CcType.UNKNOWN;
1793 }
1794
1795 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1796 String result;
1797 StringBuilder valueString = new StringBuilder();
1798 String typeString = type.toString();
1799 Object value = bundle.get(key);
1800
1801 if (value == null) {
1802 valueString.append("null");
1803 } else {
1804 switch (type) {
1805 case DOUBLE_ARRAY: {
1806 // Format the string representation of the int array as value1 value2......
1807 double[] valueArray = (double[]) value;
1808 for (int i = 0; i < valueArray.length; i++) {
1809 if (i != 0) {
1810 valueString.append(" ");
1811 }
1812 valueString.append(valueArray[i]);
1813 }
1814 break;
1815 }
1816 case INT_ARRAY: {
1817 // Format the string representation of the int array as value1 value2......
1818 int[] valueArray = (int[]) value;
1819 for (int i = 0; i < valueArray.length; i++) {
1820 if (i != 0) {
1821 valueString.append(" ");
1822 }
1823 valueString.append(valueArray[i]);
1824 }
1825 break;
1826 }
1827 case LONG_ARRAY: {
1828 // Format the string representation of the int array as value1 value2......
1829 long[] valueArray = (long[]) value;
1830 for (int i = 0; i < valueArray.length; i++) {
1831 if (i != 0) {
1832 valueString.append(" ");
1833 }
1834 valueString.append(valueArray[i]);
1835 }
1836 break;
1837 }
1838 case STRING: {
1839 valueString.append("\"" + value.toString() + "\"");
1840 break;
1841 }
1842 case STRING_ARRAY: {
1843 // Format the string representation of the string array as "value1" "value2"....
1844 String[] valueArray = (String[]) value;
1845 for (int i = 0; i < valueArray.length; i++) {
1846 if (i != 0) {
1847 valueString.append(" ");
1848 }
1849 if (valueArray[i] != null) {
1850 valueString.append("\"" + valueArray[i] + "\"");
1851 } else {
1852 valueString.append("null");
1853 }
1854 }
1855 break;
1856 }
1857 default: {
1858 valueString.append(value.toString());
1859 }
1860 }
1861 }
1862 return String.format("%-70s %-15s %s", key, typeString, valueString);
1863 }
1864
1865 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1866 ArrayList<String> valueList) {
1867 PrintWriter errPw = getErrPrintWriter();
1868 PersistableBundle bundle = new PersistableBundle();
1869
1870 // First verify that a valid number of values has been provided for the type.
1871 switch (type) {
1872 case BOOLEAN:
1873 case DOUBLE:
1874 case INT:
1875 case LONG: {
1876 if (valueList.size() != 1) {
1877 errPw.println(tag + "Expected 1 value for type " + type
1878 + ". Found: " + valueList.size());
1879 return null;
1880 }
1881 break;
1882 }
1883 case STRING: {
1884 if (valueList.size() > 1) {
1885 errPw.println(tag + "Expected 0 or 1 values for type " + type
1886 + ". Found: " + valueList.size());
1887 return null;
1888 }
1889 break;
1890 }
1891 }
1892
1893 // Parse the value according to type and add it to the Bundle.
1894 switch (type) {
1895 case BOOLEAN: {
1896 if ("true".equalsIgnoreCase(valueList.get(0))) {
1897 bundle.putBoolean(key, true);
1898 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1899 bundle.putBoolean(key, false);
1900 } else {
1901 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1902 return null;
1903 }
1904 break;
1905 }
1906 case DOUBLE: {
1907 try {
1908 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1909 } catch (NumberFormatException nfe) {
1910 // Not a valid double
1911 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1912 return null;
1913 }
1914 break;
1915 }
1916 case DOUBLE_ARRAY: {
1917 double[] valueDoubleArray = null;
1918 if (valueList.size() > 0) {
1919 valueDoubleArray = new double[valueList.size()];
1920 for (int i = 0; i < valueList.size(); i++) {
1921 try {
1922 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1923 } catch (NumberFormatException nfe) {
1924 // Not a valid double
1925 errPw.println(
1926 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1927 return null;
1928 }
1929 }
1930 }
1931 bundle.putDoubleArray(key, valueDoubleArray);
1932 break;
1933 }
1934 case INT: {
1935 try {
1936 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1937 } catch (NumberFormatException nfe) {
1938 // Not a valid integer
1939 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1940 return null;
1941 }
1942 break;
1943 }
1944 case INT_ARRAY: {
1945 int[] valueIntArray = null;
1946 if (valueList.size() > 0) {
1947 valueIntArray = new int[valueList.size()];
1948 for (int i = 0; i < valueList.size(); i++) {
1949 try {
1950 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1951 } catch (NumberFormatException nfe) {
1952 // Not a valid integer
1953 errPw.println(tag
1954 + "Unable to parse " + valueList.get(i) + " as an integer.");
1955 return null;
1956 }
1957 }
1958 }
1959 bundle.putIntArray(key, valueIntArray);
1960 break;
1961 }
1962 case LONG: {
1963 try {
1964 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1965 } catch (NumberFormatException nfe) {
1966 // Not a valid long
1967 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1968 return null;
1969 }
1970 break;
1971 }
1972 case LONG_ARRAY: {
1973 long[] valueLongArray = null;
1974 if (valueList.size() > 0) {
1975 valueLongArray = new long[valueList.size()];
1976 for (int i = 0; i < valueList.size(); i++) {
1977 try {
1978 valueLongArray[i] = Long.parseLong(valueList.get(i));
1979 } catch (NumberFormatException nfe) {
1980 // Not a valid long
1981 errPw.println(
1982 tag + "Unable to parse " + valueList.get(i) + " as a long");
1983 return null;
1984 }
1985 }
1986 }
1987 bundle.putLongArray(key, valueLongArray);
1988 break;
1989 }
1990 case STRING: {
1991 String value = null;
1992 if (valueList.size() > 0) {
1993 value = valueList.get(0);
1994 }
1995 bundle.putString(key, value);
1996 break;
1997 }
1998 case STRING_ARRAY: {
1999 String[] valueStringArray = null;
2000 if (valueList.size() > 0) {
2001 valueStringArray = new String[valueList.size()];
2002 valueList.toArray(valueStringArray);
2003 }
2004 bundle.putStringArray(key, valueStringArray);
2005 break;
2006 }
2007 }
2008 return bundle;
2009 }
Shuo Qian489d9282020-07-09 11:30:03 -07002010
2011 private int handleEndBlockSuppressionCommand() {
2012 if (!checkShellUid()) {
2013 return -1;
2014 }
2015
2016 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2017 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2018 }
2019 return 0;
2020 }
Hui Wang641e81c2020-10-12 12:14:23 -07002021
Michele Berionne54af4632020-12-28 20:23:16 +00002022 private int handleRestartModemCommand() {
2023 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2024 // non user build.
2025 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2026 getErrPrintWriter().println("RestartModem: Permission denied.");
2027 return -1;
2028 }
2029
2030 boolean result = TelephonyManager.getDefault().rebootRadio();
2031 getOutPrintWriter().println(result);
2032
2033 return result ? 0 : -1;
2034 }
2035
Ling Ma4fbab492022-01-25 22:36:16 +00002036 private int handleGetImei() {
2037 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2038 // non user build.
2039 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2040 getErrPrintWriter().println("Device IMEI: Permission denied.");
2041 return -1;
2042 }
2043
2044 final long identity = Binder.clearCallingIdentity();
2045
2046 String imei = null;
2047 String arg = getNextArg();
2048 if (arg != null) {
2049 try {
2050 int specifiedSlotIndex = Integer.parseInt(arg);
2051 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2052 } catch (NumberFormatException exception) {
2053 PrintWriter errPw = getErrPrintWriter();
2054 errPw.println("-s requires an integer as slot index.");
2055 return -1;
2056 }
2057
2058 } else {
2059 imei = TelephonyManager.from(mContext).getImei();
2060 }
2061 getOutPrintWriter().println("Device IMEI: " + imei);
2062
2063 Binder.restoreCallingIdentity(identity);
2064 return 0;
2065 }
2066
Michele Berionne5e411512020-11-13 02:36:59 +00002067 private int handleUnattendedReboot() {
2068 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2069 // non user build.
2070 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2071 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2072 return -1;
2073 }
2074
2075 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2076 getOutPrintWriter().println("result: " + result);
2077
2078 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2079 }
2080
Aman Gupta07124872022-02-09 08:02:14 +00002081 private int handleGetSimSlotsMapping() {
2082 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2083 // non user build.
2084 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2085 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2086 return -1;
2087 }
2088 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2089 String result = telephonyManager.getSimSlotMapping().toString();
2090 getOutPrintWriter().println("simSlotsMapping: " + result);
2091
2092 return 0;
2093 }
2094
Hui Wang641e81c2020-10-12 12:14:23 -07002095 private int handleGbaCommand() {
2096 String arg = getNextArg();
2097 if (arg == null) {
2098 onHelpGba();
2099 return 0;
2100 }
2101
2102 switch (arg) {
2103 case GBA_SET_SERVICE: {
2104 return handleGbaSetServiceCommand();
2105 }
2106 case GBA_GET_SERVICE: {
2107 return handleGbaGetServiceCommand();
2108 }
2109 case GBA_SET_RELEASE_TIME: {
2110 return handleGbaSetReleaseCommand();
2111 }
2112 case GBA_GET_RELEASE_TIME: {
2113 return handleGbaGetReleaseCommand();
2114 }
2115 }
2116
2117 return -1;
2118 }
2119
2120 private int getSubId(String cmd) {
2121 int slotId = getDefaultSlot();
2122 String opt = getNextOption();
2123 if (opt != null && opt.equals("-s")) {
2124 try {
2125 slotId = Integer.parseInt(getNextArgRequired());
2126 } catch (NumberFormatException e) {
2127 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2128 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2129 }
2130 }
2131 int[] subIds = SubscriptionManager.getSubId(slotId);
2132 return subIds[0];
2133 }
2134
2135 private int handleGbaSetServiceCommand() {
2136 int subId = getSubId("gba set-service");
2137 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2138 return -1;
2139 }
2140
2141 String packageName = getNextArg();
2142 try {
2143 if (packageName == null) {
2144 packageName = "";
2145 }
2146 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2147 if (VDBG) {
2148 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2149 + packageName + ", result=" + result);
2150 }
2151 getOutPrintWriter().println(result);
2152 } catch (RemoteException e) {
2153 Log.w(LOG_TAG, "gba set-service " + subId + " "
2154 + packageName + ", error" + e.getMessage());
2155 getErrPrintWriter().println("Exception: " + e.getMessage());
2156 return -1;
2157 }
2158 return 0;
2159 }
2160
2161 private int handleGbaGetServiceCommand() {
2162 String result;
2163
2164 int subId = getSubId("gba get-service");
2165 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2166 return -1;
2167 }
2168
2169 try {
2170 result = mInterface.getBoundGbaService(subId);
2171 } catch (RemoteException e) {
2172 return -1;
2173 }
2174 if (VDBG) {
2175 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2176 }
2177 getOutPrintWriter().println(result);
2178 return 0;
2179 }
2180
2181 private int handleGbaSetReleaseCommand() {
2182 //the release time value could be -1
2183 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2184 : SubscriptionManager.getDefaultSubscriptionId();
2185 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2186 return -1;
2187 }
2188
2189 String intervalStr = getNextArg();
2190 if (intervalStr == null) {
2191 return -1;
2192 }
2193
2194 try {
2195 int interval = Integer.parseInt(intervalStr);
2196 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2197 if (VDBG) {
2198 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2199 + intervalStr + ", result=" + result);
2200 }
2201 getOutPrintWriter().println(result);
2202 } catch (NumberFormatException | RemoteException e) {
2203 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2204 + intervalStr + ", error" + e.getMessage());
2205 getErrPrintWriter().println("Exception: " + e.getMessage());
2206 return -1;
2207 }
2208 return 0;
2209 }
2210
2211 private int handleGbaGetReleaseCommand() {
2212 int subId = getSubId("gba get-release");
2213 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2214 return -1;
2215 }
2216
2217 int result = 0;
2218 try {
2219 result = mInterface.getGbaReleaseTime(subId);
2220 } catch (RemoteException e) {
2221 return -1;
2222 }
2223 if (VDBG) {
2224 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2225 }
2226 getOutPrintWriter().println(result);
2227 return 0;
2228 }
Hui Wang761a6682020-10-31 05:12:53 +00002229
2230 private int handleSingleRegistrationConfigCommand() {
2231 String arg = getNextArg();
2232 if (arg == null) {
2233 onHelpSrc();
2234 return 0;
2235 }
2236
2237 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002238 case SRC_SET_TEST_ENABLED: {
2239 return handleSrcSetTestEnabledCommand();
2240 }
2241 case SRC_GET_TEST_ENABLED: {
2242 return handleSrcGetTestEnabledCommand();
2243 }
Hui Wang761a6682020-10-31 05:12:53 +00002244 case SRC_SET_DEVICE_ENABLED: {
2245 return handleSrcSetDeviceEnabledCommand();
2246 }
2247 case SRC_GET_DEVICE_ENABLED: {
2248 return handleSrcGetDeviceEnabledCommand();
2249 }
2250 case SRC_SET_CARRIER_ENABLED: {
2251 return handleSrcSetCarrierEnabledCommand();
2252 }
2253 case SRC_GET_CARRIER_ENABLED: {
2254 return handleSrcGetCarrierEnabledCommand();
2255 }
Hui Wangb647abe2021-02-26 09:33:38 -08002256 case SRC_SET_FEATURE_ENABLED: {
2257 return handleSrcSetFeatureValidationCommand();
2258 }
2259 case SRC_GET_FEATURE_ENABLED: {
2260 return handleSrcGetFeatureValidationCommand();
2261 }
Hui Wang761a6682020-10-31 05:12:53 +00002262 }
2263
2264 return -1;
2265 }
2266
James.cf Linbcdf8b32021-01-14 16:44:13 +08002267 private int handleRcsUceCommand() {
2268 String arg = getNextArg();
2269 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002270 onHelpUce();
2271 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002272 }
2273
2274 switch (arg) {
2275 case UCE_REMOVE_EAB_CONTACT:
2276 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002277 case UCE_GET_EAB_CONTACT:
2278 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002279 case UCE_GET_EAB_CAPABILITY:
2280 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002281 case UCE_GET_DEVICE_ENABLED:
2282 return handleUceGetDeviceEnabledCommand();
2283 case UCE_SET_DEVICE_ENABLED:
2284 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002285 case UCE_OVERRIDE_PUBLISH_CAPS:
2286 return handleUceOverridePublishCaps();
2287 case UCE_GET_LAST_PIDF_XML:
2288 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002289 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2290 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002291 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2292 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002293 }
2294 return -1;
2295 }
2296
2297 private int handleRemovingEabContactCommand() {
2298 int subId = getSubId("uce remove-eab-contact");
2299 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2300 return -1;
2301 }
2302
2303 String phoneNumber = getNextArgRequired();
2304 if (TextUtils.isEmpty(phoneNumber)) {
2305 return -1;
2306 }
2307 int result = 0;
2308 try {
2309 result = mInterface.removeContactFromEab(subId, phoneNumber);
2310 } catch (RemoteException e) {
2311 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2312 getErrPrintWriter().println("Exception: " + e.getMessage());
2313 return -1;
2314 }
2315
2316 if (VDBG) {
2317 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2318 }
calvinpan293ea1b2021-02-04 17:52:13 +08002319 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002320 }
2321
calvinpane4a8a1d2021-01-25 13:51:18 +08002322 private int handleGettingEabContactCommand() {
2323 String phoneNumber = getNextArgRequired();
2324 if (TextUtils.isEmpty(phoneNumber)) {
2325 return -1;
2326 }
2327 String result = "";
2328 try {
2329 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002330 } catch (RemoteException e) {
2331 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2332 getErrPrintWriter().println("Exception: " + e.getMessage());
2333 return -1;
2334 }
2335
2336 if (VDBG) {
2337 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2338 }
calvinpan293ea1b2021-02-04 17:52:13 +08002339 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002340 return 0;
2341 }
2342
Calvin Pana1434322021-07-01 19:27:01 +08002343 private int handleGettingEabCapabilityCommand() {
2344 String phoneNumber = getNextArgRequired();
2345 if (TextUtils.isEmpty(phoneNumber)) {
2346 return -1;
2347 }
2348 String result = "";
2349 try {
2350 result = mInterface.getCapabilityFromEab(phoneNumber);
2351 } catch (RemoteException e) {
2352 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2353 getErrPrintWriter().println("Exception: " + e.getMessage());
2354 return -1;
2355 }
2356
2357 if (VDBG) {
2358 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2359 }
2360 getOutPrintWriter().println(result);
2361 return 0;
2362 }
2363
James.cf Lin4b784aa2021-01-31 03:25:15 +08002364 private int handleUceGetDeviceEnabledCommand() {
2365 boolean result = false;
2366 try {
2367 result = mInterface.getDeviceUceEnabled();
2368 } catch (RemoteException e) {
2369 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2370 return -1;
2371 }
2372 if (VDBG) {
2373 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2374 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002375 getOutPrintWriter().println(result);
2376 return 0;
2377 }
2378
James.cf Lin4b784aa2021-01-31 03:25:15 +08002379 private int handleUceSetDeviceEnabledCommand() {
2380 String enabledStr = getNextArg();
2381 if (TextUtils.isEmpty(enabledStr)) {
2382 return -1;
2383 }
2384
2385 try {
2386 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2387 mInterface.setDeviceUceEnabled(isEnabled);
2388 if (VDBG) {
2389 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2390 }
2391 } catch (NumberFormatException | RemoteException e) {
2392 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2393 getErrPrintWriter().println("Exception: " + e.getMessage());
2394 return -1;
2395 }
2396 return 0;
2397 }
2398
James.cf Line8713a42021-04-29 16:04:26 +08002399 private int handleUceRemoveRequestDisallowedStatus() {
2400 int subId = getSubId("uce remove-request-disallowed-status");
2401 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2402 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2403 return -1;
2404 }
2405 boolean result;
2406 try {
2407 result = mInterface.removeUceRequestDisallowedStatus(subId);
2408 } catch (RemoteException e) {
2409 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2410 return -1;
2411 }
2412 if (VDBG) {
2413 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2414 }
2415 getOutPrintWriter().println(result);
2416 return 0;
2417 }
2418
James.cf Lin0fc71b02021-05-25 01:37:38 +08002419 private int handleUceSetCapRequestTimeout() {
2420 int subId = getSubId("uce set-capabilities-request-timeout");
2421 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2422 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2423 return -1;
2424 }
2425 long timeoutAfterMs = Long.valueOf(getNextArg());
2426 boolean result;
2427 try {
2428 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2429 } catch (RemoteException e) {
2430 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2431 return -1;
2432 }
2433 if (VDBG) {
2434 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2435 }
2436 getOutPrintWriter().println(result);
2437 return 0;
2438 }
2439
Hui Wangbaaee6a2021-02-19 20:45:36 -08002440 private int handleSrcSetTestEnabledCommand() {
2441 String enabledStr = getNextArg();
2442 if (enabledStr == null) {
2443 return -1;
2444 }
2445
2446 try {
2447 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2448 if (VDBG) {
2449 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2450 }
2451 getOutPrintWriter().println("Done");
2452 } catch (NumberFormatException | RemoteException e) {
2453 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2454 getErrPrintWriter().println("Exception: " + e.getMessage());
2455 return -1;
2456 }
2457 return 0;
2458 }
2459
2460 private int handleSrcGetTestEnabledCommand() {
2461 boolean result = false;
2462 try {
2463 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2464 } catch (RemoteException e) {
2465 return -1;
2466 }
2467 if (VDBG) {
2468 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2469 }
2470 getOutPrintWriter().println(result);
2471 return 0;
2472 }
2473
Brad Ebinger14d467f2021-02-12 06:18:28 +00002474 private int handleUceOverridePublishCaps() {
2475 int subId = getSubId("uce override-published-caps");
2476 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2477 return -1;
2478 }
2479 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2480 String operation = getNextArgRequired();
2481 String caps = getNextArg();
2482 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2483 && !"list".equals(operation)) {
2484 getErrPrintWriter().println("Invalid operation: " + operation);
2485 return -1;
2486 }
2487
2488 // add/remove requires capabilities to be specified.
2489 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2490 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2491 + "specified");
2492 return -1;
2493 }
2494
2495 ArraySet<String> capSet = new ArraySet<>();
2496 if (!TextUtils.isEmpty(caps)) {
2497 String[] capArray = caps.split(":");
2498 for (String cap : capArray) {
2499 // Allow unknown tags to be passed in as well.
2500 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2501 }
2502 }
2503
2504 RcsContactUceCapability result = null;
2505 try {
2506 switch (operation) {
2507 case "add":
2508 result = mInterface.addUceRegistrationOverrideShell(subId,
2509 new ArrayList<>(capSet));
2510 break;
2511 case "remove":
2512 result = mInterface.removeUceRegistrationOverrideShell(subId,
2513 new ArrayList<>(capSet));
2514 break;
2515 case "clear":
2516 result = mInterface.clearUceRegistrationOverrideShell(subId);
2517 break;
2518 case "list":
2519 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2520 break;
2521 }
2522 } catch (RemoteException e) {
2523 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2524 getErrPrintWriter().println("Exception: " + e.getMessage());
2525 return -1;
2526 } catch (ServiceSpecificException sse) {
2527 // Reconstruct ImsException
2528 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2529 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2530 getErrPrintWriter().println("Exception: " + imsException);
2531 return -1;
2532 }
2533 if (result == null) {
2534 getErrPrintWriter().println("Service not available");
2535 return -1;
2536 }
2537 getOutPrintWriter().println(result);
2538 return 0;
2539 }
2540
2541 private int handleUceGetPidfXml() {
2542 int subId = getSubId("uce get-last-publish-pidf");
2543 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2544 return -1;
2545 }
2546
2547 String result;
2548 try {
2549 result = mInterface.getLastUcePidfXmlShell(subId);
2550 } catch (RemoteException e) {
2551 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2552 getErrPrintWriter().println("Exception: " + e.getMessage());
2553 return -1;
2554 } catch (ServiceSpecificException sse) {
2555 // Reconstruct ImsException
2556 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2557 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2558 getErrPrintWriter().println("Exception: " + imsException);
2559 return -1;
2560 }
2561 if (result == null) {
2562 getErrPrintWriter().println("Service not available");
2563 return -1;
2564 }
2565 getOutPrintWriter().println(result);
2566 return 0;
2567 }
2568
Hui Wang761a6682020-10-31 05:12:53 +00002569 private int handleSrcSetDeviceEnabledCommand() {
2570 String enabledStr = getNextArg();
2571 if (enabledStr == null) {
2572 return -1;
2573 }
2574
2575 try {
2576 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2577 if (VDBG) {
2578 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2579 }
2580 getOutPrintWriter().println("Done");
2581 } catch (NumberFormatException | RemoteException e) {
2582 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2583 getErrPrintWriter().println("Exception: " + e.getMessage());
2584 return -1;
2585 }
2586 return 0;
2587 }
2588
2589 private int handleSrcGetDeviceEnabledCommand() {
2590 boolean result = false;
2591 try {
2592 result = mInterface.getDeviceSingleRegistrationEnabled();
2593 } catch (RemoteException e) {
2594 return -1;
2595 }
2596 if (VDBG) {
2597 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2598 }
2599 getOutPrintWriter().println(result);
2600 return 0;
2601 }
2602
2603 private int handleSrcSetCarrierEnabledCommand() {
2604 //the release time value could be -1
2605 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2606 : SubscriptionManager.getDefaultSubscriptionId();
2607 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2608 return -1;
2609 }
2610
2611 String enabledStr = getNextArg();
2612 if (enabledStr == null) {
2613 return -1;
2614 }
2615
2616 try {
2617 boolean result =
2618 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2619 if (VDBG) {
2620 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2621 + enabledStr + ", result=" + result);
2622 }
2623 getOutPrintWriter().println(result);
2624 } catch (NumberFormatException | RemoteException e) {
2625 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2626 + enabledStr + ", error" + e.getMessage());
2627 getErrPrintWriter().println("Exception: " + e.getMessage());
2628 return -1;
2629 }
2630 return 0;
2631 }
2632
2633 private int handleSrcGetCarrierEnabledCommand() {
2634 int subId = getSubId("src get-carrier-enabled");
2635 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2636 return -1;
2637 }
2638
2639 boolean result = false;
2640 try {
2641 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2642 } catch (RemoteException e) {
2643 return -1;
2644 }
2645 if (VDBG) {
2646 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2647 }
2648 getOutPrintWriter().println(result);
2649 return 0;
2650 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002651
Hui Wangb647abe2021-02-26 09:33:38 -08002652 private int handleSrcSetFeatureValidationCommand() {
2653 //the release time value could be -1
2654 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2655 : SubscriptionManager.getDefaultSubscriptionId();
2656 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2657 return -1;
2658 }
2659
2660 String enabledStr = getNextArg();
2661 if (enabledStr == null) {
2662 return -1;
2663 }
2664
2665 try {
2666 boolean result =
2667 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2668 if (VDBG) {
2669 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2670 + enabledStr + ", result=" + result);
2671 }
2672 getOutPrintWriter().println(result);
2673 } catch (NumberFormatException | RemoteException e) {
2674 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2675 + enabledStr + ", error" + e.getMessage());
2676 getErrPrintWriter().println("Exception: " + e.getMessage());
2677 return -1;
2678 }
2679 return 0;
2680 }
2681
2682 private int handleSrcGetFeatureValidationCommand() {
2683 int subId = getSubId("src get-feature-validation");
2684 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2685 return -1;
2686 }
2687
2688 Boolean result = false;
2689 try {
2690 result = mInterface.getImsFeatureValidationOverride(subId);
2691 } catch (RemoteException e) {
2692 return -1;
2693 }
2694 if (VDBG) {
2695 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2696 }
2697 getOutPrintWriter().println(result);
2698 return 0;
2699 }
2700
2701
Hall Liuaa4211e2021-01-20 15:43:39 -08002702 private void onHelpCallComposer() {
2703 PrintWriter pw = getOutPrintWriter();
2704 pw.println("Call composer commands");
2705 pw.println(" callcomposer test-mode enable|disable|query");
2706 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2707 pw.println(" upload/download from carrier servers is disabled, and operations are");
2708 pw.println(" performed using emulated local files instead.");
2709 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2710 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2711 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002712 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2713 pw.println(" Enables or disables the user setting for call composer, as set by");
2714 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002715 }
2716
2717 private int handleCallComposerCommand() {
2718 String arg = getNextArg();
2719 if (arg == null) {
2720 onHelpCallComposer();
2721 return 0;
2722 }
2723
2724 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2725 "MODIFY_PHONE_STATE required for call composer shell cmds");
2726 switch (arg) {
2727 case CALL_COMPOSER_TEST_MODE: {
2728 String enabledStr = getNextArg();
2729 if (ENABLE.equals(enabledStr)) {
2730 CallComposerPictureManager.sTestMode = true;
2731 } else if (DISABLE.equals(enabledStr)) {
2732 CallComposerPictureManager.sTestMode = false;
2733 } else if (QUERY.equals(enabledStr)) {
2734 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2735 } else {
2736 onHelpCallComposer();
2737 return 1;
2738 }
2739 break;
2740 }
2741 case CALL_COMPOSER_SIMULATE_CALL: {
2742 int subscriptionId = Integer.valueOf(getNextArg());
2743 String uuidString = getNextArg();
2744 UUID uuid = UUID.fromString(uuidString);
2745 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2746 Binder.withCleanCallingIdentity(() -> {
2747 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2748 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2749 });
2750 try {
2751 Uri uri = storageUriFuture.get();
2752 getOutPrintWriter().println(String.valueOf(uri));
2753 } catch (Exception e) {
2754 throw new RuntimeException(e);
2755 }
2756 break;
2757 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002758 case CALL_COMPOSER_USER_SETTING: {
2759 try {
2760 int subscriptionId = Integer.valueOf(getNextArg());
2761 String enabledStr = getNextArg();
2762 if (ENABLE.equals(enabledStr)) {
2763 mInterface.setCallComposerStatus(subscriptionId,
2764 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2765 } else if (DISABLE.equals(enabledStr)) {
2766 mInterface.setCallComposerStatus(subscriptionId,
2767 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2768 } else if (QUERY.equals(enabledStr)) {
2769 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2770 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2771 } else {
2772 onHelpCallComposer();
2773 return 1;
2774 }
2775 } catch (RemoteException e) {
2776 e.printStackTrace(getOutPrintWriter());
2777 return 1;
2778 }
2779 break;
2780 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002781 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002782 return 0;
2783 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002784
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002785 private int handleHasCarrierPrivilegesCommand() {
2786 String packageName = getNextArgRequired();
2787
2788 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002789 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002790 try {
2791 hasCarrierPrivileges =
2792 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2793 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2794 } catch (RemoteException e) {
2795 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2796 getErrPrintWriter().println("Exception: " + e.getMessage());
2797 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002798 } finally {
2799 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002800 }
2801
2802 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002803 return 0;
2804 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002805
2806 private int handleAllowedNetworkTypesCommand(String command) {
2807 if (!checkShellUid()) {
2808 return -1;
2809 }
2810
2811 PrintWriter errPw = getErrPrintWriter();
2812 String tag = command + ": ";
2813 String opt;
2814 int subId = -1;
2815 Log.v(LOG_TAG, command + " start");
2816
2817 while ((opt = getNextOption()) != null) {
2818 if (opt.equals("-s")) {
2819 try {
2820 subId = slotStringToSubId(tag, getNextArgRequired());
2821 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2822 errPw.println(tag + "No valid subscription found.");
2823 return -1;
2824 }
2825 } catch (IllegalArgumentException e) {
2826 // Missing slot id
2827 errPw.println(tag + "SLOT_ID expected after -s.");
2828 return -1;
2829 }
2830 } else {
2831 errPw.println(tag + "Unknown option " + opt);
2832 return -1;
2833 }
2834 }
2835
2836 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2837 return handleGetAllowedNetworkTypesCommand(subId);
2838 }
2839 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2840 return handleSetAllowedNetworkTypesCommand(subId);
2841 }
2842 return -1;
2843 }
2844
2845 private int handleGetAllowedNetworkTypesCommand(int subId) {
2846 PrintWriter errPw = getErrPrintWriter();
2847
2848 long result = -1;
2849 try {
2850 if (mInterface != null) {
2851 result = mInterface.getAllowedNetworkTypesForReason(subId,
2852 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2853 } else {
2854 throw new IllegalStateException("telephony service is null.");
2855 }
2856 } catch (RemoteException e) {
2857 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2858 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2859 return -1;
2860 }
2861
2862 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2863 return 0;
2864 }
2865
2866 private int handleSetAllowedNetworkTypesCommand(int subId) {
2867 PrintWriter errPw = getErrPrintWriter();
2868
2869 String bitmaskString = getNextArg();
2870 if (TextUtils.isEmpty(bitmaskString)) {
2871 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2872 return -1;
2873 }
2874 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2875 if (allowedNetworkTypes < 0) {
2876 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2877 return -1;
2878 }
2879 boolean result = false;
2880 try {
2881 if (mInterface != null) {
2882 result = mInterface.setAllowedNetworkTypesForReason(subId,
2883 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2884 } else {
2885 throw new IllegalStateException("telephony service is null.");
2886 }
2887 } catch (RemoteException e) {
2888 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2889 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2890 return -1;
2891 }
2892
2893 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2894 if (result) {
2895 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2896 }
2897 getOutPrintWriter().println(resultMessage);
2898 return 0;
2899 }
2900
2901 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2902 if (TextUtils.isEmpty(bitmaskString)) {
2903 return -1;
2904 }
2905 if (VDBG) {
2906 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2907 + ", length: " + bitmaskString.length());
2908 }
2909 try {
2910 return Long.parseLong(bitmaskString, 2);
2911 } catch (NumberFormatException e) {
2912 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2913 return -1;
2914 }
2915 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002916
2917 private int handleGetDataMode() {
2918 if (!checkShellUid()) {
2919 return -1;
2920 }
2921
2922 boolean newDataStackEnabled = false;
2923 try {
2924 newDataStackEnabled = mInterface.isUsingNewDataStack();
2925 } catch (RemoteException e) {
2926 getOutPrintWriter().println("Something went wrong. " + e);
2927 return -1;
2928 }
2929
Jack Yu2f509862022-01-25 10:13:40 -08002930 getOutPrintWriter().println("Telephony is running with the "
2931 + (newDataStackEnabled ? "new" : "old") + " data stack.");
Jack Yu4c0a5502021-12-03 23:58:26 -08002932
2933 boolean configEnabled = Boolean.parseBoolean(DeviceConfig.getProperty(
Jack Yu31b842d2022-01-13 22:13:54 -08002934 DeviceConfig.NAMESPACE_TELEPHONY, "enable_new_data_stack"));
Jack Yu4c0a5502021-12-03 23:58:26 -08002935 if (configEnabled != newDataStackEnabled) {
Jack Yu2f509862022-01-25 10:13:40 -08002936 getOutPrintWriter().println("The new data config has been "
2937 + (configEnabled ? "enabled" : "disabled")
2938 + ". It will be effective after reboot.");
Jack Yu4c0a5502021-12-03 23:58:26 -08002939 }
2940 return 0;
2941 }
jimsun3b9ccac2021-10-26 15:01:23 +08002942
2943 private int handleRadioSetModemServiceCommand() {
2944 PrintWriter errPw = getErrPrintWriter();
2945 String serviceName = null;
2946
2947 String opt;
2948 while ((opt = getNextOption()) != null) {
2949 switch (opt) {
2950 case "-s": {
2951 serviceName = getNextArgRequired();
2952 break;
2953 }
2954 }
2955 }
2956
2957 try {
2958 boolean result = mInterface.setModemService(serviceName);
2959 if (VDBG) {
2960 Log.v(LOG_TAG,
2961 "RadioSetModemService " + serviceName + ", result = " + result);
2962 }
2963 getOutPrintWriter().println(result);
2964 } catch (RemoteException e) {
2965 Log.w(LOG_TAG,
2966 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2967 errPw.println("Exception: " + e.getMessage());
2968 return -1;
2969 }
2970 return 0;
2971 }
2972
2973 private int handleRadioGetModemServiceCommand() {
2974 PrintWriter errPw = getErrPrintWriter();
2975 String result;
2976
2977 try {
2978 result = mInterface.getModemService();
2979 getOutPrintWriter().println(result);
2980 } catch (RemoteException e) {
2981 errPw.println("Exception: " + e.getMessage());
2982 return -1;
2983 }
2984 if (VDBG) {
2985 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2986 }
2987 return 0;
2988 }
2989
2990 private int handleRadioCommand() {
2991 String arg = getNextArg();
2992 if (arg == null) {
2993 onHelpRadio();
2994 return 0;
2995 }
2996
2997 switch (arg) {
2998 case RADIO_SET_MODEM_SERVICE:
2999 return handleRadioSetModemServiceCommand();
3000
3001 case RADIO_GET_MODEM_SERVICE:
3002 return handleRadioGetModemServiceCommand();
3003 }
3004
3005 return -1;
3006 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003007}