Dismiss the mouse pointer while typing on keyboard

Fixes the borken UX to dismiss the mouse pointer while user is typing on
the physical keyboard.

Bug: b/338652288
Test: atest inputflinger_tests
Change-Id: Ifc4bfd20a44650634d007fbcfc75bf497d5f4623
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 7d3a2df..00dd6ba 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -21,6 +21,7 @@
 #if defined(__ANDROID__)
 #include <gui/SurfaceComposerClient.h>
 #endif
+#include <input/Keyboard.h>
 #include <input/PrintTools.h>
 #include <unordered_set>
 
@@ -137,6 +138,7 @@
         mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID),
         mShowTouchesEnabled(false),
         mStylusPointerIconEnabled(false),
+        mCurrentFocusedDisplay(ui::LogicalDisplayId::DEFAULT),
         mRegisterListener(registerListener),
         mUnregisterListener(unregisterListener) {}
 
@@ -168,6 +170,7 @@
 }
 
 void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
+    fadeMouseCursorOnKeyPress(args);
     mNextListener.notify(args);
 }
 
@@ -177,6 +180,32 @@
     mNextListener.notify(newArgs);
 }
 
+void PointerChoreographer::fadeMouseCursorOnKeyPress(const android::NotifyKeyArgs& args) {
+    if (args.action == AKEY_EVENT_ACTION_UP || isMetaKey(args.keyCode)) {
+        return;
+    }
+    // Meta state for these keys is ignored for dismissing cursor while typing
+    constexpr static int32_t ALLOW_FADING_META_STATE_MASK = AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON |
+            AMETA_SCROLL_LOCK_ON | AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON;
+    if (args.metaState & ~ALLOW_FADING_META_STATE_MASK) {
+        // Do not fade if any other meta state is active
+        return;
+    }
+    if (!mPolicy.isInputMethodConnectionActive()) {
+        return;
+    }
+
+    std::scoped_lock _l(mLock);
+    ui::LogicalDisplayId targetDisplay = args.displayId;
+    if (targetDisplay == ui::LogicalDisplayId::INVALID) {
+        targetDisplay = mCurrentFocusedDisplay;
+    }
+    auto it = mMousePointersByDisplay.find(targetDisplay);
+    if (it != mMousePointersByDisplay.end()) {
+        it->second->fade(PointerControllerInterface::Transition::GRADUAL);
+    }
+}
+
 NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& args) {
     std::scoped_lock _l(mLock);
 
@@ -806,6 +835,11 @@
     }
 }
 
+void PointerChoreographer::setFocusedDisplay(ui::LogicalDisplayId displayId) {
+    std::scoped_lock lock(mLock);
+    mCurrentFocusedDisplay = displayId;
+}
+
 PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
         ui::LogicalDisplayId displayId) {
     std::function<std::shared_ptr<PointerControllerInterface>()> ctor =