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

Commit f092a7cb authored by Taran Singh's avatar Taran Singh
Browse files

Improve handwriting Ink window lifetime

1. When the system removes the last known stylus device
and has no other stylus available, remove the Ink window.

2. Create InkWindow only if the device+IME combination supports
handwriting and the stylus is being used.

Bug: 243571274
Bug: 239121683
Bug: 210039666

Test: atest StylusHandwritingTest
Change-Id: Icd3eea91fe144cff7100d3ecf19191c064c0d196
parent b40e48cd
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ class IInputMethodWrapper extends IInputMethod.Stub
    private static final int DO_INIT_INK_WINDOW = 120;
    private static final int DO_FINISH_STYLUS_HANDWRITING = 130;
    private static final int DO_UPDATE_TOOL_TYPE = 140;
    private static final int DO_REMOVE_STYLUS_HANDWRITING_WINDOW = 150;

    final WeakReference<InputMethodServiceInternal> mTarget;
    final Context mContext;
@@ -254,6 +255,10 @@ class IInputMethodWrapper extends IInputMethod.Stub
                inputMethod.finishStylusHandwriting();
                return;
            }
            case DO_REMOVE_STYLUS_HANDWRITING_WINDOW: {
                inputMethod.removeStylusHandwritingWindow();
                return;
            }

        }
        Log.w(TAG, "Unhandled message code: " + msg.what);
@@ -434,4 +439,10 @@ class IInputMethodWrapper extends IInputMethod.Stub
    public void finishStylusHandwriting() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_STYLUS_HANDWRITING));
    }

    @BinderThread
    @Override
    public void removeStylusHandwritingWindow() {
        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_STYLUS_HANDWRITING_WINDOW));
    }
}
+46 −8
Original line number Diff line number Diff line
@@ -708,9 +708,6 @@ public class InputMethodService extends AbstractInputMethodService {
            mConfigTracker.onInitialize(params.configChanges);
            mPrivOps.set(params.privilegedOperations);
            InputMethodPrivilegedOperationsRegistry.put(params.token, mPrivOps);
            if (params.stylusHandWritingSupported) {
                mInkWindow = new InkWindow(mWindow.getContext());
            }
            mNavigationBarController.onNavButtonFlagsChanged(params.navigationBarFlags);
            attachToken(params.token);
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
@@ -744,9 +741,6 @@ public class InputMethodService extends AbstractInputMethodService {
            attachToWindowToken(token);
            mToken = token;
            mWindow.setToken(token);
            if (mInkWindow != null) {
                mInkWindow.setToken(token);
            }
        }

        /**
@@ -785,7 +779,7 @@ public class InputMethodService extends AbstractInputMethodService {
            mInputConnection = null;
            // free-up cached InkWindow surface on detaching from current client.
            if (mInkWindow != null) {
                mInkWindow.hide(true /* remove */);
                removeHandwritingInkWindow();
            }
        }

@@ -972,6 +966,7 @@ public class InputMethodService extends AbstractInputMethodService {
                Log.d(TAG, "Input should have started before starting Stylus handwriting.");
                return;
            }
            maybeCreateInkWindow();
            if (!mOnPreparedStylusHwCalled) {
                // prepare hasn't been called by Stylus HOVER.
                onPrepareStylusHandwriting();
@@ -1031,11 +1026,23 @@ public class InputMethodService extends AbstractInputMethodService {
         */
        @Override
        public void initInkWindow() {
            maybeCreateInkWindow();
            mInkWindow.initOnly();
            onPrepareStylusHandwriting();
            mOnPreparedStylusHwCalled = true;
        }

        /**
         * Create and attach token to Ink window if it wasn't already created.
         */
        private void maybeCreateInkWindow() {
            if (mInkWindow == null) {
                mInkWindow = new InkWindow(mWindow.getContext());
                mInkWindow.setToken(mToken);
            }
            // TODO(b/243571274): set an idle-timeout after which InkWindow is removed.
        }

        /**
         * {@inheritDoc}
         * @hide
@@ -1045,6 +1052,15 @@ public class InputMethodService extends AbstractInputMethodService {
            InputMethodService.this.finishStylusHandwriting();
        }

        /**
         * {@inheritDoc}
         * @hide
         */
        @Override
        public void removeStylusHandwritingWindow() {
            InputMethodService.this.removeStylusHandwritingWindow();
        }

        /**
         * {@inheritDoc}
         */
@@ -2511,6 +2527,7 @@ public class InputMethodService extends AbstractInputMethodService {

        mHandwritingEventReceiver.dispose();
        mHandwritingEventReceiver = null;
        // TODO(b/243571274): set an idle-timeout after which InkWindow is removed.
        mInkWindow.hide(false /* remove */);

        mPrivOps.resetStylusHandwriting(requestId);
@@ -2518,6 +2535,27 @@ public class InputMethodService extends AbstractInputMethodService {
        onFinishStylusHandwriting();
    }

    /**
     * Remove Stylus handwriting window.
     * Typically, this is called when {@link InkWindow} should no longer be holding a surface in
     * memory.
     */
    private void removeStylusHandwritingWindow() {
        if (mInkWindow != null) {
            if (mHandwritingRequestId.isPresent()) {
                // if handwriting session is still ongoing. This shouldn't happen.
                finishStylusHandwriting();
            }
            removeHandwritingInkWindow();
        }
    }

    private void removeHandwritingInkWindow() {
        mInkWindow.hide(true /* remove */);
        mInkWindow.destroy();
        mInkWindow = null;
    }

    /**
     * Sets the duration after which an ongoing stylus handwriting session that hasn't received new
     * {@link MotionEvent}s will time out and {@link #finishStylusHandwriting()} will be called.
+7 −0
Original line number Diff line number Diff line
@@ -410,4 +410,11 @@ public interface InputMethod {
        // intentionally empty
    }

    /**
     * Remove stylus handwriting window.
     * @hide
     */
    default void removeStylusHandwritingWindow() {
        // intentionally empty
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ oneway interface IInputMethod {
        IBinder token;
        IInputMethodPrivilegedOperations privilegedOperations;
        int configChanges;
        boolean stylusHandWritingSupported;
        int navigationBarFlags;
    }

@@ -86,4 +85,6 @@ oneway interface IInputMethod {
    void initInkWindow();

    void finishStylusHandwriting();

    void removeStylusHandwritingWindow();
}
+10 −3
Original line number Diff line number Diff line
@@ -109,13 +109,11 @@ final class IInputMethodInvoker {

    @AnyThread
    void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privilegedOperations,
            int configChanges, boolean stylusHandWritingSupported,
            @InputMethodNavButtonFlags int navigationBarFlags) {
            int configChanges, @InputMethodNavButtonFlags int navigationBarFlags) {
        final IInputMethod.InitParams params = new IInputMethod.InitParams();
        params.token = token;
        params.privilegedOperations = privilegedOperations;
        params.configChanges = configChanges;
        params.stylusHandWritingSupported = stylusHandWritingSupported;
        params.navigationBarFlags = navigationBarFlags;
        try {
            mTarget.initializeInternal(params);
@@ -279,4 +277,13 @@ final class IInputMethodInvoker {
            logRemoteException(e);
        }
    }

    @AnyThread
    void removeStylusHandwritingWindow() {
        try {
            mTarget.removeStylusHandwritingWindow();
        } catch (RemoteException e) {
            logRemoteException(e);
        }
    }
}
Loading