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

Commit 6b2391ae authored by Tiger's avatar Tiger
Browse files

Use the ID to create the InsetsSourceProvider

We still use the internal insets type as the ID for now. But when
InsetsFrameProvider have enough information for us to create the ID, we
will be ready to switch to it, and then we can remove all the internal
insets types.

This CL also refines the life cycle of InsetsSources and
InsetsSourceProviders. When an insets hosting window is removed, the
sources and the providers provided by it will be removed as well.

Bug: 234093736
Test: atest ActivityRecordTests DisplayPolicyLayoutTests
            InsetsStateControllerTest WindowStateTests WindowTokenTests
Change-Id: I72f42e128b2a15bc2522b8be874487504eb8a178
parent cff14c06
Loading
Loading
Loading
Loading
+19 −42
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@ import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
import static android.view.Display.STATE_UNKNOWN;
import static android.view.Display.isSuspendedState;
import static android.view.InsetsSource.ID_IME;
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
import static android.view.InsetsState.ITYPE_RIGHT_GESTURES;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -57,6 +55,7 @@ import static android.view.WindowInsets.Type.displayCutout;
import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.systemBars;
import static android.view.WindowInsets.Type.systemGestures;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowManager.DISPLAY_IME_POLICY_FALLBACK_DISPLAY;
import static android.view.WindowManager.DISPLAY_IME_POLICY_LOCAL;
@@ -174,6 +173,7 @@ import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.graphics.Insets;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
@@ -221,7 +221,6 @@ import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.MagnificationSpec;
import android.view.PrivacyIndicatorBounds;
import android.view.RemoteAnimationDefinition;
@@ -248,7 +247,6 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.inputmethod.InputMethodManagerInternal;
@@ -466,6 +464,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
    private boolean mSystemGestureExclusionWasRestricted = false;
    private final Region mSystemGestureExclusionUnrestricted = new Region();
    private int mSystemGestureExclusionLimit;
    private final Rect mSystemGestureFrameLeft = new Rect();
    private final Rect mSystemGestureFrameRight = new Rect();

    private Set<Rect> mRestrictedKeepClearAreas = new ArraySet<>();
    private Set<Rect> mUnrestrictedKeepClearAreas = new ArraySet<>();
@@ -1517,31 +1517,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return mDisplayRotation;
    }

    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider) {
        setInsetProvider(type, win, frameProvider, null /* overrideFrameProviders */);
    }

    /**
     * Marks a window as providing insets for the rest of the windows in the system.
     *
     * @param type The type of inset this window provides.
     * @param win The window.
     * @param frameProvider Function to compute the frame, or {@code null} if the just the frame of
     *                      the window should be taken. Only for non-WindowState providers, nav bar
     *                      and status bar.
     * @param overrideFrameProviders Functions to compute the frame when dispatching insets to the
     *                               given window types, or {@code null} if the normal frame should
     *                               be taken.
     */
    void setInsetProvider(@InternalInsetsType int type, WindowContainer win,
            @Nullable TriConsumer<DisplayFrames, WindowContainer, Rect> frameProvider,
            @Nullable SparseArray<TriConsumer<DisplayFrames, WindowContainer, Rect>>
                    overrideFrameProviders) {
        mInsetsStateController.getSourceProvider(type).setWindowContainer(win, frameProvider,
                overrideFrameProviders);
    }

    InsetsStateController getInsetsStateController() {
        return mInsetsStateController;
    }
