1 /*
2  * Copyright (C) 2022 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.wm.shell;
18 
19 import com.android.wm.shell.protolog.ShellProtoLogImpl;
20 import com.android.wm.shell.sysui.ShellCommandHandler;
21 import com.android.wm.shell.sysui.ShellInit;
22 
23 import java.io.PrintWriter;
24 import java.util.Arrays;
25 
26 /**
27  * Controls the {@link ShellProtoLogImpl} in WMShell via adb shell commands.
28  *
29  * Use with {@code adb shell dumpsys activity service SystemUIService WMShell protolog ...}.
30  */
31 public class ProtoLogController implements ShellCommandHandler.ShellCommandActionHandler {
32     private final ShellCommandHandler mShellCommandHandler;
33     private final ShellProtoLogImpl mShellProtoLog;
34 
ProtoLogController(ShellInit shellInit, ShellCommandHandler shellCommandHandler)35     public ProtoLogController(ShellInit shellInit,
36             ShellCommandHandler shellCommandHandler) {
37         shellInit.addInitCallback(this::onInit, this);
38         mShellCommandHandler = shellCommandHandler;
39         mShellProtoLog = ShellProtoLogImpl.getSingleInstance();
40     }
41 
onInit()42     void onInit() {
43         mShellCommandHandler.addCommandCallback("protolog", this, this);
44     }
45 
46     @Override
onShellCommand(String[] args, PrintWriter pw)47     public boolean onShellCommand(String[] args, PrintWriter pw) {
48         switch (args[0]) {
49             case "status": {
50                 pw.println(mShellProtoLog.getStatus());
51                 return true;
52             }
53             case "start": {
54                 mShellProtoLog.startProtoLog(pw);
55                 return true;
56             }
57             case "stop": {
58                 mShellProtoLog.stopProtoLog(pw, true /* writeToFile */);
59                 return true;
60             }
61             case "enable-text": {
62                 String[] groups = Arrays.copyOfRange(args, 1, args.length);
63                 int result = mShellProtoLog.startTextLogging(groups, pw);
64                 if (result == 0) {
65                     pw.println("Starting logging on groups: " + Arrays.toString(groups));
66                     return true;
67                 }
68                 return false;
69             }
70             case "disable-text": {
71                 String[] groups = Arrays.copyOfRange(args, 1, args.length);
72                 int result = mShellProtoLog.stopTextLogging(groups, pw);
73                 if (result == 0) {
74                     pw.println("Stopping logging on groups: " + Arrays.toString(groups));
75                     return true;
76                 }
77                 return false;
78             }
79             case "enable": {
80                 String[] groups = Arrays.copyOfRange(args, 1, args.length);
81                 return mShellProtoLog.startTextLogging(groups, pw) == 0;
82             }
83             case "disable": {
84                 String[] groups = Arrays.copyOfRange(args, 1, args.length);
85                 return mShellProtoLog.stopTextLogging(groups, pw) == 0;
86             }
87             case "save-for-bugreport": {
88                 if (!mShellProtoLog.isProtoEnabled()) {
89                     pw.println("Logging to proto is not enabled for WMShell.");
90                     return false;
91                 }
92                 mShellProtoLog.stopProtoLog(pw, true /* writeToFile */);
93                 mShellProtoLog.startProtoLog(pw);
94                 return true;
95             }
96             default: {
97                 pw.println("Invalid command: " + args[0]);
98                 printShellCommandHelp(pw, "");
99                 return false;
100             }
101         }
102     }
103 
104     @Override
printShellCommandHelp(PrintWriter pw, String prefix)105     public void printShellCommandHelp(PrintWriter pw, String prefix) {
106         pw.println(prefix + "status");
107         pw.println(prefix + "  Get current ProtoLog status.");
108         pw.println(prefix + "start");
109         pw.println(prefix + "  Start proto logging.");
110         pw.println(prefix + "stop");
111         pw.println(prefix + "  Stop proto logging and flush to file.");
112         pw.println(prefix + "enable [group...]");
113         pw.println(prefix + "  Enable proto logging for given groups.");
114         pw.println(prefix + "disable [group...]");
115         pw.println(prefix + "  Disable proto logging for given groups.");
116         pw.println(prefix + "enable-text [group...]");
117         pw.println(prefix + "  Enable logcat logging for given groups.");
118         pw.println(prefix + "disable-text [group...]");
119         pw.println(prefix + "  Disable logcat logging for given groups.");
120         pw.println(prefix + "save-for-bugreport");
121         pw.println(prefix + "  Flush proto logging to file, only if it's enabled.");
122     }
123 }
124