Handle ProtoLog logging command in WMShell

Added a ProtoLogController class that hooks into ShellCommandHandler to
handle the adb shell command for ProtoLog in WMShell.

Removed the proxy in WM to pipe the adb shell command to WMShell via
StatusBarManagerService.

Bug: 243447162
Test: adb shell dumpsys activity service \
        SystemUIService WMShell protolog help
Change-Id: I9175ec88dcbae53508c97b4df1c2378b3eb9d648
This commit is contained in:
Hongwei Wang
2022-08-31 13:39:09 -07:00
parent 77338a2cf4
commit 5ec2f4d52e
8 changed files with 125 additions and 107 deletions

View File

@@ -263,11 +263,6 @@ oneway interface IStatusBar
*/
void stopTracing();
/**
* Handles a logging command from the WM shell command.
*/
void handleWindowManagerLoggingCommand(in String[] args, in ParcelFileDescriptor outFd);
/**
* If true, suppresses the ambient display from showing. If false, re-enables the ambient
* display.

View File

@@ -0,0 +1,112 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.wm.shell;
import com.android.wm.shell.protolog.ShellProtoLogImpl;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellInit;
import java.io.PrintWriter;
import java.util.Arrays;
/**
* Controls the {@link ShellProtoLogImpl} in WMShell via adb shell commands.
*
* Use with {@code adb shell dumpsys activity service SystemUIService WMShell protolog ...}.
*/
public class ProtoLogController implements ShellCommandHandler.ShellCommandActionHandler {
private final ShellCommandHandler mShellCommandHandler;
private final ShellProtoLogImpl mShellProtoLog;
public ProtoLogController(ShellInit shellInit,
ShellCommandHandler shellCommandHandler) {
shellInit.addInitCallback(this::onInit, this);
mShellCommandHandler = shellCommandHandler;
mShellProtoLog = ShellProtoLogImpl.getSingleInstance();
}
void onInit() {
mShellCommandHandler.addCommandCallback("protolog", this, this);
}
@Override
public boolean onShellCommand(String[] args, PrintWriter pw) {
switch (args[0]) {
case "status": {
pw.println(mShellProtoLog.getStatus());
return true;
}
case "start": {
mShellProtoLog.startProtoLog(pw);
return true;
}
case "stop": {
mShellProtoLog.stopProtoLog(pw, true /* writeToFile */);
return true;
}
case "enable-text": {
String[] groups = Arrays.copyOfRange(args, 1, args.length);
int result = mShellProtoLog.startTextLogging(groups, pw);
if (result == 0) {
pw.println("Starting logging on groups: " + Arrays.toString(groups));
return true;
}
return false;
}
case "disable-text": {
String[] groups = Arrays.copyOfRange(args, 1, args.length);
int result = mShellProtoLog.stopTextLogging(groups, pw);
if (result == 0) {
pw.println("Stopping logging on groups: " + Arrays.toString(groups));
return true;
}
return false;
}
case "enable": {
String[] groups = Arrays.copyOfRange(args, 1, args.length);
return mShellProtoLog.startTextLogging(groups, pw) == 0;
}
case "disable": {
String[] groups = Arrays.copyOfRange(args, 1, args.length);
return mShellProtoLog.stopTextLogging(groups, pw) == 0;
}
default: {
pw.println("Invalid command: " + args[0]);
printShellCommandHelp(pw, "");
return false;
}
}
}
@Override
public void printShellCommandHelp(PrintWriter pw, String prefix) {
pw.println(prefix + "status");
pw.println(prefix + " Get current ProtoLog status.");
pw.println(prefix + "start");
pw.println(prefix + " Start proto logging.");
pw.println(prefix + "stop");
pw.println(prefix + " Stop proto logging and flush to file.");
pw.println(prefix + "enable [group...]");
pw.println(prefix + " Enable proto logging for given groups.");
pw.println(prefix + "disable [group...]");
pw.println(prefix + " Disable proto logging for given groups.");
pw.println(prefix + "enable-text [group...]");
pw.println(prefix + " Enable logcat logging for given groups.");
pw.println(prefix + "disable-text [group...]");
pw.println(prefix + " Disable logcat logging for given groups.");
}
}