@@ -4034,7 +4009,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            final int imePid = mInputMethodWindow.mSession.mPid;
            mAtmService.onImeWindowSetOnDisplayArea(imePid, mImeWindowsContainer);
        }
        mInsetsStateController.getSourceProvider(ID_IME).setWindowContainer(win,
        mInsetsStateController.getImeSourceProvider().setWindowContainer(win,
                mDisplayPolicy.getImeSourceFrameProvider(), null);
        computeImeTarget(true /* updateImeTarget */);
        updateImeControlTarget();
@@ -5705,10 +5680,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        final Region unhandled = Region.obtain();
        unhandled.set(0, 0, mDisplayFrames.mWidth, mDisplayFrames.mHeight);

        final Rect leftEdge = mInsetsStateController.getSourceProvider(ITYPE_LEFT_GESTURES)
                .getSource().getFrame();
        final Rect rightEdge = mInsetsStateController.getSourceProvider(ITYPE_RIGHT_GESTURES)
                .getSource().getFrame();
        final InsetsState state = mInsetsStateController.getRawInsetsState();
        final Rect df = state.getDisplayFrame();
        final Insets gestureInsets = state.calculateInsets(df, systemGestures(),
                false /* ignoreVisibility */);
        mSystemGestureFrameLeft.set(df.left, df.top, gestureInsets.left, df.bottom);
        mSystemGestureFrameRight.set(gestureInsets.right, df.top, df.right, df.bottom);

        final Region touchableRegion = Region.obtain();
        final Region local = Region.obtain();
@@ -5752,25 +5729,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            if (needsGestureExclusionRestrictions(w, false /* ignoreRequest */)) {

                // Processes the region along the left edge.
                remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
                        remainingLeftRight[0], w, EXCLUSION_LEFT);
                remainingLeftRight[0] = addToGlobalAndConsumeLimit(local, outExclusion,
                        mSystemGestureFrameLeft, remainingLeftRight[0], w, EXCLUSION_LEFT);

                // Processes the region along the right edge.
                remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
                        remainingLeftRight[1], w, EXCLUSION_RIGHT);
                remainingLeftRight[1] = addToGlobalAndConsumeLimit(local, outExclusion,
                        mSystemGestureFrameRight, remainingLeftRight[1], w, EXCLUSION_RIGHT);

                // Adds the middle (unrestricted area)
                final Region middle = Region.obtain(local);
                middle.op(leftEdge, Op.DIFFERENCE);
                middle.op(rightEdge, Op.DIFFERENCE);
                middle.op(mSystemGestureFrameLeft, Op.DIFFERENCE);
                middle.op(mSystemGestureFrameRight, Op.DIFFERENCE);
                outExclusion.op(middle, Op.UNION);
                middle.recycle();
            } else {
                boolean loggable = needsGestureExclusionRestrictions(w, true /* ignoreRequest */);
                if (loggable) {
                    addToGlobalAndConsumeLimit(local, outExclusion, leftEdge,
                    addToGlobalAndConsumeLimit(local, outExclusion, mSystemGestureFrameLeft,
                            Integer.MAX_VALUE, w, EXCLUSION_LEFT);
                    addToGlobalAndConsumeLimit(local, outExclusion, rightEdge,
                    addToGlobalAndConsumeLimit(local, outExclusion, mSystemGestureFrameRight,
                            Integer.MAX_VALUE, w, EXCLUSION_RIGHT);
                }
                outExclusion.op(local, Op.UNION);
+51 −35
Original line number Diff line number Diff line
@@ -1076,8 +1076,16 @@ public class DisplayPolicy {
                } else {
                    overrideProviders = null;
                }
                mDisplayContent.setInsetProvider(provider.type, win, frameProvider,
                        overrideProviders);
                // TODO (b/234093736): Let InsetsFrameProvider have the following fields:
                //                     - IBinder owner.
                //                     - int index.
                //                     - @InsetsType int type.
                //                     So we can create the id by using InsetsSource#createId.
                //                     And we won't need toPublicType anymore.
                final int id = provider.type;
                final @InsetsType int type = InsetsState.toPublicType(id);
                mDisplayContent.getInsetsStateController().getOrCreateSourceProvider(id, type)
                        .setWindowContainer(win, frameProvider, overrideProviders);
                mInsetsSourceWindowsExceptIme.add(win);
            }
        }
@@ -1170,10 +1178,17 @@ public class DisplayPolicy {
            mLastFocusedWindow = null;
        }

        final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
        for (int index = sources.size() - 1; index >= 0; index--) {
            final @InternalInsetsType int type = sources.keyAt(index);
            mDisplayContent.setInsetProvider(type, null /* win */, null /* frameProvider */);
        if (win.hasInsetsSourceProvider()) {
            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
            final InsetsStateController controller = mDisplayContent.getInsetsStateController();
            for (int index = providers.size() - 1; index >= 0; index--) {
                final InsetsSourceProvider provider = providers.valueAt(index);
                provider.setWindowContainer(
                        null /* windowContainer */,
                        null /* frameProvider */,
                        null /* overrideFrameProviders */);
                controller.removeSourceProvider(provider.getSource().getId());
            }
        }
        mInsetsSourceWindowsExceptIme.remove(win);
    }
@@ -1242,7 +1257,6 @@ public class DisplayPolicy {
     * some temporal states, but doesn't change the window frames used to show on screen.
     */
    void simulateLayoutDisplay(DisplayFrames displayFrames) {
        final InsetsStateController controller = mDisplayContent.getInsetsStateController();
        sTmpClientFrames.attachedFrame = null;
        for (int i = mInsetsSourceWindowsExceptIme.size() - 1; i >= 0; i--) {
            final WindowState win = mInsetsSourceWindowsExceptIme.valueAt(i);
@@ -1251,11 +1265,10 @@ public class DisplayPolicy {
                    displayFrames.mUnrestricted, win.getWindowingMode(), UNSPECIFIED_LENGTH,
                    UNSPECIFIED_LENGTH, win.getRequestedVisibleTypes(), win.mGlobalScale,
                    sTmpClientFrames);
            final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
            final InsetsState state = displayFrames.mInsetsState;
            for (int index = sources.size() - 1; index >= 0; index--) {
                final int type = sources.keyAt(index);
                state.addSource(controller.getSourceProvider(type).createSimulatedSource(
            for (int index = providers.size() - 1; index >= 0; index--) {
                state.addSource(providers.valueAt(index).createSimulatedSource(
                        displayFrames, sTmpClientFrames.frame));
            }
        }
@@ -1358,10 +1371,12 @@ public class DisplayPolicy {
            mIsFreeformWindowOverlappingWithNavBar = true;
        }

        final SparseArray<InsetsSource> sources = win.getProvidedInsetsSources();
        if (win.hasInsetsSourceProvider()) {
            final SparseArray<InsetsSourceProvider> providers = win.getInsetsSourceProviders();
            final Rect bounds = win.getBounds();
        for (int index = sources.size() - 1; index >= 0; index--) {
            final InsetsSource source = sources.valueAt(index);
            for (int index = providers.size() - 1; index >= 0; index--) {
                final InsetsSourceProvider provider = providers.valueAt(index);
                final InsetsSource source = provider.getSource();
                if ((source.getType()
                        & (Type.systemGestures() | Type.mandatorySystemGestures())) == 0) {
                    continue;
@@ -1384,6 +1399,7 @@ public class DisplayPolicy {
                    mBottomGestureHost = win;
                }
            }
        }

        if (!affectsSystemUi) {
            return;
+3 −4
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import android.app.StatusBarManager;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.res.Resources;
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.InsetsAnimationControlCallbacks;
import android.view.InsetsAnimationControlImpl;
@@ -242,7 +241,7 @@ class InsetsPolicy {

        startAnimation(false /* show */, () -> {
            synchronized (mDisplayContent.mWmService.mGlobalLock) {
                final ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers =
                final SparseArray<WindowContainerInsetsSourceProvider> providers =
                        mStateController.getSourceProviders();
                for (int i = providers.size() - 1; i >= 0; i--) {
                    final WindowContainerInsetsSourceProvider provider = providers.valueAt(i);
@@ -345,8 +344,8 @@ class InsetsPolicy {
            }
        }

        final ArrayMap<Integer, WindowContainerInsetsSourceProvider> providers = mStateController
                .getSourceProviders();
        final SparseArray<WindowContainerInsetsSourceProvider> providers =
                mStateController.getSourceProviders();
        final int windowType = attrs.type;
        for (int i = providers.size() - 1; i >= 0; i--) {
            final WindowContainerInsetsSourceProvider otherProvider = providers.valueAt(i);
+2 −2
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@ abstract class InsetsSourceProvider {
            // TODO: Ideally, we should wait for the animation to finish so previous window can
            // animate-out as new one animates-in.
            mWindowContainer.cancelAnimation();
            mWindowContainer.getProvidedInsetsSources().remove(mSource.getId());
            mWindowContainer.getInsetsSourceProviders().remove(mSource.getId());
            mSeamlessRotating = false;
        }
        ProtoLog.d(WM_DEBUG_WINDOW_INSETS, "InsetsSource setWin %s for type %s",
@@ -180,7 +180,7 @@ abstract class InsetsSourceProvider {
            mSource.setInsetsRoundedCornerFrame(false);
            mSourceFrame.setEmpty();
        } else {
            mWindowContainer.getProvidedInsetsSources().put(mSource.getId(), mSource);
            mWindowContainer.getInsetsSourceProviders().put(mSource.getId(), this);
            if (mControllable) {
                mWindowContainer.setControllableInsetProvider(this);
                if (mPendingControlTarget != null) {
+25 −18
Original line number Diff line number Diff line
@@ -34,9 +34,9 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.InsetsState.InternalInsetsType;
import android.view.WindowInsets;
import android.view.WindowInsets.Type.InsetsType;

@@ -46,7 +46,6 @@ import com.android.server.inputmethod.InputMethodManagerInternal;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * Manages global window inset state in the system represented by {@link InsetsState}.
@@ -57,8 +56,7 @@ class InsetsStateController {
    private final InsetsState mState = new InsetsState();
    private final DisplayContent mDisplayContent;

    private final ArrayMap<Integer, WindowContainerInsetsSourceProvider> mProviders =
            new ArrayMap<>();
    private final SparseArray<WindowContainerInsetsSourceProvider> mProviders = new SparseArray<>();
    private final ArrayMap<InsetsControlTarget, ArrayList<InsetsSourceProvider>>
            mControlTargetProvidersMap = new ArrayMap<>();
    private final SparseArray<InsetsControlTarget> mIdControlTargetMap = new SparseArray<>();
@@ -87,15 +85,8 @@ class InsetsStateController {
        }
    };

    private final Function<Integer, WindowContainerInsetsSourceProvider> mSourceProviderFunc;

    InsetsStateController(DisplayContent displayContent) {
        mDisplayContent = displayContent;
        mSourceProviderFunc = id -> (id == ID_IME)
                ? new ImeInsetsSourceProvider(mState.getOrCreateSource(
                        id, ime()), this, mDisplayContent)
                : new WindowContainerInsetsSourceProvider(mState.getOrCreateSource(
                        id, InsetsState.toPublicType(id)), this, mDisplayContent);
    }

    InsetsState getRawInsetsState() {
@@ -115,27 +106,43 @@ class InsetsStateController {
        return result;
    }

    ArrayMap<Integer, WindowContainerInsetsSourceProvider> getSourceProviders() {
    SparseArray<WindowContainerInsetsSourceProvider> getSourceProviders() {
        return mProviders;
    }

    /**
     * @return The provider of a specific source ID.
     */
    WindowContainerInsetsSourceProvider getSourceProvider(int id) {
        return mProviders.computeIfAbsent(id, mSourceProviderFunc);
    WindowContainerInsetsSourceProvider getOrCreateSourceProvider(int id, @InsetsType int type) {
        WindowContainerInsetsSourceProvider provider = mProviders.get(id);
        if (provider != null) {
            return provider;
        }
        final InsetsSource source = mState.getOrCreateSource(id, type);
        provider = id == ID_IME
                ? new ImeInsetsSourceProvider(source, this, mDisplayContent)
                : new WindowContainerInsetsSourceProvider(source, this, mDisplayContent);
        mProviders.put(id, provider);
        return provider;
    }

    ImeInsetsSourceProvider getImeSourceProvider() {
        return (ImeInsetsSourceProvider) getSourceProvider(ID_IME);
        return (ImeInsetsSourceProvider) getOrCreateSourceProvider(ID_IME, ime());
    }

    void removeSourceProvider(int id) {
        if (id != ID_IME) {
            mState.removeSource(id);
            mProviders.remove(id);
        }
    }

    /**
     * @return The provider of a specific type or null if we don't have it.
     * @return The provider of a source ID or null if we don't have it.
     */
    @Nullable
    WindowContainerInsetsSourceProvider peekSourceProvider(@InternalInsetsType int type) {
        return mProviders.get(type);
    WindowContainerInsetsSourceProvider peekSourceProvider(int id) {
        return mProviders.get(id);
    }

    /**
Loading