• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.server.om;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.om.IOverlayManager;
22 import android.content.om.OverlayInfo;
23 import android.os.RemoteException;
24 import android.os.ShellCommand;
25 import android.os.UserHandle;
26 
27 import java.io.PrintWriter;
28 import java.util.List;
29 import java.util.Map;
30 
31 /**
32  * Implementation of 'cmd overlay' commands.
33  *
34  * This class provides an interface to the OverlayManagerService via adb.
35  * Intended only for manual debugging. Execute 'adb exec-out cmd overlay help'
36  * for a list of available commands.
37  */
38 final class OverlayManagerShellCommand extends ShellCommand {
39     private final IOverlayManager mInterface;
40 
OverlayManagerShellCommand(@onNull final IOverlayManager iom)41     OverlayManagerShellCommand(@NonNull final IOverlayManager iom) {
42         mInterface = iom;
43     }
44 
45     @Override
onCommand(@ullable final String cmd)46     public int onCommand(@Nullable final String cmd) {
47         if (cmd == null) {
48             return handleDefaultCommands(cmd);
49         }
50         final PrintWriter err = getErrPrintWriter();
51         try {
52             switch (cmd) {
53                 case "list":
54                     return runList();
55                 case "enable":
56                     return runEnableDisable(true);
57                 case "disable":
58                     return runEnableDisable(false);
59                 case "enable-exclusive":
60                     return runEnableExclusive();
61                 case "set-priority":
62                     return runSetPriority();
63                 default:
64                     return handleDefaultCommands(cmd);
65             }
66         } catch (IllegalArgumentException e) {
67             err.println("Error: " + e.getMessage());
68         } catch (RemoteException e) {
69             err.println("Remote exception: " + e);
70         }
71         return -1;
72     }
73 
74     @Override
onHelp()75     public void onHelp() {
76         final PrintWriter out = getOutPrintWriter();
77         out.println("Overlay manager (overlay) commands:");
78         out.println("  help");
79         out.println("    Print this help text.");
80         out.println("  dump [--verbose] [--user USER_ID] [[FIELD] PACKAGE]");
81         out.println("    Print debugging information about the overlay manager.");
82         out.println("    With optional parameter PACKAGE, limit output to the specified");
83         out.println("    package. With optional parameter FIELD, limit output to");
84         out.println("    the value of that SettingsItem field. Field names are");
85         out.println("    case insensitive and out.println the m prefix can be omitted,");
86         out.println("    so the following are equivalent: mState, mstate, State, state.");
87         out.println("  list [--user USER_ID] [PACKAGE]");
88         out.println("    Print information about target and overlay packages.");
89         out.println("    Overlay packages are printed in priority order. With optional");
90         out.println("    parameter PACKAGE, limit output to the specified package.");
91         out.println("  enable [--user USER_ID] PACKAGE");
92         out.println("    Enable overlay package PACKAGE.");
93         out.println("  disable [--user USER_ID] PACKAGE");
94         out.println("    Disable overlay package PACKAGE.");
95         out.println("  enable-exclusive [--user USER_ID] [--category] PACKAGE");
96         out.println("    Enable overlay package PACKAGE and disable all other overlays for");
97         out.println("    its target package. If the --category option is given, only disables");
98         out.println("    other overlays in the same category.");
99         out.println("  set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest");
100         out.println("    Change the priority of the overlay PACKAGE to be just higher than");
101         out.println("    the priority of PACKAGE_PARENT If PARENT is the special keyword");
102         out.println("    'lowest', change priority of PACKAGE to the lowest priority.");
103         out.println("    If PARENT is the special keyword 'highest', change priority of");
104         out.println("    PACKAGE to the highest priority.");
105     }
106 
runList()107     private int runList() throws RemoteException {
108         final PrintWriter out = getOutPrintWriter();
109         final PrintWriter err = getErrPrintWriter();
110 
111         int userId = UserHandle.USER_SYSTEM;
112         String opt;
113         while ((opt = getNextOption()) != null) {
114             switch (opt) {
115                 case "--user":
116                     userId = UserHandle.parseUserArg(getNextArgRequired());
117                     break;
118                 default:
119                     err.println("Error: Unknown option: " + opt);
120                     return 1;
121             }
122         }
123 
124         final String packageName = getNextArg();
125         if (packageName != null) {
126             List<OverlayInfo> overlaysForTarget = mInterface.getOverlayInfosForTarget(
127                     packageName, userId);
128 
129             // If the package is not targeted by any overlays, check if the package is an overlay.
130             if (overlaysForTarget.isEmpty()) {
131                 final OverlayInfo info = mInterface.getOverlayInfo(packageName, userId);
132                 if (info != null) {
133                     printListOverlay(out, info);
134                 }
135                 return 0;
136             }
137 
138             out.println(packageName);
139 
140             // Print the overlays for the target.
141             final int n = overlaysForTarget.size();
142             for (int i = 0; i < n; i++) {
143                 printListOverlay(out, overlaysForTarget.get(i));
144             }
145 
146             return 0;
147         }
148 
149         // Print all overlays grouped by target package name.
150         final Map<String, List<OverlayInfo>> allOverlays = mInterface.getAllOverlays(userId);
151         for (final String targetPackageName : allOverlays.keySet()) {
152             out.println(targetPackageName);
153 
154             List<OverlayInfo> overlaysForTarget = allOverlays.get(targetPackageName);
155             final int n = overlaysForTarget.size();
156             for (int i = 0; i < n; i++) {
157                 printListOverlay(out, overlaysForTarget.get(i));
158             }
159             out.println();
160         }
161 
162         return 0;
163     }
164 
printListOverlay(PrintWriter out, OverlayInfo oi)165     private void printListOverlay(PrintWriter out, OverlayInfo oi) {
166         String status;
167         switch (oi.state) {
168             case OverlayInfo.STATE_ENABLED_STATIC:
169             case OverlayInfo.STATE_ENABLED:
170                 status = "[x]";
171                 break;
172             case OverlayInfo.STATE_DISABLED:
173                 status = "[ ]";
174                 break;
175             default:
176                 status = "---";
177                 break;
178         }
179         out.println(String.format("%s %s", status, oi.packageName));
180     }
181 
runEnableDisable(final boolean enable)182     private int runEnableDisable(final boolean enable) throws RemoteException {
183         final PrintWriter err = getErrPrintWriter();
184 
185         int userId = UserHandle.USER_SYSTEM;
186         String opt;
187         while ((opt = getNextOption()) != null) {
188             switch (opt) {
189                 case "--user":
190                     userId = UserHandle.parseUserArg(getNextArgRequired());
191                     break;
192                 default:
193                     err.println("Error: Unknown option: " + opt);
194                     return 1;
195             }
196         }
197 
198         final String packageName = getNextArgRequired();
199         return mInterface.setEnabled(packageName, enable, userId) ? 0 : 1;
200     }
201 
runEnableExclusive()202     private int runEnableExclusive() throws RemoteException {
203         final PrintWriter err = getErrPrintWriter();
204 
205         int userId = UserHandle.USER_SYSTEM;
206         boolean inCategory = false;
207         String opt;
208         while ((opt = getNextOption()) != null) {
209             switch (opt) {
210                 case "--user":
211                     userId = UserHandle.parseUserArg(getNextArgRequired());
212                     break;
213                 case "--category":
214                     inCategory = true;
215                     break;
216                 default:
217                     err.println("Error: Unknown option: " + opt);
218                     return 1;
219             }
220         }
221         final String overlay = getNextArgRequired();
222         if (inCategory) {
223             return mInterface.setEnabledExclusiveInCategory(overlay, userId) ? 0 : 1;
224         } else {
225             return mInterface.setEnabledExclusive(overlay, true, userId) ? 0 : 1;
226         }
227     }
228 
runSetPriority()229     private int runSetPriority() throws RemoteException {
230         final PrintWriter err = getErrPrintWriter();
231 
232         int userId = UserHandle.USER_SYSTEM;
233         String opt;
234         while ((opt = getNextOption()) != null) {
235             switch (opt) {
236                 case "--user":
237                     userId = UserHandle.parseUserArg(getNextArgRequired());
238                     break;
239                 default:
240                     err.println("Error: Unknown option: " + opt);
241                     return 1;
242             }
243         }
244 
245         final String packageName = getNextArgRequired();
246         final String newParentPackageName = getNextArgRequired();
247 
248         if ("highest".equals(newParentPackageName)) {
249             return mInterface.setHighestPriority(packageName, userId) ? 0 : 1;
250         } else if ("lowest".equals(newParentPackageName)) {
251             return mInterface.setLowestPriority(packageName, userId) ? 0 : 1;
252         } else {
253             return mInterface.setPriority(packageName, newParentPackageName, userId) ? 0 : 1;
254         }
255     }
256 }
257