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

Commit 7a13e728 authored by Tiger's avatar Tiger
Browse files

Let insets source be user-controllable even if it doesn't provide insets

If an insets source doesn't provide insets, the app is not able to
change its position. But the app should still be able to change the
alpha.

Fix: 285584763
Test: WindowInsetsTests:
      Drag to show floating IME in 3-button nav mode in landscape.
      See if the visibility of IME is as expected.
Change-Id: I3210df9bcc087f5fba712e0e7ac4922475c3b88d
parent 227073ae
Loading
Loading
Loading
Loading
+9 −14
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import static android.view.InsetsAnimationControlImplProto.PENDING_FRACTION;
import static android.view.InsetsAnimationControlImplProto.PENDING_INSETS;
import static android.view.InsetsAnimationControlImplProto.SHOWN_ON_FINISH;
import static android.view.InsetsAnimationControlImplProto.TMP_MATRIX;
import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN;
@@ -285,15 +284,11 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
            return false;
        }
        final Insets offset = Insets.subtract(mShownInsets, mPendingInsets);
        ArrayList<SurfaceParams> params = new ArrayList<>();
        updateLeashesForSide(ISIDE_LEFT, offset.left, mPendingInsets.left, params, outState,
                mPendingAlpha);
        updateLeashesForSide(ISIDE_TOP, offset.top, mPendingInsets.top, params, outState,
                mPendingAlpha);
        updateLeashesForSide(ISIDE_RIGHT, offset.right, mPendingInsets.right, params, outState,
                mPendingAlpha);
        updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mPendingInsets.bottom, params, outState,
                mPendingAlpha);
        final ArrayList<SurfaceParams> params = new ArrayList<>();
        updateLeashesForSide(ISIDE_LEFT, offset.left, params, outState, mPendingAlpha);
        updateLeashesForSide(ISIDE_TOP, offset.top, params, outState, mPendingAlpha);
        updateLeashesForSide(ISIDE_RIGHT, offset.right, params, outState, mPendingAlpha);
        updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, params, outState, mPendingAlpha);

        mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()]));
        mCurrentInsets = mPendingInsets;
