Merge "Centralize latency measurement of recents animation" into tm-qpr-dev am: 0cfbb12708

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19029532

Change-Id: Iac62bafcb5c23e14bb4fc879f02dce8d2e9f1564
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Riddle Hsu
2022-07-13 12:48:32 +00:00
committed by Automerger Merge Worker
2 changed files with 26 additions and 27 deletions

View File

@@ -148,6 +148,12 @@ class ActivityMetricsLogger {
*/ */
private static final long UNKNOWN_VISIBILITY_CHECK_DELAY_MS = 3000; private static final long UNKNOWN_VISIBILITY_CHECK_DELAY_MS = 3000;
/**
* If the recents animation is finished before the delay since the window drawn, do not log the
* action because the duration is too small that may be just an accidentally touch.
*/
private static final long LATENCY_TRACKER_RECENTS_DELAY_MS = 300;
/** /**
* The flag for {@link #notifyActivityLaunching} to skip associating a new launch with an active * The flag for {@link #notifyActivityLaunching} to skip associating a new launch with an active
* transition, in the case the launch is standalone (e.g. from recents). * transition, in the case the launch is standalone (e.g. from recents).
@@ -738,10 +744,6 @@ class ActivityMetricsLogger {
if (info.mLoggedTransitionStarting) { if (info.mLoggedTransitionStarting) {
done(false /* abort */, info, "notifyWindowsDrawn", timestampNs); done(false /* abort */, info, "notifyWindowsDrawn", timestampNs);
} }
if (r.mWmService.isRecentsAnimationTarget(r)) {
r.mWmService.getRecentsAnimationController().logRecentsAnimationStartTime(
info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs);
}
return infoSnapshot; return infoSnapshot;
} }
@@ -786,12 +788,6 @@ class ActivityMetricsLogger {
info.mReason = activityToReason.valueAt(index); info.mReason = activityToReason.valueAt(index);
info.mLoggedTransitionStarting = true; info.mLoggedTransitionStarting = true;
if (info.mIsDrawn) { if (info.mIsDrawn) {
if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
mLoggerHandler.post(() -> latencyTracker.logAction(
LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
}
done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs); done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
} }
} }
@@ -959,6 +955,9 @@ class ActivityMetricsLogger {
launchObserverNotifyActivityLaunchFinished(info, timestampNs); launchObserverNotifyActivityLaunchFinished(info, timestampNs);
} }
logAppTransitionFinished(info, isHibernating != null ? isHibernating : false); logAppTransitionFinished(info, isHibernating != null ? isHibernating : false);
if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
logRecentsAnimationLatency(info);
}
} }
mTransitionInfoList.remove(info); mTransitionInfoList.remove(info);
} }
@@ -1114,6 +1113,22 @@ class ActivityMetricsLogger {
Log.i(TAG, sb.toString()); Log.i(TAG, sb.toString());
} }
private void logRecentsAnimationLatency(TransitionInfo info) {
final int duration = info.mSourceEventDelayMs + info.mWindowsDrawnDelayMs;
final ActivityRecord r = info.mLastLaunchedActivity;
final long lastTopLossTime = r.topResumedStateLossTime;
final WindowManagerService wm = mSupervisor.mService.mWindowManager;
final Object controller = wm.getRecentsAnimationController();
mLoggerHandler.postDelayed(() -> {
if (lastTopLossTime != r.topResumedStateLossTime
|| controller != wm.getRecentsAnimationController()) {
// Skip if the animation was finished in a short time.
return;
}
wm.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration);
}, LATENCY_TRACKER_RECENTS_DELAY_MS);
}
private static int getAppStartTransitionType(int tronType, boolean relaunched) { private static int getAppStartTransitionType(int tronType, boolean relaunched) {
if (tronType == TYPE_TRANSITION_COLD_LAUNCH) { if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD; return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;

View File

@@ -71,9 +71,7 @@ import android.window.TaskSnapshot;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.inputmethod.SoftInputShowHideReason; import com.android.internal.inputmethod.SoftInputShowHideReason;
import com.android.internal.os.BackgroundThread;
import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledConsumer; import com.android.internal.util.function.pooled.PooledConsumer;
import com.android.internal.util.function.pooled.PooledLambda; import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.LocalServices; import com.android.server.LocalServices;
@@ -99,11 +97,6 @@ import java.util.stream.Collectors;
public class RecentsAnimationController implements DeathRecipient { public class RecentsAnimationController implements DeathRecipient {
private static final String TAG = RecentsAnimationController.class.getSimpleName(); private static final String TAG = RecentsAnimationController.class.getSimpleName();
private static final long FAILSAFE_DELAY = 1000; private static final long FAILSAFE_DELAY = 1000;
/**
* If the recents animation is canceled before the delay since the window drawn, do not log the
* action because the duration is too small that may be just a mistouch.
*/
private static final long LATENCY_TRACKER_LOG_DELAY_MS = 300;
// Constant for a yet-to-be-calculated {@link RemoteAnimationTarget#Mode} state // Constant for a yet-to-be-calculated {@link RemoteAnimationTarget#Mode} state
private static final int MODE_UNKNOWN = -1; private static final int MODE_UNKNOWN = -1;
@@ -144,7 +137,7 @@ public class RecentsAnimationController implements DeathRecipient {
private boolean mPendingStart = true; private boolean mPendingStart = true;
// Set when the animation has been canceled // Set when the animation has been canceled
private volatile boolean mCanceled; private boolean mCanceled;
// Whether or not the input consumer is enabled. The input consumer must be both registered and // Whether or not the input consumer is enabled. The input consumer must be both registered and
// enabled for it to start intercepting touch events. // enabled for it to start intercepting touch events.
@@ -785,15 +778,6 @@ public class RecentsAnimationController implements DeathRecipient {
}, false /* traverseTopToBottom */); }, false /* traverseTopToBottom */);
} }
void logRecentsAnimationStartTime(int durationMs) {
BackgroundThread.getHandler().postDelayed(() -> {
if (!mCanceled) {
mService.mLatencyTracker.logAction(LatencyTracker.ACTION_START_RECENTS_ANIMATION,
durationMs);
}
}, LATENCY_TRACKER_LOG_DELAY_MS);
}
private boolean removeTaskInternal(int taskId) { private boolean removeTaskInternal(int taskId) {
boolean result = false; boolean result = false;
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) { for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {