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] [PACKAGE [PACKAGE [...]]]"); 81 out.println(" Print debugging information about the overlay manager."); 82 out.println(" list [--user USER_ID] [PACKAGE [PACKAGE [...]]]"); 83 out.println(" Print information about target and overlay packages."); 84 out.println(" Overlay packages are printed in priority order. With optional"); 85 out.println(" parameters PACKAGEs, limit output to the specified packages"); 86 out.println(" but include more information about each package."); 87 out.println(" enable [--user USER_ID] PACKAGE"); 88 out.println(" Enable overlay package PACKAGE."); 89 out.println(" disable [--user USER_ID] PACKAGE"); 90 out.println(" Disable overlay package PACKAGE."); 91 out.println(" enable-exclusive [--user USER_ID] [--category] PACKAGE"); 92 out.println(" Enable overlay package PACKAGE and disable all other overlays for"); 93 out.println(" its target package. If the --category option is given, only disables"); 94 out.println(" other overlays in the same category."); 95 out.println(" set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest"); 96 out.println(" Change the priority of the overlay PACKAGE to be just higher than"); 97 out.println(" the priority of PACKAGE_PARENT If PARENT is the special keyword"); 98 out.println(" 'lowest', change priority of PACKAGE to the lowest priority."); 99 out.println(" If PARENT is the special keyword 'highest', change priority of"); 100 out.println(" PACKAGE to the highest priority."); 101 } 102 runList()103 private int runList() throws RemoteException { 104 final PrintWriter out = getOutPrintWriter(); 105 final PrintWriter err = getErrPrintWriter(); 106 107 int userId = UserHandle.USER_SYSTEM; 108 String opt; 109 while ((opt = getNextOption()) != null) { 110 switch (opt) { 111 case "--user": 112 userId = UserHandle.parseUserArg(getNextArgRequired()); 113 break; 114 default: 115 err.println("Error: Unknown option: " + opt); 116 return 1; 117 } 118 } 119 120 final Map<String, List<OverlayInfo>> allOverlays = mInterface.getAllOverlays(userId); 121 for (final String targetPackageName : allOverlays.keySet()) { 122 out.println(targetPackageName); 123 List<OverlayInfo> overlaysForTarget = allOverlays.get(targetPackageName); 124 final int N = overlaysForTarget.size(); 125 for (int i = 0; i < N; i++) { 126 final OverlayInfo oi = overlaysForTarget.get(i); 127 String status; 128 switch (oi.state) { 129 case OverlayInfo.STATE_ENABLED_STATIC: 130 case OverlayInfo.STATE_ENABLED: 131 status = "[x]"; 132 break; 133 case OverlayInfo.STATE_DISABLED: 134 status = "[ ]"; 135 break; 136 default: 137 status = "---"; 138 break; 139 } 140 out.println(String.format("%s %s", status, oi.packageName)); 141 } 142 out.println(); 143 } 144 return 0; 145 } 146 runEnableDisable(final boolean enable)147 private int runEnableDisable(final boolean enable) throws RemoteException { 148 final PrintWriter err = getErrPrintWriter(); 149 150 int userId = UserHandle.USER_SYSTEM; 151 String opt; 152 while ((opt = getNextOption()) != null) { 153 switch (opt) { 154 case "--user": 155 userId = UserHandle.parseUserArg(getNextArgRequired()); 156 break; 157 default: 158 err.println("Error: Unknown option: " + opt); 159 return 1; 160 } 161 } 162 163 final String packageName = getNextArgRequired(); 164 return mInterface.setEnabled(packageName, enable, userId) ? 0 : 1; 165 } 166 runEnableExclusive()167 private int runEnableExclusive() throws RemoteException { 168 final PrintWriter err = getErrPrintWriter(); 169 170 int userId = UserHandle.USER_SYSTEM; 171 boolean inCategory = false; 172 String opt; 173 while ((opt = getNextOption()) != null) { 174 switch (opt) { 175 case "--user": 176 userId = UserHandle.parseUserArg(getNextArgRequired()); 177 break; 178 case "--category": 179 inCategory = true; 180 break; 181 default: 182 err.println("Error: Unknown option: " + opt); 183 return 1; 184 } 185 } 186 final String overlay = getNextArgRequired(); 187 if (inCategory) { 188 return mInterface.setEnabledExclusiveInCategory(overlay, userId) ? 0 : 1; 189 } else { 190 return mInterface.setEnabledExclusive(overlay, true, userId) ? 0 : 1; 191 } 192 } 193 runSetPriority()194 private int runSetPriority() throws RemoteException { 195 final PrintWriter err = getErrPrintWriter(); 196 197 int userId = UserHandle.USER_SYSTEM; 198 String opt; 199 while ((opt = getNextOption()) != null) { 200 switch (opt) { 201 case "--user": 202 userId = UserHandle.parseUserArg(getNextArgRequired()); 203 break; 204 default: 205 err.println("Error: Unknown option: " + opt); 206 return 1; 207 } 208 } 209 210 final String packageName = getNextArgRequired(); 211 final String newParentPackageName = getNextArgRequired(); 212 213 if ("highest".equals(newParentPackageName)) { 214 return mInterface.setHighestPriority(packageName, userId) ? 0 : 1; 215 } else if ("lowest".equals(newParentPackageName)) { 216 return mInterface.setLowestPriority(packageName, userId) ? 0 : 1; 217 } else { 218 return mInterface.setPriority(packageName, newParentPackageName, userId) ? 0 : 1; 219 } 220 } 221 } 222