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 Original line Diff line number Diff line
@@ -46,7 +46,6 @@ InputManager::~InputManager() {
}
}


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


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


    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    result = mReader->start();
    if (result) {
    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();
        mDispatcherThread->requestExit();
        return result;
        return result;
@@ -69,9 +68,9 @@ status_t InputManager::start() {
}
}


status_t InputManager::stop() {
status_t InputManager::stop() {
    status_t result = mReaderThread->requestExitAndWait();
    status_t result = mReader->stop();
    if (result) {
    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();
    result = mDispatcherThread->requestExitAndWait();
+5 −6
Original line number Original line 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 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,
 * 1. The InputReader class starts a thread that reads and preprocesses raw input events, applies
 *    applies policy, and posts messages to a queue managed by the DispatcherThread.
 *    policy, and posts messages to a queue managed by the InputDispatcherThread.
 * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
 * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
 *    queue and asynchronously dispatches them to applications.
 *    queue and asynchronously dispatches them to applications.
 *
 *
 * By design, the InputReaderThread class and InputDispatcherThread class do not share any
 * By design, the InputReader class and InputDispatcherThread class do not share any
 * internal state.  Moreover, all communication is done one way from the InputReaderThread
 * 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
 * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
 * InputDispatchPolicy, however.
 * InputDispatchPolicy, however.
 *
 *
@@ -102,7 +102,6 @@ public:


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


    sp<InputClassifierInterface> mClassifier;
    sp<InputClassifierInterface> mClassifier;


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


namespace android {
namespace android {


// --- InputReaderThread ---

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

InputReaderThread::~InputReaderThread() {
}

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

// --- InputReaderConfiguration ---
// --- InputReaderConfiguration ---


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


#include "PointerControllerInterface.h"
#include "PointerControllerInterface.h"


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


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


namespace android {
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 {
class InputReaderInterface : public virtual RefBase {
protected:
protected:
    InputReaderInterface() { }
    InputReaderInterface() { }
@@ -56,18 +65,17 @@ public:
     * This method may be called on any thread (usually by the input manager). */
     * This method may be called on any thread (usually by the input manager). */
    virtual void dump(std::string& dump) = 0;
    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;
    virtual void monitor() = 0;


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


    /* Runs a single iteration of the processing loop.
    /* Makes the reader start processing events from the kernel. */
     * Nominally reads and processes one incoming message from the EventHub.
    virtual status_t start() = 0;
     *

     * This method should be called on the input reader thread.
    /* Makes the reader stop processing any more events. */
     */
    virtual status_t stop() = 0;
    virtual void loopOnce() = 0;


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


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

private:
    sp<InputReaderInterface> mReader;

    virtual bool threadLoop();
};


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


// --- TouchAffineTransformation ---

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


// --- InputReaderPolicyInterface ---

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


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


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

#include <utils/Thread.h>


using android::base::StringPrintf;
using android::base::StringPrintf;


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


    { // acquire lock
    { // acquire lock
        AutoMutex _l(mLock);
        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() {
void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t oldGeneration;
    int32_t timeoutMillis;
    int32_t timeoutMillis;
Loading