diff options
6 files changed, 107 insertions, 31 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 3c61854c89f0..a1ef6ec01dd9 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -6569,10 +6569,15 @@ public final class ViewRootImpl implements ViewParent, // Use the newer global config and last reported override config. mPendingMergedConfiguration.setConfiguration(config, mLastReportedMergedConfiguration.getOverrideConfiguration()); + if (mPendingActivityWindowInfo != null) { + mPendingActivityWindowInfo.set(mLastReportedActivityWindowInfo); + } performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration), false /* force */, INVALID_DISPLAY /* same display */, - mLastReportedActivityWindowInfo); + mPendingActivityWindowInfo != null + ? new ActivityWindowInfo(mPendingActivityWindowInfo) + : null); } break; case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: { setAccessibilityFocus(null, null); @@ -9014,6 +9019,7 @@ public final class ViewRootImpl implements ViewParent, mPendingActivityWindowInfo.set(outInfo); } } + mRelayoutBundle.clear(); mWinFrameInScreen.set(mTmpFrames.frame); if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 17e699668d14..cfb9b561f843 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -3198,10 +3198,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!Flags.activityWindowInfoFlag() || !isAttached()) { return mTmpActivityWindowInfo; } - mTmpActivityWindowInfo.set( - isEmbeddedInHostContainer(), - getTask().getBounds(), - getTaskFragment().getBounds()); + if (isFixedRotationTransforming()) { + // Fixed rotation only applied to fullscreen activity, thus using the activity bounds + // for Task/TaskFragment so that it is "pre-rotated" and in sync with the Configuration + // update. + final Rect bounds = getBounds(); + mTmpActivityWindowInfo.set(false /* isEmbedded */, bounds, bounds); + } else { + mTmpActivityWindowInfo.set( + isEmbeddedInHostContainer(), + getTask().getBounds(), + getTaskFragment().getBounds()); + } return mTmpActivityWindowInfo; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f09ef9643433..3986adcf56ab 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2581,14 +2581,18 @@ public class WindowManagerService extends IWindowManager.Stub } if (outFrames != null && outMergedConfiguration != null) { + final boolean shouldReportActivityWindowInfo = outBundle != null + && win.mLastReportedActivityWindowInfo != null; + final ActivityWindowInfo outActivityWindowInfo = shouldReportActivityWindowInfo + ? new ActivityWindowInfo() + : null; + win.fillClientWindowFramesAndConfiguration(outFrames, outMergedConfiguration, - false /* useLatestConfig */, shouldRelayout); - if (Flags.activityWindowInfoFlag() && outBundle != null - && win.mActivityRecord != null) { - final ActivityWindowInfo activityWindowInfo = win.mActivityRecord - .getActivityWindowInfo(); + outActivityWindowInfo, false /* useLatestConfig */, shouldRelayout); + + if (shouldReportActivityWindowInfo) { outBundle.putParcelable(IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, - activityWindowInfo); + outActivityWindowInfo); } // Set resize-handled here because the values are sent back to the client. diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 37b2d0e82366..2c435e8f5efe 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -421,6 +421,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP */ private final MergedConfiguration mLastReportedConfiguration = new MergedConfiguration(); + /** + * Similar to {@link #mLastReportedConfiguration}, used to store last reported to client + * ActivityWindowInfo. {@code null} if this is not an Activity window. + */ + @Nullable + final ActivityWindowInfo mLastReportedActivityWindowInfo; + /** @see #isLastConfigReportedToClient() */ private boolean mLastConfigReportedToClient; @@ -1080,6 +1087,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mPolicy = mWmService.mPolicy; mContext = mWmService.mContext; mForceSeamlesslyRotate = token.mRoundedCornerOverlay; + mLastReportedActivityWindowInfo = Flags.activityWindowInfoFlag() && mActivityRecord != null + ? new ActivityWindowInfo() + : null; mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle( mActivityRecord != null ? mActivityRecord.getInputApplicationHandle(false /* update */) : null, @@ -3603,12 +3613,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP * * @param outFrames The frames that will be sent to the client. * @param outMergedConfiguration The configuration that will be sent to the client. + * @param outActivityWindowInfo The ActivityWindowInfo that will be sent to the client if set. + * {@code null} if this is not activity window. * @param useLatestConfig Whether to use the latest configuration. * @param relayoutVisible Whether to consider visibility to use the latest configuration. */ - void fillClientWindowFramesAndConfiguration(ClientWindowFrames outFrames, - MergedConfiguration outMergedConfiguration, boolean useLatestConfig, - boolean relayoutVisible) { + void fillClientWindowFramesAndConfiguration(@NonNull ClientWindowFrames outFrames, + @NonNull MergedConfiguration outMergedConfiguration, + @Nullable ActivityWindowInfo outActivityWindowInfo, + boolean useLatestConfig, boolean relayoutVisible) { outFrames.frame.set(mWindowFrames.mCompatFrame); outFrames.displayFrame.set(mWindowFrames.mDisplayFrame); if (mInvGlobalScale != 1f) { @@ -3638,8 +3651,15 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP if (outMergedConfiguration != mLastReportedConfiguration) { mLastReportedConfiguration.setTo(outMergedConfiguration); } + if (outActivityWindowInfo != null && mLastReportedActivityWindowInfo != null) { + outActivityWindowInfo.set(mActivityRecord.getActivityWindowInfo()); + mLastReportedActivityWindowInfo.set(outActivityWindowInfo); + } } else { outMergedConfiguration.setTo(mLastReportedConfiguration); + if (outActivityWindowInfo != null && mLastReportedActivityWindowInfo != null) { + outActivityWindowInfo.set(mLastReportedActivityWindowInfo); + } } mLastConfigReportedToClient = true; } @@ -3676,10 +3696,22 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP mDragResizingChangeReported = true; mWindowFrames.clearReportResizeHints(); + // App window resize may trigger Activity#onConfigurationChanged, so we need to update + // ActivityWindowInfo as well. + final IBinder activityToken; + final ActivityWindowInfo activityWindowInfo; + if (mLastReportedActivityWindowInfo != null) { + activityToken = mActivityRecord.token; + activityWindowInfo = mLastReportedActivityWindowInfo; + } else { + activityToken = null; + activityWindowInfo = null; + } + final int prevRotation = mLastReportedConfiguration .getMergedConfiguration().windowConfiguration.getRotation(); fillClientWindowFramesAndConfiguration(mClientWindowFrames, mLastReportedConfiguration, - true /* useLatestConfig */, false /* relayoutVisible */); + activityWindowInfo, true /* useLatestConfig */, false /* relayoutVisible */); final boolean syncRedraw = shouldSendRedrawForSync(); final boolean syncWithBuffers = syncRedraw && shouldSyncWithBuffers(); final boolean reportDraw = syncRedraw || drawPending; @@ -3697,18 +3729,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP markRedrawForSyncReported(); - // App window resize may trigger Activity#onConfigurationChanged, so we need to update - // ActivityWindowInfo as well. - final IBinder activityToken; - final ActivityWindowInfo activityWindowInfo; - if (Flags.activityWindowInfoFlag() && mActivityRecord != null) { - activityToken = mActivityRecord.token; - activityWindowInfo = mActivityRecord.getActivityWindowInfo(); - } else { - activityToken = null; - activityWindowInfo = null; - } - if (Flags.bundleClientTransactionFlag()) { getProcess().scheduleClientTransactionItem( WindowStateResizeItem.obtain(mClient, mClientWindowFrames, reportDraw, @@ -4132,6 +4152,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP } pw.println(prefix + "mFullConfiguration=" + getConfiguration()); pw.println(prefix + "mLastReportedConfiguration=" + getLastReportedConfiguration()); + if (mLastReportedActivityWindowInfo != null) { + pw.println(prefix + "mLastReportedActivityWindowInfo=" + + mLastReportedActivityWindowInfo); + } } pw.println(prefix + "mHasSurface=" + mHasSurface + " isReadyForDisplay()=" + isReadyForDisplay() diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java index 48b12f729e08..2e2eceea5f52 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java @@ -319,7 +319,8 @@ public class WindowManagerServiceTests extends WindowTestsBase { // Non activity window can still get the last config. win.mActivityRecord = null; win.fillClientWindowFramesAndConfiguration(outFrames, outConfig, - false /* useLatestConfig */, true /* relayoutVisible */); + null /* outActivityWindowInfo*/, false /* useLatestConfig */, + true /* relayoutVisible */); assertEquals(win.getConfiguration().densityDpi, outConfig.getMergedConfiguration().densityDpi); } @@ -1239,12 +1240,43 @@ public class WindowManagerServiceTests extends WindowTestsBase { final InsetsSourceControl.Array outControls = new InsetsSourceControl.Array(); final Bundle outBundle = new Bundle(); - mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.GONE, 0, 0, 0, + final ActivityRecord activity = win.mActivityRecord; + final ActivityWindowInfo expectedInfo = new ActivityWindowInfo(); + expectedInfo.set(true, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 500, 2000)); + doReturn(expectedInfo).when(activity).getActivityWindowInfo(); + activity.setVisibleRequested(false); + activity.setVisible(false); + + mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0, outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle); + // No latest reported value, so return empty when activity is invisible final ActivityWindowInfo activityWindowInfo = outBundle.getParcelable( IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class); - assertEquals(win.mActivityRecord.getActivityWindowInfo(), activityWindowInfo); + assertEquals(new ActivityWindowInfo(), activityWindowInfo); + + activity.setVisibleRequested(true); + activity.setVisible(true); + + mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0, + outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle); + + // Report the latest when activity is visible. + final ActivityWindowInfo activityWindowInfo2 = outBundle.getParcelable( + IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class); + assertEquals(expectedInfo, activityWindowInfo2); + + expectedInfo.set(false, new Rect(0, 0, 1000, 2000), new Rect(0, 0, 1000, 2000)); + activity.setVisibleRequested(false); + activity.setVisible(false); + + mWm.relayoutWindow(win.mSession, win.mClient, win.mAttrs, w, h, View.VISIBLE, 0, 0, 0, + outFrames, outConfig, outSurfaceControl, outInsetsState, outControls, outBundle); + + // Report the last reported value when activity is invisible. + final ActivityWindowInfo activityWindowInfo3 = outBundle.getParcelable( + IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO, ActivityWindowInfo.class); + assertEquals(activityWindowInfo2, activityWindowInfo3); } class TestResultReceiver implements IResultReceiver { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 28e03bfeaadb..6bd08740916d 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -107,6 +107,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManager.DisplayImePolicy; import android.view.inputmethod.ImeTracker; +import android.window.ActivityWindowInfo; import android.window.ClientWindowFrames; import android.window.ITaskFragmentOrganizer; import android.window.ITransitionPlayer; @@ -694,7 +695,8 @@ class WindowTestsBase extends SystemServiceTestsBase { static void makeLastConfigReportedToClient(WindowState w, boolean visible) { w.fillClientWindowFramesAndConfiguration(new ClientWindowFrames(), - new MergedConfiguration(), true /* useLatestConfig */, visible); + new MergedConfiguration(), new ActivityWindowInfo(), true /* useLatestConfig */, + visible); } /** |