blob: 70912c14af323c049d3321d4e960ad090e7e4aac [file] [log] [blame]
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.phone;
18
Tyler Gunn92479152021-01-20 16:30:10 -080019import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_AUDIO_CODEC;
20import static com.android.internal.telephony.d2d.Communicator.MESSAGE_CALL_RADIO_ACCESS_TYPE;
21import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_BATTERY_STATE;
22import static com.android.internal.telephony.d2d.Communicator.MESSAGE_DEVICE_NETWORK_COVERAGE;
23
Cole Faustc16d5292022-10-15 21:33:27 -070024import static java.util.Map.entry;
25
Hall Liuaa4211e2021-01-20 15:43:39 -080026import android.Manifest;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010027import android.content.Context;
Hall Liuaa4211e2021-01-20 15:43:39 -080028import android.net.Uri;
Hall Liud892bec2018-11-30 14:51:45 -080029import android.os.Binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010030import android.os.PersistableBundle;
Hall Liud892bec2018-11-30 14:51:45 -080031import android.os.Process;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070032import android.os.RemoteException;
Brad Ebinger14d467f2021-02-12 06:18:28 +000033import android.os.ServiceSpecificException;
Shuo Qian489d9282020-07-09 11:30:03 -070034import android.provider.BlockedNumberContract;
Nazanin014f41e2021-05-06 17:26:31 -070035import android.telephony.BarringInfo;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010036import android.telephony.CarrierConfigManager;
Jordan Liu0ccee222021-04-27 11:55:13 -070037import android.telephony.SubscriptionInfo;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070038import android.telephony.SubscriptionManager;
Michele Berionne54af4632020-12-28 20:23:16 +000039import android.telephony.TelephonyManager;
Nazanin014f41e2021-05-06 17:26:31 -070040import android.telephony.TelephonyRegistryManager;
sqian9d4df8b2019-01-15 18:32:07 -080041import android.telephony.emergency.EmergencyNumber;
Brad Ebinger14d467f2021-02-12 06:18:28 +000042import android.telephony.ims.ImsException;
43import android.telephony.ims.RcsContactUceCapability;
Brad Ebinger24c29992019-12-05 13:03:21 -080044import android.telephony.ims.feature.ImsFeature;
James.cf Linbcdf8b32021-01-14 16:44:13 +080045import android.text.TextUtils;
Brad Ebinger14d467f2021-02-12 06:18:28 +000046import android.util.ArrayMap;
47import android.util.ArraySet;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070048import android.util.Log;
Nazanin014f41e2021-05-06 17:26:31 -070049import android.util.SparseArray;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070050
Brad Ebinger14d467f2021-02-12 06:18:28 +000051import com.android.ims.rcs.uce.util.FeatureTags;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070052import com.android.internal.telephony.ITelephony;
Qiong Liuf25799b2020-09-10 10:13:46 +080053import com.android.internal.telephony.Phone;
54import com.android.internal.telephony.PhoneFactory;
Tyler Gunn92479152021-01-20 16:30:10 -080055import com.android.internal.telephony.d2d.Communicator;
sqian9d4df8b2019-01-15 18:32:07 -080056import com.android.internal.telephony.emergency.EmergencyNumberTracker;
Meng Wangc4f61042019-11-21 10:51:05 -080057import com.android.internal.telephony.util.TelephonyUtils;
Chiachang Wang99890092020-11-04 10:59:17 +080058import com.android.modules.utils.BasicShellCommandHandler;
Hall Liuaa4211e2021-01-20 15:43:39 -080059import com.android.phone.callcomposer.CallComposerPictureManager;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070060
Allen Xuee00f0e2022-03-14 21:04:49 +000061import java.io.IOException;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070062import java.io.PrintWriter;
sqian9d4df8b2019-01-15 18:32:07 -080063import java.util.ArrayList;
Brad Ebinger14d467f2021-02-12 06:18:28 +000064import java.util.Arrays;
65import java.util.Collections;
Brad Ebinger24c29992019-12-05 13:03:21 -080066import java.util.List;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010067import java.util.Map;
Brad Ebinger14d467f2021-02-12 06:18:28 +000068import java.util.Set;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010069import java.util.TreeSet;
Hall Liuaa4211e2021-01-20 15:43:39 -080070import java.util.UUID;
71import java.util.concurrent.CompletableFuture;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070072
73/**
74 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
75 * permission checks have been done before onCommand was called. Make sure any commands processed
76 * here also contain the appropriate permissions checks.
77 */
78
Hall Liua1548bd2019-12-24 14:14:12 -080079public class TelephonyShellCommand extends BasicShellCommandHandler {
Brad Ebinger4dc095a2018-04-03 15:17:52 -070080
81 private static final String LOG_TAG = "TelephonyShellCommand";
82 // Don't commit with this true.
83 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070084 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070085
Hall Liuaa4211e2021-01-20 15:43:39 -080086 private static final String CALL_COMPOSER_SUBCOMMAND = "callcomposer";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070087 private static final String IMS_SUBCOMMAND = "ims";
Hall Liud892bec2018-11-30 14:51:45 -080088 private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
Shuo Qianccbaf742021-02-22 18:32:21 -080089 private static final String EMERGENCY_CALLBACK_MODE = "emergency-callback-mode";
sqian9d4df8b2019-01-15 18:32:07 -080090 private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
Shuo Qian489d9282020-07-09 11:30:03 -070091 private static final String END_BLOCK_SUPPRESSION = "end-block-suppression";
Michele Berionne54af4632020-12-28 20:23:16 +000092 private static final String RESTART_MODEM = "restart-modem";
Michele Berionne5e411512020-11-13 02:36:59 +000093 private static final String UNATTENDED_REBOOT = "unattended-reboot";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +010094 private static final String CARRIER_CONFIG_SUBCOMMAND = "cc";
Shuo Qianf5125122019-12-16 17:03:07 -080095 private static final String DATA_TEST_MODE = "data";
Hall Liuaa4211e2021-01-20 15:43:39 -080096 private static final String ENABLE = "enable";
97 private static final String DISABLE = "disable";
98 private static final String QUERY = "query";
Benedict Wong45280102023-02-03 23:30:57 +000099 private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
100 "set-carrier-service-package-override";
101 private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
102 "clear-carrier-service-package-override";
Hall Liuaa4211e2021-01-20 15:43:39 -0800103
Hall Liu7135e502021-02-04 16:58:17 -0800104 private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
Hall Liuaa4211e2021-01-20 15:43:39 -0800105 private static final String CALL_COMPOSER_SIMULATE_CALL = "simulate-outgoing-call";
Hall Liu7917ecf2021-02-23 12:22:31 -0800106 private static final String CALL_COMPOSER_USER_SETTING = "user-setting";
Hall Liud892bec2018-11-30 14:51:45 -0800107
Brad Ebinger999d3302020-11-25 14:31:39 -0800108 private static final String IMS_SET_IMS_SERVICE = "set-ims-service";
109 private static final String IMS_GET_IMS_SERVICE = "get-ims-service";
110 private static final String IMS_CLEAR_SERVICE_OVERRIDE = "clear-ims-service-override";
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700111 // Used to disable or enable processing of conference event package data from the network.
112 // This is handy for testing scenarios where CEP data does not exist on a network which does
113 // support CEP data.
114 private static final String IMS_CEP = "conference-event-package";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700115
Hall Liud892bec2018-11-30 14:51:45 -0800116 private static final String NUMBER_VERIFICATION_OVERRIDE_PACKAGE = "override-package";
Hall Liuca5af3a2018-12-04 16:58:23 -0800117 private static final String NUMBER_VERIFICATION_FAKE_CALL = "fake-call";
Hall Liud892bec2018-11-30 14:51:45 -0800118
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100119 private static final String CC_GET_VALUE = "get-value";
120 private static final String CC_SET_VALUE = "set-value";
Allen Xuee00f0e2022-03-14 21:04:49 +0000121 private static final String CC_SET_VALUES_FROM_XML = "set-values-from-xml";
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100122 private static final String CC_CLEAR_VALUES = "clear-values";
123
Hui Wang641e81c2020-10-12 12:14:23 -0700124 private static final String GBA_SUBCOMMAND = "gba";
125 private static final String GBA_SET_SERVICE = "set-service";
126 private static final String GBA_GET_SERVICE = "get-service";
127 private static final String GBA_SET_RELEASE_TIME = "set-release";
128 private static final String GBA_GET_RELEASE_TIME = "get-release";
129
Hui Wang761a6682020-10-31 05:12:53 +0000130 private static final String SINGLE_REGISTATION_CONFIG = "src";
131 private static final String SRC_SET_DEVICE_ENABLED = "set-device-enabled";
132 private static final String SRC_GET_DEVICE_ENABLED = "get-device-enabled";
133 private static final String SRC_SET_CARRIER_ENABLED = "set-carrier-enabled";
134 private static final String SRC_GET_CARRIER_ENABLED = "get-carrier-enabled";
Hui Wangbaaee6a2021-02-19 20:45:36 -0800135 private static final String SRC_SET_TEST_ENABLED = "set-test-enabled";
136 private static final String SRC_GET_TEST_ENABLED = "get-test-enabled";
Hui Wangb647abe2021-02-26 09:33:38 -0800137 private static final String SRC_SET_FEATURE_ENABLED = "set-feature-validation";
138 private static final String SRC_GET_FEATURE_ENABLED = "get-feature-validation";
Hui Wang761a6682020-10-31 05:12:53 +0000139
Tyler Gunn92479152021-01-20 16:30:10 -0800140 private static final String D2D_SUBCOMMAND = "d2d";
141 private static final String D2D_SEND = "send";
Tyler Gunnbabbda02021-02-10 11:05:02 -0800142 private static final String D2D_TRANSPORT = "transport";
Tyler Gunnd4575212021-05-03 14:46:49 -0700143 private static final String D2D_SET_DEVICE_SUPPORT = "set-device-support";
Tyler Gunn92479152021-01-20 16:30:10 -0800144
Nazanin014f41e2021-05-06 17:26:31 -0700145 private static final String BARRING_SUBCOMMAND = "barring";
146 private static final String BARRING_SEND_INFO = "send";
147
James.cf Linbcdf8b32021-01-14 16:44:13 +0800148 private static final String RCS_UCE_COMMAND = "uce";
calvinpane4a8a1d2021-01-25 13:51:18 +0800149 private static final String UCE_GET_EAB_CONTACT = "get-eab-contact";
Calvin Pana1434322021-07-01 19:27:01 +0800150 private static final String UCE_GET_EAB_CAPABILITY = "get-eab-capability";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800151 private static final String UCE_REMOVE_EAB_CONTACT = "remove-eab-contact";
James.cf Lin4b784aa2021-01-31 03:25:15 +0800152 private static final String UCE_GET_DEVICE_ENABLED = "get-device-enabled";
153 private static final String UCE_SET_DEVICE_ENABLED = "set-device-enabled";
Brad Ebinger14d467f2021-02-12 06:18:28 +0000154 private static final String UCE_OVERRIDE_PUBLISH_CAPS = "override-published-caps";
155 private static final String UCE_GET_LAST_PIDF_XML = "get-last-publish-pidf";
James.cf Line8713a42021-04-29 16:04:26 +0800156 private static final String UCE_REMOVE_REQUEST_DISALLOWED_STATUS =
157 "remove-request-disallowed-status";
James.cf Lin0fc71b02021-05-25 01:37:38 +0800158 private static final String UCE_SET_CAPABILITY_REQUEST_TIMEOUT =
159 "set-capabilities-request-timeout";
James.cf Linbcdf8b32021-01-14 16:44:13 +0800160
jimsun3b9ccac2021-10-26 15:01:23 +0800161 private static final String RADIO_SUBCOMMAND = "radio";
162 private static final String RADIO_SET_MODEM_SERVICE = "set-modem-service";
163 private static final String RADIO_GET_MODEM_SERVICE = "get-modem-service";
164
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800165 // Check if a package has carrier privileges on any SIM, regardless of subId/phoneId.
166 private static final String HAS_CARRIER_PRIVILEGES_COMMAND = "has-carrier-privileges";
167
Jordan Liu0ccee222021-04-27 11:55:13 -0700168 private static final String DISABLE_PHYSICAL_SUBSCRIPTION = "disable-physical-subscription";
169 private static final String ENABLE_PHYSICAL_SUBSCRIPTION = "enable-physical-subscription";
170
Jack Nudelman644b91a2021-03-12 14:09:48 -0800171 private static final String THERMAL_MITIGATION_COMMAND = "thermal-mitigation";
172 private static final String ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "allow-package";
173 private static final String DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND = "disallow-package";
174
SongFerngWang98dd5992021-05-13 17:50:00 +0800175 private static final String GET_ALLOWED_NETWORK_TYPES_FOR_USER =
176 "get-allowed-network-types-for-users";
177 private static final String SET_ALLOWED_NETWORK_TYPES_FOR_USER =
178 "set-allowed-network-types-for-users";
Ling Ma4fbab492022-01-25 22:36:16 +0000179 private static final String GET_IMEI = "get-imei";
Aman Gupta07124872022-02-09 08:02:14 +0000180 private static final String GET_SIM_SLOTS_MAPPING = "get-sim-slots-mapping";
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700181 // Take advantage of existing methods that already contain permissions checks when possible.
182 private final ITelephony mInterface;
183
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100184 private SubscriptionManager mSubscriptionManager;
185 private CarrierConfigManager mCarrierConfigManager;
Nazanin014f41e2021-05-06 17:26:31 -0700186 private TelephonyRegistryManager mTelephonyRegistryManager;
Shuo Qian489d9282020-07-09 11:30:03 -0700187 private Context mContext;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100188
189 private enum CcType {
190 BOOLEAN, DOUBLE, DOUBLE_ARRAY, INT, INT_ARRAY, LONG, LONG_ARRAY, STRING,
Allen Xuee00f0e2022-03-14 21:04:49 +0000191 STRING_ARRAY, PERSISTABLE_BUNDLE, UNKNOWN
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100192 }
193
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100194 private class CcOptionParseResult {
195 public int mSubId;
196 public boolean mPersistent;
197 }
198
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100199 // Maps carrier config keys to type. It is possible to infer the type for most carrier config
200 // keys by looking at the end of the string which usually tells the type.
201 // For instance: "xxxx_string", "xxxx_string_array", etc.
202 // The carrier config keys in this map does not follow this convention. It is therefore not
203 // possible to infer the type for these keys by looking at the string.
Cole Faustc16d5292022-10-15 21:33:27 -0700204 private static final Map<String, CcType> CC_TYPE_MAP = Map.ofEntries(
205 entry(CarrierConfigManager.Gps.KEY_A_GLONASS_POS_PROTOCOL_SELECT_STRING,
206 CcType.STRING),
207 entry(CarrierConfigManager.Gps.KEY_ES_EXTENSION_SEC_STRING, CcType.STRING),
208 entry(CarrierConfigManager.Gps.KEY_GPS_LOCK_STRING, CcType.STRING),
209 entry(CarrierConfigManager.Gps.KEY_LPP_PROFILE_STRING, CcType.STRING),
210 entry(CarrierConfigManager.Gps.KEY_NFW_PROXY_APPS_STRING, CcType.STRING),
211 entry(CarrierConfigManager.Gps.KEY_SUPL_ES_STRING, CcType.STRING),
212 entry(CarrierConfigManager.Gps.KEY_SUPL_HOST_STRING, CcType.STRING),
213 entry(CarrierConfigManager.Gps.KEY_SUPL_MODE_STRING, CcType.STRING),
214 entry(CarrierConfigManager.Gps.KEY_SUPL_PORT_STRING, CcType.STRING),
215 entry(CarrierConfigManager.Gps.KEY_SUPL_VER_STRING, CcType.STRING),
216 entry(CarrierConfigManager.Gps.KEY_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL_STRING,
217 CcType.STRING),
218 entry(CarrierConfigManager.KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
219 CcType.STRING_ARRAY),
220 entry(CarrierConfigManager.KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
221 CcType.STRING_ARRAY),
222 entry(CarrierConfigManager.KEY_CARRIER_CALL_SCREENING_APP_STRING, CcType.STRING),
223 entry(CarrierConfigManager.KEY_MMS_EMAIL_GATEWAY_NUMBER_STRING, CcType.STRING),
224 entry(CarrierConfigManager.KEY_MMS_HTTP_PARAMS_STRING, CcType.STRING),
225 entry(CarrierConfigManager.KEY_MMS_NAI_SUFFIX_STRING, CcType.STRING),
226 entry(CarrierConfigManager.KEY_MMS_UA_PROF_TAG_NAME_STRING, CcType.STRING),
227 entry(CarrierConfigManager.KEY_MMS_UA_PROF_URL_STRING, CcType.STRING),
228 entry(CarrierConfigManager.KEY_MMS_USER_AGENT_STRING, CcType.STRING),
229 entry(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES, CcType.STRING_ARRAY));
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100230
Brad Ebinger14d467f2021-02-12 06:18:28 +0000231 /**
232 * Map from a shorthand string to the feature tags required in registration required in order
233 * for the RCS feature to be considered "capable".
234 */
235 private static final Map<String, Set<String>> TEST_FEATURE_TAG_MAP;
236 static {
237 ArrayMap<String, Set<String>> map = new ArrayMap<>(18);
238 map.put("chat_v1", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_IM));
239 map.put("chat_v2", Collections.singleton(FeatureTags.FEATURE_TAG_CHAT_SESSION));
240 map.put("ft", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER));
241 map.put("ft_sms", Collections.singleton(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS));
242 map.put("mmtel", Collections.singleton(FeatureTags.FEATURE_TAG_MMTEL));
243 map.put("mmtel_vt", new ArraySet<>(Arrays.asList(FeatureTags.FEATURE_TAG_MMTEL,
244 FeatureTags.FEATURE_TAG_VIDEO)));
245 map.put("geo_push", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH));
246 map.put("geo_push_sms", Collections.singleton(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS));
247 map.put("call_comp",
248 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING));
249 map.put("call_comp_mmtel",
250 Collections.singleton(FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY));
251 map.put("call_post", Collections.singleton(FeatureTags.FEATURE_TAG_POST_CALL));
252 map.put("map", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_MAP));
253 map.put("sketch", Collections.singleton(FeatureTags.FEATURE_TAG_SHARED_SKETCH));
254 // Feature tags defined twice for chatbot session because we want v1 and v2 based on bot
255 // version
256 map.put("chatbot", new ArraySet<>(Arrays.asList(
257 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
258 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
259 map.put("chatbot_v2", new ArraySet<>(Arrays.asList(
260 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION,
Hyunho38970ab2022-01-11 12:44:19 +0000261 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000262 map.put("chatbot_sa", new ArraySet<>(Arrays.asList(
263 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
264 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED)));
265 map.put("chatbot_sa_v2", new ArraySet<>(Arrays.asList(
266 FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG,
Hyunho38970ab2022-01-11 12:44:19 +0000267 FeatureTags.FEATURE_TAG_CHATBOT_VERSION_V2_SUPPORTED)));
Brad Ebinger14d467f2021-02-12 06:18:28 +0000268 map.put("chatbot_role", Collections.singleton(FeatureTags.FEATURE_TAG_CHATBOT_ROLE));
269 TEST_FEATURE_TAG_MAP = Collections.unmodifiableMap(map);
270 }
271
272
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100273 public TelephonyShellCommand(ITelephony binder, Context context) {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700274 mInterface = binder;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100275 mCarrierConfigManager =
276 (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
277 mSubscriptionManager = (SubscriptionManager)
278 context.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
Nazanin014f41e2021-05-06 17:26:31 -0700279 mTelephonyRegistryManager = (TelephonyRegistryManager)
280 context.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
Shuo Qian489d9282020-07-09 11:30:03 -0700281 mContext = context;
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700282 }
283
284 @Override
285 public int onCommand(String cmd) {
286 if (cmd == null) {
287 return handleDefaultCommands(null);
288 }
289
290 switch (cmd) {
291 case IMS_SUBCOMMAND: {
292 return handleImsCommand();
293 }
James.cf Linbcdf8b32021-01-14 16:44:13 +0800294 case RCS_UCE_COMMAND:
295 return handleRcsUceCommand();
Hall Liud892bec2018-11-30 14:51:45 -0800296 case NUMBER_VERIFICATION_SUBCOMMAND:
297 return handleNumberVerificationCommand();
Shuo Qianccbaf742021-02-22 18:32:21 -0800298 case EMERGENCY_CALLBACK_MODE:
299 return handleEmergencyCallbackModeCommand();
sqian9d4df8b2019-01-15 18:32:07 -0800300 case EMERGENCY_NUMBER_TEST_MODE:
301 return handleEmergencyNumberTestModeCommand();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100302 case CARRIER_CONFIG_SUBCOMMAND: {
303 return handleCcCommand();
304 }
Shuo Qianf5125122019-12-16 17:03:07 -0800305 case DATA_TEST_MODE:
306 return handleDataTestModeCommand();
Shuo Qian489d9282020-07-09 11:30:03 -0700307 case END_BLOCK_SUPPRESSION:
308 return handleEndBlockSuppressionCommand();
Hui Wang641e81c2020-10-12 12:14:23 -0700309 case GBA_SUBCOMMAND:
310 return handleGbaCommand();
Tyler Gunn92479152021-01-20 16:30:10 -0800311 case D2D_SUBCOMMAND:
312 return handleD2dCommand();
Nazanin014f41e2021-05-06 17:26:31 -0700313 case BARRING_SUBCOMMAND:
314 return handleBarringCommand();
Hui Wang761a6682020-10-31 05:12:53 +0000315 case SINGLE_REGISTATION_CONFIG:
316 return handleSingleRegistrationConfigCommand();
Michele Berionne54af4632020-12-28 20:23:16 +0000317 case RESTART_MODEM:
318 return handleRestartModemCommand();
Hall Liuaa4211e2021-01-20 15:43:39 -0800319 case CALL_COMPOSER_SUBCOMMAND:
320 return handleCallComposerCommand();
Michele Berionne5e411512020-11-13 02:36:59 +0000321 case UNATTENDED_REBOOT:
322 return handleUnattendedReboot();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800323 case HAS_CARRIER_PRIVILEGES_COMMAND:
324 return handleHasCarrierPrivilegesCommand();
Jack Nudelman644b91a2021-03-12 14:09:48 -0800325 case THERMAL_MITIGATION_COMMAND:
326 return handleThermalMitigationCommand();
Jordan Liu0ccee222021-04-27 11:55:13 -0700327 case DISABLE_PHYSICAL_SUBSCRIPTION:
328 return handleEnablePhysicalSubscription(false);
329 case ENABLE_PHYSICAL_SUBSCRIPTION:
330 return handleEnablePhysicalSubscription(true);
SongFerngWang98dd5992021-05-13 17:50:00 +0800331 case GET_ALLOWED_NETWORK_TYPES_FOR_USER:
332 case SET_ALLOWED_NETWORK_TYPES_FOR_USER:
333 return handleAllowedNetworkTypesCommand(cmd);
Ling Ma4fbab492022-01-25 22:36:16 +0000334 case GET_IMEI:
335 return handleGetImei();
Aman Gupta07124872022-02-09 08:02:14 +0000336 case GET_SIM_SLOTS_MAPPING:
337 return handleGetSimSlotsMapping();
jimsun3b9ccac2021-10-26 15:01:23 +0800338 case RADIO_SUBCOMMAND:
339 return handleRadioCommand();
Benedict Wong45280102023-02-03 23:30:57 +0000340 case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
341 return setCarrierServicePackageOverride();
342 case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
343 return clearCarrierServicePackageOverride();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700344 default: {
345 return handleDefaultCommands(cmd);
346 }
347 }
348 }
349
350 @Override
351 public void onHelp() {
352 PrintWriter pw = getOutPrintWriter();
353 pw.println("Telephony Commands:");
354 pw.println(" help");
355 pw.println(" Print this help text.");
356 pw.println(" ims");
357 pw.println(" IMS Commands.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800358 pw.println(" uce");
359 pw.println(" RCS User Capability Exchange Commands.");
sqian9d4df8b2019-01-15 18:32:07 -0800360 pw.println(" emergency-number-test-mode");
361 pw.println(" Emergency Number Test Mode Commands.");
Shuo Qian489d9282020-07-09 11:30:03 -0700362 pw.println(" end-block-suppression");
363 pw.println(" End Block Suppression command.");
Shuo Qianf5125122019-12-16 17:03:07 -0800364 pw.println(" data");
365 pw.println(" Data Test Mode Commands.");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100366 pw.println(" cc");
367 pw.println(" Carrier Config Commands.");
Hui Wang641e81c2020-10-12 12:14:23 -0700368 pw.println(" gba");
369 pw.println(" GBA Commands.");
Hui Wang761a6682020-10-31 05:12:53 +0000370 pw.println(" src");
371 pw.println(" RCS VoLTE Single Registration Config Commands.");
Michele Berionne54af4632020-12-28 20:23:16 +0000372 pw.println(" restart-modem");
373 pw.println(" Restart modem command.");
Michele Berionne5e411512020-11-13 02:36:59 +0000374 pw.println(" unattended-reboot");
375 pw.println(" Prepare for unattended reboot.");
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -0800376 pw.println(" has-carrier-privileges [package]");
377 pw.println(" Query carrier privilege status for a package. Prints true or false.");
SongFerngWang98dd5992021-05-13 17:50:00 +0800378 pw.println(" get-allowed-network-types-for-users");
379 pw.println(" Get the Allowed Network Types.");
380 pw.println(" set-allowed-network-types-for-users");
381 pw.println(" Set the Allowed Network Types.");
jimsun3b9ccac2021-10-26 15:01:23 +0800382 pw.println(" radio");
383 pw.println(" Radio Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700384 onHelpIms();
James.cf Linbcdf8b32021-01-14 16:44:13 +0800385 onHelpUce();
sqian9d4df8b2019-01-15 18:32:07 -0800386 onHelpEmergencyNumber();
Shuo Qian489d9282020-07-09 11:30:03 -0700387 onHelpEndBlockSupperssion();
Shuo Qianf5125122019-12-16 17:03:07 -0800388 onHelpDataTestMode();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100389 onHelpCc();
Hui Wang641e81c2020-10-12 12:14:23 -0700390 onHelpGba();
Hui Wang761a6682020-10-31 05:12:53 +0000391 onHelpSrc();
Tyler Gunn92479152021-01-20 16:30:10 -0800392 onHelpD2D();
Jordan Liu0ccee222021-04-27 11:55:13 -0700393 onHelpDisableOrEnablePhysicalSubscription();
SongFerngWang98dd5992021-05-13 17:50:00 +0800394 onHelpAllowedNetworkTypes();
jimsun3b9ccac2021-10-26 15:01:23 +0800395 onHelpRadio();
Ling Ma4fbab492022-01-25 22:36:16 +0000396 onHelpImei();
Tyler Gunn92479152021-01-20 16:30:10 -0800397 }
398
399 private void onHelpD2D() {
400 PrintWriter pw = getOutPrintWriter();
401 pw.println("D2D Comms Commands:");
402 pw.println(" d2d send TYPE VALUE");
403 pw.println(" Sends a D2D message of specified type and value.");
404 pw.println(" Type: " + MESSAGE_CALL_RADIO_ACCESS_TYPE + " - "
405 + Communicator.messageToString(MESSAGE_CALL_RADIO_ACCESS_TYPE));
406 pw.println(" Type: " + MESSAGE_CALL_AUDIO_CODEC + " - " + Communicator.messageToString(
407 MESSAGE_CALL_AUDIO_CODEC));
408 pw.println(" Type: " + MESSAGE_DEVICE_BATTERY_STATE + " - "
409 + Communicator.messageToString(
410 MESSAGE_DEVICE_BATTERY_STATE));
411 pw.println(" Type: " + MESSAGE_DEVICE_NETWORK_COVERAGE + " - "
412 + Communicator.messageToString(MESSAGE_DEVICE_NETWORK_COVERAGE));
Tyler Gunnbabbda02021-02-10 11:05:02 -0800413 pw.println(" d2d transport TYPE");
414 pw.println(" Forces the specified D2D transport TYPE to be active. Use the");
415 pw.println(" short class name of the transport; i.e. DtmfTransport or RtpTransport.");
Tyler Gunnd4575212021-05-03 14:46:49 -0700416 pw.println(" d2d set-device-support true/default");
417 pw.println(" true - forces device support to be enabled for D2D.");
418 pw.println(" default - clear any previously set force-enable of D2D, reverting to ");
419 pw.println(" the current device's configuration.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700420 }
421
Nazanin014f41e2021-05-06 17:26:31 -0700422 private void onHelpBarring() {
423 PrintWriter pw = getOutPrintWriter();
424 pw.println("Barring Commands:");
425 pw.println(" barring send -s SLOT_ID -b BARRING_TYPE -c IS_CONDITIONALLY_BARRED"
426 + " -t CONDITIONAL_BARRING_TIME_SECS");
427 pw.println(" Notifies of a barring info change for the specified slot id.");
428 pw.println(" BARRING_TYPE: 0 for BARRING_TYPE_NONE");
429 pw.println(" BARRING_TYPE: 1 for BARRING_TYPE_UNCONDITIONAL");
430 pw.println(" BARRING_TYPE: 2 for BARRING_TYPE_CONDITIONAL");
431 pw.println(" BARRING_TYPE: -1 for BARRING_TYPE_UNKNOWN");
432 }
433
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700434 private void onHelpIms() {
435 PrintWriter pw = getOutPrintWriter();
436 pw.println("IMS Commands:");
Brad Ebinger24c29992019-12-05 13:03:21 -0800437 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d | -f) PACKAGE_NAME");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700438 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
439 pw.println(" ImsService. Options are:");
440 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
441 pw.println(" is specified, it will choose the default voice SIM slot.");
442 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
443 pw.println(" -d: Override the ImsService defined in the device overlay.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800444 pw.println(" -f: Set the feature that this override if for, if no option is");
445 pw.println(" specified, the new package name will be used for all features.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700446 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
447 pw.println(" Gets the package name of the currently defined ImsService.");
448 pw.println(" Options are:");
449 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
450 pw.println(" is specified, it will choose the default voice SIM slot.");
451 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
Peter Kalauskas1defdc32020-09-03 19:20:26 +0000452 pw.println(" -d: The ImsService defined as the device default ImsService.");
Brad Ebinger24c29992019-12-05 13:03:21 -0800453 pw.println(" -f: The feature type that the query will be requested for. If none is");
454 pw.println(" specified, the returned package name will correspond to MMTEL.");
Brad Ebinger999d3302020-11-25 14:31:39 -0800455 pw.println(" ims clear-ims-service-override [-s SLOT_ID]");
456 pw.println(" Clear all carrier ImsService overrides. This does not work for device ");
457 pw.println(" configuration overrides. Options are:");
458 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
459 pw.println(" is specified, it will choose the default voice SIM slot.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700460 pw.println(" ims enable [-s SLOT_ID]");
461 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
462 pw.println(" if none is specified.");
463 pw.println(" ims disable [-s SLOT_ID]");
464 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
465 pw.println(" slot if none is specified.");
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700466 pw.println(" ims conference-event-package [enable/disable]");
467 pw.println(" enables or disables handling or network conference event package data.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700468 }
469
James.cf Linbcdf8b32021-01-14 16:44:13 +0800470 private void onHelpUce() {
471 PrintWriter pw = getOutPrintWriter();
472 pw.println("User Capability Exchange Commands:");
calvinpane4a8a1d2021-01-25 13:51:18 +0800473 pw.println(" uce get-eab-contact [PHONE_NUMBER]");
474 pw.println(" Get the EAB contacts from the EAB database.");
475 pw.println(" Options are:");
476 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
477 pw.println(" Expected output format :");
478 pw.println(" [PHONE_NUMBER],[RAW_CONTACT_ID],[CONTACT_ID],[DATA_ID]");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800479 pw.println(" uce remove-eab-contact [-s SLOT_ID] [PHONE_NUMBER]");
480 pw.println(" Remove the EAB contacts from the EAB database.");
481 pw.println(" Options are:");
482 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
483 pw.println(" is specified, it will choose the default voice SIM slot.");
484 pw.println(" PHONE_NUMBER: The phone numbers to be removed from the EAB databases");
James.cf Lin4b784aa2021-01-31 03:25:15 +0800485 pw.println(" uce get-device-enabled");
486 pw.println(" Get the config to check whether the device supports RCS UCE or not.");
487 pw.println(" uce set-device-enabled true|false");
488 pw.println(" Set the device config for RCS User Capability Exchange to the value.");
489 pw.println(" The value could be true, false.");
Brad Ebinger14d467f2021-02-12 06:18:28 +0000490 pw.println(" uce override-published-caps [-s SLOT_ID] add|remove|clear [CAPABILITIES]");
491 pw.println(" Override the existing SIP PUBLISH with different capabilities.");
492 pw.println(" Options are:");
493 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
494 pw.println(" is specified, it will choose the default voice SIM slot.");
495 pw.println(" add [CAPABILITY]: add a new capability");
496 pw.println(" remove [CAPABILITY]: remove a capability");
497 pw.println(" clear: clear all capability overrides");
498 pw.println(" CAPABILITY: \":\" separated list of capabilities.");
499 pw.println(" Valid options are: [mmtel(_vt), chat_v1, chat_v2, ft, ft_sms,");
500 pw.println(" geo_push, geo_push_sms, call_comp, call_post, map, sketch, chatbot,");
501 pw.println(" chatbot_sa, chatbot_role] as well as full length");
502 pw.println(" featureTag=\"featureValue\" feature tags that are not defined here.");
503 pw.println(" uce get-last-publish-pidf [-s SLOT_ID]");
504 pw.println(" Get the PIDF XML included in the last SIP PUBLISH, or \"none\" if no ");
505 pw.println(" PUBLISH is active");
James.cf Line8713a42021-04-29 16:04:26 +0800506 pw.println(" uce remove-request-disallowed-status [-s SLOT_ID]");
507 pw.println(" Remove the UCE is disallowed to execute UCE requests status");
James.cf Lin0fc71b02021-05-25 01:37:38 +0800508 pw.println(" uce set-capabilities-request-timeout [-s SLOT_ID] [REQUEST_TIMEOUT_MS]");
509 pw.println(" Set the timeout for contact capabilities request.");
James.cf Linbcdf8b32021-01-14 16:44:13 +0800510 }
511
Hall Liud892bec2018-11-30 14:51:45 -0800512 private void onHelpNumberVerification() {
513 PrintWriter pw = getOutPrintWriter();
514 pw.println("Number verification commands");
515 pw.println(" numverify override-package PACKAGE_NAME;");
516 pw.println(" Set the authorized package for number verification.");
517 pw.println(" Leave the package name blank to reset.");
Hall Liuca5af3a2018-12-04 16:58:23 -0800518 pw.println(" numverify fake-call NUMBER;");
519 pw.println(" Fake an incoming call from NUMBER. This is for testing. Output will be");
520 pw.println(" 1 if the call would have been intercepted, 0 otherwise.");
Hall Liud892bec2018-11-30 14:51:45 -0800521 }
522
Jack Nudelman644b91a2021-03-12 14:09:48 -0800523 private void onHelpThermalMitigation() {
524 PrintWriter pw = getOutPrintWriter();
525 pw.println("Thermal mitigation commands");
526 pw.println(" thermal-mitigation allow-package PACKAGE_NAME");
527 pw.println(" Set the package as one of authorized packages for thermal mitigation.");
528 pw.println(" thermal-mitigation disallow-package PACKAGE_NAME");
529 pw.println(" Remove the package from one of the authorized packages for thermal "
530 + "mitigation.");
531 }
532
Jordan Liu0ccee222021-04-27 11:55:13 -0700533 private void onHelpDisableOrEnablePhysicalSubscription() {
534 PrintWriter pw = getOutPrintWriter();
535 pw.println("Disable or enable a physical subscription");
536 pw.println(" disable-physical-subscription SUB_ID");
537 pw.println(" Disable the physical subscription with the provided subId, if allowed.");
538 pw.println(" enable-physical-subscription SUB_ID");
539 pw.println(" Enable the physical subscription with the provided subId, if allowed.");
540 }
541
Shuo Qianf5125122019-12-16 17:03:07 -0800542 private void onHelpDataTestMode() {
543 PrintWriter pw = getOutPrintWriter();
544 pw.println("Mobile Data Test Mode Commands:");
545 pw.println(" data enable: enable mobile data connectivity");
546 pw.println(" data disable: disable mobile data connectivity");
547 }
548
sqian9d4df8b2019-01-15 18:32:07 -0800549 private void onHelpEmergencyNumber() {
550 PrintWriter pw = getOutPrintWriter();
551 pw.println("Emergency Number Test Mode Commands:");
552 pw.println(" emergency-number-test-mode ");
553 pw.println(" Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
554 + " the test mode");
555 pw.println(" -a <emergency number address>: add an emergency number address for the"
sqian9121f982019-03-14 19:45:39 -0700556 + " test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800557 pw.println(" -c: clear the emergency number list in the test mode.");
558 pw.println(" -r <emergency number address>: remove an existing emergency number"
sqian9121f982019-03-14 19:45:39 -0700559 + " address added by the test mode, only allows '0'-'9', '*', '#' or '+'.");
sqian9d4df8b2019-01-15 18:32:07 -0800560 pw.println(" -p: get the full emergency number list in the test mode.");
561 }
562
Shuo Qian489d9282020-07-09 11:30:03 -0700563 private void onHelpEndBlockSupperssion() {
564 PrintWriter pw = getOutPrintWriter();
565 pw.println("End Block Suppression command:");
566 pw.println(" end-block-suppression: disable suppressing blocking by contact");
567 pw.println(" with emergency services.");
568 }
569
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100570 private void onHelpCc() {
571 PrintWriter pw = getOutPrintWriter();
572 pw.println("Carrier Config Commands:");
573 pw.println(" cc get-value [-s SLOT_ID] [KEY]");
574 pw.println(" Print carrier config values.");
575 pw.println(" Options are:");
576 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
577 pw.println(" is specified, it will choose the default voice SIM slot.");
578 pw.println(" KEY: The key to the carrier config value to print. All values are printed");
579 pw.println(" if KEY is not specified.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100580 pw.println(" cc set-value [-s SLOT_ID] [-p] KEY [NEW_VALUE]");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100581 pw.println(" Set carrier config KEY to NEW_VALUE.");
582 pw.println(" Options are:");
583 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
584 pw.println(" is specified, it will choose the default voice SIM slot.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +0100585 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100586 pw.println(" NEW_VALUE specifies the new value for carrier config KEY. Null will be");
587 pw.println(" used if NEW_VALUE is not set. Strings should be encapsulated with");
588 pw.println(" quotation marks. Spaces needs to be escaped. Example: \"Hello\\ World\"");
589 pw.println(" Separate items in arrays with space . Example: \"item1\" \"item2\"");
Allen Xuee00f0e2022-03-14 21:04:49 +0000590 pw.println(" cc set-values-from-xml [-s SLOT_ID] [-p] < XML_FILE_PATH");
591 pw.println(" Set carrier config based on the contents of the XML_FILE. File must be");
592 pw.println(" provided through standard input and follow CarrierConfig XML format.");
593 pw.println(" Example: packages/apps/CarrierConfig/assets/*.xml");
594 pw.println(" Options are:");
595 pw.println(" -s: The SIM slot ID to set carrier config value for. If no option");
596 pw.println(" is specified, it will choose the default voice SIM slot.");
597 pw.println(" -p: Value will be stored persistent");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100598 pw.println(" cc clear-values [-s SLOT_ID]");
599 pw.println(" Clear all carrier override values that has previously been set");
Allen Xuee00f0e2022-03-14 21:04:49 +0000600 pw.println(" with set-value or set-values-from-xml");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +0100601 pw.println(" Options are:");
602 pw.println(" -s: The SIM slot ID to clear carrier config values for. If no option");
603 pw.println(" is specified, it will choose the default voice SIM slot.");
604 }
605
Hui Wang641e81c2020-10-12 12:14:23 -0700606 private void onHelpGba() {
607 PrintWriter pw = getOutPrintWriter();
608 pw.println("Gba Commands:");
609 pw.println(" gba set-service [-s SLOT_ID] PACKAGE_NAME");
610 pw.println(" Sets the GbaService defined in PACKAGE_NAME to to be the bound.");
611 pw.println(" Options are:");
612 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
613 pw.println(" is specified, it will choose the default voice SIM slot.");
614 pw.println(" gba get-service [-s SLOT_ID]");
615 pw.println(" Gets the package name of the currently defined GbaService.");
616 pw.println(" Options are:");
617 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
618 pw.println(" is specified, it will choose the default voice SIM slot.");
619 pw.println(" gba set-release [-s SLOT_ID] n");
620 pw.println(" Sets the time to release/unbind GbaService in n milli-second.");
621 pw.println(" Do not release/unbind if n is -1.");
622 pw.println(" Options are:");
623 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
624 pw.println(" is specified, it will choose the default voice SIM slot.");
625 pw.println(" gba get-release [-s SLOT_ID]");
626 pw.println(" Gets the time to release/unbind GbaService in n milli-sencond.");
627 pw.println(" Options are:");
628 pw.println(" -s: The SIM slot ID to read carrier config value for. If no option");
629 pw.println(" is specified, it will choose the default voice SIM slot.");
630 }
631
Hui Wang761a6682020-10-31 05:12:53 +0000632 private void onHelpSrc() {
633 PrintWriter pw = getOutPrintWriter();
634 pw.println("RCS VoLTE Single Registration Config Commands:");
Hui Wangbaaee6a2021-02-19 20:45:36 -0800635 pw.println(" src set-test-enabled true|false");
636 pw.println(" Sets the test mode enabled for RCS VoLTE single registration.");
637 pw.println(" The value could be true, false, or null(undefined).");
638 pw.println(" src get-test-enabled");
639 pw.println(" Gets the test mode for RCS VoLTE single registration.");
Hui Wang761a6682020-10-31 05:12:53 +0000640 pw.println(" src set-device-enabled true|false|null");
641 pw.println(" Sets the device config for RCS VoLTE single registration to the value.");
642 pw.println(" The value could be true, false, or null(undefined).");
643 pw.println(" src get-device-enabled");
644 pw.println(" Gets the device config for RCS VoLTE single registration.");
645 pw.println(" src set-carrier-enabled [-s SLOT_ID] true|false|null");
646 pw.println(" Sets the carrier config for RCS VoLTE single registration to the value.");
647 pw.println(" The value could be true, false, or null(undefined).");
648 pw.println(" Options are:");
649 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
650 pw.println(" is specified, it will choose the default voice SIM slot.");
651 pw.println(" src get-carrier-enabled [-s SLOT_ID]");
652 pw.println(" Gets the carrier config for RCS VoLTE single registration.");
653 pw.println(" Options are:");
654 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
655 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wangb647abe2021-02-26 09:33:38 -0800656 pw.println(" src set-feature-validation [-s SLOT_ID] true|false|null");
657 pw.println(" Sets ims feature validation result.");
658 pw.println(" The value could be true, false, or null(undefined).");
659 pw.println(" Options are:");
660 pw.println(" -s: The SIM slot ID to set the config value for. If no option");
661 pw.println(" is specified, it will choose the default voice SIM slot.");
662 pw.println(" src get-feature-validation [-s SLOT_ID]");
663 pw.println(" Gets ims feature validation override value.");
664 pw.println(" Options are:");
665 pw.println(" -s: The SIM slot ID to read the config value for. If no option");
666 pw.println(" is specified, it will choose the default voice SIM slot.");
Hui Wang761a6682020-10-31 05:12:53 +0000667 }
668
SongFerngWang98dd5992021-05-13 17:50:00 +0800669 private void onHelpAllowedNetworkTypes() {
670 PrintWriter pw = getOutPrintWriter();
671 pw.println("Allowed Network Types Commands:");
672 pw.println(" get-allowed-network-types-for-users [-s SLOT_ID]");
673 pw.println(" Print allowed network types value.");
674 pw.println(" Options are:");
675 pw.println(" -s: The SIM slot ID to read allowed network types value for. If no");
676 pw.println(" option is specified, it will choose the default voice SIM slot.");
677 pw.println(" set-allowed-network-types-for-users [-s SLOT_ID] [NETWORK_TYPES_BITMASK]");
678 pw.println(" Sets allowed network types to NETWORK_TYPES_BITMASK.");
679 pw.println(" Options are:");
680 pw.println(" -s: The SIM slot ID to set allowed network types value for. If no");
681 pw.println(" option is specified, it will choose the default voice SIM slot.");
682 pw.println(" NETWORK_TYPES_BITMASK specifies the new network types value and this type");
683 pw.println(" is bitmask in binary format. Reference the NetworkTypeBitMask");
684 pw.println(" at TelephonyManager.java");
685 pw.println(" For example:");
686 pw.println(" NR only : 10000000000000000000");
687 pw.println(" NR|LTE : 11000001000000000000");
688 pw.println(" NR|LTE|CDMA|EVDO|GSM|WCDMA : 11001111101111111111");
689 pw.println(" LTE|CDMA|EVDO|GSM|WCDMA : 01001111101111111111");
690 pw.println(" LTE only : 01000001000000000000");
691 }
692
jimsun3b9ccac2021-10-26 15:01:23 +0800693 private void onHelpRadio() {
694 PrintWriter pw = getOutPrintWriter();
695 pw.println("Radio Commands:");
696 pw.println(" radio set-modem-service [-s SERVICE_NAME]");
697 pw.println(" Sets the class name of modem service defined in SERVICE_NAME");
698 pw.println(" to be the bound. Options are:");
699 pw.println(" -s: the service name that the modem service should be bound for.");
700 pw.println(" If no option is specified, it will bind to the default.");
701 pw.println(" radio get-modem-service");
702 pw.println(" Gets the service name of the currently defined modem service.");
703 pw.println(" If it is binding to default, 'default' returns.");
704 pw.println(" If it doesn't bind to any modem service for some reasons,");
705 pw.println(" the result would be 'unknown'.");
706 }
707
Ling Ma4fbab492022-01-25 22:36:16 +0000708 private void onHelpImei() {
709 PrintWriter pw = getOutPrintWriter();
710 pw.println("IMEI Commands:");
711 pw.println(" get-imei [-s SLOT_ID]");
712 pw.println(" Gets the device IMEI. Options are:");
713 pw.println(" -s: the slot ID to get the IMEI. If no option");
714 pw.println(" is specified, it will choose the default voice SIM slot.");
715 }
716
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700717 private int handleImsCommand() {
718 String arg = getNextArg();
719 if (arg == null) {
720 onHelpIms();
721 return 0;
722 }
723
724 switch (arg) {
Brad Ebinger999d3302020-11-25 14:31:39 -0800725 case IMS_SET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700726 return handleImsSetServiceCommand();
727 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800728 case IMS_GET_IMS_SERVICE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700729 return handleImsGetServiceCommand();
730 }
Brad Ebinger999d3302020-11-25 14:31:39 -0800731 case IMS_CLEAR_SERVICE_OVERRIDE: {
732 return handleImsClearCarrierServiceCommand();
733 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800734 case ENABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700735 return handleEnableIms();
736 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800737 case DISABLE: {
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700738 return handleDisableIms();
739 }
Tyler Gunn7bcdc742019-10-04 15:56:59 -0700740 case IMS_CEP: {
741 return handleCepChange();
742 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700743 }
744
745 return -1;
746 }
747
Shuo Qianf5125122019-12-16 17:03:07 -0800748 private int handleDataTestModeCommand() {
749 PrintWriter errPw = getErrPrintWriter();
750 String arg = getNextArgRequired();
751 if (arg == null) {
752 onHelpDataTestMode();
753 return 0;
754 }
755 switch (arg) {
Hall Liuaa4211e2021-01-20 15:43:39 -0800756 case ENABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800757 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700758 mInterface.enableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800759 } catch (RemoteException ex) {
760 Log.w(LOG_TAG, "data enable, error " + ex.getMessage());
761 errPw.println("Exception: " + ex.getMessage());
762 return -1;
763 }
764 break;
765 }
Hall Liuaa4211e2021-01-20 15:43:39 -0800766 case DISABLE: {
Shuo Qianf5125122019-12-16 17:03:07 -0800767 try {
Sarah Chinecc78c42022-03-31 21:16:48 -0700768 mInterface.disableDataConnectivity(mContext.getOpPackageName());
Shuo Qianf5125122019-12-16 17:03:07 -0800769 } catch (RemoteException ex) {
770 Log.w(LOG_TAG, "data disable, error " + ex.getMessage());
771 errPw.println("Exception: " + ex.getMessage());
772 return -1;
773 }
774 break;
775 }
776 default:
777 onHelpDataTestMode();
778 break;
779 }
780 return 0;
781 }
782
Shuo Qianccbaf742021-02-22 18:32:21 -0800783 private int handleEmergencyCallbackModeCommand() {
784 PrintWriter errPw = getErrPrintWriter();
785 try {
786 mInterface.startEmergencyCallbackMode();
787 Log.d(LOG_TAG, "handleEmergencyCallbackModeCommand: triggered");
788 } catch (RemoteException ex) {
789 Log.w(LOG_TAG, "emergency-callback-mode error: " + ex.getMessage());
790 errPw.println("Exception: " + ex.getMessage());
791 return -1;
792 }
793 return 0;
794 }
795
sqian9d4df8b2019-01-15 18:32:07 -0800796 private int handleEmergencyNumberTestModeCommand() {
797 PrintWriter errPw = getErrPrintWriter();
798 String opt = getNextOption();
799 if (opt == null) {
800 onHelpEmergencyNumber();
801 return 0;
802 }
803
804 switch (opt) {
805 case "-a": {
806 String emergencyNumberCmd = getNextArgRequired();
807 if (emergencyNumberCmd == null
808 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700809 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800810 + " to be specified after -a in the command ");
811 return -1;
812 }
813 try {
814 mInterface.updateEmergencyNumberListTestMode(
815 EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
816 new EmergencyNumber(emergencyNumberCmd, "", "",
817 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
818 new ArrayList<String>(),
819 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
820 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
821 } catch (RemoteException ex) {
822 Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
823 + ", error " + ex.getMessage());
824 errPw.println("Exception: " + ex.getMessage());
825 return -1;
826 }
827 break;
828 }
829 case "-c": {
830 try {
831 mInterface.updateEmergencyNumberListTestMode(
832 EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
833 } catch (RemoteException ex) {
834 Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
835 errPw.println("Exception: " + ex.getMessage());
836 return -1;
837 }
838 break;
839 }
840 case "-r": {
841 String emergencyNumberCmd = getNextArgRequired();
842 if (emergencyNumberCmd == null
843 || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
sqian9121f982019-03-14 19:45:39 -0700844 errPw.println("An emergency number (only allow '0'-'9', '*', '#' or '+') needs"
sqian9d4df8b2019-01-15 18:32:07 -0800845 + " to be specified after -r in the command ");
846 return -1;
847 }
848 try {
849 mInterface.updateEmergencyNumberListTestMode(
850 EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
851 new EmergencyNumber(emergencyNumberCmd, "", "",
852 EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
853 new ArrayList<String>(),
854 EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
855 EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
856 } catch (RemoteException ex) {
857 Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
858 + ", error " + ex.getMessage());
859 errPw.println("Exception: " + ex.getMessage());
860 return -1;
861 }
862 break;
863 }
864 case "-p": {
865 try {
866 getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
867 } catch (RemoteException ex) {
868 Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
869 errPw.println("Exception: " + ex.getMessage());
870 return -1;
871 }
872 break;
873 }
874 default:
875 onHelpEmergencyNumber();
876 break;
877 }
878 return 0;
879 }
880
Hall Liud892bec2018-11-30 14:51:45 -0800881 private int handleNumberVerificationCommand() {
882 String arg = getNextArg();
883 if (arg == null) {
884 onHelpNumberVerification();
885 return 0;
886 }
887
Hall Liuca5af3a2018-12-04 16:58:23 -0800888 if (!checkShellUid()) {
889 return -1;
890 }
891
Hall Liud892bec2018-11-30 14:51:45 -0800892 switch (arg) {
893 case NUMBER_VERIFICATION_OVERRIDE_PACKAGE: {
Hall Liud892bec2018-11-30 14:51:45 -0800894 NumberVerificationManager.overrideAuthorizedPackage(getNextArg());
895 return 0;
896 }
Hall Liuca5af3a2018-12-04 16:58:23 -0800897 case NUMBER_VERIFICATION_FAKE_CALL: {
898 boolean val = NumberVerificationManager.getInstance()
899 .checkIncomingCall(getNextArg());
900 getOutPrintWriter().println(val ? "1" : "0");
901 return 0;
902 }
Hall Liud892bec2018-11-30 14:51:45 -0800903 }
904
905 return -1;
906 }
907
Jordan Liu0ccee222021-04-27 11:55:13 -0700908 private boolean subIsEsim(int subId) {
909 SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(subId);
910 if (info != null) {
911 return info.isEmbedded();
912 }
913 return false;
914 }
915
916 private int handleEnablePhysicalSubscription(boolean enable) {
917 PrintWriter errPw = getErrPrintWriter();
918 int subId = 0;
919 try {
920 subId = Integer.parseInt(getNextArgRequired());
921 } catch (NumberFormatException e) {
922 errPw.println((enable ? "enable" : "disable")
923 + "-physical-subscription requires an integer as a subId.");
924 return -1;
925 }
926 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
927 // non user build.
928 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
929 errPw.println("cc: Permission denied.");
930 return -1;
931 }
932 // Verify that the subId represents a physical sub
933 if (subIsEsim(subId)) {
934 errPw.println("SubId " + subId + " is not for a physical subscription");
935 return -1;
936 }
937 Log.d(LOG_TAG, (enable ? "Enabling" : "Disabling")
938 + " physical subscription with subId=" + subId);
939 mSubscriptionManager.setUiccApplicationsEnabled(subId, enable);
940 return 0;
941 }
942
Jack Nudelman644b91a2021-03-12 14:09:48 -0800943 private int handleThermalMitigationCommand() {
944 String arg = getNextArg();
945 String packageName = getNextArg();
946 if (arg == null || packageName == null) {
947 onHelpThermalMitigation();
948 return 0;
949 }
950
951 if (!checkShellUid()) {
952 return -1;
953 }
954
955 switch (arg) {
956 case ALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
957 PhoneInterfaceManager.addPackageToThermalMitigationAllowlist(packageName, mContext);
958 return 0;
959 }
960 case DISALLOW_THERMAL_MITIGATION_PACKAGE_SUBCOMMAND: {
961 PhoneInterfaceManager.removePackageFromThermalMitigationAllowlist(packageName,
962 mContext);
963 return 0;
964 }
965 default:
966 onHelpThermalMitigation();
967 }
968
969 return -1;
970
971 }
972
Tyler Gunn92479152021-01-20 16:30:10 -0800973 private int handleD2dCommand() {
974 String arg = getNextArg();
975 if (arg == null) {
976 onHelpD2D();
977 return 0;
978 }
979
980 switch (arg) {
981 case D2D_SEND: {
982 return handleD2dSendCommand();
983 }
Tyler Gunnbabbda02021-02-10 11:05:02 -0800984 case D2D_TRANSPORT: {
985 return handleD2dTransportCommand();
986 }
Tyler Gunnd4575212021-05-03 14:46:49 -0700987 case D2D_SET_DEVICE_SUPPORT: {
988 return handleD2dDeviceSupportedCommand();
989 }
Tyler Gunn92479152021-01-20 16:30:10 -0800990 }
991
992 return -1;
993 }
994
995 private int handleD2dSendCommand() {
996 PrintWriter errPw = getErrPrintWriter();
Tyler Gunn92479152021-01-20 16:30:10 -0800997 int messageType = -1;
998 int messageValue = -1;
999
Tyler Gunn92479152021-01-20 16:30:10 -08001000 String arg = getNextArg();
1001 if (arg == null) {
1002 onHelpD2D();
1003 return 0;
1004 }
1005 try {
1006 messageType = Integer.parseInt(arg);
1007 } catch (NumberFormatException e) {
1008 errPw.println("message type must be a valid integer");
1009 return -1;
1010 }
1011
1012 arg = getNextArg();
1013 if (arg == null) {
1014 onHelpD2D();
1015 return 0;
1016 }
1017 try {
1018 messageValue = Integer.parseInt(arg);
1019 } catch (NumberFormatException e) {
1020 errPw.println("message value must be a valid integer");
1021 return -1;
1022 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08001023
Tyler Gunn92479152021-01-20 16:30:10 -08001024 try {
1025 mInterface.sendDeviceToDeviceMessage(messageType, messageValue);
1026 } catch (RemoteException e) {
1027 Log.w(LOG_TAG, "d2d send error: " + e.getMessage());
1028 errPw.println("Exception: " + e.getMessage());
1029 return -1;
1030 }
1031
1032 return 0;
1033 }
1034
Tyler Gunnbabbda02021-02-10 11:05:02 -08001035 private int handleD2dTransportCommand() {
1036 PrintWriter errPw = getErrPrintWriter();
1037
1038 String arg = getNextArg();
1039 if (arg == null) {
1040 onHelpD2D();
1041 return 0;
1042 }
1043
1044 try {
1045 mInterface.setActiveDeviceToDeviceTransport(arg);
1046 } catch (RemoteException e) {
1047 Log.w(LOG_TAG, "d2d transport error: " + e.getMessage());
1048 errPw.println("Exception: " + e.getMessage());
1049 return -1;
1050 }
1051 return 0;
1052 }
Nazanin014f41e2021-05-06 17:26:31 -07001053 private int handleBarringCommand() {
1054 String arg = getNextArg();
1055 if (arg == null) {
1056 onHelpBarring();
1057 return 0;
1058 }
1059
1060 switch (arg) {
1061 case BARRING_SEND_INFO: {
1062 return handleBarringSendCommand();
1063 }
1064 }
1065 return -1;
1066 }
1067
1068 private int handleBarringSendCommand() {
1069 PrintWriter errPw = getErrPrintWriter();
1070 int slotId = getDefaultSlot();
Jack Yude40a3f2022-11-19 22:29:12 -08001071 int subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001072 @BarringInfo.BarringServiceInfo.BarringType int barringType =
1073 BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
1074 boolean isConditionallyBarred = false;
1075 int conditionalBarringTimeSeconds = 0;
1076
1077 String opt;
1078 while ((opt = getNextOption()) != null) {
1079 switch (opt) {
1080 case "-s": {
1081 try {
1082 slotId = Integer.parseInt(getNextArgRequired());
Jack Yude40a3f2022-11-19 22:29:12 -08001083 subId = SubscriptionManager.getSubscriptionId(slotId);
Nazanin014f41e2021-05-06 17:26:31 -07001084 } catch (NumberFormatException e) {
1085 errPw.println("barring send requires an integer as a SLOT_ID.");
1086 return -1;
1087 }
1088 break;
1089 }
1090 case "-b": {
1091 try {
1092 barringType = Integer.parseInt(getNextArgRequired());
1093 if (barringType < -1 || barringType > 2) {
1094 throw new NumberFormatException();
1095 }
1096
1097 } catch (NumberFormatException e) {
1098 errPw.println("barring send requires an integer in range [-1,2] as "
1099 + "a BARRING_TYPE.");
1100 return -1;
1101 }
1102 break;
1103 }
1104 case "-c": {
1105 try {
1106 isConditionallyBarred = Boolean.parseBoolean(getNextArgRequired());
1107 } catch (Exception e) {
1108 errPw.println("barring send requires a boolean after -c indicating"
1109 + " conditional barring");
1110 return -1;
1111 }
1112 break;
1113 }
1114 case "-t": {
1115 try {
1116 conditionalBarringTimeSeconds = Integer.parseInt(getNextArgRequired());
1117 } catch (NumberFormatException e) {
1118 errPw.println("barring send requires an integer for time of barring"
1119 + " in seconds after -t for conditional barring");
1120 return -1;
1121 }
1122 break;
1123 }
1124 }
1125 }
1126 SparseArray<BarringInfo.BarringServiceInfo> barringServiceInfos = new SparseArray<>();
1127 BarringInfo.BarringServiceInfo bsi = new BarringInfo.BarringServiceInfo(
1128 barringType, isConditionallyBarred, 0, conditionalBarringTimeSeconds);
1129 barringServiceInfos.append(0, bsi);
1130 BarringInfo barringInfo = new BarringInfo(null, barringServiceInfos);
1131 try {
1132 mTelephonyRegistryManager.notifyBarringInfoChanged(slotId, subId, barringInfo);
1133 } catch (Exception e) {
1134 Log.w(LOG_TAG, "barring send error: " + e.getMessage());
1135 errPw.println("Exception: " + e.getMessage());
1136 return -1;
1137 }
1138 return 0;
1139 }
Tyler Gunnbabbda02021-02-10 11:05:02 -08001140
Tyler Gunnd4575212021-05-03 14:46:49 -07001141 private int handleD2dDeviceSupportedCommand() {
1142 PrintWriter errPw = getErrPrintWriter();
1143
1144 String arg = getNextArg();
1145 if (arg == null) {
1146 onHelpD2D();
1147 return 0;
1148 }
1149
1150 boolean isEnabled = "true".equals(arg.toLowerCase());
1151 try {
1152 mInterface.setDeviceToDeviceForceEnabled(isEnabled);
1153 } catch (RemoteException e) {
1154 Log.w(LOG_TAG, "Error forcing D2D enabled: " + e.getMessage());
1155 errPw.println("Exception: " + e.getMessage());
1156 return -1;
1157 }
1158 return 0;
1159 }
1160
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001161 // ims set-ims-service
1162 private int handleImsSetServiceCommand() {
1163 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001164 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001165 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001166 List<Integer> featuresList = new ArrayList<>();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001167
1168 String opt;
1169 while ((opt = getNextOption()) != null) {
1170 switch (opt) {
1171 case "-s": {
1172 try {
1173 slotId = Integer.parseInt(getNextArgRequired());
1174 } catch (NumberFormatException e) {
1175 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1176 return -1;
1177 }
1178 break;
1179 }
1180 case "-c": {
1181 isCarrierService = true;
1182 break;
1183 }
1184 case "-d": {
1185 isCarrierService = false;
1186 break;
1187 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001188 case "-f": {
1189 String featureString = getNextArgRequired();
1190 String[] features = featureString.split(",");
1191 for (int i = 0; i < features.length; i++) {
1192 try {
1193 Integer result = Integer.parseInt(features[i]);
1194 if (result < ImsFeature.FEATURE_EMERGENCY_MMTEL
1195 || result >= ImsFeature.FEATURE_MAX) {
1196 errPw.println("ims set-ims-service -f " + result
1197 + " is an invalid feature.");
1198 return -1;
1199 }
1200 featuresList.add(result);
1201 } catch (NumberFormatException e) {
1202 errPw.println("ims set-ims-service -f tried to parse " + features[i]
1203 + " as an integer.");
1204 return -1;
1205 }
1206 }
1207 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001208 }
1209 }
1210 // Mandatory param, either -c or -d
1211 if (isCarrierService == null) {
1212 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
1213 return -1;
1214 }
1215
1216 String packageName = getNextArg();
1217
1218 try {
1219 if (packageName == null) {
1220 packageName = "";
1221 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001222 int[] featureArray = new int[featuresList.size()];
1223 for (int i = 0; i < featuresList.size(); i++) {
1224 featureArray[i] = featuresList.get(i);
1225 }
1226 boolean result = mInterface.setBoundImsServiceOverride(slotId, isCarrierService,
1227 featureArray, packageName);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001228 if (VDBG) {
1229 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001230 + (isCarrierService ? "-c " : "-d ")
1231 + "-f " + featuresList + " "
1232 + packageName + ", result=" + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001233 }
1234 getOutPrintWriter().println(result);
1235 } catch (RemoteException e) {
1236 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001237 + (isCarrierService ? "-c " : "-d ")
1238 + "-f " + featuresList + " "
1239 + packageName + ", error" + e.getMessage());
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001240 errPw.println("Exception: " + e.getMessage());
1241 return -1;
1242 }
1243 return 0;
1244 }
1245
Brad Ebinger999d3302020-11-25 14:31:39 -08001246 // ims clear-ims-service-override
1247 private int handleImsClearCarrierServiceCommand() {
1248 PrintWriter errPw = getErrPrintWriter();
1249 int slotId = getDefaultSlot();
1250
1251 String opt;
1252 while ((opt = getNextOption()) != null) {
1253 switch (opt) {
1254 case "-s": {
1255 try {
1256 slotId = Integer.parseInt(getNextArgRequired());
1257 } catch (NumberFormatException e) {
1258 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1259 return -1;
1260 }
1261 break;
1262 }
1263 }
1264 }
1265
1266 try {
1267 boolean result = mInterface.clearCarrierImsServiceOverride(slotId);
1268 if (VDBG) {
1269 Log.v(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1270 + ", result=" + result);
1271 }
1272 getOutPrintWriter().println(result);
1273 } catch (RemoteException e) {
1274 Log.w(LOG_TAG, "ims clear-ims-service-override -s " + slotId
1275 + ", error" + e.getMessage());
1276 errPw.println("Exception: " + e.getMessage());
1277 return -1;
1278 }
1279 return 0;
1280 }
1281
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001282 // ims get-ims-service
1283 private int handleImsGetServiceCommand() {
1284 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001285 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001286 Boolean isCarrierService = null;
Brad Ebinger24c29992019-12-05 13:03:21 -08001287 Integer featureType = ImsFeature.FEATURE_MMTEL;
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001288
1289 String opt;
1290 while ((opt = getNextOption()) != null) {
1291 switch (opt) {
1292 case "-s": {
1293 try {
1294 slotId = Integer.parseInt(getNextArgRequired());
1295 } catch (NumberFormatException e) {
1296 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
1297 return -1;
1298 }
1299 break;
1300 }
1301 case "-c": {
1302 isCarrierService = true;
1303 break;
1304 }
1305 case "-d": {
1306 isCarrierService = false;
1307 break;
1308 }
Brad Ebinger24c29992019-12-05 13:03:21 -08001309 case "-f": {
1310 try {
1311 featureType = Integer.parseInt(getNextArg());
1312 } catch (NumberFormatException e) {
1313 errPw.println("ims get-ims-service -f requires valid integer as feature.");
1314 return -1;
1315 }
1316 if (featureType < ImsFeature.FEATURE_EMERGENCY_MMTEL
1317 || featureType >= ImsFeature.FEATURE_MAX) {
1318 errPw.println("ims get-ims-service -f invalid feature.");
1319 return -1;
1320 }
1321 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001322 }
1323 }
1324 // Mandatory param, either -c or -d
1325 if (isCarrierService == null) {
Brad Ebinger24c29992019-12-05 13:03:21 -08001326 errPw.println("ims get-ims-service requires either \"-c\" or \"-d\" to be set.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001327 return -1;
1328 }
1329
1330 String result;
1331 try {
Brad Ebinger24c29992019-12-05 13:03:21 -08001332 result = mInterface.getBoundImsServicePackage(slotId, isCarrierService, featureType);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001333 } catch (RemoteException e) {
1334 return -1;
1335 }
1336 if (VDBG) {
1337 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
Brad Ebinger24c29992019-12-05 13:03:21 -08001338 + (isCarrierService ? "-c " : "-d ")
1339 + (featureType != null ? ("-f " + featureType) : "") + " , returned: "
1340 + result);
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001341 }
1342 getOutPrintWriter().println(result);
1343 return 0;
1344 }
1345
1346 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001347 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001348 String opt;
1349 while ((opt = getNextOption()) != null) {
1350 switch (opt) {
1351 case "-s": {
1352 try {
1353 slotId = Integer.parseInt(getNextArgRequired());
1354 } catch (NumberFormatException e) {
1355 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
1356 return -1;
1357 }
1358 break;
1359 }
1360 }
1361 }
1362 try {
1363 mInterface.enableIms(slotId);
1364 } catch (RemoteException e) {
1365 return -1;
1366 }
1367 if (VDBG) {
1368 Log.v(LOG_TAG, "ims enable -s " + slotId);
1369 }
1370 return 0;
1371 }
1372
1373 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001374 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -07001375 String opt;
1376 while ((opt = getNextOption()) != null) {
1377 switch (opt) {
1378 case "-s": {
1379 try {
1380 slotId = Integer.parseInt(getNextArgRequired());
1381 } catch (NumberFormatException e) {
1382 getErrPrintWriter().println(
1383 "ims disable requires an integer as a SLOT_ID.");
1384 return -1;
1385 }
1386 break;
1387 }
1388 }
1389 }
1390 try {
1391 mInterface.disableIms(slotId);
1392 } catch (RemoteException e) {
1393 return -1;
1394 }
1395 if (VDBG) {
1396 Log.v(LOG_TAG, "ims disable -s " + slotId);
1397 }
1398 return 0;
1399 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001400
Tyler Gunn7bcdc742019-10-04 15:56:59 -07001401 private int handleCepChange() {
1402 Log.i(LOG_TAG, "handleCepChange");
1403 String opt = getNextArg();
1404 if (opt == null) {
1405 return -1;
1406 }
1407 boolean isCepEnabled = opt.equals("enable");
1408
1409 try {
1410 mInterface.setCepEnabled(isCepEnabled);
1411 } catch (RemoteException e) {
1412 return -1;
1413 }
1414 return 0;
1415 }
1416
Brad Ebinger0aa2f242018-04-12 09:49:23 -07001417 private int getDefaultSlot() {
1418 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
1419 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
1420 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
1421 // If there is no default, default to slot 0.
1422 slotId = DEFAULT_PHONE_ID;
1423 }
1424 return slotId;
1425 }
sqian2fff4a32018-11-05 14:18:37 -08001426
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001427 // Parse options related to Carrier Config Commands.
1428 private CcOptionParseResult parseCcOptions(String tag, boolean allowOptionPersistent) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001429 PrintWriter errPw = getErrPrintWriter();
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001430 CcOptionParseResult result = new CcOptionParseResult();
1431 result.mSubId = SubscriptionManager.getDefaultSubscriptionId();
1432 result.mPersistent = false;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001433
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001434 String opt;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001435 while ((opt = getNextOption()) != null) {
1436 switch (opt) {
1437 case "-s": {
1438 try {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001439 result.mSubId = slotStringToSubId(tag, getNextArgRequired());
1440 if (!SubscriptionManager.isValidSubscriptionId(result.mSubId)) {
1441 errPw.println(tag + "No valid subscription found.");
1442 return null;
1443 }
1444
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001445 } catch (IllegalArgumentException e) {
1446 // Missing slot id
1447 errPw.println(tag + "SLOT_ID expected after -s.");
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001448 return null;
1449 }
1450 break;
1451 }
1452 case "-p": {
1453 if (allowOptionPersistent) {
1454 result.mPersistent = true;
1455 } else {
1456 errPw.println(tag + "Unexpected option " + opt);
1457 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001458 }
1459 break;
1460 }
1461 default: {
1462 errPw.println(tag + "Unknown option " + opt);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001463 return null;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001464 }
1465 }
1466 }
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001467 return result;
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001468 }
1469
1470 private int slotStringToSubId(String tag, String slotString) {
1471 int slotId = -1;
1472 try {
1473 slotId = Integer.parseInt(slotString);
1474 } catch (NumberFormatException e) {
Qiong Liuf25799b2020-09-10 10:13:46 +08001475 getErrPrintWriter().println(tag + slotString + " is not a valid number for SLOT_ID.");
1476 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1477 }
1478
1479 if (!SubscriptionManager.isValidPhoneId(slotId)) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001480 getErrPrintWriter().println(tag + slotString + " is not a valid SLOT_ID.");
1481 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1482 }
1483
Qiong Liuf25799b2020-09-10 10:13:46 +08001484 Phone phone = PhoneFactory.getPhone(slotId);
1485 if (phone == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001486 getErrPrintWriter().println(tag + "No subscription found in slot " + slotId + ".");
1487 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
1488 }
Qiong Liuf25799b2020-09-10 10:13:46 +08001489 return phone.getSubId();
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001490 }
1491
Hall Liud892bec2018-11-30 14:51:45 -08001492 private boolean checkShellUid() {
Hall Liu2ddfc7e2018-12-06 13:09:45 -08001493 // adb can run as root or as shell, depending on whether the device is rooted.
1494 return Binder.getCallingUid() == Process.SHELL_UID
1495 || Binder.getCallingUid() == Process.ROOT_UID;
Hall Liud892bec2018-11-30 14:51:45 -08001496 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001497
1498 private int handleCcCommand() {
1499 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
1500 // non user build.
Meng Wangc4f61042019-11-21 10:51:05 -08001501 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001502 getErrPrintWriter().println("cc: Permission denied.");
1503 return -1;
1504 }
1505
1506 String arg = getNextArg();
1507 if (arg == null) {
1508 onHelpCc();
1509 return 0;
1510 }
1511
1512 switch (arg) {
1513 case CC_GET_VALUE: {
1514 return handleCcGetValue();
1515 }
1516 case CC_SET_VALUE: {
1517 return handleCcSetValue();
1518 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001519 case CC_SET_VALUES_FROM_XML: {
1520 return handleCcSetValuesFromXml();
1521 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001522 case CC_CLEAR_VALUES: {
1523 return handleCcClearValues();
1524 }
1525 default: {
1526 getErrPrintWriter().println("cc: Unknown argument: " + arg);
1527 }
1528 }
1529 return -1;
1530 }
1531
1532 // cc get-value
1533 private int handleCcGetValue() {
1534 PrintWriter errPw = getErrPrintWriter();
1535 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_GET_VALUE + ": ";
1536 String key = null;
1537
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001538 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001539 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001540 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001541 return -1;
1542 }
1543
1544 // Get bundle containing all carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001545 PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001546 if (bundle == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001547 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001548 return -1;
1549 }
1550
1551 // Get the key.
1552 key = getNextArg();
1553 if (key != null) {
1554 // A key was provided. Verify if it is a valid key
1555 if (!bundle.containsKey(key)) {
1556 errPw.println(tag + key + " is not a valid key.");
1557 return -1;
1558 }
1559
1560 // Print the carrier config value for key.
1561 getOutPrintWriter().println(ccValueToString(key, getType(tag, key, bundle), bundle));
1562 } else {
1563 // No key provided. Show all values.
1564 // Iterate over a sorted list of all carrier config keys and print them.
1565 TreeSet<String> sortedSet = new TreeSet<String>(bundle.keySet());
1566 for (String k : sortedSet) {
1567 getOutPrintWriter().println(ccValueToString(k, getType(tag, k, bundle), bundle));
1568 }
1569 }
1570 return 0;
1571 }
1572
1573 // cc set-value
1574 private int handleCcSetValue() {
1575 PrintWriter errPw = getErrPrintWriter();
1576 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUE + ": ";
1577
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001578 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001579 CcOptionParseResult options = parseCcOptions(tag, true);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001580 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001581 return -1;
1582 }
1583
1584 // Get bundle containing all current carrier configuration values.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001585 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001586 if (originalValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001587 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001588 return -1;
1589 }
1590
1591 // Get the key.
1592 String key = getNextArg();
1593 if (key == null || key.equals("")) {
1594 errPw.println(tag + "KEY is missing");
1595 return -1;
1596 }
1597
1598 // Verify if the key is valid
1599 if (!originalValues.containsKey(key)) {
1600 errPw.println(tag + key + " is not a valid key.");
1601 return -1;
1602 }
1603
1604 // Remaining arguments is a list of new values. Add them all into an ArrayList.
1605 ArrayList<String> valueList = new ArrayList<String>();
1606 while (peekNextArg() != null) {
1607 valueList.add(getNextArg());
1608 }
1609
1610 // Find the type of the carrier config value
1611 CcType type = getType(tag, key, originalValues);
1612 if (type == CcType.UNKNOWN) {
1613 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1614 return -1;
1615 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001616 if (type == CcType.PERSISTABLE_BUNDLE) {
1617 errPw.println(tag + "ERROR: Overriding of persistable bundle type is not supported. "
1618 + "Use set-values-from-xml instead.");
1619 return -1;
1620 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001621
1622 // Create an override bundle containing the key and value that should be overriden.
1623 PersistableBundle overrideBundle = getOverrideBundle(tag, type, key, valueList);
1624 if (overrideBundle == null) {
1625 return -1;
1626 }
1627
1628 // Override the value
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001629 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001630
1631 // Find bundle containing all new carrier configuration values after the override.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001632 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001633 if (newValues == null) {
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001634 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001635 return -1;
1636 }
1637
1638 // Print the original and new value.
1639 String originalValueString = ccValueToString(key, type, originalValues);
1640 String newValueString = ccValueToString(key, type, newValues);
1641 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1642 getOutPrintWriter().println("New value: \n" + newValueString);
1643
1644 return 0;
1645 }
1646
Allen Xuee00f0e2022-03-14 21:04:49 +00001647 // cc set-values-from-xml
1648 private int handleCcSetValuesFromXml() {
1649 PrintWriter errPw = getErrPrintWriter();
1650 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_SET_VALUES_FROM_XML + ": ";
1651
1652 // Parse all options
Allen Xud8db8332022-05-20 22:26:42 +00001653 CcOptionParseResult options = parseCcOptions(tag, true);
Allen Xuee00f0e2022-03-14 21:04:49 +00001654 if (options == null) {
1655 return -1;
1656 }
1657
1658 // Get bundle containing all current carrier configuration values.
1659 PersistableBundle originalValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1660 if (originalValues == null) {
1661 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1662 return -1;
1663 }
1664
1665 PersistableBundle overrideBundle = readPersistableBundleFromXml(tag);
1666 if (overrideBundle == null) {
1667 return -1;
1668 }
1669
1670 // Verify all values are valid types
1671 for (String key : overrideBundle.keySet()) {
1672 CcType type = getType(tag, key, originalValues);
1673 if (type == CcType.UNKNOWN) {
1674 errPw.println(tag + "ERROR: Not possible to override key with unknown type.");
1675 return -1;
1676 }
1677 }
1678
1679 // Override the value
1680 mCarrierConfigManager.overrideConfig(options.mSubId, overrideBundle, options.mPersistent);
1681
1682 // Find bundle containing all new carrier configuration values after the override.
1683 PersistableBundle newValues = mCarrierConfigManager.getConfigForSubId(options.mSubId);
1684 if (newValues == null) {
1685 errPw.println(tag + "No carrier config values found for subId " + options.mSubId + ".");
1686 return -1;
1687 }
1688
1689 // Print the original and new values
1690 overrideBundle.keySet().forEach(key -> {
1691 CcType type = getType(tag, key, originalValues);
1692 String originalValueString = ccValueToString(key, type, originalValues);
1693 String newValueString = ccValueToString(key, type, newValues);
1694 getOutPrintWriter().println("Previous value: \n" + originalValueString);
1695 getOutPrintWriter().println("New value: \n" + newValueString);
1696 });
1697
1698 return 0;
1699 }
1700
1701 private PersistableBundle readPersistableBundleFromXml(String tag) {
1702 PersistableBundle subIdBundles;
1703 try {
1704 subIdBundles = PersistableBundle.readFromStream(getRawInputStream());
1705 } catch (IOException | RuntimeException e) {
1706 PrintWriter errPw = getErrPrintWriter();
1707 errPw.println(tag + e);
1708 return null;
1709 }
1710
1711 return subIdBundles;
1712 }
1713
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001714 // cc clear-values
1715 private int handleCcClearValues() {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001716 String tag = CARRIER_CONFIG_SUBCOMMAND + " " + CC_CLEAR_VALUES + ": ";
1717
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001718 // Parse all options
Allen Xuee00f0e2022-03-14 21:04:49 +00001719 CcOptionParseResult options = parseCcOptions(tag, false);
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001720 if (options == null) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001721 return -1;
1722 }
1723
1724 // Clear all values that has previously been set.
Torbjorn Eklund723527a2019-02-13 11:16:25 +01001725 mCarrierConfigManager.overrideConfig(options.mSubId, null, true);
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001726 getOutPrintWriter()
1727 .println("All previously set carrier config override values has been cleared");
1728 return 0;
1729 }
1730
1731 private CcType getType(String tag, String key, PersistableBundle bundle) {
1732 // Find the type by checking the type of the current value stored in the bundle.
1733 Object value = bundle.get(key);
1734
1735 if (CC_TYPE_MAP.containsKey(key)) {
1736 return CC_TYPE_MAP.get(key);
1737 } else if (value != null) {
1738 if (value instanceof Boolean) {
1739 return CcType.BOOLEAN;
Allen Xuee00f0e2022-03-14 21:04:49 +00001740 }
1741 if (value instanceof Double) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001742 return CcType.DOUBLE;
Allen Xuee00f0e2022-03-14 21:04:49 +00001743 }
1744 if (value instanceof double[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001745 return CcType.DOUBLE_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001746 }
1747 if (value instanceof Integer) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001748 return CcType.INT;
Allen Xuee00f0e2022-03-14 21:04:49 +00001749 }
1750 if (value instanceof int[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001751 return CcType.INT_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001752 }
1753 if (value instanceof Long) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001754 return CcType.LONG;
Allen Xuee00f0e2022-03-14 21:04:49 +00001755 }
1756 if (value instanceof long[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001757 return CcType.LONG_ARRAY;
Allen Xuee00f0e2022-03-14 21:04:49 +00001758 }
1759 if (value instanceof String) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001760 return CcType.STRING;
Allen Xuee00f0e2022-03-14 21:04:49 +00001761 }
1762 if (value instanceof String[]) {
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001763 return CcType.STRING_ARRAY;
1764 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001765 if (value instanceof PersistableBundle) {
1766 return CcType.PERSISTABLE_BUNDLE;
1767 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001768 } else {
1769 // Current value was null and can therefore not be used in order to find the type.
1770 // Check the name of the key to infer the type. This check is not needed for primitive
1771 // data types (boolean, double, int and long), since they can not be null.
1772 if (key.endsWith("double_array")) {
1773 return CcType.DOUBLE_ARRAY;
1774 }
1775 if (key.endsWith("int_array")) {
1776 return CcType.INT_ARRAY;
1777 }
1778 if (key.endsWith("long_array")) {
1779 return CcType.LONG_ARRAY;
1780 }
1781 if (key.endsWith("string")) {
1782 return CcType.STRING;
1783 }
1784 if (key.endsWith("string_array") || key.endsWith("strings")) {
1785 return CcType.STRING_ARRAY;
1786 }
Allen Xuee00f0e2022-03-14 21:04:49 +00001787 if (key.endsWith("bundle")) {
1788 return CcType.PERSISTABLE_BUNDLE;
1789 }
Torbjorn Eklund1050cb02018-11-16 14:05:38 +01001790 }
1791
1792 // Not possible to infer the type by looking at the current value or the key.
1793 PrintWriter errPw = getErrPrintWriter();
1794 errPw.println(tag + "ERROR: " + key + " has unknown type.");
1795 return CcType.UNKNOWN;
1796 }
1797
1798 private String ccValueToString(String key, CcType type, PersistableBundle bundle) {
1799 String result;
1800 StringBuilder valueString = new StringBuilder();
1801 String typeString = type.toString();
1802 Object value = bundle.get(key);
1803
1804 if (value == null) {
1805 valueString.append("null");
1806 } else {
1807 switch (type) {
1808 case DOUBLE_ARRAY: {
1809 // Format the string representation of the int array as value1 value2......
1810 double[] valueArray = (double[]) value;
1811 for (int i = 0; i < valueArray.length; i++) {
1812 if (i != 0) {
1813 valueString.append(" ");
1814 }
1815 valueString.append(valueArray[i]);
1816 }
1817 break;
1818 }
1819 case INT_ARRAY: {
1820 // Format the string representation of the int array as value1 value2......
1821 int[] valueArray = (int[]) value;
1822 for (int i = 0; i < valueArray.length; i++) {
1823 if (i != 0) {
1824 valueString.append(" ");
1825 }
1826 valueString.append(valueArray[i]);
1827 }
1828 break;
1829 }
1830 case LONG_ARRAY: {
1831 // Format the string representation of the int array as value1 value2......
1832 long[] valueArray = (long[]) value;
1833 for (int i = 0; i < valueArray.length; i++) {
1834 if (i != 0) {
1835 valueString.append(" ");
1836 }
1837 valueString.append(valueArray[i]);
1838 }
1839 break;
1840 }
1841 case STRING: {
1842 valueString.append("\"" + value.toString() + "\"");
1843 break;
1844 }
1845 case STRING_ARRAY: {
1846 // Format the string representation of the string array as "value1" "value2"....
1847 String[] valueArray = (String[]) value;
1848 for (int i = 0; i < valueArray.length; i++) {
1849 if (i != 0) {
1850 valueString.append(" ");
1851 }
1852 if (valueArray[i] != null) {
1853 valueString.append("\"" + valueArray[i] + "\"");
1854 } else {
1855 valueString.append("null");
1856 }
1857 }
1858 break;
1859 }
1860 default: {
1861 valueString.append(value.toString());
1862 }
1863 }
1864 }
1865 return String.format("%-70s %-15s %s", key, typeString, valueString);
1866 }
1867
1868 private PersistableBundle getOverrideBundle(String tag, CcType type, String key,
1869 ArrayList<String> valueList) {
1870 PrintWriter errPw = getErrPrintWriter();
1871 PersistableBundle bundle = new PersistableBundle();
1872
1873 // First verify that a valid number of values has been provided for the type.
1874 switch (type) {
1875 case BOOLEAN:
1876 case DOUBLE:
1877 case INT:
1878 case LONG: {
1879 if (valueList.size() != 1) {
1880 errPw.println(tag + "Expected 1 value for type " + type
1881 + ". Found: " + valueList.size());
1882 return null;
1883 }
1884 break;
1885 }
1886 case STRING: {
1887 if (valueList.size() > 1) {
1888 errPw.println(tag + "Expected 0 or 1 values for type " + type
1889 + ". Found: " + valueList.size());
1890 return null;
1891 }
1892 break;
1893 }
1894 }
1895
1896 // Parse the value according to type and add it to the Bundle.
1897 switch (type) {
1898 case BOOLEAN: {
1899 if ("true".equalsIgnoreCase(valueList.get(0))) {
1900 bundle.putBoolean(key, true);
1901 } else if ("false".equalsIgnoreCase(valueList.get(0))) {
1902 bundle.putBoolean(key, false);
1903 } else {
1904 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1905 return null;
1906 }
1907 break;
1908 }
1909 case DOUBLE: {
1910 try {
1911 bundle.putDouble(key, Double.parseDouble(valueList.get(0)));
1912 } catch (NumberFormatException nfe) {
1913 // Not a valid double
1914 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1915 return null;
1916 }
1917 break;
1918 }
1919 case DOUBLE_ARRAY: {
1920 double[] valueDoubleArray = null;
1921 if (valueList.size() > 0) {
1922 valueDoubleArray = new double[valueList.size()];
1923 for (int i = 0; i < valueList.size(); i++) {
1924 try {
1925 valueDoubleArray[i] = Double.parseDouble(valueList.get(i));
1926 } catch (NumberFormatException nfe) {
1927 // Not a valid double
1928 errPw.println(
1929 tag + "Unable to parse " + valueList.get(i) + " as a double.");
1930 return null;
1931 }
1932 }
1933 }
1934 bundle.putDoubleArray(key, valueDoubleArray);
1935 break;
1936 }
1937 case INT: {
1938 try {
1939 bundle.putInt(key, Integer.parseInt(valueList.get(0)));
1940 } catch (NumberFormatException nfe) {
1941 // Not a valid integer
1942 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as an " + type);
1943 return null;
1944 }
1945 break;
1946 }
1947 case INT_ARRAY: {
1948 int[] valueIntArray = null;
1949 if (valueList.size() > 0) {
1950 valueIntArray = new int[valueList.size()];
1951 for (int i = 0; i < valueList.size(); i++) {
1952 try {
1953 valueIntArray[i] = Integer.parseInt(valueList.get(i));
1954 } catch (NumberFormatException nfe) {
1955 // Not a valid integer
1956 errPw.println(tag
1957 + "Unable to parse " + valueList.get(i) + " as an integer.");
1958 return null;
1959 }
1960 }
1961 }
1962 bundle.putIntArray(key, valueIntArray);
1963 break;
1964 }
1965 case LONG: {
1966 try {
1967 bundle.putLong(key, Long.parseLong(valueList.get(0)));
1968 } catch (NumberFormatException nfe) {
1969 // Not a valid long
1970 errPw.println(tag + "Unable to parse " + valueList.get(0) + " as a " + type);
1971 return null;
1972 }
1973 break;
1974 }
1975 case LONG_ARRAY: {
1976 long[] valueLongArray = null;
1977 if (valueList.size() > 0) {
1978 valueLongArray = new long[valueList.size()];
1979 for (int i = 0; i < valueList.size(); i++) {
1980 try {
1981 valueLongArray[i] = Long.parseLong(valueList.get(i));
1982 } catch (NumberFormatException nfe) {
1983 // Not a valid long
1984 errPw.println(
1985 tag + "Unable to parse " + valueList.get(i) + " as a long");
1986 return null;
1987 }
1988 }
1989 }
1990 bundle.putLongArray(key, valueLongArray);
1991 break;
1992 }
1993 case STRING: {
1994 String value = null;
1995 if (valueList.size() > 0) {
1996 value = valueList.get(0);
1997 }
1998 bundle.putString(key, value);
1999 break;
2000 }
2001 case STRING_ARRAY: {
2002 String[] valueStringArray = null;
2003 if (valueList.size() > 0) {
2004 valueStringArray = new String[valueList.size()];
2005 valueList.toArray(valueStringArray);
2006 }
2007 bundle.putStringArray(key, valueStringArray);
2008 break;
2009 }
2010 }
2011 return bundle;
2012 }
Shuo Qian489d9282020-07-09 11:30:03 -07002013
2014 private int handleEndBlockSuppressionCommand() {
2015 if (!checkShellUid()) {
2016 return -1;
2017 }
2018
2019 if (BlockedNumberContract.SystemContract.getBlockSuppressionStatus(mContext).isSuppressed) {
2020 BlockedNumberContract.SystemContract.endBlockSuppression(mContext);
2021 }
2022 return 0;
2023 }
Hui Wang641e81c2020-10-12 12:14:23 -07002024
Michele Berionne54af4632020-12-28 20:23:16 +00002025 private int handleRestartModemCommand() {
2026 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2027 // non user build.
2028 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2029 getErrPrintWriter().println("RestartModem: Permission denied.");
2030 return -1;
2031 }
2032
2033 boolean result = TelephonyManager.getDefault().rebootRadio();
2034 getOutPrintWriter().println(result);
2035
2036 return result ? 0 : -1;
2037 }
2038
Ling Ma4fbab492022-01-25 22:36:16 +00002039 private int handleGetImei() {
2040 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2041 // non user build.
2042 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2043 getErrPrintWriter().println("Device IMEI: Permission denied.");
2044 return -1;
2045 }
2046
2047 final long identity = Binder.clearCallingIdentity();
2048
2049 String imei = null;
2050 String arg = getNextArg();
2051 if (arg != null) {
2052 try {
2053 int specifiedSlotIndex = Integer.parseInt(arg);
2054 imei = TelephonyManager.from(mContext).getImei(specifiedSlotIndex);
2055 } catch (NumberFormatException exception) {
2056 PrintWriter errPw = getErrPrintWriter();
2057 errPw.println("-s requires an integer as slot index.");
2058 return -1;
2059 }
2060
2061 } else {
2062 imei = TelephonyManager.from(mContext).getImei();
2063 }
2064 getOutPrintWriter().println("Device IMEI: " + imei);
2065
2066 Binder.restoreCallingIdentity(identity);
2067 return 0;
2068 }
2069
Michele Berionne5e411512020-11-13 02:36:59 +00002070 private int handleUnattendedReboot() {
2071 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2072 // non user build.
2073 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2074 getErrPrintWriter().println("UnattendedReboot: Permission denied.");
2075 return -1;
2076 }
2077
2078 int result = TelephonyManager.getDefault().prepareForUnattendedReboot();
2079 getOutPrintWriter().println("result: " + result);
2080
2081 return result != TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR ? 0 : -1;
2082 }
2083
Aman Gupta07124872022-02-09 08:02:14 +00002084 private int handleGetSimSlotsMapping() {
2085 // Verify that the user is allowed to run the command. Only allowed in rooted device in a
2086 // non user build.
2087 if (Binder.getCallingUid() != Process.ROOT_UID || TelephonyUtils.IS_USER) {
2088 getErrPrintWriter().println("GetSimSlotsMapping: Permission denied.");
2089 return -1;
2090 }
2091 TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
2092 String result = telephonyManager.getSimSlotMapping().toString();
2093 getOutPrintWriter().println("simSlotsMapping: " + result);
2094
2095 return 0;
2096 }
2097
Hui Wang641e81c2020-10-12 12:14:23 -07002098 private int handleGbaCommand() {
2099 String arg = getNextArg();
2100 if (arg == null) {
2101 onHelpGba();
2102 return 0;
2103 }
2104
2105 switch (arg) {
2106 case GBA_SET_SERVICE: {
2107 return handleGbaSetServiceCommand();
2108 }
2109 case GBA_GET_SERVICE: {
2110 return handleGbaGetServiceCommand();
2111 }
2112 case GBA_SET_RELEASE_TIME: {
2113 return handleGbaSetReleaseCommand();
2114 }
2115 case GBA_GET_RELEASE_TIME: {
2116 return handleGbaGetReleaseCommand();
2117 }
2118 }
2119
2120 return -1;
2121 }
2122
2123 private int getSubId(String cmd) {
2124 int slotId = getDefaultSlot();
2125 String opt = getNextOption();
2126 if (opt != null && opt.equals("-s")) {
2127 try {
2128 slotId = Integer.parseInt(getNextArgRequired());
2129 } catch (NumberFormatException e) {
2130 getErrPrintWriter().println(cmd + " requires an integer as a SLOT_ID.");
2131 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
2132 }
2133 }
Jack Yude40a3f2022-11-19 22:29:12 -08002134 return SubscriptionManager.getSubscriptionId(slotId);
Hui Wang641e81c2020-10-12 12:14:23 -07002135 }
2136
2137 private int handleGbaSetServiceCommand() {
2138 int subId = getSubId("gba set-service");
2139 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2140 return -1;
2141 }
2142
2143 String packageName = getNextArg();
2144 try {
2145 if (packageName == null) {
2146 packageName = "";
2147 }
2148 boolean result = mInterface.setBoundGbaServiceOverride(subId, packageName);
2149 if (VDBG) {
2150 Log.v(LOG_TAG, "gba set-service -s " + subId + " "
2151 + packageName + ", result=" + result);
2152 }
2153 getOutPrintWriter().println(result);
2154 } catch (RemoteException e) {
2155 Log.w(LOG_TAG, "gba set-service " + subId + " "
2156 + packageName + ", error" + e.getMessage());
2157 getErrPrintWriter().println("Exception: " + e.getMessage());
2158 return -1;
2159 }
2160 return 0;
2161 }
2162
2163 private int handleGbaGetServiceCommand() {
2164 String result;
2165
2166 int subId = getSubId("gba get-service");
2167 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2168 return -1;
2169 }
2170
2171 try {
2172 result = mInterface.getBoundGbaService(subId);
2173 } catch (RemoteException e) {
2174 return -1;
2175 }
2176 if (VDBG) {
2177 Log.v(LOG_TAG, "gba get-service -s " + subId + ", returned: " + result);
2178 }
2179 getOutPrintWriter().println(result);
2180 return 0;
2181 }
2182
2183 private int handleGbaSetReleaseCommand() {
2184 //the release time value could be -1
2185 int subId = getRemainingArgsCount() > 1 ? getSubId("gba set-release")
2186 : SubscriptionManager.getDefaultSubscriptionId();
2187 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2188 return -1;
2189 }
2190
2191 String intervalStr = getNextArg();
2192 if (intervalStr == null) {
2193 return -1;
2194 }
2195
2196 try {
2197 int interval = Integer.parseInt(intervalStr);
2198 boolean result = mInterface.setGbaReleaseTimeOverride(subId, interval);
2199 if (VDBG) {
2200 Log.v(LOG_TAG, "gba set-release -s " + subId + " "
2201 + intervalStr + ", result=" + result);
2202 }
2203 getOutPrintWriter().println(result);
2204 } catch (NumberFormatException | RemoteException e) {
2205 Log.w(LOG_TAG, "gba set-release -s " + subId + " "
2206 + intervalStr + ", error" + e.getMessage());
2207 getErrPrintWriter().println("Exception: " + e.getMessage());
2208 return -1;
2209 }
2210 return 0;
2211 }
2212
2213 private int handleGbaGetReleaseCommand() {
2214 int subId = getSubId("gba get-release");
2215 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2216 return -1;
2217 }
2218
2219 int result = 0;
2220 try {
2221 result = mInterface.getGbaReleaseTime(subId);
2222 } catch (RemoteException e) {
2223 return -1;
2224 }
2225 if (VDBG) {
2226 Log.v(LOG_TAG, "gba get-release -s " + subId + ", returned: " + result);
2227 }
2228 getOutPrintWriter().println(result);
2229 return 0;
2230 }
Hui Wang761a6682020-10-31 05:12:53 +00002231
2232 private int handleSingleRegistrationConfigCommand() {
2233 String arg = getNextArg();
2234 if (arg == null) {
2235 onHelpSrc();
2236 return 0;
2237 }
2238
2239 switch (arg) {
Hui Wangbaaee6a2021-02-19 20:45:36 -08002240 case SRC_SET_TEST_ENABLED: {
2241 return handleSrcSetTestEnabledCommand();
2242 }
2243 case SRC_GET_TEST_ENABLED: {
2244 return handleSrcGetTestEnabledCommand();
2245 }
Hui Wang761a6682020-10-31 05:12:53 +00002246 case SRC_SET_DEVICE_ENABLED: {
2247 return handleSrcSetDeviceEnabledCommand();
2248 }
2249 case SRC_GET_DEVICE_ENABLED: {
2250 return handleSrcGetDeviceEnabledCommand();
2251 }
2252 case SRC_SET_CARRIER_ENABLED: {
2253 return handleSrcSetCarrierEnabledCommand();
2254 }
2255 case SRC_GET_CARRIER_ENABLED: {
2256 return handleSrcGetCarrierEnabledCommand();
2257 }
Hui Wangb647abe2021-02-26 09:33:38 -08002258 case SRC_SET_FEATURE_ENABLED: {
2259 return handleSrcSetFeatureValidationCommand();
2260 }
2261 case SRC_GET_FEATURE_ENABLED: {
2262 return handleSrcGetFeatureValidationCommand();
2263 }
Hui Wang761a6682020-10-31 05:12:53 +00002264 }
2265
2266 return -1;
2267 }
2268
James.cf Linbcdf8b32021-01-14 16:44:13 +08002269 private int handleRcsUceCommand() {
2270 String arg = getNextArg();
2271 if (arg == null) {
Brad Ebinger14d467f2021-02-12 06:18:28 +00002272 onHelpUce();
2273 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002274 }
2275
2276 switch (arg) {
2277 case UCE_REMOVE_EAB_CONTACT:
2278 return handleRemovingEabContactCommand();
calvinpane4a8a1d2021-01-25 13:51:18 +08002279 case UCE_GET_EAB_CONTACT:
2280 return handleGettingEabContactCommand();
Calvin Pana1434322021-07-01 19:27:01 +08002281 case UCE_GET_EAB_CAPABILITY:
2282 return handleGettingEabCapabilityCommand();
James.cf Lin4b784aa2021-01-31 03:25:15 +08002283 case UCE_GET_DEVICE_ENABLED:
2284 return handleUceGetDeviceEnabledCommand();
2285 case UCE_SET_DEVICE_ENABLED:
2286 return handleUceSetDeviceEnabledCommand();
Brad Ebinger14d467f2021-02-12 06:18:28 +00002287 case UCE_OVERRIDE_PUBLISH_CAPS:
2288 return handleUceOverridePublishCaps();
2289 case UCE_GET_LAST_PIDF_XML:
2290 return handleUceGetPidfXml();
James.cf Line8713a42021-04-29 16:04:26 +08002291 case UCE_REMOVE_REQUEST_DISALLOWED_STATUS:
2292 return handleUceRemoveRequestDisallowedStatus();
James.cf Lin0fc71b02021-05-25 01:37:38 +08002293 case UCE_SET_CAPABILITY_REQUEST_TIMEOUT:
2294 return handleUceSetCapRequestTimeout();
James.cf Linbcdf8b32021-01-14 16:44:13 +08002295 }
2296 return -1;
2297 }
2298
2299 private int handleRemovingEabContactCommand() {
2300 int subId = getSubId("uce remove-eab-contact");
2301 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2302 return -1;
2303 }
2304
2305 String phoneNumber = getNextArgRequired();
2306 if (TextUtils.isEmpty(phoneNumber)) {
2307 return -1;
2308 }
2309 int result = 0;
2310 try {
2311 result = mInterface.removeContactFromEab(subId, phoneNumber);
2312 } catch (RemoteException e) {
2313 Log.w(LOG_TAG, "uce remove-eab-contact -s " + subId + ", error " + e.getMessage());
2314 getErrPrintWriter().println("Exception: " + e.getMessage());
2315 return -1;
2316 }
2317
2318 if (VDBG) {
2319 Log.v(LOG_TAG, "uce remove-eab-contact -s " + subId + ", result: " + result);
2320 }
calvinpan293ea1b2021-02-04 17:52:13 +08002321 return 0;
James.cf Linbcdf8b32021-01-14 16:44:13 +08002322 }
2323
calvinpane4a8a1d2021-01-25 13:51:18 +08002324 private int handleGettingEabContactCommand() {
2325 String phoneNumber = getNextArgRequired();
2326 if (TextUtils.isEmpty(phoneNumber)) {
2327 return -1;
2328 }
2329 String result = "";
2330 try {
2331 result = mInterface.getContactFromEab(phoneNumber);
calvinpane4a8a1d2021-01-25 13:51:18 +08002332 } catch (RemoteException e) {
2333 Log.w(LOG_TAG, "uce get-eab-contact, error " + e.getMessage());
2334 getErrPrintWriter().println("Exception: " + e.getMessage());
2335 return -1;
2336 }
2337
2338 if (VDBG) {
2339 Log.v(LOG_TAG, "uce get-eab-contact, result: " + result);
2340 }
calvinpan293ea1b2021-02-04 17:52:13 +08002341 getOutPrintWriter().println(result);
James.cf Lin4b784aa2021-01-31 03:25:15 +08002342 return 0;
2343 }
2344
Calvin Pana1434322021-07-01 19:27:01 +08002345 private int handleGettingEabCapabilityCommand() {
2346 String phoneNumber = getNextArgRequired();
2347 if (TextUtils.isEmpty(phoneNumber)) {
2348 return -1;
2349 }
2350 String result = "";
2351 try {
2352 result = mInterface.getCapabilityFromEab(phoneNumber);
2353 } catch (RemoteException e) {
2354 Log.w(LOG_TAG, "uce get-eab-capability, error " + e.getMessage());
2355 getErrPrintWriter().println("Exception: " + e.getMessage());
2356 return -1;
2357 }
2358
2359 if (VDBG) {
2360 Log.v(LOG_TAG, "uce get-eab-capability, result: " + result);
2361 }
2362 getOutPrintWriter().println(result);
2363 return 0;
2364 }
2365
James.cf Lin4b784aa2021-01-31 03:25:15 +08002366 private int handleUceGetDeviceEnabledCommand() {
2367 boolean result = false;
2368 try {
2369 result = mInterface.getDeviceUceEnabled();
2370 } catch (RemoteException e) {
2371 Log.w(LOG_TAG, "uce get-device-enabled, error " + e.getMessage());
2372 return -1;
2373 }
2374 if (VDBG) {
2375 Log.v(LOG_TAG, "uce get-device-enabled, returned: " + result);
2376 }
calvinpane4a8a1d2021-01-25 13:51:18 +08002377 getOutPrintWriter().println(result);
2378 return 0;
2379 }
2380
James.cf Lin4b784aa2021-01-31 03:25:15 +08002381 private int handleUceSetDeviceEnabledCommand() {
2382 String enabledStr = getNextArg();
2383 if (TextUtils.isEmpty(enabledStr)) {
2384 return -1;
2385 }
2386
2387 try {
2388 boolean isEnabled = Boolean.parseBoolean(enabledStr);
2389 mInterface.setDeviceUceEnabled(isEnabled);
2390 if (VDBG) {
2391 Log.v(LOG_TAG, "uce set-device-enabled " + enabledStr + ", done");
2392 }
2393 } catch (NumberFormatException | RemoteException e) {
2394 Log.w(LOG_TAG, "uce set-device-enabled " + enabledStr + ", error " + e.getMessage());
2395 getErrPrintWriter().println("Exception: " + e.getMessage());
2396 return -1;
2397 }
2398 return 0;
2399 }
2400
James.cf Line8713a42021-04-29 16:04:26 +08002401 private int handleUceRemoveRequestDisallowedStatus() {
2402 int subId = getSubId("uce remove-request-disallowed-status");
2403 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2404 Log.w(LOG_TAG, "uce remove-request-disallowed-status, Invalid subscription ID");
2405 return -1;
2406 }
2407 boolean result;
2408 try {
2409 result = mInterface.removeUceRequestDisallowedStatus(subId);
2410 } catch (RemoteException e) {
2411 Log.w(LOG_TAG, "uce remove-request-disallowed-status, error " + e.getMessage());
2412 return -1;
2413 }
2414 if (VDBG) {
2415 Log.v(LOG_TAG, "uce remove-request-disallowed-status, returned: " + result);
2416 }
2417 getOutPrintWriter().println(result);
2418 return 0;
2419 }
2420
James.cf Lin0fc71b02021-05-25 01:37:38 +08002421 private int handleUceSetCapRequestTimeout() {
2422 int subId = getSubId("uce set-capabilities-request-timeout");
2423 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2424 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, Invalid subscription ID");
2425 return -1;
2426 }
2427 long timeoutAfterMs = Long.valueOf(getNextArg());
2428 boolean result;
2429 try {
2430 result = mInterface.setCapabilitiesRequestTimeout(subId, timeoutAfterMs);
2431 } catch (RemoteException e) {
2432 Log.w(LOG_TAG, "uce set-capabilities-request-timeout, error " + e.getMessage());
2433 return -1;
2434 }
2435 if (VDBG) {
2436 Log.v(LOG_TAG, "uce set-capabilities-request-timeout, returned: " + result);
2437 }
2438 getOutPrintWriter().println(result);
2439 return 0;
2440 }
2441
Hui Wangbaaee6a2021-02-19 20:45:36 -08002442 private int handleSrcSetTestEnabledCommand() {
2443 String enabledStr = getNextArg();
2444 if (enabledStr == null) {
2445 return -1;
2446 }
2447
2448 try {
2449 mInterface.setRcsSingleRegistrationTestModeEnabled(Boolean.parseBoolean(enabledStr));
2450 if (VDBG) {
2451 Log.v(LOG_TAG, "src set-test-enabled " + enabledStr + ", done");
2452 }
2453 getOutPrintWriter().println("Done");
2454 } catch (NumberFormatException | RemoteException e) {
2455 Log.w(LOG_TAG, "src set-test-enabled " + enabledStr + ", error" + e.getMessage());
2456 getErrPrintWriter().println("Exception: " + e.getMessage());
2457 return -1;
2458 }
2459 return 0;
2460 }
2461
2462 private int handleSrcGetTestEnabledCommand() {
2463 boolean result = false;
2464 try {
2465 result = mInterface.getRcsSingleRegistrationTestModeEnabled();
2466 } catch (RemoteException e) {
2467 return -1;
2468 }
2469 if (VDBG) {
2470 Log.v(LOG_TAG, "src get-test-enabled, returned: " + result);
2471 }
2472 getOutPrintWriter().println(result);
2473 return 0;
2474 }
2475
Brad Ebinger14d467f2021-02-12 06:18:28 +00002476 private int handleUceOverridePublishCaps() {
2477 int subId = getSubId("uce override-published-caps");
2478 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2479 return -1;
2480 }
2481 //uce override-published-caps [-s SLOT_ID] add|remove|clear|list [CAPABILITIES]
2482 String operation = getNextArgRequired();
2483 String caps = getNextArg();
2484 if (!"add".equals(operation) && !"remove".equals(operation) && !"clear".equals(operation)
2485 && !"list".equals(operation)) {
2486 getErrPrintWriter().println("Invalid operation: " + operation);
2487 return -1;
2488 }
2489
2490 // add/remove requires capabilities to be specified.
2491 if ((!"clear".equals(operation) && !"list".equals(operation)) && TextUtils.isEmpty(caps)) {
2492 getErrPrintWriter().println("\"" + operation + "\" requires capabilities to be "
2493 + "specified");
2494 return -1;
2495 }
2496
2497 ArraySet<String> capSet = new ArraySet<>();
2498 if (!TextUtils.isEmpty(caps)) {
2499 String[] capArray = caps.split(":");
2500 for (String cap : capArray) {
2501 // Allow unknown tags to be passed in as well.
2502 capSet.addAll(TEST_FEATURE_TAG_MAP.getOrDefault(cap, Collections.singleton(cap)));
2503 }
2504 }
2505
2506 RcsContactUceCapability result = null;
2507 try {
2508 switch (operation) {
2509 case "add":
2510 result = mInterface.addUceRegistrationOverrideShell(subId,
2511 new ArrayList<>(capSet));
2512 break;
2513 case "remove":
2514 result = mInterface.removeUceRegistrationOverrideShell(subId,
2515 new ArrayList<>(capSet));
2516 break;
2517 case "clear":
2518 result = mInterface.clearUceRegistrationOverrideShell(subId);
2519 break;
2520 case "list":
2521 result = mInterface.getLatestRcsContactUceCapabilityShell(subId);
2522 break;
2523 }
2524 } catch (RemoteException e) {
2525 Log.w(LOG_TAG, "uce override-published-caps, error " + e.getMessage());
2526 getErrPrintWriter().println("Exception: " + e.getMessage());
2527 return -1;
2528 } catch (ServiceSpecificException sse) {
2529 // Reconstruct ImsException
2530 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2531 Log.w(LOG_TAG, "uce override-published-caps, error " + imsException);
2532 getErrPrintWriter().println("Exception: " + imsException);
2533 return -1;
2534 }
2535 if (result == null) {
2536 getErrPrintWriter().println("Service not available");
2537 return -1;
2538 }
2539 getOutPrintWriter().println(result);
2540 return 0;
2541 }
2542
2543 private int handleUceGetPidfXml() {
2544 int subId = getSubId("uce get-last-publish-pidf");
2545 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2546 return -1;
2547 }
2548
2549 String result;
2550 try {
2551 result = mInterface.getLastUcePidfXmlShell(subId);
2552 } catch (RemoteException e) {
2553 Log.w(LOG_TAG, "uce get-last-publish-pidf, error " + e.getMessage());
2554 getErrPrintWriter().println("Exception: " + e.getMessage());
2555 return -1;
2556 } catch (ServiceSpecificException sse) {
2557 // Reconstruct ImsException
2558 ImsException imsException = new ImsException(sse.getMessage(), sse.errorCode);
2559 Log.w(LOG_TAG, "uce get-last-publish-pidf error " + imsException);
2560 getErrPrintWriter().println("Exception: " + imsException);
2561 return -1;
2562 }
2563 if (result == null) {
2564 getErrPrintWriter().println("Service not available");
2565 return -1;
2566 }
2567 getOutPrintWriter().println(result);
2568 return 0;
2569 }
2570
Hui Wang761a6682020-10-31 05:12:53 +00002571 private int handleSrcSetDeviceEnabledCommand() {
2572 String enabledStr = getNextArg();
2573 if (enabledStr == null) {
2574 return -1;
2575 }
2576
2577 try {
2578 mInterface.setDeviceSingleRegistrationEnabledOverride(enabledStr);
2579 if (VDBG) {
2580 Log.v(LOG_TAG, "src set-device-enabled " + enabledStr + ", done");
2581 }
2582 getOutPrintWriter().println("Done");
2583 } catch (NumberFormatException | RemoteException e) {
2584 Log.w(LOG_TAG, "src set-device-enabled " + enabledStr + ", error" + e.getMessage());
2585 getErrPrintWriter().println("Exception: " + e.getMessage());
2586 return -1;
2587 }
2588 return 0;
2589 }
2590
2591 private int handleSrcGetDeviceEnabledCommand() {
2592 boolean result = false;
2593 try {
2594 result = mInterface.getDeviceSingleRegistrationEnabled();
2595 } catch (RemoteException e) {
2596 return -1;
2597 }
2598 if (VDBG) {
2599 Log.v(LOG_TAG, "src get-device-enabled, returned: " + result);
2600 }
2601 getOutPrintWriter().println(result);
2602 return 0;
2603 }
2604
2605 private int handleSrcSetCarrierEnabledCommand() {
2606 //the release time value could be -1
2607 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-carrier-enabled")
2608 : SubscriptionManager.getDefaultSubscriptionId();
2609 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2610 return -1;
2611 }
2612
2613 String enabledStr = getNextArg();
2614 if (enabledStr == null) {
2615 return -1;
2616 }
2617
2618 try {
2619 boolean result =
2620 mInterface.setCarrierSingleRegistrationEnabledOverride(subId, enabledStr);
2621 if (VDBG) {
2622 Log.v(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2623 + enabledStr + ", result=" + result);
2624 }
2625 getOutPrintWriter().println(result);
2626 } catch (NumberFormatException | RemoteException e) {
2627 Log.w(LOG_TAG, "src set-carrier-enabled -s " + subId + " "
2628 + enabledStr + ", error" + e.getMessage());
2629 getErrPrintWriter().println("Exception: " + e.getMessage());
2630 return -1;
2631 }
2632 return 0;
2633 }
2634
2635 private int handleSrcGetCarrierEnabledCommand() {
2636 int subId = getSubId("src get-carrier-enabled");
2637 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2638 return -1;
2639 }
2640
2641 boolean result = false;
2642 try {
2643 result = mInterface.getCarrierSingleRegistrationEnabled(subId);
2644 } catch (RemoteException e) {
2645 return -1;
2646 }
2647 if (VDBG) {
2648 Log.v(LOG_TAG, "src get-carrier-enabled -s " + subId + ", returned: " + result);
2649 }
2650 getOutPrintWriter().println(result);
2651 return 0;
2652 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002653
Hui Wangb647abe2021-02-26 09:33:38 -08002654 private int handleSrcSetFeatureValidationCommand() {
2655 //the release time value could be -1
2656 int subId = getRemainingArgsCount() > 1 ? getSubId("src set-feature-validation")
2657 : SubscriptionManager.getDefaultSubscriptionId();
2658 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2659 return -1;
2660 }
2661
2662 String enabledStr = getNextArg();
2663 if (enabledStr == null) {
2664 return -1;
2665 }
2666
2667 try {
2668 boolean result =
2669 mInterface.setImsFeatureValidationOverride(subId, enabledStr);
2670 if (VDBG) {
2671 Log.v(LOG_TAG, "src set-feature-validation -s " + subId + " "
2672 + enabledStr + ", result=" + result);
2673 }
2674 getOutPrintWriter().println(result);
2675 } catch (NumberFormatException | RemoteException e) {
2676 Log.w(LOG_TAG, "src set-feature-validation -s " + subId + " "
2677 + enabledStr + ", error" + e.getMessage());
2678 getErrPrintWriter().println("Exception: " + e.getMessage());
2679 return -1;
2680 }
2681 return 0;
2682 }
2683
2684 private int handleSrcGetFeatureValidationCommand() {
2685 int subId = getSubId("src get-feature-validation");
2686 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
2687 return -1;
2688 }
2689
2690 Boolean result = false;
2691 try {
2692 result = mInterface.getImsFeatureValidationOverride(subId);
2693 } catch (RemoteException e) {
2694 return -1;
2695 }
2696 if (VDBG) {
2697 Log.v(LOG_TAG, "src get-feature-validation -s " + subId + ", returned: " + result);
2698 }
2699 getOutPrintWriter().println(result);
2700 return 0;
2701 }
2702
2703
Hall Liuaa4211e2021-01-20 15:43:39 -08002704 private void onHelpCallComposer() {
2705 PrintWriter pw = getOutPrintWriter();
2706 pw.println("Call composer commands");
2707 pw.println(" callcomposer test-mode enable|disable|query");
2708 pw.println(" Enables or disables test mode for call composer. In test mode, picture");
2709 pw.println(" upload/download from carrier servers is disabled, and operations are");
2710 pw.println(" performed using emulated local files instead.");
2711 pw.println(" callcomposer simulate-outgoing-call [subId] [UUID]");
2712 pw.println(" Simulates an outgoing call being placed with the picture ID as");
2713 pw.println(" the provided UUID. This triggers storage to the call log.");
Hall Liu7917ecf2021-02-23 12:22:31 -08002714 pw.println(" callcomposer user-setting [subId] enable|disable|query");
2715 pw.println(" Enables or disables the user setting for call composer, as set by");
2716 pw.println(" TelephonyManager#setCallComposerStatus.");
Hall Liuaa4211e2021-01-20 15:43:39 -08002717 }
2718
2719 private int handleCallComposerCommand() {
2720 String arg = getNextArg();
2721 if (arg == null) {
2722 onHelpCallComposer();
2723 return 0;
2724 }
2725
2726 mContext.enforceCallingPermission(Manifest.permission.MODIFY_PHONE_STATE,
2727 "MODIFY_PHONE_STATE required for call composer shell cmds");
2728 switch (arg) {
2729 case CALL_COMPOSER_TEST_MODE: {
2730 String enabledStr = getNextArg();
2731 if (ENABLE.equals(enabledStr)) {
2732 CallComposerPictureManager.sTestMode = true;
2733 } else if (DISABLE.equals(enabledStr)) {
2734 CallComposerPictureManager.sTestMode = false;
2735 } else if (QUERY.equals(enabledStr)) {
2736 getOutPrintWriter().println(CallComposerPictureManager.sTestMode);
2737 } else {
2738 onHelpCallComposer();
2739 return 1;
2740 }
2741 break;
2742 }
2743 case CALL_COMPOSER_SIMULATE_CALL: {
2744 int subscriptionId = Integer.valueOf(getNextArg());
2745 String uuidString = getNextArg();
2746 UUID uuid = UUID.fromString(uuidString);
2747 CompletableFuture<Uri> storageUriFuture = new CompletableFuture<>();
2748 Binder.withCleanCallingIdentity(() -> {
2749 CallComposerPictureManager.getInstance(mContext, subscriptionId)
2750 .storeUploadedPictureToCallLog(uuid, storageUriFuture::complete);
2751 });
2752 try {
2753 Uri uri = storageUriFuture.get();
2754 getOutPrintWriter().println(String.valueOf(uri));
2755 } catch (Exception e) {
2756 throw new RuntimeException(e);
2757 }
2758 break;
2759 }
Hall Liu7917ecf2021-02-23 12:22:31 -08002760 case CALL_COMPOSER_USER_SETTING: {
2761 try {
2762 int subscriptionId = Integer.valueOf(getNextArg());
2763 String enabledStr = getNextArg();
2764 if (ENABLE.equals(enabledStr)) {
2765 mInterface.setCallComposerStatus(subscriptionId,
2766 TelephonyManager.CALL_COMPOSER_STATUS_ON);
2767 } else if (DISABLE.equals(enabledStr)) {
2768 mInterface.setCallComposerStatus(subscriptionId,
2769 TelephonyManager.CALL_COMPOSER_STATUS_OFF);
2770 } else if (QUERY.equals(enabledStr)) {
2771 getOutPrintWriter().println(mInterface.getCallComposerStatus(subscriptionId)
2772 == TelephonyManager.CALL_COMPOSER_STATUS_ON);
2773 } else {
2774 onHelpCallComposer();
2775 return 1;
2776 }
2777 } catch (RemoteException e) {
2778 e.printStackTrace(getOutPrintWriter());
2779 return 1;
2780 }
2781 break;
2782 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002783 }
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002784 return 0;
2785 }
Hall Liuaa4211e2021-01-20 15:43:39 -08002786
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002787 private int handleHasCarrierPrivilegesCommand() {
2788 String packageName = getNextArgRequired();
2789
2790 boolean hasCarrierPrivileges;
Nazanin1adf4562021-03-29 15:35:30 -07002791 final long token = Binder.clearCallingIdentity();
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002792 try {
2793 hasCarrierPrivileges =
2794 mInterface.checkCarrierPrivilegesForPackageAnyPhone(packageName)
2795 == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
2796 } catch (RemoteException e) {
2797 Log.w(LOG_TAG, HAS_CARRIER_PRIVILEGES_COMMAND + " exception", e);
2798 getErrPrintWriter().println("Exception: " + e.getMessage());
2799 return -1;
Nazanin1adf4562021-03-29 15:35:30 -07002800 } finally {
2801 Binder.restoreCallingIdentity(token);
Hunter Knepshieldb6907bd2021-03-02 13:07:53 -08002802 }
2803
2804 getOutPrintWriter().println(hasCarrierPrivileges);
Hall Liuaa4211e2021-01-20 15:43:39 -08002805 return 0;
2806 }
SongFerngWang98dd5992021-05-13 17:50:00 +08002807
2808 private int handleAllowedNetworkTypesCommand(String command) {
2809 if (!checkShellUid()) {
2810 return -1;
2811 }
2812
2813 PrintWriter errPw = getErrPrintWriter();
2814 String tag = command + ": ";
2815 String opt;
2816 int subId = -1;
2817 Log.v(LOG_TAG, command + " start");
2818
2819 while ((opt = getNextOption()) != null) {
2820 if (opt.equals("-s")) {
2821 try {
2822 subId = slotStringToSubId(tag, getNextArgRequired());
2823 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2824 errPw.println(tag + "No valid subscription found.");
2825 return -1;
2826 }
2827 } catch (IllegalArgumentException e) {
2828 // Missing slot id
2829 errPw.println(tag + "SLOT_ID expected after -s.");
2830 return -1;
2831 }
2832 } else {
2833 errPw.println(tag + "Unknown option " + opt);
2834 return -1;
2835 }
2836 }
2837
2838 if (GET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2839 return handleGetAllowedNetworkTypesCommand(subId);
2840 }
2841 if (SET_ALLOWED_NETWORK_TYPES_FOR_USER.equals(command)) {
2842 return handleSetAllowedNetworkTypesCommand(subId);
2843 }
2844 return -1;
2845 }
2846
2847 private int handleGetAllowedNetworkTypesCommand(int subId) {
2848 PrintWriter errPw = getErrPrintWriter();
2849
2850 long result = -1;
2851 try {
2852 if (mInterface != null) {
2853 result = mInterface.getAllowedNetworkTypesForReason(subId,
2854 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
2855 } else {
2856 throw new IllegalStateException("telephony service is null.");
2857 }
2858 } catch (RemoteException e) {
2859 Log.e(TAG, "getAllowedNetworkTypesForReason RemoteException" + e);
2860 errPw.println(GET_ALLOWED_NETWORK_TYPES_FOR_USER + "RemoteException " + e);
2861 return -1;
2862 }
2863
2864 getOutPrintWriter().println(TelephonyManager.convertNetworkTypeBitmaskToString(result));
2865 return 0;
2866 }
2867
2868 private int handleSetAllowedNetworkTypesCommand(int subId) {
2869 PrintWriter errPw = getErrPrintWriter();
2870
2871 String bitmaskString = getNextArg();
2872 if (TextUtils.isEmpty(bitmaskString)) {
2873 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No NETWORK_TYPES_BITMASK");
2874 return -1;
2875 }
2876 long allowedNetworkTypes = convertNetworkTypeBitmaskFromStringToLong(bitmaskString);
2877 if (allowedNetworkTypes < 0) {
2878 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " No valid NETWORK_TYPES_BITMASK");
2879 return -1;
2880 }
2881 boolean result = false;
2882 try {
2883 if (mInterface != null) {
2884 result = mInterface.setAllowedNetworkTypesForReason(subId,
2885 TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER, allowedNetworkTypes);
2886 } else {
2887 throw new IllegalStateException("telephony service is null.");
2888 }
2889 } catch (RemoteException e) {
2890 Log.e(TAG, "setAllowedNetworkTypesForReason RemoteException" + e);
2891 errPw.println(SET_ALLOWED_NETWORK_TYPES_FOR_USER + " RemoteException " + e);
2892 return -1;
2893 }
2894
2895 String resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " failed";
2896 if (result) {
2897 resultMessage = SET_ALLOWED_NETWORK_TYPES_FOR_USER + " completed";
2898 }
2899 getOutPrintWriter().println(resultMessage);
2900 return 0;
2901 }
2902
2903 private long convertNetworkTypeBitmaskFromStringToLong(String bitmaskString) {
2904 if (TextUtils.isEmpty(bitmaskString)) {
2905 return -1;
2906 }
2907 if (VDBG) {
2908 Log.v(LOG_TAG, "AllowedNetworkTypes:" + bitmaskString
2909 + ", length: " + bitmaskString.length());
2910 }
2911 try {
2912 return Long.parseLong(bitmaskString, 2);
2913 } catch (NumberFormatException e) {
2914 Log.e(LOG_TAG, "AllowedNetworkTypes: " + e);
2915 return -1;
2916 }
2917 }
Jack Yu4c0a5502021-12-03 23:58:26 -08002918
jimsun3b9ccac2021-10-26 15:01:23 +08002919 private int handleRadioSetModemServiceCommand() {
2920 PrintWriter errPw = getErrPrintWriter();
2921 String serviceName = null;
2922
2923 String opt;
2924 while ((opt = getNextOption()) != null) {
2925 switch (opt) {
2926 case "-s": {
2927 serviceName = getNextArgRequired();
2928 break;
2929 }
2930 }
2931 }
2932
2933 try {
2934 boolean result = mInterface.setModemService(serviceName);
2935 if (VDBG) {
2936 Log.v(LOG_TAG,
2937 "RadioSetModemService " + serviceName + ", result = " + result);
2938 }
2939 getOutPrintWriter().println(result);
2940 } catch (RemoteException e) {
2941 Log.w(LOG_TAG,
2942 "RadioSetModemService: " + serviceName + ", error = " + e.getMessage());
2943 errPw.println("Exception: " + e.getMessage());
2944 return -1;
2945 }
2946 return 0;
2947 }
2948
2949 private int handleRadioGetModemServiceCommand() {
2950 PrintWriter errPw = getErrPrintWriter();
2951 String result;
2952
2953 try {
2954 result = mInterface.getModemService();
2955 getOutPrintWriter().println(result);
2956 } catch (RemoteException e) {
2957 errPw.println("Exception: " + e.getMessage());
2958 return -1;
2959 }
2960 if (VDBG) {
2961 Log.v(LOG_TAG, "RadioGetModemService, result = " + result);
2962 }
2963 return 0;
2964 }
2965
2966 private int handleRadioCommand() {
2967 String arg = getNextArg();
2968 if (arg == null) {
2969 onHelpRadio();
2970 return 0;
2971 }
2972
2973 switch (arg) {
2974 case RADIO_SET_MODEM_SERVICE:
2975 return handleRadioSetModemServiceCommand();
2976
2977 case RADIO_GET_MODEM_SERVICE:
2978 return handleRadioGetModemServiceCommand();
2979 }
2980
2981 return -1;
2982 }
Benedict Wong45280102023-02-03 23:30:57 +00002983
2984 // set-carrier-service-package-override
2985 private int setCarrierServicePackageOverride() {
2986 PrintWriter errPw = getErrPrintWriter();
2987 int subId = SubscriptionManager.getDefaultSubscriptionId();
2988
2989 String opt;
2990 while ((opt = getNextOption()) != null) {
2991 switch (opt) {
2992 case "-s":
2993 try {
2994 subId = Integer.parseInt(getNextArgRequired());
2995 } catch (NumberFormatException e) {
2996 errPw.println(
2997 "set-carrier-service-package-override requires an integer as a"
2998 + " subscription ID.");
2999 return -1;
3000 }
3001 break;
3002 }
3003 }
3004
3005 String packageName = getNextArg();
3006 if (packageName == null) {
3007 errPw.println("set-carrier-service-package-override requires a override package name.");
3008 return -1;
3009 }
3010
3011 try {
3012 mInterface.setCarrierServicePackageOverride(
3013 subId, packageName, mContext.getOpPackageName());
3014
3015 if (VDBG) {
3016 Log.v(
3017 LOG_TAG,
3018 "set-carrier-service-package-override -s " + subId + " " + packageName);
3019 }
3020 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3021 Log.w(
3022 LOG_TAG,
3023 "set-carrier-service-package-override -s "
3024 + subId
3025 + " "
3026 + packageName
3027 + ", error"
3028 + e.getMessage());
3029 errPw.println("Exception: " + e.getMessage());
3030 return -1;
3031 }
3032 return 0;
3033 }
3034
3035 // clear-carrier-service-package-override
3036 private int clearCarrierServicePackageOverride() {
3037 PrintWriter errPw = getErrPrintWriter();
3038 int subId = getDefaultSlot();
3039
3040 String opt;
3041 while ((opt = getNextOption()) != null) {
3042 switch (opt) {
3043 case "-s":
3044 try {
3045 subId = Integer.parseInt(getNextArgRequired());
3046 } catch (NumberFormatException e) {
3047 errPw.println(
3048 "clear-carrier-service-package-override requires an integer as a"
3049 + " subscription ID.");
3050 return -1;
3051 }
3052 break;
3053 }
3054 }
3055
3056 try {
3057 mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
3058
3059 if (VDBG) {
3060 Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
3061 }
3062 } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
3063 Log.w(
3064 LOG_TAG,
3065 "clear-carrier-service-package-override -s "
3066 + subId
3067 + ", error"
3068 + e.getMessage());
3069 errPw.println("Exception: " + e.getMessage());
3070 return -1;
3071 }
3072 return 0;
3073 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -07003074}