Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd6acd13 authored by Chris Li's avatar Chris Li
Browse files

Update ActivityWindowInfo from app window resizing

Similar to Activity#onConfigurationChanged, updating ActivityWindowInfo
if an app window is resized.

Bug: 287582673
Bug: 329084449
Test: No flaky test
Change-Id: Id8a76407917e577d29eb8678e039fe8e959d88dc
parent b41eda86
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -712,16 +712,22 @@ public final class ActivityThread extends ClientTransactionHandler
            stopped = false;
            hideForNow = false;
            activityConfigCallback = new ViewRootImpl.ActivityConfigCallback() {

                @Override
                public void onConfigurationChanged(Configuration overrideConfig,
                        int newDisplayId) {
                public void onConfigurationChanged(@NonNull Configuration overrideConfig,
                        int newDisplayId, @Nullable ActivityWindowInfo activityWindowInfo) {
                    if (activity == null) {
                        throw new IllegalStateException(
                                "Received config update for non-existing activity");
                    }
                    if (activityWindowInfoFlag() && activityWindowInfo == null) {
                        Log.w(TAG, "Received empty ActivityWindowInfo update for r=" + activity);
                        activityWindowInfo = mActivityWindowInfo;
                    }
                    activity.mMainThread.handleActivityConfigurationChanged(
                            ActivityClientRecord.this, overrideConfig, newDisplayId,
                            mActivityWindowInfo, false /* alwaysReportChange */);
                            activityWindowInfo,
                            false /* alwaysReportChange */);
                }

                @Override
+93 −17
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodCl
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
import static com.android.input.flags.Flags.enablePointerChoreographer;
import static com.android.window.flags.Flags.activityWindowInfoFlag;
import static com.android.window.flags.Flags.enableBufferTransformHintFromDisplay;
import android.Manifest;
@@ -233,6 +234,7 @@ import android.view.contentcapture.ContentCaptureSession;
import android.view.inputmethod.ImeTracker;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
import android.window.ActivityWindowInfo;
import android.window.BackEvent;
import android.window.ClientWindowFrames;
import android.window.CompatOnBackInvokedCallback;
@@ -435,13 +437,27 @@ public final class ViewRootImpl implements ViewParent,
     * Callback for notifying activities.
     */
    public interface ActivityConfigCallback {
        /**
         * Notifies about override config change and/or move to different display.
         * @param overrideConfig New override config to apply to activity.
         * @param newDisplayId New display id, {@link Display#INVALID_DISPLAY} if not changed.
         */
        default void onConfigurationChanged(@NonNull Configuration overrideConfig,
                int newDisplayId) {
            // Must override one of the #onConfigurationChanged.
            throw new IllegalStateException("Not implemented");
        }
        /**
         * Notifies about override config change and/or move to different display.
         * @param overrideConfig New override config to apply to activity.
         * @param newDisplayId New display id, {@link Display#INVALID_DISPLAY} if not changed.
         * @param activityWindowInfo New ActivityWindowInfo to apply to activity.
         */
        void onConfigurationChanged(Configuration overrideConfig, int newDisplayId);
        default void onConfigurationChanged(@NonNull Configuration overrideConfig,
                int newDisplayId, @Nullable ActivityWindowInfo activityWindowInfo) {
            onConfigurationChanged(overrideConfig, newDisplayId);
        }
        /**
         * Notify the corresponding activity about the request to show or hide a camera compat
@@ -467,7 +483,7 @@ public final class ViewRootImpl implements ViewParent,
     * In that case we receive a call back from {@link ActivityThread} and this flag is used to
     * preserve the initial value.
     *
     * @see #performConfigurationChange(MergedConfiguration, boolean, int)
     * @see #performConfigurationChange
     */
    private boolean mForceNextConfigUpdate;
@@ -814,6 +830,13 @@ public final class ViewRootImpl implements ViewParent,
    /** Configurations waiting to be applied. */
    private final MergedConfiguration mPendingMergedConfiguration = new MergedConfiguration();
    /** Non-{@code null} if {@link #mActivityConfigCallback} is not {@code null}. */
    @Nullable
    private ActivityWindowInfo mPendingActivityWindowInfo;
    /** Non-{@code null} if {@link #mActivityConfigCallback} is not {@code null}. */
    @Nullable
    private ActivityWindowInfo mLastReportedActivityWindowInfo;
    boolean mScrollMayChange;
    @SoftInputModeFlags
    int mSoftInputMode;
@@ -1260,8 +1283,18 @@ public final class ViewRootImpl implements ViewParent,
     * Add activity config callback to be notified about override config changes and camera
     * compat control state updates.
     */
    public void setActivityConfigCallback(ActivityConfigCallback callback) {
    public void setActivityConfigCallback(@Nullable ActivityConfigCallback callback) {
        mActivityConfigCallback = callback;
        if (!activityWindowInfoFlag()) {
            return;
        }
        if (callback == null) {
            mPendingActivityWindowInfo = null;
            mLastReportedActivityWindowInfo = null;
        } else {
            mPendingActivityWindowInfo = new ActivityWindowInfo();
            mLastReportedActivityWindowInfo = new ActivityWindowInfo();
        }
    }
    public void setOnContentApplyWindowInsetsListener(OnContentApplyWindowInsetsListener listener) {
@@ -2096,7 +2129,8 @@ public final class ViewRootImpl implements ViewParent,
    /** Handles messages {@link #MSG_RESIZED} and {@link #MSG_RESIZED_REPORT}. */
    private void handleResized(ClientWindowFrames frames, boolean reportDraw,
            MergedConfiguration mergedConfiguration, InsetsState insetsState, boolean forceLayout,
            boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, boolean dragResizing) {
            boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, boolean dragResizing,
            @Nullable ActivityWindowInfo activityWindowInfo) {
        if (!mAdded) {
            return;
        }
@@ -2114,7 +2148,14 @@ public final class ViewRootImpl implements ViewParent,
        mInsetsController.onStateChanged(insetsState);
        final float compatScale = frames.compatScale;
        final boolean frameChanged = !mWinFrame.equals(frame);
        final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration);
        final boolean shouldReportActivityWindowInfoChanged =
                // Can be null if callbacks is not set
                mLastReportedActivityWindowInfo != null
                        // Can be null if not activity window
                        && activityWindowInfo != null
                        && !mLastReportedActivityWindowInfo.equals(activityWindowInfo);
        final boolean configChanged = !mLastReportedMergedConfiguration.equals(mergedConfiguration)
                || shouldReportActivityWindowInfoChanged;
        final boolean attachedFrameChanged =
                !Objects.equals(mTmpFrames.attachedFrame, attachedFrame);
        final boolean displayChanged = mDisplay.getDisplayId() != displayId;
@@ -2133,7 +2174,8 @@ public final class ViewRootImpl implements ViewParent,
        if (configChanged) {
            // If configuration changed - notify about that and, maybe, about move to display.
            performConfigurationChange(mergedConfiguration, false /* force */,
                    displayChanged ? displayId : INVALID_DISPLAY /* same display */);
                    displayChanged ? displayId : INVALID_DISPLAY /* same display */,
                    activityWindowInfo);
        } else if (displayChanged) {
            // Moved to display without config change - report last applied one.
            onMovedToDisplay(displayId, mLastConfigurationFromResources);
@@ -3532,12 +3574,18 @@ public final class ViewRootImpl implements ViewParent,
                // WindowManagerService has reported back a frame from a configuration not yet
                // handled by the client. In this case, we need to accept the configuration so we
                // do not lay out and draw with the wrong configuration.
                if (mRelayoutRequested
                        && !mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
                boolean shouldPerformConfigurationUpdate =
                        !mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)
                                || !Objects.equals(mPendingActivityWindowInfo,
                                mLastReportedActivityWindowInfo);
                if (mRelayoutRequested && shouldPerformConfigurationUpdate) {
                    if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
                            + mPendingMergedConfiguration.getMergedConfiguration());
                    performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration),
                            !mFirst, INVALID_DISPLAY /* same display */);
                            !mFirst, INVALID_DISPLAY /* same display */,
                            mPendingActivityWindowInfo != null
                                    ? new ActivityWindowInfo(mPendingActivityWindowInfo)
                                    : null);
                    updatedConfiguration = true;
                }
                final boolean updateSurfaceNeeded = mUpdateSurfaceNeeded;
