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

Commit 39cece1e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure stale event does not cause ANR" into tm-dev

parents cc71acd1 289e9249
Loading
Loading
Loading
Loading
+10 −8
Original line number Original line Diff line number Diff line
@@ -160,10 +160,7 @@ const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::mil
// when an application takes too long to respond and the user has pressed an app switch key.
// when an application takes too long to respond and the user has pressed an app switch key.
constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
constexpr nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec


// Amount of time to allow for an event to be dispatched (measured since its eventTime)
const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
// before considering it stale and dropping it.
const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL // 10sec
        * HwTimeoutMultiplier();


// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
@@ -364,10 +361,6 @@ bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second)
            first->applicationInfo.token == second->applicationInfo.token;
            first->applicationInfo.token == second->applicationInfo.token;
}
}


bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
    return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
}

std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
                                                   std::shared_ptr<EventEntry> eventEntry,
                                                   std::shared_ptr<EventEntry> eventEntry,
                                                   int32_t inputTargetFlags) {
                                                   int32_t inputTargetFlags) {
@@ -568,6 +561,10 @@ bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
// --- InputDispatcher ---
// --- InputDispatcher ---


InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
      : InputDispatcher(policy, STALE_EVENT_TIMEOUT) {}

InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
                                 std::chrono::nanoseconds staleEventTimeout)
      : mPolicy(policy),
      : mPolicy(policy),
        mPendingEvent(nullptr),
        mPendingEvent(nullptr),
        mLastDropReason(DropReason::NOT_DROPPED),
        mLastDropReason(DropReason::NOT_DROPPED),
@@ -586,6 +583,7 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
        mMaximumObscuringOpacityForTouch(1.0f),
        mMaximumObscuringOpacityForTouch(1.0f),
        mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
        mFocusedDisplayId(ADISPLAY_ID_DEFAULT),
        mWindowTokenWithPointerCapture(nullptr),
        mWindowTokenWithPointerCapture(nullptr),
        mStaleEventTimeout(staleEventTimeout),
        mLatencyAggregator(),
        mLatencyAggregator(),
        mLatencyTracker(&mLatencyAggregator) {
        mLatencyTracker(&mLatencyAggregator) {
    mLooper = new Looper(false);
    mLooper = new Looper(false);
@@ -943,6 +941,10 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    }
    }
}
}


bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
    return std::chrono::nanoseconds(currentTime - entry.eventTime) >= mStaleEventTimeout;
}

/**
/**
 * Return true if the events preceding this incoming motion event should be dropped
 * Return true if the events preceding this incoming motion event should be dropped
 * Return false otherwise (the default behaviour)
 * Return false otherwise (the default behaviour)
+7 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,8 @@ public:
    static constexpr bool kDefaultInTouchMode = true;
    static constexpr bool kDefaultInTouchMode = true;


    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
                             std::chrono::nanoseconds staleEventTimeout);
    ~InputDispatcher() override;
    ~InputDispatcher() override;


    void dump(std::string& dump) override;
    void dump(std::string& dump) override;
@@ -471,6 +473,11 @@ private:
     */
     */
    std::optional<nsecs_t> mNoFocusedWindowTimeoutTime GUARDED_BY(mLock);
    std::optional<nsecs_t> mNoFocusedWindowTimeoutTime GUARDED_BY(mLock);


    // Amount of time to allow for an event to be dispatched (measured since its eventTime)
    // before considering it stale and dropping it.
    const std::chrono::nanoseconds mStaleEventTimeout;
    bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry);

    bool shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) REQUIRES(mLock);
    bool shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) REQUIRES(mLock);


    /**
    /**
+35 −1
Original line number Original line Diff line number Diff line
@@ -65,6 +65,8 @@ static const int32_t INJECTOR_UID = 1001;
// An arbitrary pid of the gesture monitor window
// An arbitrary pid of the gesture monitor window
static constexpr int32_t MONITOR_PID = 2001;
static constexpr int32_t MONITOR_PID = 2001;


static constexpr std::chrono::duration STALE_EVENT_TIMEOUT = 1000ms;

struct PointF {
struct PointF {
    float x;
    float x;
    float y;
    float y;
@@ -489,7 +491,7 @@ protected:


    void SetUp() override {
    void SetUp() override {
        mFakePolicy = new FakeInputDispatcherPolicy();
        mFakePolicy = new FakeInputDispatcherPolicy();
        mDispatcher = std::make_unique<InputDispatcher>(mFakePolicy);
        mDispatcher = std::make_unique<InputDispatcher>(mFakePolicy, STALE_EVENT_TIMEOUT);
        mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
        mDispatcher->setInputDispatchMode(/*enabled*/ true, /*frozen*/ false);
        // Start InputDispatcher thread
        // Start InputDispatcher thread
        ASSERT_EQ(OK, mDispatcher->start());
        ASSERT_EQ(OK, mDispatcher->start());
@@ -4451,6 +4453,38 @@ TEST_F(InputDispatcherSingleWindowAnr, FocusedApplication_NoFocusedWindow) {
    ASSERT_TRUE(mDispatcher->waitForIdle());
    ASSERT_TRUE(mDispatcher->waitForIdle());
}
}


/**
 * Make sure the stale key is dropped before causing an ANR. So even if there's no focused window,
 * there will not be an ANR.
 */
TEST_F(InputDispatcherSingleWindowAnr, StaleKeyEventDoesNotAnr) {
    mWindow->setFocusable(false);
    mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
    mWindow->consumeFocusEvent(false);

    KeyEvent event;
    const nsecs_t eventTime = systemTime(SYSTEM_TIME_MONOTONIC) -
            std::chrono::nanoseconds(STALE_EVENT_TIMEOUT).count();

    // Define a valid key down event that is stale (too old).
    event.initialize(InputEvent::nextId(), DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
                     INVALID_HMAC, AKEY_EVENT_ACTION_DOWN, /* flags */ 0, AKEYCODE_A, KEY_A,
                     AMETA_NONE, 1 /*repeatCount*/, eventTime, eventTime);

    const int32_t policyFlags = POLICY_FLAG_FILTERED | POLICY_FLAG_PASS_TO_USER;

    InputEventInjectionResult result =
            mDispatcher->injectInputEvent(&event, INJECTOR_PID, INJECTOR_UID,
                                          InputEventInjectionSync::WAIT_FOR_RESULT,
                                          INJECT_EVENT_TIMEOUT, policyFlags);
    ASSERT_EQ(InputEventInjectionResult::FAILED, result)
            << "Injection should fail because the event is stale";

    ASSERT_TRUE(mDispatcher->waitForIdle());
    mFakePolicy->assertNotifyAnrWasNotCalled();
    mWindow->assertNoEvents();
}

// We have a focused application, but no focused window
// We have a focused application, but no focused window
// Make sure that we don't notify policy twice about the same ANR.
// Make sure that we don't notify policy twice about the same ANR.
TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DoesNotSendDuplicateAnr) {
TEST_F(InputDispatcherSingleWindowAnr, NoFocusedWindow_DoesNotSendDuplicateAnr) {