Link wm shell command to enable protolog in shell

- Pass through unhandled logging commands to SysUI to simplify
  enabling/disabling logging for the shell.

Bug: 168497382
Test: adb shell wm logging enable-text WM_SHELL_TASK_ORG
Test: adb shell wm logging enable-text WM_DEBUG_RECENTS_ANIMATIONS
Change-Id: I37942eaee82fdcf545212b18375f3d3e2638b8ee
This commit is contained in:
Winson Chung
2020-09-14 12:56:42 -07:00
parent 9c9331caee
commit d2b6017684
11 changed files with 137 additions and 33 deletions

View File

@@ -263,6 +263,18 @@ public abstract class BasicShellCommandHandler {
}
}
/**
* @return all the remaining arguments in the command without moving the current position.
*/
public String[] peekRemainingArgs() {
int remaining = getRemainingArgsCount();
String[] args = new String[remaining];
for (int pos = mArgPos; pos < mArgs.length; pos++) {
args[pos - mArgPos] = mArgs[pos];
}
return args;
}
/**
* Returns number of arguments that haven't been processed yet.
*/

View File

@@ -277,7 +277,6 @@ public class BaseProtoLogImpl {
String group = groups[i];
IProtoLogGroup g = LOG_GROUPS.get(group);
if (g != null) {
System.out.println("G: "+ g);
if (setTextLogging) {
g.setLogToLogcat(value);
} else {

View File

@@ -22,6 +22,7 @@ import android.graphics.Rect;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.service.notification.StatusBarNotification;
import com.android.internal.statusbar.StatusBarIcon;
@@ -223,6 +224,11 @@ 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

@@ -24,6 +24,8 @@ import com.android.internal.protolog.common.IProtoLogGroup;
* This file is used by the ProtoLogTool to generate optimized logging code.
*/
public enum ShellProtoLogGroup implements IProtoLogGroup {
// NOTE: Since we enable these from the same WM ShellCommand, these names should not conflict
// with those in the framework ProtoLogGroup
WM_SHELL_TASK_ORG(Consts.ENABLE_DEBUG, Consts.ENABLE_LOG_TO_PROTO_DEBUG, false,
Consts.TAG_WM_SHELL),
TEST_GROUP(true, true, false, "WindowManagerShellProtoLogTest");

View File

@@ -44,8 +44,6 @@ public class ShellProtoLogImpl extends BaseProtoLogImpl {
private static ShellProtoLogImpl sServiceInstance = null;
private final PrintWriter mSystemOutWriter;
static {
addLogGroupEnum(ShellProtoLogGroup.values());
}
@@ -111,11 +109,11 @@ public class ShellProtoLogImpl extends BaseProtoLogImpl {
return sServiceInstance;
}
public void startTextLogging(Context context, String... groups) {
public int startTextLogging(Context context, String[] groups, PrintWriter pw) {
try {
mViewerConfig.loadViewerConfig(
context.getResources().openRawResource(R.raw.wm_shell_protolog));
setLogging(true /* setTextLogging */, true, mSystemOutWriter, groups);
return setLogging(true /* setTextLogging */, true, pw, groups);
} catch (IOException e) {
Log.i(TAG, "Unable to load log definitions: IOException while reading "
+ "wm_shell_protolog. " + e);
@@ -123,16 +121,15 @@ public class ShellProtoLogImpl extends BaseProtoLogImpl {
Log.i(TAG, "Unable to load log definitions: JSON parsing exception while reading "
+ "wm_shell_protolog. " + e);
}
return -1;
}
public void stopTextLogging(String... groups) {
setLogging(true /* setTextLogging */, false, mSystemOutWriter, groups);
public int stopTextLogging(String[] groups, PrintWriter pw) {
return setLogging(true /* setTextLogging */, false, pw, groups);
}
private ShellProtoLogImpl() {
super(new File(LOG_FILENAME), null, BUFFER_CAPACITY,
new ProtoLogViewerConfigReader());
mSystemOutWriter = new PrintWriter(System.out, true);
super(new File(LOG_FILENAME), null, BUFFER_CAPACITY, new ProtoLogViewerConfigReader());
}
}

View File

@@ -44,6 +44,8 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.view.InsetsState.InternalInsetsType;
@@ -59,7 +61,9 @@ import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.policy.CallbackController;
import com.android.systemui.tracing.ProtoTracer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
/**
* This class takes the functions from IStatusBar that come in on
@@ -70,6 +74,8 @@ import java.util.ArrayList;
*/
public class CommandQueue extends IStatusBar.Stub implements CallbackController<Callbacks>,
DisplayManager.DisplayListener {
private static final String TAG = CommandQueue.class.getSimpleName();
private static final int INDEX_MASK = 0xffff;
private static final int MSG_SHIFT = 16;
private static final int MSG_MASK = 0xffff << MSG_SHIFT;
@@ -131,6 +137,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
private static final int MSG_TRACING_STATE_CHANGED = 55 << MSG_SHIFT;
private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 56 << MSG_SHIFT;
private static final int MSG_REQUEST_WINDOW_MAGNIFICATION_CONNECTION = 57 << MSG_SHIFT;
private static final int MSG_HANDLE_WINDOW_MANAGER_LOGGING_COMMAND = 58 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -353,6 +360,11 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
* @param connect {@code true} if needs connection, otherwise set the connection to null.
*/
default void requestWindowMagnificationConnection(boolean connect) { }
/**
* Handles a window manager shell logging command.
*/
default void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {}
}
public CommandQueue(Context context) {
@@ -983,6 +995,17 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
}
}
@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) {
@@ -1334,6 +1357,18 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
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;
}
}
}

View File

@@ -28,6 +28,7 @@ import android.content.Context;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import com.android.internal.annotations.VisibleForTesting;
@@ -56,6 +57,7 @@ import com.android.wm.shell.protolog.ShellProtoLogImpl;
import com.android.wm.shell.splitscreen.SplitScreen;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Optional;
@@ -66,7 +68,8 @@ import javax.inject.Inject;
* Proxy in SysUiScope to delegate events to controllers in WM Shell library.
*/
@SysUISingleton
public final class WMShell extends SystemUI implements ProtoTraceable<SystemUiTraceProto> {
public final class WMShell extends SystemUI
implements CommandQueue.Callbacks, ProtoTraceable<SystemUiTraceProto> {
private final CommandQueue mCommandQueue;
private final DisplayImeController mDisplayImeController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -100,6 +103,7 @@ public final class WMShell extends SystemUI implements ProtoTraceable<SystemUiTr
ProtoTracer protoTracer) {
super(context);
mCommandQueue = commandQueue;
mCommandQueue.addCallback(this);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mActivityManagerWrapper = activityManagerWrapper;
mDisplayImeController = displayImeController;
@@ -293,31 +297,43 @@ public final class WMShell extends SystemUI implements ProtoTraceable<SystemUiTr
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
// Handle commands if provided
for (int i = 0; i < args.length; i++) {
switch (args[i]) {
case "enable-text-logging": {
String[] groups = Arrays.copyOfRange(args, i + 1, args.length);
startTextLogging(groups);
pw.println("Starting logging on groups: " + Arrays.toString(groups));
return;
}
case "disable-text-logging": {
String[] groups = Arrays.copyOfRange(args, i + 1, args.length);
stopTextLogging(groups);
pw.println("Stopping logging on groups: " + Arrays.toString(groups));
return;
}
}
if (handleLoggingCommand(args, pw)) {
return;
}
// Dump WMShell stuff here if no commands were handled
}
private void startTextLogging(String... groups) {
ShellProtoLogImpl.getSingleInstance().startTextLogging(mContext, groups);
@Override
public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
PrintWriter pw = new PrintWriter(new ParcelFileDescriptor.AutoCloseOutputStream(outFd));
handleLoggingCommand(args, pw);
pw.flush();
pw.close();
}
private void stopTextLogging(String... groups) {
ShellProtoLogImpl.getSingleInstance().stopTextLogging(groups);
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(mContext, 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

@@ -17,6 +17,7 @@
package com.android.systemui.wmshell;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -88,7 +89,8 @@ public class WMShellTest extends SysuiTestCase {
public void initPip_registersCommandQueueCallback() {
mWMShell.initPip(mPip);
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
// Once for the shell, once for pip
verify(mCommandQueue, times(2)).addCallback(any(CommandQueue.Callbacks.class));
}
@Test
@@ -106,7 +108,8 @@ public class WMShellTest extends SysuiTestCase {
mWMShell.initOneHanded(mOneHanded);
verify(mKeyguardUpdateMonitor).registerCallback(any(KeyguardUpdateMonitorCallback.class));
verify(mCommandQueue).addCallback(any(CommandQueue.Callbacks.class));
// Once for the shell, once for the one handed mode
verify(mCommandQueue, times(2)).addCallback(any(CommandQueue.Callbacks.class));
verify(mScreenLifecycle).addObserver(any(ScreenLifecycle.Observer.class));
verify(mNavigationModeController).addListener(
any(NavigationModeController.ModeChangedListener.class));

View File

@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.app.ITransientNotificationCallback;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.view.InsetsState.InternalInsetsType;
import android.view.WindowInsetsController.Appearance;
@@ -143,4 +144,9 @@ public interface StatusBarManagerInternal {
* request)
*/
void requestWindowMagnificationConnection(boolean request);
/**
* Handles a logging command from the WM shell command.
*/
void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd);
}

View File

@@ -36,6 +36,7 @@ import android.os.Binder;
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;
@@ -534,6 +535,15 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
} catch (RemoteException ex) { }
}
}
@Override
public void handleWindowManagerLoggingCommand(String[] args, ParcelFileDescriptor outFd) {
if (mBar != null) {
try {
mBar.handleWindowManagerLoggingCommand(args, outFd);
} catch (RemoteException ex) { }
}
}
};
private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() {

View File

@@ -20,6 +20,7 @@ import static android.os.Build.IS_USER;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ShellCommand;
import android.os.UserHandle;
@@ -32,10 +33,13 @@ 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 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;
@@ -83,7 +87,21 @@ public class WindowManagerShellCommand extends ShellCommand {
// trace files can be written.
return mInternal.mWindowTracing.onShellCommand(this);
case "logging":
return ProtoLogImpl.getSingleInstance().onShellCommand(this);
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());
}
}
return result;
case "set-user-rotation":
return runSetDisplayUserRotation(pw);
case "set-fix-to-user-rotation":