Finish handwriting session for recents gesture

Finish stylus handwriting session when user swipes to recent.
Bug: 223748964
Test: Manually:
     1. Open an app with editor
     2. swipe on editor with stylus [or emulated stylus]
     3. Observe ink trail drawn on screen
     4. quickly sipe to recents, ink should go away.
     5. repeat steps 1-3 for swipe to home

Change-Id: Id750ff55cb447247c3eca75daf37cb5aeb1d0cfa
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 02302a2..f9ed0e3d 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -81,6 +81,7 @@
     private static final int DO_CAN_START_STYLUS_HANDWRITING = 100;
     private static final int DO_START_STYLUS_HANDWRITING = 110;
     private static final int DO_INIT_INK_WINDOW = 120;
+    private static final int DO_FINISH_STYLUS_HANDWRITING = 130;
 
     final WeakReference<InputMethodServiceInternal> mTarget;
     final Context mContext;
@@ -263,6 +264,10 @@
                 inputMethod.initInkWindow();
                 return;
             }
+            case DO_FINISH_STYLUS_HANDWRITING: {
+                inputMethod.finishStylusHandwriting();
+                return;
+            }
 
         }
         Log.w(TAG, "Unhandled message code: " + msg.what);
@@ -427,4 +432,10 @@
     public void initInkWindow() {
         mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_INIT_INK_WINDOW));
     }
+
+    @BinderThread
+    @Override
+    public void finishStylusHandwriting() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_STYLUS_HANDWRITING));
+    }
 }
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index b46bb32..4fdd534 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -994,6 +994,15 @@
 
         /**
          * {@inheritDoc}
+         * @hide
+         */
+        @Override
+        public void finishStylusHandwriting() {
+            InputMethodService.this.finishStylusHandwriting();
+        }
+
+        /**
+         * {@inheritDoc}
          */
         @MainThread
         @Override
@@ -2461,7 +2470,7 @@
         mHandwritingEventReceiver = null;
         mInkWindow.hide(false /* remove */);
 
-        mPrivOps.finishStylusHandwriting(requestId);
+        mPrivOps.resetStylusHandwriting(requestId);
         mOnPreparedStylusHwCalled = false;
         onFinishStylusHandwriting();
     }
diff --git a/core/java/android/view/inputmethod/InputMethod.java b/core/java/android/view/inputmethod/InputMethod.java
index fd336a2..6209b46 100644
--- a/core/java/android/view/inputmethod/InputMethod.java
+++ b/core/java/android/view/inputmethod/InputMethod.java
@@ -414,4 +414,12 @@
         // intentionally empty
     }
 
+    /**
+     * Finish stylus handwriting session.
+     * @hide
+     */
+    default void finishStylusHandwriting() {
+        // intentionally empty
+    }
+
 }
diff --git a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
index b18c98b..2ee47b6 100644
--- a/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
+++ b/core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl
@@ -43,5 +43,5 @@
     void notifyUserActionAsync();
     void applyImeVisibilityAsync(IBinder showOrHideInputToken, boolean setVisible);
     void onStylusHandwritingReady(int requestId, int pid);
-    void finishStylusHandwriting(int requestId);
+    void resetStylusHandwriting(int requestId);
 }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
index e8a2d81..15d7acf 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodPrivilegedOperations.java
@@ -416,13 +416,13 @@
      * @param requestId
      */
     @AnyThread
-    public void finishStylusHandwriting(int requestId) {
+    public void resetStylusHandwriting(int requestId) {
         final IInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
         if (ops == null) {
             return;
         }
         try {
-            ops.finishStylusHandwriting(requestId);
+            ops.resetStylusHandwriting(requestId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/com/android/internal/view/IInputMethod.aidl b/core/java/com/android/internal/view/IInputMethod.aidl
index 273c5f1..40d89db6 100644
--- a/core/java/com/android/internal/view/IInputMethod.aidl
+++ b/core/java/com/android/internal/view/IInputMethod.aidl
@@ -67,4 +67,6 @@
             in List<MotionEvent> events);
 
     void initInkWindow();
+
+    void finishStylusHandwriting();
 }
diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
index e6fd409..e62c5c1 100644
--- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
+++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java
@@ -245,4 +245,13 @@
             logRemoteException(e);
         }
     }
