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

Commit d332901c authored by Taran Singh's avatar Taran Singh Committed by Android (Google) Code Review
Browse files

Merge "IME transitions without pre-rendering."

parents d383981f 92d2dd36
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.inputmethodservice;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;

import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -62,6 +63,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
@@ -595,12 +597,12 @@ public class InputMethodService extends AbstractInputMethodService {
            if (DEBUG) Log.v(TAG, "hideSoftInput()");
            final boolean wasVisible = mIsPreRendered
                    ? mDecorViewVisible && mWindowVisible : isInputViewShown();
            applyVisibilityInInsetsConsumerIfNecessary(false /* setVisible */);
            if (mIsPreRendered) {
                if (DEBUG) {
                    Log.v(TAG, "Making IME window invisible");
                }
                setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
                applyVisibilityInInsetsConsumer(false /* setVisible */);
                onPreRenderedWindowVisibilityChanged(false /* setVisible */);
            } else {
                mShowInputFlags = 0;
@@ -632,11 +634,11 @@ public class InputMethodService extends AbstractInputMethodService {
                    if (DEBUG) {
                        Log.v(TAG, "Making IME window visible");
                    }
                    applyVisibilityInInsetsConsumer(true /* setVisible */);
                    onPreRenderedWindowVisibilityChanged(true /* setVisible */);
                } else {
                    showWindow(true);
                }
                applyVisibilityInInsetsConsumerIfNecessary(true /* setVisible */);
            }
            // If user uses hard keyboard, IME button should always be shown.
            setImeWindowStatus(mapToImeWindowStatus(), mBackDisposition);
@@ -1974,16 +1976,20 @@ public class InputMethodService extends AbstractInputMethodService {

    /**
     * Apply the IME visibility in {@link android.view.ImeInsetsSourceConsumer} when
     * pre-rendering is enabled.
     * {@link ViewRootImpl.sNewInsetsMode} is enabled.
     * @param setVisible {@code true} to make it visible, false to hide it.
     */
    private void applyVisibilityInInsetsConsumer(boolean setVisible) {
        if (!mIsPreRendered) {
    private void applyVisibilityInInsetsConsumerIfNecessary(boolean setVisible) {
        if (!isVisibilityAppliedUsingInsetsConsumer()) {
            return;
        }
        mPrivOps.applyImeVisibility(setVisible);
    }

    private boolean isVisibilityAppliedUsingInsetsConsumer() {
        return ViewRootImpl.sNewInsetsMode > NEW_INSETS_MODE_NONE;
    }

    private void finishViews(boolean finishingInput) {
        if (mInputViewStarted) {
            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
@@ -2007,7 +2013,11 @@ public class InputMethodService extends AbstractInputMethodService {
        mWindowVisible = false;
        finishViews(false /* finishingInput */);
        if (mDecorViewVisible) {
            // When insets API is enabled, it is responsible for client and server side
            // visibility of IME window.
            if (!isVisibilityAppliedUsingInsetsConsumer()) {
                mWindow.hide();
            }
            mDecorViewVisible = false;
            onWindowHidden();
            mDecorViewWasVisible = false;
+2 −8
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
     * editor {@link #mFocusedEditor} if {@link #isServedEditorRendered} is {@code true}.
     */
    private boolean mShowOnNextImeRender;
    private boolean mHasWindowFocus;

    public ImeInsetsSourceConsumer(
            InsetsState state, Supplier<Transaction> transactionSupplier,
@@ -68,23 +67,18 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
    }

    public void applyImeVisibility(boolean setVisible) {
        if (!mHasWindowFocus) {
            // App window doesn't have focus, any visibility changes would be no-op.
            return;
        }

        mController.applyImeVisibility(setVisible);
    }

    @Override
    public void onWindowFocusGained() {
        mHasWindowFocus = true;
        super.onWindowFocusGained();
        getImm().registerImeConsumer(this);
    }

    @Override
    public void onWindowFocusLost() {
        mHasWindowFocus = false;
        super.onWindowFocusLost();
        getImm().unregisterImeConsumer(this);
    }

+17 −7
Original line number Diff line number Diff line
@@ -296,7 +296,8 @@ public class InsetsController implements WindowInsetsController {
        final ArraySet<Integer> internalTypes = mState.toInternalType(types);
        final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();

        Pair<Integer, Boolean> typesReadyPair = collectConsumers(fromIme, internalTypes, consumers);
        Pair<Integer, Boolean> typesReadyPair = collectConsumers(
                fromIme, internalTypes, consumers, listener);
        int typesReady = typesReadyPair.first;
        boolean isReady = typesReadyPair.second;
        if (!isReady) {
@@ -324,13 +325,16 @@ public class InsetsController implements WindowInsetsController {
     * @return Pair of (types ready to animate, is ready to animate).
     */
    private Pair<Integer, Boolean> collectConsumers(boolean fromIme,
            ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers) {
            ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers,
            WindowInsetsAnimationControlListener listener) {
        int typesReady = 0;
        boolean isReady = true;
        for (int i = internalTypes.size() - 1; i >= 0; i--) {
            InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
            if (consumer.getControl() != null) {
                if (!consumer.isVisible()) {
            // Double check for IME that IME target window has focus.
            if (consumer.getType() != TYPE_IME || consumer.hasWindowFocus()) {
                boolean setVisible = !consumer.isVisible();
                if (setVisible) {
                    // Show request
                    switch(consumer.requestShow(fromIme)) {
                        case ShowResult.SHOW_IMMEDIATELY:
@@ -357,8 +361,11 @@ public class InsetsController implements WindowInsetsController {
                }
                consumers.put(consumer.getType(), consumer);
            } else {
                // TODO: Let calling app know it's not possible, or wait
                // TODO: Remove it from types
                // window doesnt have focus, no-op.
                isReady = false;
                // TODO: Let the calling app know that window has lost focus and
                //       show()/hide()/controlWindowInsetsAnimation requests will be ignored.
                typesReady &= ~InsetsState.toPublicType(consumer.getType());
            }
        }
        return new Pair<>(typesReady, isReady);
@@ -533,8 +540,11 @@ public class InsetsController implements WindowInsetsController {

            @Override
            public void onCancelled() {
                // Animator can be null when it is cancelled before onReady() completes.
                if (mAnimator != null) {
                    mAnimator.cancel();
                }
            }

            private void onAnimationFinish() {
                mAnimationDirection = DIRECTION_NONE;
+11 −3
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ public class InsetsSourceConsumer {
    private final @InternalInsetType int mType;
    private final InsetsState mState;
    private @Nullable InsetsSourceControl mSourceControl;
    private boolean mHasWindowFocus;

    public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
            Supplier<Transaction> transactionSupplier, InsetsController controller) {
@@ -104,12 +105,20 @@ public class InsetsSourceConsumer {
    /**
     * Called when current window gains focus
     */
    public void onWindowFocusGained() {}
    public void onWindowFocusGained() {
        mHasWindowFocus = true;
    }

    /**
     * Called when current window loses focus.
     */
    public void onWindowFocusLost() {}
    public void onWindowFocusLost() {
        mHasWindowFocus = false;
    }

    boolean hasWindowFocus() {
        return mHasWindowFocus;
    }

    boolean applyLocalVisibilityOverride() {

@@ -153,7 +162,6 @@ public class InsetsSourceConsumer {
            return;
        }
        mVisible = visible;
        applyHiddenToControl();
        applyLocalVisibilityOverride();
        mController.notifyVisibilityChanged();
    }
+4 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_IME;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.SIZE;
@@ -161,13 +162,15 @@ public class InsetsState implements Parcelable {
                continue;
            }

            boolean skipNonImeInImeMode = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_IME
                    && source.getType() != TYPE_IME;
            boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
                    && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
            boolean skipIme = source.getType() == TYPE_IME
                    && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
            boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
                    && (toPublicType(type) & Type.compatSystemInsets()) != 0;
            if (skipSystemBars || skipIme || skipLegacyTypes) {
            if (skipSystemBars || skipIme || skipLegacyTypes || skipNonImeInImeMode) {
                typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
                continue;
            }
Loading