Merge "Migrate screen rotation latency tracker with shell transition" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2021-10-20 02:12:34 +00:00
committed by Android (Google) Code Review
10 changed files with 155 additions and 3 deletions

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2021 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 android.window;
import android.os.IBinder;
/**
* Implemented by WM Core to know the metrics of transition that runs on a different process.
* @hide
*/
oneway interface ITransitionMetricsReporter {
/**
* Called when the transition animation starts.
*
* @param startTime The time when the animation started.
*/
void reportAnimationStart(IBinder transitionToken, long startTime);
}

View File

@@ -23,6 +23,7 @@ import android.view.RemoteAnimationAdapter;
import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskFragmentOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.ITransitionMetricsReporter;
import android.window.ITransitionPlayer;
import android.window.IWindowContainerTransactionCallback;
import android.window.WindowContainerToken;
@@ -98,4 +99,7 @@ interface IWindowOrganizerController {
* this will replace the existing one if set.
*/
void registerTransitionPlayer(in ITransitionPlayer player);
/** @return An interface enabling the transition players to report its metrics. */
ITransitionMetricsReporter getTransitionMetricsReporter();
}

View File

@@ -140,7 +140,7 @@ public final class TransitionInfo implements Parcelable {
private TransitionInfo(Parcel in) {
mType = in.readInt();
mFlags = in.readInt();
in.readList(mChanges, null /* classLoader */);
in.readTypedList(mChanges, Change.CREATOR);
mRootLeash = new SurfaceControl();
mRootLeash.readFromParcel(in);
mRootOffset.readFromParcel(in);
@@ -152,7 +152,7 @@ public final class TransitionInfo implements Parcelable {
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeInt(mFlags);
dest.writeList(mChanges);
dest.writeTypedList(mChanges);
mRootLeash.writeToParcel(dest, flags);
mRootOffset.writeToParcel(dest, flags);
dest.writeTypedObject(mOptions, flags);

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 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 android.window;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Singleton;
/**
* A helper class for who plays transition animation can report its metrics easily.
* @hide
*/
public class TransitionMetrics {
private final ITransitionMetricsReporter mTransitionMetricsReporter;
private TransitionMetrics(ITransitionMetricsReporter reporter) {
mTransitionMetricsReporter = reporter;
}
/** Reports the current timestamp as when the transition animation starts. */
public void reportAnimationStart(IBinder transitionToken) {
try {
mTransitionMetricsReporter.reportAnimationStart(transitionToken,
SystemClock.elapsedRealtime());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}
/** Gets the singleton instance of TransitionMetrics. */
public static TransitionMetrics getInstance() {
return sTransitionMetrics.get();
}
private static final Singleton<TransitionMetrics> sTransitionMetrics = new Singleton<>() {
@Override
protected TransitionMetrics create() {
return new TransitionMetrics(WindowOrganizer.getTransitionMetricsReporter());
}
};
}

View File

@@ -159,7 +159,19 @@ public class WindowOrganizer {
}
}
IWindowOrganizerController getWindowOrganizerController() {
/**
* @see TransitionMetrics
* @hide
*/
public static ITransitionMetricsReporter getTransitionMetricsReporter() {
try {
return getWindowOrganizerController().getTransitionMetricsReporter();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
static IWindowOrganizerController getWindowOrganizerController() {
return IWindowOrganizerControllerSingleton.get();
}

View File

@@ -70,6 +70,7 @@ import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.window.TransitionInfo;
import android.window.TransitionMetrics;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerToken;
import android.window.WindowContainerTransaction;
@@ -362,6 +363,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
}
}
startTransaction.apply();
TransitionMetrics.getInstance().reportAnimationStart(transition);
// run finish now in-case there are no animations
onAnimFinish.run();
return true;

View File

@@ -44,6 +44,7 @@ import android.window.ITransitionPlayer;
import android.window.RemoteTransition;
import android.window.TransitionFilter;
import android.window.TransitionInfo;
import android.window.TransitionMetrics;
import android.window.TransitionRequestInfo;
import android.window.WindowContainerTransaction;
import android.window.WindowContainerTransactionCallback;
@@ -192,6 +193,8 @@ public class Transitions implements RemoteCallable<Transitions> {
public void register(ShellTaskOrganizer taskOrganizer) {
if (mPlayerImpl == null) return;
taskOrganizer.registerTransitionPlayer(mPlayerImpl);
// Pre-load the instance.
TransitionMetrics.getInstance();
}
/**

View File

@@ -93,6 +93,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
@@ -3230,6 +3231,11 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
}
final Transition t = controller.requestTransitionIfNeeded(TRANSIT_CHANGE, this);
if (t != null) {
if (getRotation() != getWindowConfiguration().getRotation()) {
mWmService.mLatencyTracker.onActionStart(ACTION_ROTATE_SCREEN);
controller.mTransitionMetricsReporter.associate(t,
startTime -> mWmService.mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN));
}
t.setKnownConfigChanges(this, changes);
}
}

View File

@@ -30,10 +30,12 @@ import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.WindowManager;
import android.window.IRemoteTransition;
import android.window.ITransitionMetricsReporter;
import android.window.ITransitionPlayer;
import android.window.RemoteTransition;
import android.window.TransitionInfo;
@@ -45,6 +47,7 @@ import com.android.server.LocalServices;
import com.android.server.statusbar.StatusBarManagerInternal;
import java.util.ArrayList;
import java.util.function.LongConsumer;
/**
* Handles all the aspects of recording and synchronizing transitions.
@@ -58,6 +61,8 @@ class TransitionController {
private static final int LEGACY_STATE_RUNNING = 2;
private ITransitionPlayer mTransitionPlayer;
final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
final ActivityTaskManagerService mAtm;
final TaskSnapshotController mTaskSnapshotController;
@@ -324,6 +329,8 @@ class TransitionController {
/** @see Transition#finishTransition */
void finishTransition(@NonNull IBinder token) {
// It is usually a no-op but make sure that the metric consumer is removed.
mTransitionMetricsReporter.reportAnimationStart(token, 0 /* startTime */);
final Transition record = Transition.fromBinder(token);
if (record == null || !mPlayingTransitions.contains(record)) {
Slog.e(TAG, "Trying to finish a non-playing transition " + token);
@@ -420,6 +427,28 @@ class TransitionController {
proto.end(token);
}
static class TransitionMetricsReporter extends ITransitionMetricsReporter.Stub {
private final ArrayMap<IBinder, LongConsumer> mMetricConsumers = new ArrayMap<>();
void associate(IBinder transitionToken, LongConsumer consumer) {
synchronized (mMetricConsumers) {
mMetricConsumers.put(transitionToken, consumer);
}
}
@Override
public void reportAnimationStart(IBinder transitionToken, long startTime) {
final LongConsumer c;
synchronized (mMetricConsumers) {
if (mMetricConsumers.isEmpty()) return;
c = mMetricConsumers.remove(transitionToken);
}
if (c != null) {
c.accept(startTime);
}
}
}
class Lock {
private int mTransitionWaiters = 0;
void runWhenIdle(long timeout, Runnable r) {

View File

@@ -66,6 +66,7 @@ import android.window.IDisplayAreaOrganizerController;
import android.window.ITaskFragmentOrganizer;
import android.window.ITaskFragmentOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.ITransitionMetricsReporter;
import android.window.ITransitionPlayer;
import android.window.IWindowContainerTransactionCallback;
import android.window.IWindowOrganizerController;
@@ -1040,6 +1041,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
}
@Override
public ITransitionMetricsReporter getTransitionMetricsReporter() {
return mTransitionController.mTransitionMetricsReporter;
}
/** Whether the configuration changes are important to report back to an organizer. */
static boolean configurationsAreEqualForOrganizer(
Configuration newConfig, @Nullable Configuration oldConfig) {