+
+    @AnyThread
+    void finishStylusHandwriting() {
+        try {
+            mTarget.finishStylusHandwriting();
+        } catch (RemoteException e) {
+            logRemoteException(e);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
index 29dcdfa..a2d3588 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerInternal.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
+import android.inputmethodservice.InputMethodService;
 import android.os.IBinder;
 import android.view.inputmethod.InlineSuggestionsRequest;
 import android.view.inputmethod.InputMethodInfo;
@@ -150,6 +151,12 @@
     public abstract void updateImeWindowStatus(boolean disableImeIcon);
 
     /**
+     * Finish stylus handwriting by calling {@link InputMethodService#finishStylusHandwriting()} if
+     * there is an ongoing handwriting session.
+     */
+    public abstract void maybeFinishStylusHandwriting();
+
+    /**
      * Callback when the IInputMethodSession from the accessibility service with the specified
      * accessibilityConnectionId is created.
      *
@@ -239,6 +246,10 @@
                 @Override
                 public void unbindAccessibilityFromCurrentClient(int accessibilityConnectionId) {
                 }
+
+                @Override
+                public void maybeFinishStylusHandwriting() {
+                }
             };
 
     /**
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 77dcbd3..831c809 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -230,6 +230,7 @@
 
     private static final int MSG_RESET_HANDWRITING = 1090;
     private static final int MSG_START_HANDWRITING = 1100;
+    private static final int MSG_FINISH_HANDWRITING = 1110;
 
     private static final int MSG_UNBIND_CLIENT = 3000;
     private static final int MSG_UNBIND_ACCESSIBILITY_SERVICE = 3001;
@@ -4430,7 +4431,7 @@
     }
 
     @BinderThread
-    private void finishStylusHandwriting(int requestId) {
+    private void resetStylusHandwriting(int requestId) {
         synchronized (ImfLock.class) {
             final OptionalInt curRequest = mHwController.getCurrentRequestId();
             if (!curRequest.isPresent() || curRequest.getAsInt() != requestId) {
@@ -4797,6 +4798,14 @@
                     }
                 }
                 return true;
+            case MSG_FINISH_HANDWRITING:
+                synchronized (ImfLock.class) {
+                    IInputMethodInvoker curMethod = getCurMethodLocked();
+                    if (curMethod != null && mHwController.getCurrentRequestId().isPresent()) {
+                        curMethod.finishStylusHandwriting();
+                    }
+                }
+                return true;
         }
         return false;
     }
@@ -5435,6 +5444,12 @@
                 }
             }
         }
+
+        @Override
+        public void maybeFinishStylusHandwriting() {
+            mHandler.removeMessages(MSG_FINISH_HANDWRITING);
+            mHandler.obtainMessage(MSG_FINISH_HANDWRITING).sendToTarget();
+        }
     }
 
     @BinderThread
@@ -6388,8 +6403,8 @@
 
         @BinderThread
         @Override
-        public void finishStylusHandwriting(int requestId) {
-            mImms.finishStylusHandwriting(requestId);
+        public void resetStylusHandwriting(int requestId) {
+            mImms.resetStylusHandwriting(requestId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index a4d338c..e21ae05 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -281,6 +281,7 @@
                             task.setCanAffectSystemUiFlags(behindSystemBars);
                         }
                     }
+                    InputMethodManagerInternal.get().maybeFinishStylusHandwriting();
                     if (!behindSystemBars) {
                         // Hiding IME if IME window is not attached to app.
                         // Since some windowing mode is not proper to snapshot Task with IME window