@@ -457,7 +452,7 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
        return alpha >= 1 ? 1 : (alpha <= 0 ? 0 : alpha);
    }

    private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
    private void updateLeashesForSide(@InternalInsetsSide int side, int offset,
            ArrayList<SurfaceParams> surfaceParams, @Nullable InsetsState outState, float alpha) {
        final ArraySet<InsetsSourceControl> controls = mSideControlsMap.get(side);
        if (controls == null) {
@@ -475,9 +470,9 @@ public class InsetsAnimationControlImpl implements InternalInsetsAnimationContro
            }
            addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);

            final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM
                    ? (mAnimationType == ANIMATION_TYPE_SHOW || !mFinished)
                    : inset != 0;
            final boolean visible = mPendingFraction == 0 && source != null
                    ? source.isVisible()
                    : !mFinished || mShownOnFinish;

            if (outState != null && source != null) {
                outState.addSource(new InsetsSource(source)
+1 −51
Original line number Diff line number Diff line
@@ -662,9 +662,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    /** Set of inset types for which an animation was started since last resetting this field */
    private @InsetsType int mLastStartedAnimTypes;

    /** Set of inset types which cannot be controlled by the user animation */
    private @InsetsType int mDisabledUserAnimationInsetsTypes;

    /** Set of inset types which are existing */
    private @InsetsType int mExistingTypes = 0;

@@ -877,21 +874,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        mState.set(newState, 0 /* types */);
        @InsetsType int existingTypes = 0;
        @InsetsType int visibleTypes = 0;
        @InsetsType int disabledUserAnimationTypes = 0;
        @InsetsType int[] cancelledUserAnimationTypes = {0};
        for (int i = 0, size = newState.sourceSize(); i < size; i++) {
            final InsetsSource source = newState.sourceAt(i);
            @InsetsType int type = source.getType();
            @AnimationType int animationType = getAnimationType(type);
            if (!source.isUserControllable()) {
                // The user animation is not allowed when visible frame is empty.
                disabledUserAnimationTypes |= type;
                if (animationType == ANIMATION_TYPE_USER) {
                    // Existing user animation needs to be cancelled.
                    animationType = ANIMATION_TYPE_NONE;
                    cancelledUserAnimationTypes[0] |= type;
                }
            }
            final InsetsSourceConsumer consumer = mSourceConsumers.get(source.getId());
            if (consumer != null) {
                consumer.updateSource(source, animationType);
@@ -921,28 +908,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        }
        InsetsState.traverse(mState, newState, mRemoveGoneSources);

        updateDisabledUserAnimationTypes(disabledUserAnimationTypes);

        if (cancelledUserAnimationTypes[0] != 0) {
            mHandler.post(() -> show(cancelledUserAnimationTypes[0]));
        }
    }

    private void updateDisabledUserAnimationTypes(@InsetsType int disabledUserAnimationTypes) {
        @InsetsType int diff = mDisabledUserAnimationInsetsTypes ^ disabledUserAnimationTypes;
        if (diff != 0) {
            for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
                InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
                if (consumer.getControl() != null && (consumer.getType() & diff) != 0) {
                    mHandler.removeCallbacks(mInvokeControllableInsetsChangedListeners);
                    mHandler.post(mInvokeControllableInsetsChangedListeners);
                    break;
                }
            }
            mDisabledUserAnimationInsetsTypes = disabledUserAnimationTypes;
        }
    }

    private boolean captionInsetsUnchanged() {
        if (CAPTION_ON_SHELL) {
            return false;
@@ -1316,26 +1286,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                    + " while an existing " + Type.toString(mTypesBeingCancelled)
                    + " is being cancelled.");
        }
        if (animationType == ANIMATION_TYPE_USER) {
            final @InsetsType int disabledTypes = types & mDisabledUserAnimationInsetsTypes;
            if (DEBUG) Log.d(TAG, "user animation disabled types: " + disabledTypes);
            types &= ~mDisabledUserAnimationInsetsTypes;

            if ((disabledTypes & ime()) != 0) {
                ImeTracker.forLogging().onFailed(statsToken,
                        ImeTracker.PHASE_CLIENT_DISABLED_USER_ANIMATION);

                if (fromIme
                        && !mState.isSourceOrDefaultVisible(mImeSourceConsumer.getId(), ime())) {
                    // We've requested IMM to show IME, but the IME is not controllable. We need to
                    // cancel the request.
                    setRequestedVisibleTypes(0 /* visibleTypes */, ime());
                    if (mImeSourceConsumer.onAnimationStateChanged(false /* running */)) {
                        notifyVisibilityChanged();
                    }
                }
            }
        }
        if (types == 0) {
            // nothing to animate.
            listener.onCancelled(null);
@@ -1908,7 +1858,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
            InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
            InsetsSource source = mState.peekSource(consumer.getId());
            if (consumer.getControl() != null && source != null && source.isUserControllable()) {
            if (consumer.getControl() != null && source != null) {
                result |= consumer.getType();
            }
        }
+0 −5
Original line number Diff line number Diff line
@@ -183,11 +183,6 @@ public class InsetsSource implements Parcelable {
        return (mFlags & flags) == flags;
    }

    boolean isUserControllable() {
        // If mVisibleFrame is null, it will be the same area as mFrame.
        return mVisibleFrame == null || !mVisibleFrame.isEmpty();
    }

    /**
     * Calculates the insets this source will cause to a client window.
     *
+4 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.google.android.test.windowinsetstests;

import static android.view.WindowInsets.Type.ime;
import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;

import static java.lang.Math.max;
import static java.lang.Math.min;

@@ -41,11 +42,11 @@ import android.view.WindowInsetsAnimationController;
import android.view.animation.LinearInterpolator;
import android.widget.LinearLayout;

import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AppCompatActivity;

public class ChatActivity extends AppCompatActivity {

    private View mRoot;
@@ -148,7 +149,7 @@ public class ChatActivity extends AppCompatActivity {
                inset = min(inset, shown);
                mAnimationController.setInsetsAndAlpha(
                        Insets.of(0, 0, 0, inset),
                        1f, (inset - start) / (float)(end - start));
                        1f, start == end ? 1f : (inset - start) / (float) (end - start));
            }
        });