Loading core/java/android/view/ViewRootImpl.java +7 −1 Original line number Diff line number Diff line Loading @@ -6574,10 +6574,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); Loading Loading @@ -9019,6 +9024,7 @@ public final class ViewRootImpl implements ViewParent, mPendingActivityWindowInfo.set(outInfo); } } mRelayoutBundle.clear(); mWinFrameInScreen.set(mTmpFrames.frame); if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); Loading services/core/java/com/android/server/wm/ActivityRecord.java +12 −4 Original line number Diff line number Diff line Loading @@ -3198,10 +3198,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!Flags.activityWindowInfoFlag() || !isAttached()) { return mTmpActivityWindowInfo; } 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; } Loading services/core/java/com/android/server/wm/WindowManagerService.java +10 −6 Original line number Diff line number Diff line Loading @@ -2584,14 +2584,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. Loading services/core/java/com/android/server/wm/WindowState.java +40 −16 Original line number Diff line number Diff line Loading @@ -422,6 +422,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; Loading Loading @@ -1081,6 +1088,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, Loading Loading @@ -3607,12 +3617,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) { Loading Loading @@ -3642,8 +3655,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; } Loading Loading @@ -3680,10 +3700,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; Loading @@ -3701,18 +3733,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, Loading Loading @@ -4136,6 +4156,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() Loading services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +35 −3 Original line number Diff line number Diff line Loading @@ -320,7 +320,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); } Loading Loading @@ -1268,12 +1269,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 { Loading Loading
core/java/android/view/ViewRootImpl.java +7 −1 Original line number Diff line number Diff line Loading @@ -6574,10 +6574,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); Loading Loading @@ -9019,6 +9024,7 @@ public final class ViewRootImpl implements ViewParent, mPendingActivityWindowInfo.set(outInfo); } } mRelayoutBundle.clear(); mWinFrameInScreen.set(mTmpFrames.frame); if (mTranslator != null) { mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame); Loading
services/core/java/com/android/server/wm/ActivityRecord.java +12 −4 Original line number Diff line number Diff line Loading @@ -3198,10 +3198,18 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (!Flags.activityWindowInfoFlag() || !isAttached()) { return mTmpActivityWindowInfo; } 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; } Loading
services/core/java/com/android/server/wm/WindowManagerService.java +10 −6 Original line number Diff line number Diff line Loading @@ -2584,14 +2584,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. Loading
services/core/java/com/android/server/wm/WindowState.java +40 −16 Original line number Diff line number Diff line Loading @@ -422,6 +422,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; Loading Loading @@ -1081,6 +1088,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, Loading Loading @@ -3607,12 +3617,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) { Loading Loading @@ -3642,8 +3655,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; } Loading Loading @@ -3680,10 +3700,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; Loading @@ -3701,18 +3733,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, Loading Loading @@ -4136,6 +4156,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() Loading
services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java +35 −3 Original line number Diff line number Diff line Loading @@ -320,7 +320,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); } Loading Loading @@ -1268,12 +1269,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 { Loading