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

Commit 94c9a832 authored by Tarandeep Singh's avatar Tarandeep Singh Committed by Taran Singh
Browse files

Remove IME surface when hidden

When IME is no longer shown, notify IMS to hide the window surface.
This reclaims the memory allocated to IME window surface.

Fix: 150163310
Test: atest CtsInputMethodTests
      Manually:
      1. Open any app that has editor  and run
         adb shell  dumpsys SurfaceFlinger | grep Total
      2. Note down total memory
      3. Tap on editor and IME shows. Note down memory
         using command in #1. It should go up by ~27MB
      4. Hide IME and note down memory again.
         It should revert to original value in #1.

Change-Id: I6c2a13dd40b22d3fd62b4763ba369992e5ff1138
parent d506a78e
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
    private static final int DO_FINISH_SESSION = 110;
    private static final int DO_VIEW_CLICKED = 115;
    private static final int DO_NOTIFY_IME_HIDDEN = 120;
    private static final int DO_REMOVE_IME_SURFACE = 130;

    @UnsupportedAppUsage
    HandlerCaller mCaller;
@@ -136,6 +137,10 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
                mInputMethodSession.notifyImeHidden();
                return;
            }
            case DO_REMOVE_IME_SURFACE: {
                mInputMethodSession.removeImeSurface();
                return;
            }
        }
        Log.w(TAG, "Unhandled message code: " + msg.what);
    }
@@ -183,6 +188,11 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_IME_HIDDEN));
    }

    @Override
    public void removeImeSurface() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_IME_SURFACE));
    }

    @Override
    public void updateCursor(Rect newCursor) {
        mCaller.executeOrSendMessage(
+15 −0
Original line number Diff line number Diff line
@@ -814,6 +814,13 @@ public class InputMethodService extends AbstractInputMethodService {
        onPreRenderedWindowVisibilityChanged(false /* setVisible */);
    }

    private void removeImeSurface() {
        if (!mShowInputRequested && !mWindowVisible) {
            // hiding a window removes its surface.
            mWindow.hide();
        }
    }

    private void setImeWindowStatus(int visibilityFlags, int backDisposition) {
        mPrivOps.setImeWindowStatus(visibilityFlags, backDisposition);
    }
@@ -932,6 +939,14 @@ public class InputMethodService extends AbstractInputMethodService {
        public final void notifyImeHidden() {
            InputMethodService.this.notifyImeHidden();
        }

        /**
         * Notify IME that surface can be now removed.
         * @hide
         */
        public final void removeImeSurface() {
            InputMethodService.this.removeImeSurface();
        }
    }
    
    /**
+6 −0
Original line number Diff line number Diff line
@@ -296,6 +296,12 @@ final class MultiClientInputMethodClientCallbackAdaptor {
            // no-op for multi-session since IME is responsible controlling navigation bar buttons.
            reportNotSupported();
        }

        @Override
        public void removeImeSurface() {
            // no-op for multi-session
            reportNotSupported();
        }
    }

    private static final class MultiClientInputMethodSessionImpl
+14 −1
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package android.view;

import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.toPublicType;

import android.annotation.Nullable;
import android.inputmethodservice.InputMethodService;
@@ -99,6 +98,15 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        }
    }

    @Override
    void hide(boolean animationFinished) {
        super.hide();
        if (animationFinished) {
            // remove IME surface as IME has finished hide animation.
            removeSurface();
        }
    }

    /**
     * Request {@link InputMethodManager} to show the IME.
     * @return @see {@link android.view.InsetsSourceConsumer.ShowResult}.
@@ -127,6 +135,11 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer {
        getImm().notifyImeHidden();
    }

    @Override
    public void removeSurface() {
        getImm().removeImeSurface();
    }

    @Override
    public void setControl(@Nullable InsetsSourceControl control, int[] showTypes,
            int[] hideTypes) {
+4 −4
Original line number Diff line number Diff line
@@ -694,7 +694,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (shown) {
            showDirectly(controller.getTypes());
        } else {
            hideDirectly(controller.getTypes());
            hideDirectly(controller.getTypes(), true /* animationFinished */);
        }
    }

@@ -852,10 +852,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
                        : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN);
    }

    private void hideDirectly(@InsetsType int types) {
    private void hideDirectly(@InsetsType int types, boolean animationFinished) {
        final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
        for (int i = internalTypes.size() - 1; i >= 0; i--) {
            getSourceConsumer(internalTypes.valueAt(i)).hide();
            getSourceConsumer(internalTypes.valueAt(i)).hide(animationFinished);
        }
    }

@@ -887,7 +887,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
        if (layoutDuringAnimation == LAYOUT_INSETS_DURING_ANIMATION_SHOWN) {
            showDirectly(types);
        } else {
            hideDirectly(types);
            hideDirectly(types, false /* animationFinished */);
        }
        if (mViewRoot.mView == null) {
            return;
Loading