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

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

Merge "Reland "Let InputReader handle its own thread""

parents cebbdade f15a8aa3
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ InputManager::~InputManager() {
}

void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}

@@ -57,9 +56,9 @@ status_t InputManager::start() {
        return result;
    }

    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    result = mReader->start();
    if (result) {
        ALOGE("Could not start InputReader thread due to error %d.", result);
        ALOGE("Could not start InputReader due to error %d.", result);

        mDispatcherThread->requestExit();
        return result;
@@ -69,9 +68,9 @@ status_t InputManager::start() {
}

status_t InputManager::stop() {
    status_t result = mReaderThread->requestExitAndWait();
    status_t result = mReader->stop();
    if (result) {
        ALOGW("Could not stop InputReader thread due to error %d.", result);
        ALOGW("Could not stop InputReader due to error %d.", result);
    }

    result = mDispatcherThread->requestExitAndWait();
+5 −6
Original line number Diff line number Diff line
@@ -43,15 +43,15 @@ class InputDispatcherThread;
/*
 * The input manager is the core of the system event processing.
 *
 * The input manager uses two threads.
 * The input manager has two components.
 *
 * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
 *    applies policy, and posts messages to a queue managed by the DispatcherThread.
 * 1. The InputReader class starts a thread that reads and preprocesses raw input events, applies
 *    policy, and posts messages to a queue managed by the InputDispatcherThread.
 * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
 *    queue and asynchronously dispatches them to applications.
 *
 * By design, the InputReaderThread class and InputDispatcherThread class do not share any
 * internal state.  Moreover, all communication is done one way from the InputReaderThread
 * By design, the InputReader class and InputDispatcherThread class do not share any
 * internal state.  Moreover, all communication is done one way from the InputReader
 * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
 * InputDispatchPolicy, however.
 *
@@ -102,7 +102,6 @@ public:

private:
    sp<InputReaderInterface> mReader;
    sp<InputReaderThread> mReaderThread;

    sp<InputClassifierInterface> mClassifier;

+0 −14
Original line number Diff line number Diff line
@@ -33,20 +33,6 @@ using android::base::StringPrintf;

namespace android {

// --- InputReaderThread ---

InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
        Thread(/*canCallJava*/ true), mReader(reader) {
}

InputReaderThread::~InputReaderThread() {
}

bool InputReaderThread::threadLoop() {
    mReader->loopOnce();
    return true;
}

// --- InputReaderConfiguration ---

std::string InputReaderConfiguration::changesToString(uint32_t changes) {
+25 −23
Original line number Diff line number Diff line
@@ -19,12 +19,12 @@

#include "PointerControllerInterface.h"

#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <input/InputDevice.h>
#include <input/DisplayViewport.h>
#include <input/VelocityControl.h>
#include <input/VelocityTracker.h>
#include <utils/Thread.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>

#include <stddef.h>
@@ -44,7 +44,16 @@

namespace android {

/* Processes raw input events and sends cooked event data to an input listener. */
// --- InputReaderInterface ---

/* The interface for the InputReader shared library.
 *
 * Manages one or more threads that process raw input events and sends cooked event data to an
 * input listener.
 *
 * The implementation must guarantee thread safety for this interface. However, since the input
 * listener is NOT thread safe, all calls to the listener must happen from the same thread.
 */
class InputReaderInterface : public virtual RefBase {
protected:
    InputReaderInterface() { }
@@ -56,18 +65,17 @@ public:
     * This method may be called on any thread (usually by the input manager). */
    virtual void dump(std::string& dump) = 0;

    /* Called by the heatbeat to ensures that the reader has not deadlocked. */
    /* Called by the heartbeat to ensures that the reader has not deadlocked. */
    virtual void monitor() = 0;

    /* Returns true if the input device is enabled. */
    virtual bool isInputDeviceEnabled(int32_t deviceId) = 0;

    /* Runs a single iteration of the processing loop.
     * Nominally reads and processes one incoming message from the EventHub.
     *
     * This method should be called on the input reader thread.
     */
    virtual void loopOnce() = 0;
    /* Makes the reader start processing events from the kernel. */
    virtual status_t start() = 0;

    /* Makes the reader stop processing any more events. */
    virtual status_t stop() = 0;

    /* Gets information about all input devices.
     *
@@ -104,17 +112,7 @@ public:
    virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) = 0;
};

/* Reads raw events from the event hub and processes them, endlessly. */
class InputReaderThread : public Thread {
public:
    explicit InputReaderThread(const sp<InputReaderInterface>& reader);
    virtual ~InputReaderThread();

private:
    sp<InputReaderInterface> mReader;

    virtual bool threadLoop();
};
// --- InputReaderConfiguration ---

/*
 * Input reader configuration.
@@ -285,6 +283,8 @@ private:
    std::vector<DisplayViewport> mDisplays;
};

// --- TouchAffineTransformation ---

struct TouchAffineTransformation {
    float x_scale;
    float x_ymix;
@@ -307,6 +307,8 @@ struct TouchAffineTransformation {
    void applyTo(float& x, float& y) const;
};

// --- InputReaderPolicyInterface ---

/*
 * Input reader policy interface.
 *
@@ -316,8 +318,8 @@ struct TouchAffineTransformation {
 * The actual implementation is partially supported by callbacks into the DVM
 * via JNI.  This interface is also mocked in the unit tests.
 *
 * These methods must NOT re-enter the input reader since they may be called while
 * holding the input reader lock.
 * These methods will NOT re-enter the input reader interface, so they may be called from
 * any method in the input reader interface.
 */
class InputReaderPolicyInterface : public virtual RefBase {
protected:
+46 −1
Original line number Diff line number Diff line
@@ -38,16 +38,38 @@
#include <unistd.h>

#include <log/log.h>
#include <utils/Errors.h>

#include <android-base/stringprintf.h>
#include <input/Keyboard.h>
#include <input/VirtualKeyMap.h>

#include <utils/Thread.h>

using android::base::StringPrintf;

namespace android {

// --- InputReader::InputReaderThread ---

/* Thread that reads raw events from the event hub and processes them, endlessly. */
class InputReader::InputReaderThread : public Thread {
public:
    explicit InputReaderThread(InputReader* reader)
          : Thread(/* canCallJava */ true), mReader(reader) {}

    ~InputReaderThread() {}

private:
    InputReader* mReader;

    bool threadLoop() override {
        mReader->loopOnce();
        return true;
    }
};

// --- InputReader ---

InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         const sp<InputListenerInterface>& listener)
@@ -61,6 +83,7 @@ InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    mQueuedListener = new QueuedInputListener(listener);
    mThread = new InputReaderThread(this);

    { // acquire lock
        AutoMutex _l(mLock);
@@ -76,6 +99,28 @@ InputReader::~InputReader() {
    }
}

status_t InputReader::start() {
    if (mThread->isRunning()) {
        return ALREADY_EXISTS;
    }
    return mThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
}

status_t InputReader::stop() {
    if (!mThread->isRunning()) {
        return OK;
    }
    if (gettid() == mThread->getTid()) {
        ALOGE("InputReader can only be stopped from outside of the InputReaderThread!");
        return INVALID_OPERATION;
    }
    // Directly calling requestExitAndWait() causes the thread to not exit
    // if mEventHub is waiting for a long timeout.
    mThread->requestExit();
    mEventHub->wake();
    return mThread->requestExitAndWait();
}

void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
Loading