Merge "Migrate screen rotation latency tracker with shell transition" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a18b8a827e
33
core/java/android/window/ITransitionMetricsReporter.aidl
Normal file
33
core/java/android/window/ITransitionMetricsReporter.aidl
Normal 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);
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@ import android.view.RemoteAnimationAdapter;
|
|||||||
import android.window.IDisplayAreaOrganizerController;
|
import android.window.IDisplayAreaOrganizerController;
|
||||||
import android.window.ITaskFragmentOrganizerController;
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
import android.window.ITaskOrganizerController;
|
import android.window.ITaskOrganizerController;
|
||||||
|
import android.window.ITransitionMetricsReporter;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.IWindowContainerTransactionCallback;
|
import android.window.IWindowContainerTransactionCallback;
|
||||||
import android.window.WindowContainerToken;
|
import android.window.WindowContainerToken;
|
||||||
@@ -98,4 +99,7 @@ interface IWindowOrganizerController {
|
|||||||
* this will replace the existing one if set.
|
* this will replace the existing one if set.
|
||||||
*/
|
*/
|
||||||
void registerTransitionPlayer(in ITransitionPlayer player);
|
void registerTransitionPlayer(in ITransitionPlayer player);
|
||||||
|
|
||||||
|
/** @return An interface enabling the transition players to report its metrics. */
|
||||||
|
ITransitionMetricsReporter getTransitionMetricsReporter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ public final class TransitionInfo implements Parcelable {
|
|||||||
private TransitionInfo(Parcel in) {
|
private TransitionInfo(Parcel in) {
|
||||||
mType = in.readInt();
|
mType = in.readInt();
|
||||||
mFlags = in.readInt();
|
mFlags = in.readInt();
|
||||||
in.readList(mChanges, null /* classLoader */);
|
in.readTypedList(mChanges, Change.CREATOR);
|
||||||
mRootLeash = new SurfaceControl();
|
mRootLeash = new SurfaceControl();
|
||||||
mRootLeash.readFromParcel(in);
|
mRootLeash.readFromParcel(in);
|
||||||
mRootOffset.readFromParcel(in);
|
mRootOffset.readFromParcel(in);
|
||||||
@@ -152,7 +152,7 @@ public final class TransitionInfo implements Parcelable {
|
|||||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
dest.writeInt(mType);
|
dest.writeInt(mType);
|
||||||
dest.writeInt(mFlags);
|
dest.writeInt(mFlags);
|
||||||
dest.writeList(mChanges);
|
dest.writeTypedList(mChanges);
|
||||||
mRootLeash.writeToParcel(dest, flags);
|
mRootLeash.writeToParcel(dest, flags);
|
||||||
mRootOffset.writeToParcel(dest, flags);
|
mRootOffset.writeToParcel(dest, flags);
|
||||||
dest.writeTypedObject(mOptions, flags);
|
dest.writeTypedObject(mOptions, flags);
|
||||||
|
|||||||
57
core/java/android/window/TransitionMetrics.java
Normal file
57
core/java/android/window/TransitionMetrics.java
Normal 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());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -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();
|
return IWindowOrganizerControllerSingleton.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import android.view.animation.AlphaAnimation;
|
|||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.Transformation;
|
import android.view.animation.Transformation;
|
||||||
import android.window.TransitionInfo;
|
import android.window.TransitionInfo;
|
||||||
|
import android.window.TransitionMetrics;
|
||||||
import android.window.TransitionRequestInfo;
|
import android.window.TransitionRequestInfo;
|
||||||
import android.window.WindowContainerToken;
|
import android.window.WindowContainerToken;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
@@ -362,6 +363,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
startTransaction.apply();
|
startTransaction.apply();
|
||||||
|
TransitionMetrics.getInstance().reportAnimationStart(transition);
|
||||||
// run finish now in-case there are no animations
|
// run finish now in-case there are no animations
|
||||||
onAnimFinish.run();
|
onAnimFinish.run();
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import android.window.ITransitionPlayer;
|
|||||||
import android.window.RemoteTransition;
|
import android.window.RemoteTransition;
|
||||||
import android.window.TransitionFilter;
|
import android.window.TransitionFilter;
|
||||||
import android.window.TransitionInfo;
|
import android.window.TransitionInfo;
|
||||||
|
import android.window.TransitionMetrics;
|
||||||
import android.window.TransitionRequestInfo;
|
import android.window.TransitionRequestInfo;
|
||||||
import android.window.WindowContainerTransaction;
|
import android.window.WindowContainerTransaction;
|
||||||
import android.window.WindowContainerTransactionCallback;
|
import android.window.WindowContainerTransactionCallback;
|
||||||
@@ -192,6 +193,8 @@ public class Transitions implements RemoteCallable<Transitions> {
|
|||||||
public void register(ShellTaskOrganizer taskOrganizer) {
|
public void register(ShellTaskOrganizer taskOrganizer) {
|
||||||
if (mPlayerImpl == null) return;
|
if (mPlayerImpl == null) return;
|
||||||
taskOrganizer.registerTransitionPlayer(mPlayerImpl);
|
taskOrganizer.registerTransitionPlayer(mPlayerImpl);
|
||||||
|
// Pre-load the instance.
|
||||||
|
TransitionMetrics.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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_SCREEN_ON;
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
|
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.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_ANIM;
|
||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
|
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
|
||||||
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
|
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);
|
final Transition t = controller.requestTransitionIfNeeded(TRANSIT_CHANGE, this);
|
||||||
if (t != null) {
|
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);
|
t.setKnownConfigChanges(this, changes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ import android.os.IBinder;
|
|||||||
import android.os.IRemoteCallback;
|
import android.os.IRemoteCallback;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.util.ArrayMap;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.proto.ProtoOutputStream;
|
import android.util.proto.ProtoOutputStream;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.window.IRemoteTransition;
|
import android.window.IRemoteTransition;
|
||||||
|
import android.window.ITransitionMetricsReporter;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.RemoteTransition;
|
import android.window.RemoteTransition;
|
||||||
import android.window.TransitionInfo;
|
import android.window.TransitionInfo;
|
||||||
@@ -45,6 +47,7 @@ import com.android.server.LocalServices;
|
|||||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.LongConsumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all the aspects of recording and synchronizing transitions.
|
* Handles all the aspects of recording and synchronizing transitions.
|
||||||
@@ -58,6 +61,8 @@ class TransitionController {
|
|||||||
private static final int LEGACY_STATE_RUNNING = 2;
|
private static final int LEGACY_STATE_RUNNING = 2;
|
||||||
|
|
||||||
private ITransitionPlayer mTransitionPlayer;
|
private ITransitionPlayer mTransitionPlayer;
|
||||||
|
final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
|
||||||
|
|
||||||
final ActivityTaskManagerService mAtm;
|
final ActivityTaskManagerService mAtm;
|
||||||
final TaskSnapshotController mTaskSnapshotController;
|
final TaskSnapshotController mTaskSnapshotController;
|
||||||
|
|
||||||
@@ -324,6 +329,8 @@ class TransitionController {
|
|||||||
|
|
||||||
/** @see Transition#finishTransition */
|
/** @see Transition#finishTransition */
|
||||||
void finishTransition(@NonNull IBinder token) {
|
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);
|
final Transition record = Transition.fromBinder(token);
|
||||||
if (record == null || !mPlayingTransitions.contains(record)) {
|
if (record == null || !mPlayingTransitions.contains(record)) {
|
||||||
Slog.e(TAG, "Trying to finish a non-playing transition " + token);
|
Slog.e(TAG, "Trying to finish a non-playing transition " + token);
|
||||||
@@ -420,6 +427,28 @@ class TransitionController {
|
|||||||
proto.end(token);
|
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 {
|
class Lock {
|
||||||
private int mTransitionWaiters = 0;
|
private int mTransitionWaiters = 0;
|
||||||
void runWhenIdle(long timeout, Runnable r) {
|
void runWhenIdle(long timeout, Runnable r) {
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ import android.window.IDisplayAreaOrganizerController;
|
|||||||
import android.window.ITaskFragmentOrganizer;
|
import android.window.ITaskFragmentOrganizer;
|
||||||
import android.window.ITaskFragmentOrganizerController;
|
import android.window.ITaskFragmentOrganizerController;
|
||||||
import android.window.ITaskOrganizerController;
|
import android.window.ITaskOrganizerController;
|
||||||
|
import android.window.ITransitionMetricsReporter;
|
||||||
import android.window.ITransitionPlayer;
|
import android.window.ITransitionPlayer;
|
||||||
import android.window.IWindowContainerTransactionCallback;
|
import android.window.IWindowContainerTransactionCallback;
|
||||||
import android.window.IWindowOrganizerController;
|
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. */
|
/** Whether the configuration changes are important to report back to an organizer. */
|
||||||
static boolean configurationsAreEqualForOrganizer(
|
static boolean configurationsAreEqualForOrganizer(
|
||||||
Configuration newConfig, @Nullable Configuration oldConfig) {
|
Configuration newConfig, @Nullable Configuration oldConfig) {
|
||||||
|
|||||||
Reference in New Issue
Block a user