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

Commit cb717365 authored by Michael Wright's avatar Michael Wright Committed by The Android Automerger
Browse files

Properly synchronize interactivity state.

Volatile doesn't provide any guarantees with respect to write
visibility, so it's possible that PowerManager will tell InputManager
about a change in interactivity state, but the actual dispatching
thread will never observe it.

Also, add logging about NativeInputManager state.

Bug: 22422588
Change-Id: Ifc3add992b9009d920d80a0315ff89c9574be20d
parent d205bc2d
Loading
Loading
Loading
Loading
+31 −5
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@

#include "JNIHelp.h"
#include "jni.h"
#include <atomic>
#include <cinttypes>
#include <limits.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>
@@ -56,6 +58,8 @@
#include "com_android_server_input_InputApplicationHandle.h"
#include "com_android_server_input_InputWindowHandle.h"

#define INDENT "  "

namespace android {

// The exponent used to calculate the pointer speed scaling factor.
@@ -126,6 +130,10 @@ inline static T max(const T& a, const T& b) {
    return a > b ? a : b;
}

static inline const char* toString(bool value) {
    return value ? "true" : "false";
}

static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
        const sp<InputApplicationHandle>& inputApplicationHandle) {
    if (inputApplicationHandle == NULL) {
@@ -262,7 +270,7 @@ private:
        wp<PointerController> pointerController;
    } mLocked;

    volatile bool mInteractive;
    std::atomic<bool> mInteractive;

    void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
    void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
@@ -292,6 +300,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
    }
    mInteractive = true;

    sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
@@ -305,6 +314,21 @@ NativeInputManager::~NativeInputManager() {
}

void NativeInputManager::dump(String8& dump) {
    dump.append("Input Manager State:\n");
    {
        dump.appendFormat(INDENT "Interactive: %s\n", toString(mInteractive.load()));
    }
    {
        AutoMutex _l(mLock);
        dump.appendFormat(INDENT "System UI Visibility: 0x%0" PRIx32 "\n",
                mLocked.systemUiVisibility);
        dump.appendFormat(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
        dump.appendFormat(INDENT "Pointer Gestures Enabled: %s\n",
                toString(mLocked.pointerGesturesEnabled));
        dump.appendFormat(INDENT "Show Touches: %s\n", toString(mLocked.showTouches));
    }
    dump.append("\n");

    mInputManager->getReader()->dump(dump);
    dump.append("\n");

@@ -830,7 +854,8 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
    // - Ignore untrusted events and pass them along.
    // - Ask the window manager what to do with normal events and trusted injected events.
    // - For normal events wake and brighten the screen if currently off or dim.
    if (mInteractive) {
    bool interactive = mInteractive.load();
    if (interactive) {
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    if ((policyFlags & POLICY_FLAG_TRUSTED)) {
@@ -854,7 +879,7 @@ void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,

        handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
    } else {
        if (mInteractive) {
        if (interactive) {
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        }
    }
@@ -866,7 +891,8 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p
    // - No special filtering for injected events required at this time.
    // - Filter normal events based on screen state.
    // - For normal events brighten (but do not wake) the screen if currently dim.
    if (mInteractive) {
    bool interactive = mInteractive.load();
    if (interactive) {
        policyFlags |= POLICY_FLAG_INTERACTIVE;
    }
    if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
@@ -885,7 +911,7 @@ void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& p
            handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
        }
    } else {
        if (mInteractive) {
        if (interactive) {
            policyFlags |= POLICY_FLAG_PASS_TO_USER;
        }
    }