blob: 1a25ae3ec48329e04f20028a584031d537f9b923 [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
19import android.os.RemoteException;
20import android.os.ShellCommand;
sqian2fff4a32018-11-05 14:18:37 -080021import android.os.UserHandle;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070022import android.telephony.SubscriptionManager;
23import android.util.Log;
24
25import com.android.internal.telephony.ITelephony;
26
27import java.io.PrintWriter;
28
29/**
30 * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
31 * permission checks have been done before onCommand was called. Make sure any commands processed
32 * here also contain the appropriate permissions checks.
33 */
34
35public class TelephonyShellCommand extends ShellCommand {
36
37 private static final String LOG_TAG = "TelephonyShellCommand";
38 // Don't commit with this true.
39 private static final boolean VDBG = true;
Brad Ebinger0aa2f242018-04-12 09:49:23 -070040 private static final int DEFAULT_PHONE_ID = 0;
Brad Ebinger4dc095a2018-04-03 15:17:52 -070041
42 private static final String IMS_SUBCOMMAND = "ims";
sqian2fff4a32018-11-05 14:18:37 -080043 private static final String SMS_SUBCOMMAND = "sms";
Brad Ebinger4dc095a2018-04-03 15:17:52 -070044 private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
45 private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
46 private static final String IMS_ENABLE = "enable";
47 private static final String IMS_DISABLE = "disable";
48
sqian2fff4a32018-11-05 14:18:37 -080049 private static final String SMS_GET_APPS = "get-apps";
50 private static final String SMS_GET_DEFAULT_APP = "get-default-app";
51 private static final String SMS_SET_DEFAULT_APP = "set-default-app";
52
Brad Ebinger4dc095a2018-04-03 15:17:52 -070053 // Take advantage of existing methods that already contain permissions checks when possible.
54 private final ITelephony mInterface;
55
56 public TelephonyShellCommand(ITelephony binder) {
57 mInterface = binder;
58 }
59
60 @Override
61 public int onCommand(String cmd) {
62 if (cmd == null) {
63 return handleDefaultCommands(null);
64 }
65
66 switch (cmd) {
67 case IMS_SUBCOMMAND: {
68 return handleImsCommand();
69 }
sqian2fff4a32018-11-05 14:18:37 -080070 case SMS_SUBCOMMAND: {
71 return handleSmsCommand();
72 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -070073 default: {
74 return handleDefaultCommands(cmd);
75 }
76 }
77 }
78
79 @Override
80 public void onHelp() {
81 PrintWriter pw = getOutPrintWriter();
82 pw.println("Telephony Commands:");
83 pw.println(" help");
84 pw.println(" Print this help text.");
85 pw.println(" ims");
86 pw.println(" IMS Commands.");
sqian2fff4a32018-11-05 14:18:37 -080087 pw.println(" sms");
88 pw.println(" SMS Commands.");
Brad Ebinger4dc095a2018-04-03 15:17:52 -070089 onHelpIms();
sqian2fff4a32018-11-05 14:18:37 -080090 onHelpSms();
Brad Ebinger4dc095a2018-04-03 15:17:52 -070091 }
92
93 private void onHelpIms() {
94 PrintWriter pw = getOutPrintWriter();
95 pw.println("IMS Commands:");
96 pw.println(" ims set-ims-service [-s SLOT_ID] (-c | -d) PACKAGE_NAME");
97 pw.println(" Sets the ImsService defined in PACKAGE_NAME to to be the bound");
98 pw.println(" ImsService. Options are:");
99 pw.println(" -s: the slot ID that the ImsService should be bound for. If no option");
100 pw.println(" is specified, it will choose the default voice SIM slot.");
101 pw.println(" -c: Override the ImsService defined in the carrier configuration.");
102 pw.println(" -d: Override the ImsService defined in the device overlay.");
103 pw.println(" ims get-ims-service [-s SLOT_ID] [-c | -d]");
104 pw.println(" Gets the package name of the currently defined ImsService.");
105 pw.println(" Options are:");
106 pw.println(" -s: The SIM slot ID for the registered ImsService. If no option");
107 pw.println(" is specified, it will choose the default voice SIM slot.");
108 pw.println(" -c: The ImsService defined as the carrier configured ImsService.");
109 pw.println(" -c: The ImsService defined as the device default ImsService.");
110 pw.println(" ims enable [-s SLOT_ID]");
111 pw.println(" enables IMS for the SIM slot specified, or for the default voice SIM slot");
112 pw.println(" if none is specified.");
113 pw.println(" ims disable [-s SLOT_ID]");
114 pw.println(" disables IMS for the SIM slot specified, or for the default voice SIM");
115 pw.println(" slot if none is specified.");
116 }
117
sqian2fff4a32018-11-05 14:18:37 -0800118 private void onHelpSms() {
119 PrintWriter pw = getOutPrintWriter();
120 pw.println("SMS Commands:");
121 pw.println(" sms get-apps [--user USER_ID]");
122 pw.println(" Print all SMS apps on a user.");
123 pw.println(" sms get-default-app [--user USER_ID]");
124 pw.println(" Get the default SMS app.");
125 pw.println(" sms set-default-app [--user USER_ID] PACKAGE_NAME");
126 pw.println(" Set PACKAGE_NAME as the default SMS app.");
127 }
128
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700129 private int handleImsCommand() {
130 String arg = getNextArg();
131 if (arg == null) {
132 onHelpIms();
133 return 0;
134 }
135
136 switch (arg) {
137 case IMS_SET_CARRIER_SERVICE: {
138 return handleImsSetServiceCommand();
139 }
140 case IMS_GET_CARRIER_SERVICE: {
141 return handleImsGetServiceCommand();
142 }
143 case IMS_ENABLE: {
144 return handleEnableIms();
145 }
146 case IMS_DISABLE: {
147 return handleDisableIms();
148 }
149 }
150
151 return -1;
152 }
153
154 // ims set-ims-service
155 private int handleImsSetServiceCommand() {
156 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700157 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700158 Boolean isCarrierService = null;
159
160 String opt;
161 while ((opt = getNextOption()) != null) {
162 switch (opt) {
163 case "-s": {
164 try {
165 slotId = Integer.parseInt(getNextArgRequired());
166 } catch (NumberFormatException e) {
167 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
168 return -1;
169 }
170 break;
171 }
172 case "-c": {
173 isCarrierService = true;
174 break;
175 }
176 case "-d": {
177 isCarrierService = false;
178 break;
179 }
180 }
181 }
182 // Mandatory param, either -c or -d
183 if (isCarrierService == null) {
184 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
185 return -1;
186 }
187
188 String packageName = getNextArg();
189
190 try {
191 if (packageName == null) {
192 packageName = "";
193 }
194 boolean result = mInterface.setImsService(slotId, isCarrierService, packageName);
195 if (VDBG) {
196 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
197 + (isCarrierService ? "-c " : "-d ") + packageName + ", result=" + result);
198 }
199 getOutPrintWriter().println(result);
200 } catch (RemoteException e) {
201 Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
202 + (isCarrierService ? "-c " : "-d ") + packageName + ", error"
203 + e.getMessage());
204 errPw.println("Exception: " + e.getMessage());
205 return -1;
206 }
207 return 0;
208 }
209
210 // ims get-ims-service
211 private int handleImsGetServiceCommand() {
212 PrintWriter errPw = getErrPrintWriter();
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700213 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700214 Boolean isCarrierService = null;
215
216 String opt;
217 while ((opt = getNextOption()) != null) {
218 switch (opt) {
219 case "-s": {
220 try {
221 slotId = Integer.parseInt(getNextArgRequired());
222 } catch (NumberFormatException e) {
223 errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
224 return -1;
225 }
226 break;
227 }
228 case "-c": {
229 isCarrierService = true;
230 break;
231 }
232 case "-d": {
233 isCarrierService = false;
234 break;
235 }
236 }
237 }
238 // Mandatory param, either -c or -d
239 if (isCarrierService == null) {
240 errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
241 return -1;
242 }
243
244 String result;
245 try {
246 result = mInterface.getImsService(slotId, isCarrierService);
247 } catch (RemoteException e) {
248 return -1;
249 }
250 if (VDBG) {
251 Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
252 + (isCarrierService ? "-c " : "-d ") + ", returned: " + result);
253 }
254 getOutPrintWriter().println(result);
255 return 0;
256 }
257
258 private int handleEnableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700259 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700260 String opt;
261 while ((opt = getNextOption()) != null) {
262 switch (opt) {
263 case "-s": {
264 try {
265 slotId = Integer.parseInt(getNextArgRequired());
266 } catch (NumberFormatException e) {
267 getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
268 return -1;
269 }
270 break;
271 }
272 }
273 }
274 try {
275 mInterface.enableIms(slotId);
276 } catch (RemoteException e) {
277 return -1;
278 }
279 if (VDBG) {
280 Log.v(LOG_TAG, "ims enable -s " + slotId);
281 }
282 return 0;
283 }
284
285 private int handleDisableIms() {
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700286 int slotId = getDefaultSlot();
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700287 String opt;
288 while ((opt = getNextOption()) != null) {
289 switch (opt) {
290 case "-s": {
291 try {
292 slotId = Integer.parseInt(getNextArgRequired());
293 } catch (NumberFormatException e) {
294 getErrPrintWriter().println(
295 "ims disable requires an integer as a SLOT_ID.");
296 return -1;
297 }
298 break;
299 }
300 }
301 }
302 try {
303 mInterface.disableIms(slotId);
304 } catch (RemoteException e) {
305 return -1;
306 }
307 if (VDBG) {
308 Log.v(LOG_TAG, "ims disable -s " + slotId);
309 }
310 return 0;
311 }
Brad Ebinger0aa2f242018-04-12 09:49:23 -0700312
313 private int getDefaultSlot() {
314 int slotId = SubscriptionManager.getDefaultVoicePhoneId();
315 if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
316 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
317 // If there is no default, default to slot 0.
318 slotId = DEFAULT_PHONE_ID;
319 }
320 return slotId;
321 }
sqian2fff4a32018-11-05 14:18:37 -0800322
323 private int handleSmsCommand() {
324 String arg = getNextArg();
325 if (arg == null) {
326 onHelpSms();
327 return 0;
328 }
329
330 try {
331 switch (arg) {
332 case SMS_GET_APPS: {
333 return handleSmsGetApps();
334 }
335 case SMS_GET_DEFAULT_APP: {
336 return handleSmsGetDefaultApp();
337 }
338 case SMS_SET_DEFAULT_APP: {
339 return handleSmsSetDefaultApp();
340 }
341 default:
342 getErrPrintWriter().println("Unknown command " + arg);
343 }
344 } catch (RemoteException e) {
345 getErrPrintWriter().println("RemoteException: " + e.getMessage());
346 }
347
348 return -1;
349 }
350
351 private int maybeParseUserIdArg() {
352 int userId = UserHandle.USER_SYSTEM;
353 String opt;
354 while ((opt = getNextOption()) != null) {
355 switch (opt) {
356 case "--user": {
357 try {
358 userId = Integer.parseInt(getNextArgRequired());
359 } catch (NumberFormatException e) {
360 getErrPrintWriter().println("Invalid user ID for --user");
361 return -1;
362 }
363 break;
364 }
365 }
366 }
367 return userId;
368 }
369
370 private int handleSmsGetApps() throws RemoteException {
371 final int userId = maybeParseUserIdArg();
372 if (userId < 0) {
373 return -1;
374 }
375
376 for (String packageName : mInterface.getSmsApps(userId)) {
377 getOutPrintWriter().println(packageName);
378 }
379 return 0;
380 }
381
382 private int handleSmsGetDefaultApp() throws RemoteException {
383 final int userId = maybeParseUserIdArg();
384 if (userId < 0) {
385 return -1;
386 }
387
388 getOutPrintWriter().println(mInterface.getDefaultSmsApp(userId));
389 return 0;
390 }
391
392 private int handleSmsSetDefaultApp() throws RemoteException {
393 final int userId = maybeParseUserIdArg();
394 if (userId < 0) {
395 return -1;
396 }
397
398 String packageName = getNextArgRequired();
399 mInterface.setDefaultSmsApp(userId, packageName);
400 getOutPrintWriter().println("SMS app set to " + mInterface.getDefaultSmsApp(userId));
401 return 0;
402 }
Brad Ebinger4dc095a2018-04-03 15:17:52 -0700403}