View File

@@ -27,6 +27,7 @@ import android.view.IWindowManager;
import com.android.internal.logging.UiEventLogger;
import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.ProtoLogController;
import com.android.wm.shell.RootDisplayAreaOrganizer;
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
import com.android.wm.shell.ShellTaskOrganizer;
@@ -699,6 +700,7 @@ public abstract class WMShellBaseModule {
Optional<ActivityEmbeddingController> activityEmbeddingOptional,
Transitions transitions,
StartingWindowController startingWindow,
ProtoLogController protoLogController,
@ShellCreateTriggerOverride Optional<Object> overriddenCreateTrigger) {
return new Object();
}
@@ -714,4 +716,12 @@ public abstract class WMShellBaseModule {
static ShellCommandHandler provideShellCommandHandler() {
return new ShellCommandHandler();
}
@WMSingleton
@Provides
static ProtoLogController provideProtoLogController(
ShellInit shellInit,
ShellCommandHandler shellCommandHandler) {
return new ProtoLogController(shellInit, shellCommandHandler);
}
}

View File

@@ -52,7 +52,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.InsetsState.InternalInsetsType;
@@ -76,7 +75,6 @@ import com.android.systemui.statusbar.policy.CallbackController;
import com.android.systemui.tracing.ProtoTracer;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -152,7 +150,6 @@ public class CommandQueue extends IStatusBar.Stub implements
private static final int MSG_TRACING_STATE_CHANGED = 54 << MSG_SHIFT;
private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 55 << MSG_SHIFT;
private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 56 << MSG_SHIFT;
private static final int MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND = 57 << MSG_SHIFT;
//TODO(b/169175022) Update name and when feature name is locked.
private static final int MSG_EMERGENCY_ACTION_LAUNCH_GESTURE = 58 << MSG_SHIFT;
private static final int MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED = 59 << MSG_SHIFT;
@@ -424,11 +421,6 @@ public class CommandQueue extends IStatusBar.Stub implements
*/
default void requestWindowMagnificationConnection(boolean connect) { }
/**
* Handles a window manager shell logging command.
*/
default void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {}
/**
* @see IStatusBar#setNavigationBarLumaSamplingEnabled(int, boolean)
*/
@@ -1142,17 +1134,6 @@ public class CommandQueue extends IStatusBar.Stub implements
}
}
@Override
public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
synchronized (mLock) {
SomeArgs internalArgs = SomeArgs.obtain();
internalArgs.arg1 = args;
internalArgs.arg2 = outFd;
mHandler.obtainMessage(MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND, internalArgs)
.sendToTarget();
}
}
@Override
public void suppressAmbientDisplay(boolean suppress) {
synchronized (mLock) {
@@ -1637,18 +1618,6 @@ public class CommandQueue extends IStatusBar.Stub implements
mCallbacks.get(i).requestWindowMagnificationConnection((Boolean) msg.obj);
}
break;
case MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND:
args = (SomeArgs) msg.obj;
try (ParcelFileDescriptor pfd = (ParcelFileDescriptor) args.arg2) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).handleWindowManagerLoggingCommand(
(String[]) args.arg1, pfd);
}
} catch (IOException e) {
Log.e(TAG, "Failed to handle logging command", e);
}
args.recycle();
break;
case MSG_SET_NAVIGATION_BAR_LUMA_SAMPLING_ENABLED:
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).setNavigationBarLumaSamplingEnabled(msg.arg1,

View File

@@ -34,7 +34,6 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import androidx.annotation.NonNull;
@@ -62,12 +61,10 @@ import com.android.wm.shell.onehanded.OneHandedEventCallback;
import com.android.wm.shell.onehanded.OneHandedTransitionCallback;
import com.android.wm.shell.onehanded.OneHandedUiEventLogger;
import com.android.wm.shell.pip.Pip;
import com.android.wm.shell.protolog.ShellProtoLogImpl;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.sysui.ShellInterface;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -336,44 +333,7 @@ public final class WMShell extends CoreStartable
if (mShell.handleCommand(args, pw)) {
return;
}
// Handle logging commands if provided
if (handleLoggingCommand(args, pw)) {
return;
}
// Dump WMShell stuff here if no commands were handled
mShell.dump(pw);
}
@Override
public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
PrintWriter pw = new PrintWriter(new ParcelFileDescriptor.AutoCloseOutputStream(outFd));
handleLoggingCommand(args, pw);
pw.flush();
pw.close();
}
private boolean handleLoggingCommand(String[] args, PrintWriter pw) {
ShellProtoLogImpl protoLogImpl = ShellProtoLogImpl.getSingleInstance();
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "enable-text": {
String[] groups = Arrays.copyOfRange(args, i + 1, args.length);
int result = protoLogImpl.startTextLogging(groups, pw);
if (result == 0) {
pw.println("Starting logging on groups: " + Arrays.toString(groups));
}
return true;
}
case "disable-text": {
String[] groups = Arrays.copyOfRange(args, i + 1, args.length);
int result = protoLogImpl.stopTextLogging(groups, pw);
if (result == 0) {
pw.println("Stopping logging on groups: " + Arrays.toString(groups));
}
return true;
}
}
}
return false;
}
}

