Merge "Revert "Revert "Add ability to trace shell transitions""" into tm-qpr-dev am: 9fd0212e95
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18619887 Change-Id: I0b891a8addb77fd5012cd98ed809133728a13637 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -542,6 +542,21 @@ interface IWindowManager
|
|||||||
*/
|
*/
|
||||||
boolean isWindowTraceEnabled();
|
boolean isWindowTraceEnabled();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a transition trace.
|
||||||
|
*/
|
||||||
|
void startTransitionTrace();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops a transition trace.
|
||||||
|
*/
|
||||||
|
void stopTransitionTrace();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if transition trace is enabled.
|
||||||
|
*/
|
||||||
|
boolean isTransitionTraceEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the windowing mode of the display.
|
* Gets the windowing mode of the display.
|
||||||
*
|
*
|
||||||
|
|||||||
68
core/proto/android/server/windowmanagertransitiontrace.proto
Normal file
68
core/proto/android/server/windowmanagertransitiontrace.proto
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package com.android.server.wm.shell;
|
||||||
|
|
||||||
|
import "frameworks/base/core/proto/android/server/windowmanagerservice.proto";
|
||||||
|
|
||||||
|
option java_multiple_files = true;
|
||||||
|
|
||||||
|
/* Represents a file full of transition entries.
|
||||||
|
Encoded, it should start with 0x9 0x57 0x49 0x4e 0x54 0x52 0x41 0x43 0x45 (.TRNTRACE), such
|
||||||
|
that it can be easily identified. */
|
||||||
|
message TransitionTraceProto {
|
||||||
|
|
||||||
|
/* constant; MAGIC_NUMBER = (long) MAGIC_NUMBER_H << 32 | MagicNumber.MAGIC_NUMBER_L
|
||||||
|
(this is needed because enums have to be 32 bits and there's no nice way to put 64bit
|
||||||
|
constants into .proto files. */
|
||||||
|
enum MagicNumber {
|
||||||
|
INVALID = 0;
|
||||||
|
MAGIC_NUMBER_L = 0x544e5254; /* TRNT (little-endian ASCII) */
|
||||||
|
MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */
|
||||||
|
}
|
||||||
|
|
||||||
|
fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */
|
||||||
|
int64 timestamp = 2; /* The timestamp of when the trace was started. */
|
||||||
|
repeated Transition transition = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Transition {
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
COLLECTING = 0;
|
||||||
|
PENDING = -1;
|
||||||
|
STARTED = 1;
|
||||||
|
PLAYING = 2;
|
||||||
|
ABORT = 3;
|
||||||
|
FINISHED = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 id = 1;
|
||||||
|
int32 transition_type = 2;
|
||||||
|
int64 timestamp = 3;
|
||||||
|
State state = 5;
|
||||||
|
int32 flags = 6;
|
||||||
|
repeated ChangeInfo change = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ChangeInfo {
|
||||||
|
com.android.server.wm.IdentifierProto window_identifier = 1;
|
||||||
|
int32 transit_mode = 2;
|
||||||
|
bool has_changed = 3;
|
||||||
|
int32 change_flags = 4;
|
||||||
|
}
|
||||||
@@ -95,6 +95,7 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,18 +132,27 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
*/
|
*/
|
||||||
private static final int STATE_ABORT = 3;
|
private static final int STATE_ABORT = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This transition has finished playing successfully.
|
||||||
|
*/
|
||||||
|
private static final int STATE_FINISHED = 4;
|
||||||
|
|
||||||
@IntDef(prefix = { "STATE_" }, value = {
|
@IntDef(prefix = { "STATE_" }, value = {
|
||||||
STATE_PENDING,
|
STATE_PENDING,
|
||||||
STATE_COLLECTING,
|
STATE_COLLECTING,
|
||||||
STATE_STARTED,
|
STATE_STARTED,
|
||||||
STATE_PLAYING,
|
STATE_PLAYING,
|
||||||
STATE_ABORT
|
STATE_ABORT,
|
||||||
|
STATE_FINISHED
|
||||||
})
|
})
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@interface TransitionState {}
|
@interface TransitionState {}
|
||||||
|
|
||||||
final @TransitionType int mType;
|
final @TransitionType int mType;
|
||||||
private int mSyncId = -1;
|
private int mSyncId = -1;
|
||||||
|
// Used for tracking a Transition throughout a lifecycle (i.e. from STATE_COLLECTING to
|
||||||
|
// STATE_FINISHED or STATE_ABORT), and should only be used for testing and debugging.
|
||||||
|
private int mDebugId = -1;
|
||||||
private @TransitionFlags int mFlags;
|
private @TransitionFlags int mFlags;
|
||||||
private final TransitionController mController;
|
private final TransitionController mController;
|
||||||
private final BLASTSyncEngine mSyncEngine;
|
private final BLASTSyncEngine mSyncEngine;
|
||||||
@@ -202,6 +212,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
mFlags = flags;
|
mFlags = flags;
|
||||||
mController = controller;
|
mController = controller;
|
||||||
mSyncEngine = syncEngine;
|
mSyncEngine = syncEngine;
|
||||||
|
|
||||||
|
controller.mTransitionTracer.logState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addFlag(int flag) {
|
void addFlag(int flag) {
|
||||||
@@ -272,11 +284,21 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TransitionState
|
||||||
|
int getState() {
|
||||||
|
return mState;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
int getSyncId() {
|
int getSyncId() {
|
||||||
return mSyncId;
|
return mSyncId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
int getDebugId() {
|
||||||
|
return mDebugId;
|
||||||
|
}
|
||||||
|
|
||||||
@TransitionFlags
|
@TransitionFlags
|
||||||
int getFlags() {
|
int getFlags() {
|
||||||
return mFlags;
|
return mFlags;
|
||||||
@@ -289,6 +311,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
}
|
}
|
||||||
mState = STATE_COLLECTING;
|
mState = STATE_COLLECTING;
|
||||||
mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG);
|
mSyncId = mSyncEngine.startSyncSet(this, timeoutMs, TAG);
|
||||||
|
mDebugId = mSyncId;
|
||||||
|
|
||||||
|
mController.mTransitionTracer.logState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -306,6 +331,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
|
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Starting Transition %d",
|
||||||
mSyncId);
|
mSyncId);
|
||||||
applyReady();
|
applyReady();
|
||||||
|
|
||||||
|
mController.mTransitionTracer.logState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -674,6 +701,9 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
|
|||||||
dc.removeImeSurfaceImmediately();
|
dc.removeImeSurfaceImmediately();
|
||||||
dc.handleCompleteDeferredRemoval();
|
dc.handleCompleteDeferredRemoval();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mState = STATE_FINISHED;
|
||||||
|
mController.mTransitionTracer.logState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void abort() {
|
void abort() {
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ class TransitionController {
|
|||||||
|
|
||||||
private ITransitionPlayer mTransitionPlayer;
|
private ITransitionPlayer mTransitionPlayer;
|
||||||
final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
|
final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
|
||||||
|
final TransitionTracer mTransitionTracer;
|
||||||
|
|
||||||
private IApplicationThread mTransitionPlayerThread;
|
private IApplicationThread mTransitionPlayerThread;
|
||||||
final ActivityTaskManagerService mAtm;
|
final ActivityTaskManagerService mAtm;
|
||||||
@@ -100,10 +101,12 @@ class TransitionController {
|
|||||||
final StatusBarManagerInternal mStatusBar;
|
final StatusBarManagerInternal mStatusBar;
|
||||||
|
|
||||||
TransitionController(ActivityTaskManagerService atm,
|
TransitionController(ActivityTaskManagerService atm,
|
||||||
TaskSnapshotController taskSnapshotController) {
|
TaskSnapshotController taskSnapshotController,
|
||||||
|
TransitionTracer transitionTracer) {
|
||||||
mAtm = atm;
|
mAtm = atm;
|
||||||
mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
|
mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
|
||||||
mTaskSnapshotController = taskSnapshotController;
|
mTaskSnapshotController = taskSnapshotController;
|
||||||
|
mTransitionTracer = transitionTracer;
|
||||||
mTransitionPlayerDeath = () -> {
|
mTransitionPlayerDeath = () -> {
|
||||||
synchronized (mAtm.mGlobalLock) {
|
synchronized (mAtm.mGlobalLock) {
|
||||||
// Clean-up/finish any playing transitions.
|
// Clean-up/finish any playing transitions.
|
||||||
@@ -524,6 +527,7 @@ class TransitionController {
|
|||||||
setAnimationRunning(true /* running */);
|
setAnimationRunning(true /* running */);
|
||||||
}
|
}
|
||||||
mPlayingTransitions.add(transition);
|
mPlayingTransitions.add(transition);
|
||||||
|
mTransitionTracer.logState(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setAnimationRunning(boolean running) {
|
private void setAnimationRunning(boolean running) {
|
||||||
@@ -542,6 +546,7 @@ class TransitionController {
|
|||||||
}
|
}
|
||||||
transition.abort();
|
transition.abort();
|
||||||
mCollectingTransition = null;
|
mCollectingTransition = null;
|
||||||
|
mTransitionTracer.logState(transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
234
services/core/java/com/android/server/wm/TransitionTracer.java
Normal file
234
services/core/java/com/android/server/wm/TransitionTracer.java
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* 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.server.wm;
|
||||||
|
|
||||||
|
import static android.os.Build.IS_USER;
|
||||||
|
|
||||||
|
import static com.android.server.wm.shell.ChangeInfo.CHANGE_FLAGS;
|
||||||
|
import static com.android.server.wm.shell.ChangeInfo.HAS_CHANGED;
|
||||||
|
import static com.android.server.wm.shell.ChangeInfo.TRANSIT_MODE;
|
||||||
|
import static com.android.server.wm.shell.ChangeInfo.WINDOW_IDENTIFIER;
|
||||||
|
import static com.android.server.wm.shell.Transition.CHANGE;
|
||||||
|
import static com.android.server.wm.shell.Transition.FLAGS;
|
||||||
|
import static com.android.server.wm.shell.Transition.ID;
|
||||||
|
import static com.android.server.wm.shell.Transition.STATE;
|
||||||
|
import static com.android.server.wm.shell.Transition.TIMESTAMP;
|
||||||
|
import static com.android.server.wm.shell.Transition.TRANSITION_TYPE;
|
||||||
|
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER;
|
||||||
|
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_H;
|
||||||
|
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_L;
|
||||||
|
import static com.android.server.wm.shell.TransitionTraceProto.TRANSITION;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.os.Trace;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.proto.ProtoOutputStream;
|
||||||
|
|
||||||
|
import com.android.internal.util.TraceBuffer;
|
||||||
|
import com.android.server.wm.Transition.ChangeInfo;
|
||||||
|
import com.android.server.wm.shell.TransitionTraceProto;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to collect and dump transition traces.
|
||||||
|
*/
|
||||||
|
public class TransitionTracer {
|
||||||
|
|
||||||
|
private static final String LOG_TAG = "TransitionTracer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum buffer size, currently defined as 5 MB
|
||||||
|
*/
|
||||||
|
private static final int BUFFER_CAPACITY = 5120 * 1024; // 5 MB
|
||||||
|
static final String WINSCOPE_EXT = ".winscope";
|
||||||
|
private static final String TRACE_FILE = "/data/misc/wmtrace/transition_trace" + WINSCOPE_EXT;
|
||||||
|
private static final long MAGIC_NUMBER_VALUE = ((long) MAGIC_NUMBER_H << 32) | MAGIC_NUMBER_L;
|
||||||
|
|
||||||
|
private final TransitionTraceBuffer mTraceBuffer = new TransitionTraceBuffer();
|
||||||
|
|
||||||
|
private final Object mEnabledLock = new Object();
|
||||||
|
private volatile boolean mEnabled = false;
|
||||||
|
|
||||||
|
private long mTraceStartTimestamp;
|
||||||
|
|
||||||
|
private class TransitionTraceBuffer {
|
||||||
|
private final TraceBuffer mBuffer = new TraceBuffer(BUFFER_CAPACITY);
|
||||||
|
|
||||||
|
private void pushTransitionState(Transition transition) {
|
||||||
|
final ProtoOutputStream outputStream = new ProtoOutputStream();
|
||||||
|
final long transitionEntryToken = outputStream.start(TRANSITION);
|
||||||
|
|
||||||
|
outputStream.write(ID, transition.getDebugId());
|
||||||
|
outputStream.write(TIMESTAMP, SystemClock.elapsedRealtimeNanos());
|
||||||
|
outputStream.write(TRANSITION_TYPE, transition.mType);
|
||||||
|
outputStream.write(STATE, transition.getState());
|
||||||
|
outputStream.write(FLAGS, transition.getFlags());
|
||||||
|
|
||||||
|
for (int i = 0; i < transition.mChanges.size(); ++i) {
|
||||||
|
final WindowContainer window = transition.mChanges.keyAt(i);
|
||||||
|
final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
|
||||||
|
writeChange(outputStream, window, changeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.end(transitionEntryToken);
|
||||||
|
|
||||||
|
mBuffer.add(outputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeChange(ProtoOutputStream outputStream, WindowContainer window,
|
||||||
|
ChangeInfo changeInfo) {
|
||||||
|
Trace.beginSection("TransitionProto#addChange");
|
||||||
|
final long changeEntryToken = outputStream.start(CHANGE);
|
||||||
|
|
||||||
|
final int transitMode = changeInfo.getTransitMode(window);
|
||||||
|
final boolean hasChanged = changeInfo.hasChanged(window);
|
||||||
|
final int changeFlags = changeInfo.getChangeFlags(window);
|
||||||
|
|
||||||
|
outputStream.write(TRANSIT_MODE, transitMode);
|
||||||
|
outputStream.write(HAS_CHANGED, hasChanged);
|
||||||
|
outputStream.write(CHANGE_FLAGS, changeFlags);
|
||||||
|
window.writeIdentifierToProto(outputStream, WINDOW_IDENTIFIER);
|
||||||
|
|
||||||
|
outputStream.end(changeEntryToken);
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToFile(File file, ProtoOutputStream proto) throws IOException {
|
||||||
|
mBuffer.writeTraceToFile(file, proto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
mBuffer.resetBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Records the current state of a transition in the transition trace (if it is running).
|
||||||
|
* @param transition the transition that we want to record the state of.
|
||||||
|
*/
|
||||||
|
public void logState(com.android.server.wm.Transition transition) {
|
||||||
|
if (!mEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(LOG_TAG, "Logging state of transition " + transition);
|
||||||
|
mTraceBuffer.pushTransitionState(transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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("TransitionTracer#startTrace");
|
||||||
|
LogAndPrintln.i(pw, "Starting shell transition trace.");
|
||||||
|
synchronized (mEnabledLock) {
|
||||||
|
mTraceStartTimestamp = SystemClock.elapsedRealtime();
|
||||||
|
mEnabled = true;
|
||||||
|
mTraceBuffer.reset();
|
||||||
|
}
|
||||||
|
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("TransitionTracer#stopTrace");
|
||||||
|
LogAndPrintln.i(pw, "Stopping shell transition trace.");
|
||||||
|
synchronized (mEnabledLock) {
|
||||||
|
if (!mEnabled) {
|
||||||
|
LogAndPrintln.e(pw,
|
||||||
|
"Error: Tracing can't be stopped because it hasn't been started.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mEnabled = false;
|
||||||
|
writeTraceToFileLocked(pw, outputFile);
|
||||||
|
}
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isEnabled() {
|
||||||
|
return mEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTraceToFileLocked(@Nullable PrintWriter pw, File file) {
|
||||||
|
Trace.beginSection("TransitionTracer#writeTraceToFileLocked");
|
||||||
|
try {
|
||||||
|
ProtoOutputStream proto = new ProtoOutputStream();
|
||||||
|
proto.write(MAGIC_NUMBER, MAGIC_NUMBER_VALUE);
|
||||||
|
proto.write(TransitionTraceProto.TIMESTAMP, mTraceStartTimestamp);
|
||||||
|
int pid = android.os.Process.myPid();
|
||||||
|
LogAndPrintln.i(pw, "Writing file to " + file.getAbsolutePath()
|
||||||
|
+ " from process " + pid);
|
||||||
|
mTraceBuffer.writeToFile(file, proto);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LogAndPrintln.e(pw, "Unable to write buffer to file", e);
|
||||||
|
}
|
||||||
|
Trace.endSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LogAndPrintln {
|
||||||
|
private static void i(@Nullable PrintWriter pw, String msg) {
|
||||||
|
Log.i(LOG_TAG, msg);
|
||||||
|
if (pw != null) {
|
||||||
|
pw.println(msg);
|
||||||
|
pw.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void e(@Nullable PrintWriter pw, String msg) {
|
||||||
|
Log.e(LOG_TAG, msg);
|
||||||
|
if (pw != null) {
|
||||||
|
pw.println("ERROR: " + msg);
|
||||||
|
pw.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void e(@Nullable PrintWriter pw, String msg, @NonNull Exception e) {
|
||||||
|
Log.e(LOG_TAG, msg, e);
|
||||||
|
if (pw != null) {
|
||||||
|
pw.println("ERROR: " + msg + " ::\n " + e);
|
||||||
|
pw.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -459,6 +459,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
final WindowManagerConstants mConstants;
|
final WindowManagerConstants mConstants;
|
||||||
|
|
||||||
final WindowTracing mWindowTracing;
|
final WindowTracing mWindowTracing;
|
||||||
|
final TransitionTracer mTransitionTracer;
|
||||||
|
|
||||||
private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
|
private final DisplayAreaPolicy.Provider mDisplayAreaPolicyProvider;
|
||||||
|
|
||||||
@@ -1245,6 +1246,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
|
|
||||||
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
|
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
|
||||||
Choreographer.getInstance());
|
Choreographer.getInstance());
|
||||||
|
mTransitionTracer = new TransitionTracer();
|
||||||
|
|
||||||
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
|
LocalServices.addService(WindowManagerPolicy.class, mPolicy);
|
||||||
|
|
||||||
@@ -5887,6 +5889,21 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
return mWindowTracing.isEnabled();
|
return mWindowTracing.isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startTransitionTrace() {
|
||||||
|
mTransitionTracer.startTrace(null /* printwriter */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopTransitionTrace() {
|
||||||
|
mTransitionTracer.stopTrace(null /* printwriter */);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isTransitionTraceEnabled() {
|
||||||
|
return mTransitionTracer.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean registerCrossWindowBlurEnabledListener(
|
public boolean registerCrossWindowBlurEnabledListener(
|
||||||
ICrossWindowBlurEnabledListener listener) {
|
ICrossWindowBlurEnabledListener listener) {
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
return runReset(pw);
|
return runReset(pw);
|
||||||
case "disable-blur":
|
case "disable-blur":
|
||||||
return runSetBlurDisabled(pw);
|
return runSetBlurDisabled(pw);
|
||||||
|
case "shell":
|
||||||
|
return runWmShellCommand(pw);
|
||||||
default:
|
default:
|
||||||
return handleDefaultCommands(cmd);
|
return handleDefaultCommands(cmd);
|
||||||
}
|
}
|
||||||
@@ -1235,6 +1237,47 @@ public class WindowManagerShellCommand extends ShellCommand {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int runWmShellCommand(PrintWriter pw) {
|
||||||
|
String arg = getNextArg();
|
||||||
|
|
||||||
|
switch (arg) {
|
||||||
|
case "tracing":
|
||||||
|
return runWmShellTracing(pw);
|
||||||
|
case "help":
|
||||||
|
default:
|
||||||
|
return runHelp(pw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runHelp(PrintWriter pw) {
|
||||||
|
pw.println("Window Manager Shell commands:");
|
||||||
|
pw.println(" help");
|
||||||
|
pw.println(" Print this help text.");
|
||||||
|
pw.println(" tracing <start/stop>");
|
||||||
|
pw.println(" Start/stop shell transition tracing.");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int runWmShellTracing(PrintWriter pw) {
|
||||||
|
String arg = getNextArg();
|
||||||
|
|
||||||
|
switch (arg) {
|
||||||
|
case "start":
|
||||||
|
mInternal.mTransitionTracer.startTrace(pw);
|
||||||
|
break;
|
||||||
|
case "stop":
|
||||||
|
mInternal.mTransitionTracer.stopTrace(pw);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
getErrPrintWriter()
|
||||||
|
.println("Error: expected 'start' or 'stop', but got '" + arg + "'");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private int runReset(PrintWriter pw) throws RemoteException {
|
private int runReset(PrintWriter pw) throws RemoteException {
|
||||||
int displayId = getDisplayId(getNextArg());
|
int displayId = getDisplayId(getNextArg());
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setWindowManager(WindowManagerService wms) {
|
void setWindowManager(WindowManagerService wms) {
|
||||||
mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController);
|
mTransitionController = new TransitionController(mService, wms.mTaskSnapshotController,
|
||||||
|
wms.mTransitionTracer);
|
||||||
mTransitionController.registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
|
mTransitionController.registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,11 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
final SurfaceControl.Transaction mMockT = mock(SurfaceControl.Transaction.class);
|
final SurfaceControl.Transaction mMockT = mock(SurfaceControl.Transaction.class);
|
||||||
|
|
||||||
private Transition createTestTransition(int transitType) {
|
private Transition createTestTransition(int transitType) {
|
||||||
TransitionController controller = mock(TransitionController.class);
|
TransitionTracer tracer = mock(TransitionTracer.class);
|
||||||
|
final TransitionController controller = new TransitionController(
|
||||||
|
mock(ActivityTaskManagerService.class), mock(TaskSnapshotController.class),
|
||||||
|
mock(TransitionTracer.class));
|
||||||
|
|
||||||
final BLASTSyncEngine sync = createTestBLASTSyncEngine();
|
final BLASTSyncEngine sync = createTestBLASTSyncEngine();
|
||||||
final Transition t = new Transition(transitType, 0 /* flags */, controller, sync);
|
final Transition t = new Transition(transitType, 0 /* flags */, controller, sync);
|
||||||
t.startCollecting(0 /* timeoutMs */);
|
t.startCollecting(0 /* timeoutMs */);
|
||||||
@@ -584,7 +588,7 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testTimeout() {
|
public void testTimeout() {
|
||||||
final TransitionController controller = new TransitionController(mAtm,
|
final TransitionController controller = new TransitionController(mAtm,
|
||||||
mock(TaskSnapshotController.class));
|
mock(TaskSnapshotController.class), mock(TransitionTracer.class));
|
||||||
final BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
|
final BLASTSyncEngine sync = new BLASTSyncEngine(mWm);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
final CountDownLatch latch = new CountDownLatch(1);
|
||||||
// When the timeout is reached, it will finish the sync-group and notify transaction ready.
|
// When the timeout is reached, it will finish the sync-group and notify transaction ready.
|
||||||
@@ -841,7 +845,8 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testIntermediateVisibility() {
|
public void testIntermediateVisibility() {
|
||||||
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
||||||
final TransitionController controller = new TransitionController(mAtm, snapshotController);
|
final TransitionController controller = new TransitionController(mAtm, snapshotController,
|
||||||
|
mock(TransitionTracer.class));
|
||||||
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
||||||
controller.registerTransitionPlayer(player, null /* appThread */);
|
controller.registerTransitionPlayer(player, null /* appThread */);
|
||||||
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
||||||
@@ -905,7 +910,8 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testTransientLaunch() {
|
public void testTransientLaunch() {
|
||||||
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
||||||
final TransitionController controller = new TransitionController(mAtm, snapshotController);
|
final TransitionController controller = new TransitionController(mAtm, snapshotController,
|
||||||
|
mock(TransitionTracer.class));
|
||||||
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
||||||
controller.registerTransitionPlayer(player, null /* appThread */);
|
controller.registerTransitionPlayer(player, null /* appThread */);
|
||||||
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
||||||
@@ -968,7 +974,8 @@ public class TransitionTests extends WindowTestsBase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNotReadyPushPop() {
|
public void testNotReadyPushPop() {
|
||||||
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
|
||||||
final TransitionController controller = new TransitionController(mAtm, snapshotController);
|
final TransitionController controller = new TransitionController(mAtm, snapshotController,
|
||||||
|
mock(TransitionTracer.class));
|
||||||
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
final ITransitionPlayer player = new ITransitionPlayer.Default();
|
||||||
controller.registerTransitionPlayer(player, null /* appThread */);
|
controller.registerTransitionPlayer(player, null /* appThread */);
|
||||||
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
|
||||||
|
|||||||
Reference in New Issue
Block a user