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:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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":
|
||||
|
||||
Reference in New Issue
Block a user