Add shell side transition trace to bug reports
Test: atest BugreportManagerTestCases Bug: 276701336 Bug: 277181336 Bug: 278691227 Change-Id: If53cce37f4787d4e03fbee4cbe5b2808719e011f
This commit is contained in:
@@ -112,6 +112,7 @@ public class BugreportManagerTest {
|
||||
Paths.get("/data/misc/wmtrace/layers_trace.winscope"),
|
||||
Paths.get("/data/misc/wmtrace/transactions_trace.winscope"),
|
||||
Paths.get("/data/misc/wmtrace/transition_trace.winscope"),
|
||||
Paths.get("/data/misc/wmtrace/shell_transition_trace.winscope"),
|
||||
};
|
||||
private static final Path[] UI_TRACES_GENERATED_DURING_BUGREPORT = {
|
||||
Paths.get("/data/misc/wmtrace/layers_trace_from_transactions.winscope"),
|
||||
|
||||
@@ -544,13 +544,14 @@ public abstract class WMShellBaseModule {
|
||||
DisplayController displayController,
|
||||
@ShellMainThread ShellExecutor mainExecutor,
|
||||
@ShellMainThread Handler mainHandler,
|
||||
@ShellAnimationThread ShellExecutor animExecutor) {
|
||||
@ShellAnimationThread ShellExecutor animExecutor,
|
||||
ShellCommandHandler shellCommandHandler) {
|
||||
if (!context.getResources().getBoolean(R.bool.config_registerShellTransitionsOnInit)) {
|
||||
// TODO(b/238217847): Force override shell init if registration is disabled
|
||||
shellInit = new ShellInit(mainExecutor);
|
||||
}
|
||||
return new Transitions(context, shellInit, shellController, organizer, pool,
|
||||
displayController, mainExecutor, mainHandler, animExecutor);
|
||||
displayController, mainExecutor, mainHandler, animExecutor, shellCommandHandler);
|
||||
}
|
||||
|
||||
@WMSingleton
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.util.Log;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.util.TraceBuffer;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -40,8 +41,9 @@ import java.util.Map;
|
||||
/**
|
||||
* Helper class to collect and dump transition traces.
|
||||
*/
|
||||
public class Tracer {
|
||||
public class Tracer implements ShellCommandHandler.ShellCommandActionHandler {
|
||||
private static final int ALWAYS_ON_TRACING_CAPACITY = 15 * 1024; // 15 KB
|
||||
private static final int ACTIVE_TRACING_BUFFER_CAPACITY = 5000 * 1024; // 5 MB
|
||||
|
||||
private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
|
||||
|
||||
@@ -50,6 +52,7 @@ public class Tracer {
|
||||
"/data/misc/wmtrace/shell_transition_trace" + WINSCOPE_EXT;
|
||||
|
||||
private final Object mEnabledLock = new Object();
|
||||
private boolean mActiveTracingEnabled = false;
|
||||
|
||||
private final TraceBuffer mTraceBuffer = new TraceBuffer(ALWAYS_ON_TRACING_CAPACITY,
|
||||
(proto) -> handleOnEntryRemovedFromTrace(proto));
|
||||
@@ -157,6 +160,54 @@ public class Tracer {
|
||||
mTraceBuffer.add(outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts collecting transitions for the trace.
|
||||
* If called while a trace is already running, this will reset the trace.
|
||||
*/
|
||||
public void startTrace(@Nullable PrintWriter pw) {
|
||||
if (IS_USER) {
|
||||
LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
|
||||
return;
|
||||
}
|
||||
Trace.beginSection("Tracer#startTrace");
|
||||
LogAndPrintln.i(pw, "Starting shell transition trace.");
|
||||
synchronized (mEnabledLock) {
|
||||
mActiveTracingEnabled = true;
|
||||
mTraceBuffer.resetBuffer();
|
||||
mTraceBuffer.setCapacity(ACTIVE_TRACING_BUFFER_CAPACITY);
|
||||
}
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops collecting the transition trace and dump to trace to file.
|
||||
*
|
||||
* Dumps the trace to @link{TRACE_FILE}.
|
||||
*/
|
||||
public void stopTrace(@Nullable PrintWriter pw) {
|
||||
stopTrace(pw, new File(TRACE_FILE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops collecting the transition trace and dump to trace to file.
|
||||
* @param outputFile The file to dump the transition trace to.
|
||||
*/
|
||||
public void stopTrace(@Nullable PrintWriter pw, File outputFile) {
|
||||
if (IS_USER) {
|
||||
LogAndPrintln.e(pw, "Tracing is not supported on user builds.");
|
||||
return;
|
||||
}
|
||||
Trace.beginSection("Tracer#stopTrace");
|
||||
LogAndPrintln.i(pw, "Stopping shell transition trace.");
|
||||
synchronized (mEnabledLock) {
|
||||
mActiveTracingEnabled = false;
|
||||
writeTraceToFileLocked(pw, outputFile);
|
||||
mTraceBuffer.resetBuffer();
|
||||
mTraceBuffer.setCapacity(ALWAYS_ON_TRACING_CAPACITY);
|
||||
}
|
||||
Trace.endSection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Being called while taking a bugreport so that tracing files can be included in the bugreport.
|
||||
*
|
||||
@@ -213,6 +264,39 @@ public class Tracer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShellCommand(String[] args, PrintWriter pw) {
|
||||
switch (args[0]) {
|
||||
case "start": {
|
||||
startTrace(pw);
|
||||
return true;
|
||||
}
|
||||
case "stop": {
|
||||
stopTrace(pw);
|
||||
return true;
|
||||
}
|
||||
case "save-for-bugreport": {
|
||||
saveForBugreport(pw);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
pw.println("Invalid command: " + args[0]);
|
||||
printShellCommandHelp(pw, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printShellCommandHelp(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "start");
|
||||
pw.println(prefix + " Start tracing the transitions.");
|
||||
pw.println(prefix + "stop");
|
||||
pw.println(prefix + " Stop tracing the transitions.");
|
||||
pw.println(prefix + "save-for-bugreport");
|
||||
pw.println(prefix + " Flush in memory transition trace to file.");
|
||||
}
|
||||
|
||||
private static class LogAndPrintln {
|
||||
private static final String LOG_TAG = "ShellTransitionTracer";
|
||||
|
||||
|
||||
@@ -74,10 +74,12 @@ import com.android.wm.shell.common.ShellExecutor;
|
||||
import com.android.wm.shell.common.TransactionPool;
|
||||
import com.android.wm.shell.common.annotations.ExternalThread;
|
||||
import com.android.wm.shell.protolog.ShellProtoLogGroup;
|
||||
import com.android.wm.shell.sysui.ShellCommandHandler;
|
||||
import com.android.wm.shell.sysui.ShellController;
|
||||
import com.android.wm.shell.sysui.ShellInit;
|
||||
import com.android.wm.shell.util.TransitionUtil;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -106,7 +108,8 @@ import java.util.Arrays;
|
||||
* track, it will be marked as SYNC. This means that all currently active tracks must be flushed
|
||||
* before the SYNC transition can play.
|
||||
*/
|
||||
public class Transitions implements RemoteCallable<Transitions> {
|
||||
public class Transitions implements RemoteCallable<Transitions>,
|
||||
ShellCommandHandler.ShellCommandActionHandler {
|
||||
static final String TAG = "ShellTransitions";
|
||||
|
||||
/** Set to {@code true} to enable shell transitions. */
|
||||
@@ -171,6 +174,9 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
/** List of possible handlers. Ordered by specificity (eg. tapped back to front). */
|
||||
private final ArrayList<TransitionHandler> mHandlers = new ArrayList<>();
|
||||
|
||||
@Nullable
|
||||
private final ShellCommandHandler mShellCommandHandler;
|
||||
|
||||
private final ArrayList<TransitionObserver> mObservers = new ArrayList<>();
|
||||
|
||||
/** List of {@link Runnable} instances to run when the last active transition has finished. */
|
||||
@@ -246,8 +252,23 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
@NonNull WindowOrganizer organizer,
|
||||
@NonNull TransactionPool pool,
|
||||
@NonNull DisplayController displayController,
|
||||
@NonNull ShellExecutor mainExecutor, @NonNull Handler mainHandler,
|
||||
@NonNull ShellExecutor mainExecutor,
|
||||
@NonNull Handler mainHandler,
|
||||
@NonNull ShellExecutor animExecutor) {
|
||||
this(context, shellInit, shellController, organizer, pool, displayController, mainExecutor,
|
||||
mainHandler, animExecutor, null);
|
||||
}
|
||||
|
||||
public Transitions(@NonNull Context context,
|
||||
@NonNull ShellInit shellInit,
|
||||
@NonNull ShellController shellController,
|
||||
@NonNull WindowOrganizer organizer,
|
||||
@NonNull TransactionPool pool,
|
||||
@NonNull DisplayController displayController,
|
||||
@NonNull ShellExecutor mainExecutor,
|
||||
@NonNull Handler mainHandler,
|
||||
@NonNull ShellExecutor animExecutor,
|
||||
@Nullable ShellCommandHandler shellCommandHandler) {
|
||||
mOrganizer = organizer;
|
||||
mContext = context;
|
||||
mMainExecutor = mainExecutor;
|
||||
@@ -263,6 +284,7 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Default");
|
||||
// Next lowest priority is remote transitions.
|
||||
mHandlers.add(mRemoteTransitionHandler);
|
||||
mShellCommandHandler = shellCommandHandler;
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Remote");
|
||||
shellInit.addInitCallback(this::onInit, this);
|
||||
}
|
||||
@@ -294,6 +316,10 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
// Pre-load the instance.
|
||||
TransitionMetrics.getInstance();
|
||||
}
|
||||
|
||||
if (mShellCommandHandler != null) {
|
||||
mShellCommandHandler.addCommandCallback("transitions", this, this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRegistered() {
|
||||
@@ -1373,4 +1399,26 @@ public class Transitions implements RemoteCallable<Transitions> {
|
||||
mMainExecutor.execute(() -> dispatchAnimScaleSetting(mTransitionAnimationScaleSetting));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onShellCommand(String[] args, PrintWriter pw) {
|
||||
switch (args[0]) {
|
||||
case "tracing": {
|
||||
mTracer.onShellCommand(Arrays.copyOfRange(args, 1, args.length), pw);
|
||||
return true;
|
||||
}
|
||||
default: {
|
||||
pw.println("Invalid command: " + args[0]);
|
||||
printShellCommandHelp(pw, "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printShellCommandHelp(PrintWriter pw, String prefix) {
|
||||
pw.println(prefix + "tracing");
|
||||
mTracer.printShellCommandHelp(pw, prefix + " ");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user