Home | History | Annotate | Download | only in om
      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 
     41     OverlayManagerShellCommand(@NonNull final IOverlayManager iom) {
     42         mInterface = iom;
     43     }
     44 
     45     @Override
     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
     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 
    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 
    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 
    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 
    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