• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.phone;
18 
19 import android.os.RemoteException;
20 import android.os.ShellCommand;
21 import android.telephony.SubscriptionManager;
22 import android.util.Log;
23 
24 import com.android.internal.telephony.ITelephony;
25 
26 import java.io.PrintWriter;
27 
28 /**
29  * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
30  * permission checks have been done before onCommand was called. Make sure any commands processed
31  * here also contain the appropriate permissions checks.
32  */
33 
34 public class TelephonyShellCommand extends ShellCommand {
35 
36     private static final String LOG_TAG = "TelephonyShellCommand";
37     // Don't commit with this true.
38     private static final boolean VDBG = true;
39     private static final int DEFAULT_PHONE_ID = 0;
40 
41     private static final String IMS_SUBCOMMAND = "ims";
42     private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
43     private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
44     private static final String IMS_ENABLE = "enable";
45     private static final String IMS_DISABLE = "disable";
46 
47     // Take advantage of existing methods that already contain permissions checks when possible.
48     private final ITelephony mInterface;
49 
TelephonyShellCommand(ITelephony binder)50     public TelephonyShellCommand(ITelephony binder) {
51         mInterface = binder;
52     }
53 
54     @Override
onCommand(String cmd)55     public int onCommand(String cmd) {
56         if (cmd == null) {
57             return handleDefaultCommands(null);
58         }
59 
60         switch (cmd) {
61             case IMS_SUBCOMMAND: {
62                 return handleImsCommand();
63             }
64             default: {
65                 return handleDefaultCommands(cmd);
66             }
67         }
68     }
69 
70     @Override
onHelp()71     public void onHelp() {
72         PrintWriter pw = getOutPrintWriter();
73         pw.println("Telephony Commands:");
74         pw.println("  help");
75         pw.println("    Print this help text.");
76         pw.println("  ims");
77         pw.println("    IMS Commands.");
78         onHelpIms();
79     }
80 
onHelpIms()81     private void onHelpIms() {
82         PrintWriter pw = getOutPrintWriter();
83         pw.println("IMS Commands:");
84         pw.println("  ims set-ims-service [-s SLOT_ID] (-c | -d) PACKAGE_NAME");
85         pw.println("    Sets the ImsService defined in PACKAGE_NAME to to be the bound");
86         pw.println("    ImsService. Options are:");
87         pw.println("      -s: the slot ID that the ImsService should be bound for. If no option");
88         pw.println("          is specified, it will choose the default voice SIM slot.");
89         pw.println("      -c: Override the ImsService defined in the carrier configuration.");
90         pw.println("      -d: Override the ImsService defined in the device overlay.");
91         pw.println("  ims get-ims-service [-s SLOT_ID] [-c | -d]");
92         pw.println("    Gets the package name of the currently defined ImsService.");
93         pw.println("    Options are:");
94         pw.println("      -s: The SIM slot ID for the registered ImsService. If no option");
95         pw.println("          is specified, it will choose the default voice SIM slot.");
96         pw.println("      -c: The ImsService defined as the carrier configured ImsService.");
97         pw.println("      -c: The ImsService defined as the device default ImsService.");
98         pw.println("  ims enable [-s SLOT_ID]");
99         pw.println("    enables IMS for the SIM slot specified, or for the default voice SIM slot");
100         pw.println("    if none is specified.");
101         pw.println("  ims disable [-s SLOT_ID]");
102         pw.println("    disables IMS for the SIM slot specified, or for the default voice SIM");
103         pw.println("    slot if none is specified.");
104     }
105 
handleImsCommand()106     private int handleImsCommand() {
107         String arg = getNextArg();
108         if (arg == null) {
109             onHelpIms();
110             return 0;
111         }
112 
113         switch (arg) {
114             case IMS_SET_CARRIER_SERVICE: {
115                 return handleImsSetServiceCommand();
116             }
117             case IMS_GET_CARRIER_SERVICE: {
118                 return handleImsGetServiceCommand();
119             }
120             case IMS_ENABLE: {
121                 return handleEnableIms();
122             }
123             case IMS_DISABLE: {
124                 return handleDisableIms();
125             }
126         }
127 
128         return -1;
129     }
130 
131     // ims set-ims-service
handleImsSetServiceCommand()132     private int handleImsSetServiceCommand() {
133         PrintWriter errPw = getErrPrintWriter();
134         int slotId = getDefaultSlot();
135         Boolean isCarrierService = null;
136 
137         String opt;
138         while ((opt = getNextOption()) != null) {
139             switch (opt) {
140                 case "-s": {
141                     try {
142                         slotId = Integer.parseInt(getNextArgRequired());
143                     } catch (NumberFormatException e) {
144                         errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
145                         return -1;
146                     }
147                     break;
148                 }
149                 case "-c": {
150                     isCarrierService = true;
151                     break;
152                 }
153                 case "-d": {
154                     isCarrierService = false;
155                     break;
156                 }
157             }
158         }
159         // Mandatory param, either -c or -d
160         if (isCarrierService == null) {
161             errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
162             return -1;
163         }
164 
165         String packageName = getNextArg();
166 
167         try {
168             if (packageName == null) {
169                 packageName = "";
170             }
171             boolean result = mInterface.setImsService(slotId, isCarrierService, packageName);
172             if (VDBG) {
173                 Log.v(LOG_TAG, "ims set-ims-service -s " + slotId + " "
174                         + (isCarrierService ? "-c " : "-d ") + packageName + ", result=" + result);
175             }
176             getOutPrintWriter().println(result);
177         } catch (RemoteException e) {
178             Log.w(LOG_TAG, "ims set-ims-service -s " + slotId + " "
179                     + (isCarrierService ? "-c " : "-d ") + packageName + ", error"
180                     + e.getMessage());
181             errPw.println("Exception: " + e.getMessage());
182             return -1;
183         }
184         return 0;
185     }
186 
187     // ims get-ims-service
handleImsGetServiceCommand()188     private int handleImsGetServiceCommand() {
189         PrintWriter errPw = getErrPrintWriter();
190         int slotId = getDefaultSlot();
191         Boolean isCarrierService = null;
192 
193         String opt;
194         while ((opt = getNextOption()) != null) {
195             switch (opt) {
196                 case "-s": {
197                     try {
198                         slotId = Integer.parseInt(getNextArgRequired());
199                     } catch (NumberFormatException e) {
200                         errPw.println("ims set-ims-service requires an integer as a SLOT_ID.");
201                         return -1;
202                     }
203                     break;
204                 }
205                 case "-c": {
206                     isCarrierService = true;
207                     break;
208                 }
209                 case "-d": {
210                     isCarrierService = false;
211                     break;
212                 }
213             }
214         }
215         // Mandatory param, either -c or -d
216         if (isCarrierService == null) {
217             errPw.println("ims set-ims-service requires either \"-c\" or \"-d\" to be set.");
218             return -1;
219         }
220 
221         String result;
222         try {
223             result = mInterface.getImsService(slotId, isCarrierService);
224         } catch (RemoteException e) {
225             return -1;
226         }
227         if (VDBG) {
228             Log.v(LOG_TAG, "ims get-ims-service -s " + slotId + " "
229                     + (isCarrierService ? "-c " : "-d ") + ", returned: " + result);
230         }
231         getOutPrintWriter().println(result);
232         return 0;
233     }
234 
handleEnableIms()235     private int handleEnableIms() {
236         int slotId = getDefaultSlot();
237         String opt;
238         while ((opt = getNextOption()) != null) {
239             switch (opt) {
240                 case "-s": {
241                     try {
242                         slotId = Integer.parseInt(getNextArgRequired());
243                     } catch (NumberFormatException e) {
244                         getErrPrintWriter().println("ims enable requires an integer as a SLOT_ID.");
245                         return -1;
246                     }
247                     break;
248                 }
249             }
250         }
251         try {
252             mInterface.enableIms(slotId);
253         } catch (RemoteException e) {
254             return -1;
255         }
256         if (VDBG) {
257             Log.v(LOG_TAG, "ims enable -s " + slotId);
258         }
259         return 0;
260     }
261 
handleDisableIms()262     private int handleDisableIms() {
263         int slotId = getDefaultSlot();
264         String opt;
265         while ((opt = getNextOption()) != null) {
266             switch (opt) {
267                 case "-s": {
268                     try {
269                         slotId = Integer.parseInt(getNextArgRequired());
270                     } catch (NumberFormatException e) {
271                         getErrPrintWriter().println(
272                                 "ims disable requires an integer as a SLOT_ID.");
273                         return -1;
274                     }
275                     break;
276                 }
277             }
278         }
279         try {
280             mInterface.disableIms(slotId);
281         } catch (RemoteException e) {
282             return -1;
283         }
284         if (VDBG) {
285             Log.v(LOG_TAG, "ims disable -s " + slotId);
286         }
287         return 0;
288     }
289 
getDefaultSlot()290     private int getDefaultSlot() {
291         int slotId = SubscriptionManager.getDefaultVoicePhoneId();
292         if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX
293                 || slotId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
294             // If there is no default, default to slot 0.
295             slotId = DEFAULT_PHONE_ID;
296         }
297         return slotId;
298     }
299 }
300