Merge "Tracks whether an injected MotionEvent came from an accessibility tool." into main
diff --git a/include/input/Input.h b/include/input/Input.h
index 2cabd56..e84023e 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -92,11 +92,23 @@
             static_cast<int32_t>(android::os::MotionEventFlag::NO_FOCUS_CHANGE),
 
     /**
-     * This event was generated or modified by accessibility service.
+     * This event was injected from some AccessibilityService, which may be either an
+     * Accessibility Tool OR a service using that API for purposes other than assisting users
+     * with disabilities.
      */
     AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT =
             static_cast<int32_t>(android::os::MotionEventFlag::IS_ACCESSIBILITY_EVENT),
 
+    /**
+     * This event was injected from an AccessibilityService with the
+     * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as
+     * "Accessibility Tools") are used to assist users with disabilities, so events from these
+     * services should be able to reach all Views including Views which set
+     * View#isAccessibilityDataSensitive to true.
+     */
+    AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL =
+            static_cast<int32_t>(android::os::MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL),
+
     AMOTION_EVENT_FLAG_TARGET_ACCESSIBILITY_FOCUS =
             static_cast<int32_t>(android::os::MotionEventFlag::TARGET_ACCESSIBILITY_FOCUS),
 
@@ -347,6 +359,9 @@
     POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY =
             android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY,
 
+    POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL =
+            android::os::IInputConstants::POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL,
+
     /* These flags are set by the input dispatcher. */
 
     // Indicates that the input event was injected.
diff --git a/libs/input/android/os/IInputConstants.aidl b/libs/input/android/os/IInputConstants.aidl
index 6ce3fba..4b87dab 100644
--- a/libs/input/android/os/IInputConstants.aidl
+++ b/libs/input/android/os/IInputConstants.aidl
@@ -43,8 +43,9 @@
     const int INVALID_INPUT_DEVICE_ID = -2;
 
     /**
-     * The input event was injected from accessibility. Used in policyFlags for input event
-     * injection.
+     * The input event was injected from some AccessibilityService, which may be either an
+     * Accessibility Tool OR a service using that API for purposes other than assisting users with
+     * disabilities. Used in policyFlags for input event injection.
      */
     const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY = 0x20000;
 
@@ -55,18 +56,33 @@
     const int POLICY_FLAG_KEY_GESTURE_TRIGGERED = 0x40000;
 
     /**
+     * The input event was injected from an AccessibilityService with the
+     * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as
+     * "Accessibility Tools") are used to assist users with disabilities, so events from these
+     * services should be able to reach all Views including Views which set
+     * View#isAccessibilityDataSensitive to true. Used in policyFlags for input event injection.
+     */
+    const int POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = 0x80000;
+
+    /**
      * Common input event flag used for both motion and key events for a gesture or pointer being
      * canceled.
      */
     const int INPUT_EVENT_FLAG_CANCELED = 0x20;
 
     /**
-     * Common input event flag used for both motion and key events, indicating that the event
-     * was generated or modified by accessibility service.
+     * Input event flag used for both motion and key events.
+     * See POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY for more information.
      */
     const int INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT = 0x800;
 
     /**
+     * Input event flag used for motion events.
+     * See POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL for more information.
+     */
+    const int INPUT_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL = 0x1000;
+
+    /**
      * Common input event flag used for both motion and key events, indicating that the system has
      * detected this event may be inconsistent with the current event sequence or gesture, such as
      * when a pointer move event is sent but the pointer is not down.
diff --git a/libs/input/android/os/MotionEventFlag.aidl b/libs/input/android/os/MotionEventFlag.aidl
index 2093b06..6c9ccfb 100644
--- a/libs/input/android/os/MotionEventFlag.aidl
+++ b/libs/input/android/os/MotionEventFlag.aidl
@@ -118,13 +118,24 @@
     PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION = 0x100,
 
     /**
-     * The input event was generated or modified by accessibility service.
-     * Shared by both KeyEvent and MotionEvent flags, so this value should not overlap with either
-     * set of flags, including in input/Input.h and in android/input.h.
+     * The input event was injected from some AccessibilityService, which may be either an
+     * Accessibility Tool OR a service using that API for purposes other than assisting users with
+     * disabilities. Shared by both KeyEvent and MotionEvent flags, so this value should not
+     * overlap with either set of flags, including in input/Input.h and in android/input.h.
      */
     IS_ACCESSIBILITY_EVENT = IInputConstants.INPUT_EVENT_FLAG_IS_ACCESSIBILITY_EVENT,
 
     /**
+     * The input event was injected from an AccessibilityService with the
+     * AccessibilityServiceInfo#isAccessibilityTool property set to true. These services (known as
+     * "Accessibility Tools") are used to assist users with disabilities, so events from these
+     * services should be able to reach all Views including Views which set
+     * View#isAccessibilityDataSensitive to true. Only used by MotionEvent flags.
+     */
+    INJECTED_FROM_ACCESSIBILITY_TOOL =
+        IInputConstants.INPUT_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL,
+
+    /**
      * Private flag that indicates when the system has detected that this motion event
      * may be inconsistent with respect to the sequence of previously delivered motion events,
      * such as when a pointer move event is sent but the pointer is not down.
diff --git a/libs/input/rust/input.rs b/libs/input/rust/input.rs
index 90f509d..6956a84 100644
--- a/libs/input/rust/input.rs
+++ b/libs/input/rust/input.rs
@@ -219,6 +219,9 @@
                 MotionEventFlag::PRIVATE_FLAG_SUPPORTS_DIRECTIONAL_ORIENTATION.0 as u32;
         /// FLAG_IS_ACCESSIBILITY_EVENT
         const IS_ACCESSIBILITY_EVENT = MotionEventFlag::IS_ACCESSIBILITY_EVENT.0 as u32;
+        /// FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL
+        const INJECTED_FROM_ACCESSIBILITY_TOOL =
+                MotionEventFlag::INJECTED_FROM_ACCESSIBILITY_TOOL.0 as u32;
         /// FLAG_TAINTED
         const TAINTED = MotionEventFlag::TAINTED.0 as u32;
         /// FLAG_TARGET_ACCESSIBILITY_FOCUS
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 324e601..493e480 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4856,6 +4856,10 @@
                 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
             }
 
+            if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL) {
+                flags |= AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL;
+            }
+
             mLock.lock();
 
             if (shouldRejectInjectedMotionLocked(motionEvent, resolvedDeviceId, displayId,
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7e2dcff..368db1b 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -9905,6 +9905,15 @@
                        AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT);
 }
 
+TEST_F(InputFilterInjectionPolicyTest,
+       MotionEventsInjectedFromAccessibilityTool_HaveAccessibilityFlags) {
+    testInjectedMotion(POLICY_FLAG_FILTERED | POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY |
+                               POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL,
+                       /*injectedDeviceId=*/3, /*resolvedDeviceId=*/3,
+                       AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT |
+                               AMOTION_EVENT_FLAG_INJECTED_FROM_ACCESSIBILITY_TOOL);
+}
+
 TEST_F(InputFilterInjectionPolicyTest, RegularInjectedEvents_ReceiveVirtualDeviceId) {
     testInjectedKey(/*policyFlags=*/0, /*injectedDeviceId=*/3,
                     /*resolvedDeviceId=*/VIRTUAL_KEYBOARD_ID, /*flags=*/0);