From 3878ca3333da1bf5cbc83d33e5e8b3ce68c8c5e4 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Thu, 2 Feb 2017 17:13:05 -0800 Subject: [PATCH] Fix multi-dimen app transition delay tron event Make sure to log everything. Test: Open app, inspect log. Test: com.android.systemmetrics.functional.AppStartTests Bug: 33086172 Change-Id: I6fdfef625c09267dcf20724e853cf7471abc86c9 --- .../android/app/ActivityManagerInternal.java | 23 +- proto/src/metrics_constants.proto | 15 ++ .../server/am/ActivityManagerService.java | 11 +- .../server/am/ActivityMetricsLogger.java | 201 +++++++++++++----- .../com/android/server/am/ActivityRecord.java | 14 +- .../wm/AppWindowContainerController.java | 12 ++ .../server/wm/AppWindowContainerListener.java | 6 + .../com/android/server/wm/AppWindowToken.java | 14 +- .../server/wm/WindowManagerService.java | 7 +- .../server/wm/WindowSurfacePlacer.java | 24 ++- 10 files changed, 235 insertions(+), 92 deletions(-) diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index fa64a0f553372..b36b664d6a93f 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -25,6 +25,7 @@ import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.service.voice.IVoiceInteractionSession; +import android.util.SparseIntArray; import com.android.internal.app.IVoiceInteractor; @@ -47,9 +48,9 @@ public abstract class ActivityManagerInternal { /** * Type for {@link #notifyAppTransitionStarting}: The transition was started because we drew - * the starting window. + * the splash screen. */ - public static final int APP_TRANSITION_STARTING_WINDOW = 1; + public static final int APP_TRANSITION_SPLASH_SCREEN = 1; /** * Type for {@link #notifyAppTransitionStarting}: The transition was started because we all @@ -63,6 +64,12 @@ public abstract class ActivityManagerInternal { */ public static final int APP_TRANSITION_TIMEOUT = 3; + /** + * Type for {@link #notifyAppTransitionStarting}: The transition was started because of a + * we drew a task snapshot. + */ + public static final int APP_TRANSITION_SNAPSHOT = 4; + /** * Grant Uri permissions from one app to another. This method only extends * permission grants if {@code callingUid} has permission to them. @@ -121,20 +128,14 @@ public abstract class ActivityManagerInternal { IVoiceInteractionSession mSession, IVoiceInteractor mInteractor); - /** - * Callback for window manager to let activity manager know that the starting window has been - * drawn - */ - public abstract void notifyStartingWindowDrawn(); - /** * Callback for window manager to let activity manager know that we are finally starting the * app transition; * - * @param reason The reason why the app transition started. Must be one of the APP_TRANSITION_* - * values. + * @param reasons A map from stack id to a reason integer why the transition was started,, which + * must be one of the APP_TRANSITION_* values. */ - public abstract void notifyAppTransitionStarting(int reason); + public abstract void notifyAppTransitionStarting(SparseIntArray reasons); /** * Callback for window manager to let activity manager know that the app transition was diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 072d3dc4daf03..c115c8c66594e 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -44,6 +44,18 @@ message MetricsEvent { // The view or control was updated. TYPE_UPDATE = 6; + + // Type for APP_TRANSITION event: The transition started a new activity for which it's process + // wasn't running. + TYPE_TRANSITION_COLD_LAUNCH = 7; + + // Type for APP_TRANSITION event: The transition started a new activity for which it's process + // was already running. + TYPE_TRANSITION_WARM_LAUNCH = 8; + + // Type for APP_TRANSITION event: The transition brought an already existing activity to the + // front. + TYPE_TRANSITION_HOT_LAUNCH = 9; } // Known visual elements: views or controls. @@ -3559,6 +3571,9 @@ message MetricsEvent { // ACTION: Settings > Connected devices > Bluetooth master switch Toggle ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE = 870; + // The name of the activity being launched in an app transition event. + APP_TRANSITION_ACTIVITY_NAME = 871; + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9dc59cb063d0e..6bf77ae80b448 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -22957,16 +22957,9 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void notifyStartingWindowDrawn() { + public void notifyAppTransitionStarting(SparseIntArray reasons) { synchronized (ActivityManagerService.this) { - mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn(); - } - } - - @Override - public void notifyAppTransitionStarting(int reason) { - synchronized (ActivityManagerService.this) { - mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason); + mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reasons); } } diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index ff796a549f377..ebbce0227b3e8 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -1,24 +1,36 @@ package com.android.server.am; +import static android.app.ActivityManager.START_SUCCESS; +import static android.app.ActivityManager.START_TASK_TO_FRONT; import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; - +import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_ACTIVITY_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_HOT_LAUNCH; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.ActivityStack.STACK_INVISIBLE; -import android.annotation.Nullable; import android.app.ActivityManager.StackId; import android.content.Context; +import android.metrics.LogMaker; import android.os.SystemClock; import android.util.Slog; +import android.util.SparseArray; +import android.util.SparseIntArray; -import android.metrics.LogMaker; import com.android.internal.logging.MetricsLogger; -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.util.ArrayList; @@ -48,12 +60,27 @@ class ActivityMetricsLogger { private long mLastLogTimeSecs; private final ActivityStackSupervisor mSupervisor; private final Context mContext; + private final MetricsLogger mMetricsLogger = new MetricsLogger(); private long mCurrentTransitionStartTime = INVALID_START_TIME; - private boolean mLoggedWindowsDrawn; - private boolean mLoggedStartingWindowDrawn; + + private int mCurrentTransitionDeviceUptime; + private int mCurrentTransitionDelayMs; private boolean mLoggedTransitionStarting; + private final SparseArray mStackTransitionInfo = new SparseArray<>(); + + private final class StackTransitionInfo { + private ActivityRecord launchedActivity; + private int startResult; + private boolean currentTransitionProcessRunning; + private int windowsDrawnDelayMs; + private int startingWindowDelayMs; + private int reason = APP_TRANSITION_TIMEOUT; + private boolean loggedWindowsDrawn; + private boolean loggedStartingWindowDrawn; + } + ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context) { mLastLogTimeSecs = SystemClock.elapsedRealtime() / 1000; mSupervisor = supervisor; @@ -102,7 +129,9 @@ class ActivityMetricsLogger { * activity. */ void notifyActivityLaunching() { - mCurrentTransitionStartTime = System.currentTimeMillis(); + if (!isAnyTransitionActive()) { + mCurrentTransitionStartTime = System.currentTimeMillis(); + } } /** @@ -118,9 +147,6 @@ class ActivityMetricsLogger { launchedActivity.appInfo.uid) : null; final boolean processRunning = processRecord != null; - final String componentName = launchedActivity != null - ? launchedActivity.shortComponentName - : null; // We consider this a "process switch" if the process of the activity that gets launched // didn't have an activity that was in started state. In this case, we assume that lot @@ -129,7 +155,7 @@ class ActivityMetricsLogger { final boolean processSwitch = processRecord == null || !hasStartedActivity(processRecord, launchedActivity); - notifyActivityLaunched(resultCode, componentName, processRunning, processSwitch); + notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch); } private boolean hasStartedActivity(ProcessRecord record, ActivityRecord launchedActivity) { @@ -151,92 +177,120 @@ class ActivityMetricsLogger { * * @param resultCode one of the ActivityManager.START_* flags, indicating the result of the * launch - * @param componentName the component name of the activity being launched + * @param launchedActivity the activity being launched * @param processRunning whether the process that will contains the activity is already running * @param processSwitch whether the process that will contain the activity didn't have any * activity that was stopped, i.e. the started activity is "switching" * processes */ - private void notifyActivityLaunched(int resultCode, @Nullable String componentName, + private void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity, boolean processRunning, boolean processSwitch) { - if (resultCode < 0 || componentName == null || !processSwitch) { - - // Failed to launch or it was not a process switch, so we don't care about the timing. - reset(); + // If we are already in an existing transition, only update the activity name, but not the + // other attributes. + final int stackId = launchedActivity != null && launchedActivity.getStack() != null + ? launchedActivity.getStack().mStackId + : INVALID_STACK_ID; + final StackTransitionInfo info = mStackTransitionInfo.get(stackId); + if (launchedActivity != null && info != null) { + info.launchedActivity = launchedActivity; return; } - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_COMPONENT_NAME, - componentName); - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_PROCESS_RUNNING, - processRunning); - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS, - (int) (SystemClock.uptimeMillis() / 1000)); + final boolean otherStacksLaunching = mStackTransitionInfo.size() > 0 && info == null; + if ((resultCode < 0 || launchedActivity == null || !processSwitch + || stackId == INVALID_STACK_ID) && !otherStacksLaunching) { - LogMaker builder = new LogMaker(MetricsEvent.APP_TRANSITION); - builder.addTaggedData(MetricsEvent.APP_TRANSITION_COMPONENT_NAME, componentName); - builder.addTaggedData(MetricsEvent.APP_TRANSITION_PROCESS_RUNNING, processRunning ? 1 : 0); - builder.addTaggedData(MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS, - SystemClock.uptimeMillis() / 1000); - MetricsLogger.action(builder); + // Failed to launch or it was not a process switch, so we don't care about the timing. + reset(true /* abort */); + return; + } else if (otherStacksLaunching) { + // Don't log this stack but continue with the other stacks. + return; + } + + final StackTransitionInfo newInfo = new StackTransitionInfo(); + newInfo.launchedActivity = launchedActivity; + newInfo.currentTransitionProcessRunning = processRunning; + newInfo.startResult = resultCode; + mStackTransitionInfo.append(stackId, newInfo); + mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000); } /** * Notifies the tracker that all windows of the app have been drawn. */ - void notifyWindowsDrawn() { - if (!isTransitionActive() || mLoggedWindowsDrawn) { + void notifyWindowsDrawn(int stackId) { + final StackTransitionInfo info = mStackTransitionInfo.get(stackId); + if (info == null || info.loggedWindowsDrawn) { return; } - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, - calculateCurrentDelay()); - mLoggedWindowsDrawn = true; - if (mLoggedTransitionStarting) { - reset(); + info.windowsDrawnDelayMs = calculateCurrentDelay(); + info.loggedWindowsDrawn = true; + if (allStacksWindowsDrawn() && mLoggedTransitionStarting) { + reset(false /* abort */); } } /** * Notifies the tracker that the starting window was drawn. */ - void notifyStartingWindowDrawn() { - if (!isTransitionActive() || mLoggedStartingWindowDrawn) { + void notifyStartingWindowDrawn(int stackId) { + final StackTransitionInfo info = mStackTransitionInfo.get(stackId); + if (info == null || info.loggedStartingWindowDrawn) { return; } - mLoggedStartingWindowDrawn = true; - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS, - calculateCurrentDelay()); + info.loggedStartingWindowDrawn = true; + info.startingWindowDelayMs = calculateCurrentDelay(); } /** * Notifies the tracker that the app transition is starting. * - * @param reason The reason why we started it. Must be on of - * ActivityManagerInternal.APP_TRANSITION_* reasons. + * @param stackIdReasons A map from stack id to a reason integer, which must be on of + * ActivityManagerInternal.APP_TRANSITION_* reasons. */ - void notifyTransitionStarting(int reason) { - if (!isTransitionActive() || mLoggedTransitionStarting) { + void notifyTransitionStarting(SparseIntArray stackIdReasons) { + if (!isAnyTransitionActive() || mLoggedTransitionStarting) { return; } - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_REASON, reason); - MetricsLogger.action(mContext, MetricsEvent.APP_TRANSITION_DELAY_MS, - calculateCurrentDelay()); + mCurrentTransitionDelayMs = calculateCurrentDelay(); mLoggedTransitionStarting = true; - if (mLoggedWindowsDrawn) { - reset(); + for (int index = stackIdReasons.size() - 1; index >= 0; index--) { + final int stackId = stackIdReasons.keyAt(index); + final StackTransitionInfo info = mStackTransitionInfo.get(stackId); + if (info == null) { + continue; + } + info.reason = stackIdReasons.valueAt(index); + } + if (allStacksWindowsDrawn()) { + reset(false /* abort */); } } - private boolean isTransitionActive() { - return mCurrentTransitionStartTime != INVALID_START_TIME; + private boolean allStacksWindowsDrawn() { + for (int index = mStackTransitionInfo.size() - 1; index >= 0; index--) { + if (!mStackTransitionInfo.valueAt(index).loggedWindowsDrawn) { + return false; + } + } + return true; } - private void reset() { + private boolean isAnyTransitionActive() { + return mCurrentTransitionStartTime != INVALID_START_TIME + && mStackTransitionInfo.size() > 0; + } + + private void reset(boolean abort) { + if (!abort && isAnyTransitionActive()) { + logAppTransitionMultiEvents(); + } mCurrentTransitionStartTime = INVALID_START_TIME; - mLoggedWindowsDrawn = false; + mCurrentTransitionDelayMs = -1; mLoggedTransitionStarting = false; - mLoggedStartingWindowDrawn = false; + mStackTransitionInfo.clear(); } private int calculateCurrentDelay() { @@ -244,4 +298,41 @@ class ActivityMetricsLogger { // Shouldn't take more than 25 days to launch an app, so int is fine here. return (int) (System.currentTimeMillis() - mCurrentTransitionStartTime); } + + private void logAppTransitionMultiEvents() { + for (int index = mStackTransitionInfo.size() - 1; index >= 0; index--) { + final StackTransitionInfo info = mStackTransitionInfo.valueAt(index); + final int type = getTransitionType(info); + if (type == -1) { + return; + } + final LogMaker builder = new LogMaker(APP_TRANSITION); + builder.setPackageName(info.launchedActivity.packageName); + builder.addTaggedData(APP_TRANSITION_ACTIVITY_NAME, info.launchedActivity.info.name); + builder.setType(type); + builder.addTaggedData(APP_TRANSITION_DEVICE_UPTIME_SECONDS, + mCurrentTransitionDeviceUptime); + builder.addTaggedData(APP_TRANSITION_DELAY_MS, mCurrentTransitionDelayMs); + builder.setSubtype(info.reason); + if (info.startingWindowDelayMs != -1) { + builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS, + info.startingWindowDelayMs); + } + builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs); + mMetricsLogger.write(builder); + } + } + + private int getTransitionType(StackTransitionInfo info) { + if (info.currentTransitionProcessRunning) { + if (info.startResult == START_SUCCESS) { + return TYPE_TRANSITION_WARM_LAUNCH; + } else if (info.startResult == START_TASK_TO_FRONT) { + return TYPE_TRANSITION_HOT_LAUNCH; + } + } else if (info.startResult == START_SUCCESS) { + return TYPE_TRANSITION_COLD_LAUNCH; + } + return -1; + } } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 77564bb46af45..2e26bedd50f8d 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -23,6 +23,7 @@ import static android.app.ActivityManager.StackId.ASSISTANT_STACK_ID; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE; @@ -890,6 +891,10 @@ final class ActivityRecord implements AppWindowContainerListener { return task != null ? (T) task.getStack() : null; } + private int getStackId() { + return getStack() != null ? getStack().mStackId : INVALID_STACK_ID; + } + boolean changeWindowTranslucency(boolean toOpaque) { if (fullscreen == toOpaque) { return false; @@ -1705,10 +1710,17 @@ final class ActivityRecord implements AppWindowContainerListener { stack.mLaunchStartTime = 0; } + @Override + public void onStartingWindowDrawn() { + synchronized (service) { + mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn(getStackId()); + } + } + @Override public void onWindowsDrawn() { synchronized (service) { - mStackSupervisor.mActivityMetricsLogger.notifyWindowsDrawn(); + mStackSupervisor.mActivityMetricsLogger.notifyWindowsDrawn(getStackId()); if (displayStartTime != 0) { reportLaunchTimeLocked(SystemClock.uptimeMillis()); } diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java index 266ab4cfde0bc..b90a82a886412 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerController.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java @@ -59,6 +59,15 @@ public class AppWindowContainerController private final IApplicationToken mToken; private final Handler mHandler; + private final Runnable mOnStartingWindowDrawn = () -> { + if (mListener == null) { + return; + } + if (DEBUG_VISIBILITY) Slog.v(TAG_WM, "Reporting drawn in " + + AppWindowContainerController.this.mToken); + mListener.onStartingWindowDrawn(); + }; + private final Runnable mOnWindowsDrawn = () -> { if (mListener == null) { return; @@ -655,6 +664,9 @@ public class AppWindowContainerController } } + void reportStartingWindowDrawn() { + mHandler.post(mOnStartingWindowDrawn); + } void reportWindowsDrawn() { mHandler.post(mOnWindowsDrawn); diff --git a/services/core/java/com/android/server/wm/AppWindowContainerListener.java b/services/core/java/com/android/server/wm/AppWindowContainerListener.java index 12d4b2fcb1327..9d459cfccc09d 100644 --- a/services/core/java/com/android/server/wm/AppWindowContainerListener.java +++ b/services/core/java/com/android/server/wm/AppWindowContainerListener.java @@ -24,6 +24,12 @@ public interface AppWindowContainerListener extends WindowContainerListener { void onWindowsVisible(); /** Called when the windows associated app window container are no longer visible. */ void onWindowsGone(); + + /** + * Called when the starting window for this container is drawn. + */ + void onStartingWindowDrawn(); + /** * Called when the key dispatching to a window associated with the app window container * timed-out. diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 4aa013ae90c1e..2f221df182c05 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -42,7 +42,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN; -import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.logWithStack; @@ -668,6 +667,15 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return (Task) getParent(); } + TaskStack getStack() { + final Task task = getTask(); + if (task != null) { + return task.mStack; + } else { + return null; + } + } + @Override void onParentSet() { super.onParentSet(); @@ -1329,7 +1337,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree } } } else if (w.isDrawnLw()) { - mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN); + if (getController() != null) { + getController().reportStartingWindowDrawn(); + } startingDisplayed = true; } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f9c4efd17fc13..64614fe6e03e8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -5253,7 +5253,6 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_APP_TRANSITION_STARTING = 47; public static final int NOTIFY_APP_TRANSITION_CANCELLED = 48; public static final int NOTIFY_APP_TRANSITION_FINISHED = 49; - public static final int NOTIFY_STARTING_WINDOW_DRAWN = 50; public static final int UPDATE_ANIMATION_SCALE = 51; public static final int WINDOW_HIDE_TIMEOUT = 52; public static final int NOTIFY_DOCKED_STACK_MINIMIZED_CHANGED = 53; @@ -5682,7 +5681,7 @@ public class WindowManagerService extends IWindowManager.Stub } } case NOTIFY_APP_TRANSITION_STARTING: { - mAmInternal.notifyAppTransitionStarting(msg.arg1); + mAmInternal.notifyAppTransitionStarting((SparseIntArray) msg.obj); } break; case NOTIFY_APP_TRANSITION_CANCELLED: { @@ -5693,10 +5692,6 @@ public class WindowManagerService extends IWindowManager.Stub mAmInternal.notifyAppTransitionFinished(); } break; - case NOTIFY_STARTING_WINDOW_DRAWN: { - mAmInternal.notifyStartingWindowDrawn(); - } - break; case WINDOW_HIDE_TIMEOUT: { final WindowState window = (WindowState) msg.obj; synchronized(mWindowMap) { diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index f247ebe62f8ce..3cb96a1145fc6 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1,9 +1,10 @@ package com.android.server.wm; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE; -import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW; -import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT; +import static android.app.ActivityManagerInternal.APP_TRANSITION_SNAPSHOT; +import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN; import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; @@ -45,6 +46,7 @@ import android.os.Debug; import android.os.Trace; import android.util.ArraySet; import android.util.Slog; +import android.util.SparseIntArray; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; @@ -93,6 +95,7 @@ class WindowSurfacePlacer { private final LayerAndToken mTmpLayerAndToken = new LayerAndToken(); private final ArrayList mPendingDestroyingSurfaces = new ArrayList<>(); + private final SparseIntArray mTempTransitionReasons = new SparseIntArray(); public WindowSurfacePlacer(WindowManagerService service) { mService = service; @@ -495,7 +498,7 @@ class WindowSurfacePlacer { mService.mAnimator.getScreenRotationAnimationLocked( Display.DEFAULT_DISPLAY); - int reason = APP_TRANSITION_TIMEOUT; + final SparseIntArray reasons = mTempTransitionReasons; if (!mService.mAppTransition.isTimeout()) { // Imagine the case where we are changing orientation due to an app transition, but a previous // orientation change is still in progress. We won't process the orientation change @@ -526,11 +529,15 @@ class WindowSurfacePlacer { if (!allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) { return false; } + final TaskStack stack = wtoken.getStack(); + final int stackId = stack != null ? stack.mStackId : INVALID_STACK_ID; if (allDrawn) { - reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN - : APP_TRANSITION_SAVED_SURFACE; + reasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN + : APP_TRANSITION_SAVED_SURFACE); } else { - reason = APP_TRANSITION_STARTING_WINDOW; + reasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData + ? APP_TRANSITION_SPLASH_SCREEN + : APP_TRANSITION_SNAPSHOT); } } @@ -552,12 +559,13 @@ class WindowSurfacePlacer { boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() || mWallpaperControllerLocked.wallpaperTransitionReady(); if (wallpaperReady) { - mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget(); + mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone()) + .sendToTarget(); return true; } return false; } - mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget(); + mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone()).sendToTarget(); return true; }