@@ -6063,9 +6111,11 @@ public final class ViewRootImpl implements ViewParent,
     * @param force Flag indicating if we should force apply the config.
     * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} if not
     *                     changed.
     * @param activityWindowInfo New activity window info. {@code null} if it is non-app window, or
     *                           this is not a Configuration change to the activity window (global).
     */
    private void performConfigurationChange(MergedConfiguration mergedConfiguration, boolean force,
            int newDisplayId) {
    private void performConfigurationChange(@NonNull MergedConfiguration mergedConfiguration,
            boolean force, int newDisplayId, @Nullable ActivityWindowInfo activityWindowInfo) {
        if (mergedConfiguration == null) {
            throw new IllegalArgumentException("No merged config provided.");
        }
@@ -6105,6 +6155,9 @@ public final class ViewRootImpl implements ViewParent,
        }
        mLastReportedMergedConfiguration.setConfiguration(globalConfig, overrideConfig);
        if (mLastReportedActivityWindowInfo != null && activityWindowInfo != null) {
            mLastReportedActivityWindowInfo.set(activityWindowInfo);
        }
        mForceNextConfigUpdate = force;
        if (mActivityConfigCallback != null) {
@@ -6112,7 +6165,8 @@ public final class ViewRootImpl implements ViewParent,
            // This basically initiates a round trip to ActivityThread and back, which will ensure
            // that corresponding activity and resources are updated before updating inner state of
            // ViewRootImpl. Eventually it will call #updateConfiguration().
            mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId);
            mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId,
                    activityWindowInfo);
        } else {
            // There is no activity callback - update the configuration right away.
            updateConfiguration(newDisplayId);
@@ -6354,13 +6408,15 @@ public final class ViewRootImpl implements ViewParent,
                    final boolean reportDraw = msg.what == MSG_RESIZED_REPORT;
                    final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg2;
                    final InsetsState insetsState = (InsetsState) args.arg3;
                    final ActivityWindowInfo activityWindowInfo = (ActivityWindowInfo) args.arg4;
                    final boolean forceLayout = args.argi1 != 0;
                    final boolean alwaysConsumeSystemBars = args.argi2 != 0;
                    final int displayId = args.argi3;
                    final int syncSeqId = args.argi4;
                    final boolean dragResizing = args.argi5 != 0;
                    handleResized(frames, reportDraw, mergedConfiguration, insetsState, forceLayout,
                            alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing);
                            alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing,
                            activityWindowInfo);
                    args.recycle();
                    break;
                }