View File

@@ -21,7 +21,6 @@ import android.app.ITransientNotificationCallback;
import android.hardware.fingerprint.IUdfpsHbmListener;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.view.InsetsState.InternalInsetsType;
import android.view.InsetsVisibilities;
import android.view.WindowInsetsController.Appearance;
@@ -161,11 +160,6 @@ public interface StatusBarManagerInternal {
*/
boolean requestWindowMagnificationConnection(boolean request);
/**
* Handles a logging command from the WM shell command.
*/
void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd);
/**
* @see com.android.internal.statusbar.IStatusBar#setNavigationBarLumaSamplingEnabled(int,
* boolean)

View File

@@ -62,7 +62,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -663,15 +662,6 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
return false;
}
@Override
public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
if (mBar != null) {
try {
mBar.handleWindowManagerLoggingCommand(args, outFd);
} catch (RemoteException ex) { }
}
}
@Override
public void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {
if (mBar != null) {

View File

@@ -34,7 +34,6 @@ import android.content.res.Resources.NotFoundException;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.UserHandle;
@@ -47,8 +46,6 @@ import android.view.ViewDebug;
import com.android.internal.os.ByteTransferPipe;
import com.android.internal.protolog.ProtoLogImpl;
import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.LetterboxConfiguration.LetterboxBackgroundType;
import com.android.server.wm.LetterboxConfiguration.LetterboxHorizontalReachabilityPosition;
import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilityPosition;
@@ -56,7 +53,6 @@ import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilit
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
@@ -106,19 +102,11 @@ public class WindowManagerShellCommand extends ShellCommand {
// trace files can be written.
return mInternal.mWindowTracing.onShellCommand(this);
case "logging":
String[] args = peekRemainingArgs();
int result = ProtoLogImpl.getSingleInstance().onShellCommand(this);
if (result != 0) {
// Let the shell try and handle this
try (ParcelFileDescriptor pfd
= ParcelFileDescriptor.dup(getOutFileDescriptor())){
pw.println("Not handled, calling status bar with args: "
+ Arrays.toString(args));
LocalServices.getService(StatusBarManagerInternal.class)
.handleWindowManagerLoggingCommand(args, pfd);
} catch (IOException e) {
pw.println("Failed to handle logging command: " + e.getMessage());
}
pw.println("Not handled, please use "
+ "`adb shell dumpsys activity service SystemUIService WMShell` "
+ "if you are looking for ProtoLog in WMShell");
}
return result;
case "user-rotation":