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 "set-priority":
     60                     return runSetPriority();
     61                 default:
     62                     return handleDefaultCommands(cmd);
     63             }
     64         } catch (IllegalArgumentException e) {
     65             err.println("Error: " + e.getMessage());
     66         } catch (RemoteException e) {
     67             err.println("Remote exception: " + e);
     68         }
     69         return -1;
     70     }
     71 
     72     @Override
     73     public void onHelp() {
     74         final PrintWriter out = getOutPrintWriter();
     75         out.println("Overlay manager (overlay) commands:");
     76         out.println("  help");
     77         out.println("    Print this help text.");
     78         out.println("  dump [--verbose] [--user USER_ID] [PACKAGE [PACKAGE [...]]]");
     79         out.println("    Print debugging information about the overlay manager.");
     80         out.println("  list [--user USER_ID] [PACKAGE [PACKAGE [...]]]");
     81         out.println("    Print information about target and overlay packages.");
     82         out.println("    Overlay packages are printed in priority order. With optional");
     83         out.println("    parameters PACKAGEs, limit output to the specified packages");
     84         out.println("    but include more information about each package.");
     85         out.println("  enable [--user USER_ID] PACKAGE");
     86         out.println("    Enable overlay package PACKAGE.");
     87         out.println("  disable [--user USER_ID] PACKAGE");
     88         out.println("    Disable overlay package PACKAGE.");
     89         out.println("  set-priority [--user USER_ID] PACKAGE PARENT|lowest|highest");
     90         out.println("    Change the priority of the overlay PACKAGE to be just higher than");
     91         out.println("    the priority of PACKAGE_PARENT If PARENT is the special keyword");
     92         out.println("    'lowest', change priority of PACKAGE to the lowest priority.");
     93         out.println("    If PARENT is the special keyword 'highest', change priority of");
     94         out.println("    PACKAGE to the highest priority.");
     95     }
     96 
     97     private int runList() throws RemoteException {
     98         final PrintWriter out = getOutPrintWriter();
     99         final PrintWriter err = getErrPrintWriter();
    100 
    101         int userId = UserHandle.USER_SYSTEM;
    102         String opt;
    103         while ((opt = getNextOption()) != null) {
    104             switch (opt) {
    105                 case "--user":
    106                     userId = UserHandle.parseUserArg(getNextArgRequired());
    107                     break;
    108                 default:
    109                     err.println("Error: Unknown option: " + opt);
    110                     return 1;
    111             }
    112         }
    113 
    114         final Map<String, List<OverlayInfo>> allOverlays = mInterface.getAllOverlays(userId);
    115         for (final String targetPackageName : allOverlays.keySet()) {
    116             out.println(targetPackageName);
    117             List<OverlayInfo> overlaysForTarget = allOverlays.get(targetPackageName);
    118             final int N = overlaysForTarget.size();
    119             for (int i = 0; i < N; i++) {
    120                 final OverlayInfo oi = overlaysForTarget.get(i);
    121                 String status;
    122                 switch (oi.state) {
    123                     case OverlayInfo.STATE_ENABLED:
    124                         status = "[x]";
    125                         break;
    126                     case OverlayInfo.STATE_DISABLED:
    127                         status = "[ ]";
    128                         break;
    129                     default:
    130                         status = "---";
    131                         break;
    132                 }
    133                 out.println(String.format("%s %s", status, oi.packageName));
    134             }
    135             out.println();
    136         }
    137         return 0;
    138     }
    139 
    140     private int runEnableDisable(final boolean enable) throws RemoteException {
    141         final PrintWriter err = getErrPrintWriter();
    142 
    143         int userId = UserHandle.USER_SYSTEM;
    144         String opt;
    145         while ((opt = getNextOption()) != null) {
    146             switch (opt) {
    147                 case "--user":
    148                     userId = UserHandle.parseUserArg(getNextArgRequired());
    149                     break;
    150                 default:
    151                     err.println("Error: Unknown option: " + opt);
    152                     return 1;
    153             }
    154         }
    155 
    156         final String packageName = getNextArgRequired();
    157         return mInterface.setEnabled(packageName, enable, userId) ? 0 : 1;
    158     }
    159 
    160     private int runSetPriority() throws RemoteException {
    161         final PrintWriter err = getErrPrintWriter();
    162 
    163         int userId = UserHandle.USER_SYSTEM;
    164         String opt;
    165         while ((opt = getNextOption()) != null) {
    166             switch (opt) {
    167                 case "--user":
    168                     userId = UserHandle.parseUserArg(getNextArgRequired());
    169                     break;
    170                 default:
    171                     err.println("Error: Unknown option: " + opt);
    172                     return 1;
    173             }
    174         }
    175 
    176         final String packageName = getNextArgRequired();
    177         final String newParentPackageName = getNextArgRequired();
    178 
    179         if ("highest".equals(newParentPackageName)) {
    180             return mInterface.setHighestPriority(packageName, userId) ? 0 : 1;
    181         } else if ("lowest".equals(newParentPackageName)) {
    182             return mInterface.setLowestPriority(packageName, userId) ? 0 : 1;
    183         } else {
    184             return mInterface.setPriority(packageName, newParentPackageName, userId) ? 0 : 1;
    185         }
    186     }
    187 }
    188