@@ -6504,7 +6560,8 @@ public final class ViewRootImpl implements ViewParent,
                            mLastReportedMergedConfiguration.getOverrideConfiguration());
                    performConfigurationChange(new MergedConfiguration(mPendingMergedConfiguration),
                            false /* force */, INVALID_DISPLAY /* same display */);
                            false /* force */, INVALID_DISPLAY /* same display */,
                            mLastReportedActivityWindowInfo);
                } break;
                case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
                    setAccessibilityFocus(null, null);
@@ -8938,6 +8995,14 @@ public final class ViewRootImpl implements ViewParent,
            if (maybeSyncSeqId > 0) {
                mSyncSeqId = maybeSyncSeqId;
            }
            if (activityWindowInfoFlag() && mPendingActivityWindowInfo != null) {
                final ActivityWindowInfo outInfo = mRelayoutBundle.getParcelable(
                        IWindowSession.KEY_RELAYOUT_BUNDLE_ACTIVITY_WINDOW_INFO,
                        ActivityWindowInfo.class);
                if (outInfo != null) {
                    mPendingActivityWindowInfo.set(outInfo);
                }
            }
            mWinFrameInScreen.set(mTmpFrames.frame);
            if (mTranslator != null) {
                mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
@@ -9358,6 +9423,10 @@ public final class ViewRootImpl implements ViewParent,
                + mLastReportedMergedConfiguration);
        writer.println(innerPrefix + "mLastConfigurationFromResources="
                + mLastConfigurationFromResources);
        if (mLastReportedActivityWindowInfo != null) {
            writer.println(innerPrefix + "mLastReportedActivityWindowInfo="
                    + mLastReportedActivityWindowInfo);
        }
        writer.println(innerPrefix + "mIsAmbientMode="  + mIsAmbientMode);
        writer.println(innerPrefix + "mUnbufferedInputSource="
                + Integer.toHexString(mUnbufferedInputSource));
@@ -9571,12 +9640,14 @@ public final class ViewRootImpl implements ViewParent,
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    private void dispatchResized(ClientWindowFrames frames, boolean reportDraw,
            MergedConfiguration mergedConfiguration, InsetsState insetsState, boolean forceLayout,
            boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, boolean dragResizing) {
            boolean alwaysConsumeSystemBars, int displayId, int syncSeqId, boolean dragResizing,
            @Nullable ActivityWindowInfo activityWindowInfo) {
        Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT : MSG_RESIZED);
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = frames;
        args.arg2 = mergedConfiguration;
        args.arg3 = insetsState;
        args.arg4 = activityWindowInfo;
        args.argi1 = forceLayout ? 1 : 0;
        args.argi2 = alwaysConsumeSystemBars ? 1 : 0;
        args.argi3 = displayId;
@@ -11038,6 +11109,9 @@ public final class ViewRootImpl implements ViewParent,
            if (viewAncestor == null) {
                return;
            }
            // TODO(b/26595351): update WindowStateResizeItem
            final ActivityWindowInfo activityWindowInfo = viewAncestor
                    .mLastReportedActivityWindowInfo;
            if (insetsState.isSourceOrDefaultVisible(ID_IME, Type.ime())) {
                ImeTracing.getInstance().triggerClientDump("ViewRootImpl.W#resized",
                        viewAncestor.getInsetsController().getHost().getInputMethodManager(),
@@ -11048,7 +11122,8 @@ public final class ViewRootImpl implements ViewParent,
            if (isFromResizeItem && viewAncestor.mHandler.getLooper()
                    == ActivityThread.currentActivityThread().getLooper()) {
                viewAncestor.handleResized(frames, reportDraw, mergedConfiguration, insetsState,
                        forceLayout, alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing);
                        forceLayout, alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing,
                        activityWindowInfo);
                return;
            }
            // The the parameters from WindowStateResizeItem are already copied.
@@ -11060,7 +11135,8 @@ public final class ViewRootImpl implements ViewParent,
                mergedConfiguration = new MergedConfiguration(mergedConfiguration);
            }
            viewAncestor.dispatchResized(frames, reportDraw, mergedConfiguration, insetsState,
                    forceLayout, alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing);
                    forceLayout, alwaysConsumeSystemBars, displayId, syncSeqId, dragResizing,
                    activityWindowInfo);
        }
        @Override