Commit 173b54c6 authored by Michael Wu ext:(%20%28and%20others%29)'s avatar Michael Wu ext:(%20%28and%20others%29)
Browse files

Bug 737199, part 2: Port Gonk nsAppShell to the ICS InputReader. r=cjones,gal pending-r?mwu (npotb)

parent f55b3719
Loading
Loading
Loading
Loading
+93 −206
Original line number Diff line number Diff line
@@ -66,9 +66,9 @@
#include "nsWindow.h"

#include "android/log.h"
#include "ui/EventHub.h"
#include "ui/InputReader.h"
#include "ui/InputDispatcher.h"
#include "libui/EventHub.h"
#include "libui/InputReader.h"
#include "libui/InputDispatcher.h"

#define LOG(args...)                                            \
    __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args)
@@ -165,10 +165,12 @@ addDOMTouch(UserInputData& data, nsTouchEvent& event, int i)
    const Touch& touch = data.motion.touches[i];
    event.touches.AppendElement(
        new nsDOMTouch(touch.id,
                       nsIntPoint(touch.coords.x, touch.coords.y),
                       nsIntPoint(touch.coords.size, touch.coords.size),
                       nsIntPoint(touch.coords.getX(), touch.coords.getY()),
                       nsIntPoint(touch.coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE),
                                  touch.coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE)),
                       0,
                       touch.coords.pressure));
                       touch.coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE))
    );
}

static nsEventStatus
@@ -272,19 +274,13 @@ maybeSendKeyEvent(int keyCode, bool pressed, uint64_t timeMs)
}

class GeckoInputReaderPolicy : public InputReaderPolicyInterface {
    InputReaderConfiguration mConfig;
public:
    GeckoInputReaderPolicy() {}

    virtual bool getDisplayInfo(int32_t displayId,
            int32_t* width, int32_t* height, int32_t* orientation);
    virtual bool filterTouchEvents();
    virtual bool filterJumpyTouchEvents();
    virtual nsecs_t getVirtualKeyQuietTime();
    virtual void getVirtualKeyDefinitions(const String8& deviceName,
            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
    virtual void getInputDeviceCalibration(const String8& deviceName,
            InputDeviceCalibration& outCalibration);
    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);

    void setDisplayInfo();

protected:
    virtual ~GeckoInputReaderPolicy() {}
@@ -298,30 +294,36 @@ public:

    virtual void dump(String8& dump);

    virtual void monitor() {}

    // Called on the main thread
    virtual void dispatchOnce();

    // notify* methods are called on the InputReaderThread
    virtual void notifyConfigurationChanged(nsecs_t eventTime);
    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
            int32_t scanCode, int32_t metaState, nsecs_t downTime);
    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
            uint32_t policyFlags, int32_t action, int32_t flags,
            int32_t metaState, int32_t edgeFlags,
            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
            float xPrecision, float yPrecision, nsecs_t downTime);
    virtual void notifySwitch(nsecs_t when,
            int32_t switchCode, int32_t switchValue, uint32_t policyFlags);
    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
    virtual void notifyKey(const NotifyKeyArgs* args);
    virtual void notifyMotion(const NotifyMotionArgs* args);
    virtual void notifySwitch(const NotifySwitchArgs* args);
    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);

    virtual int32_t injectInputEvent(const InputEvent* event,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
    virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
    virtual void setFocusedApplication(const InputApplication* inputApplication);
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
            uint32_t policyFlags);

    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);

    virtual void setInputDispatchMode(bool enabled, bool frozen);
    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor);
    virtual void setInputFilterEnabled(bool enabled) {}
    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
            const sp<InputChannel>& toChannel) { return true; }

    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
            const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);



protected:
    virtual ~GeckoInputDispatcher() {}

@@ -334,138 +336,30 @@ private:
};

// GeckoInputReaderPolicy
bool
GeckoInputReaderPolicy::getDisplayInfo(int32_t displayId,
                                       int32_t* width,
                                       int32_t* height,
                                       int32_t* orientation)
void
GeckoInputReaderPolicy::setDisplayInfo()
{
    MOZ_STATIC_ASSERT(nsIScreen::ROTATION_0_DEG ==
                      InputReaderPolicyInterface::ROTATION_0,
                      DISPLAY_ORIENTATION_0,
                      "Orientation enums not matched!");
    MOZ_STATIC_ASSERT(nsIScreen::ROTATION_90_DEG ==
                      InputReaderPolicyInterface::ROTATION_90,
                      DISPLAY_ORIENTATION_90,
                      "Orientation enums not matched!");
    MOZ_STATIC_ASSERT(nsIScreen::ROTATION_180_DEG ==
                      InputReaderPolicyInterface::ROTATION_180,
                      DISPLAY_ORIENTATION_180,
                      "Orientation enums not matched!");
    MOZ_STATIC_ASSERT(nsIScreen::ROTATION_270_DEG ==
                      InputReaderPolicyInterface::ROTATION_270,
                      DISPLAY_ORIENTATION_270,
                      "Orientation enums not matched!");

    // 0 is the default displayId. We only support one display
    if (displayId)
        return false;

    if (width)
        *width = gScreenBounds.width;
    if (height)
        *height = gScreenBounds.height;
    if (orientation)
        *orientation = nsScreenGonk::GetRotation();
    return true;
}

bool
GeckoInputReaderPolicy::filterTouchEvents()
{
    return false;
}

bool
GeckoInputReaderPolicy::filterJumpyTouchEvents()
{
    return false;
}

nsecs_t
GeckoInputReaderPolicy::getVirtualKeyQuietTime()
{
    return 0;
}

void
GeckoInputReaderPolicy::getVirtualKeyDefinitions(const String8& deviceName,
    Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions)
{
    outVirtualKeyDefinitions.clear();

    char vbuttonsPath[PATH_MAX];
    snprintf(vbuttonsPath, sizeof(vbuttonsPath),
             "/sys/board_properties/virtualkeys.%s",
             deviceName.string());
    ScopedClose fd(open(vbuttonsPath, O_RDONLY));
    if (0 > fd.mFd) {
        LOG("No vbuttons for mt device %s", deviceName.string());
        return;
    }

    // This device has vbuttons.  Process the configuration.
    char config[1024];
    ssize_t nread;
    do {
        nread = read(fd.mFd, config, sizeof(config));
    } while (-1 == nread && EINTR == errno);

    if (0 > nread) {
        LOG("Error reading virtualkey configuration");
        return;
    }

    config[nread] = '\0';

    LOG("Device %s has vbutton config '%s'", deviceName.string(), config);

    char* first = config;
    char* magic;
    char* state;
    while ((magic = strtok_r(first, ":", &state))) {
        // XXX not clear what "0x01" is ... maybe a version
        // number?  See InputManager.java.
        if (strcmp(magic, "0x01")) {
            LOG("  magic 0x01 tag missing");
            break;
        }
        first = NULL;

        const char *scanCode, *centerX, *centerY, *width, *height;
        if (!((scanCode = strtok_r(NULL, ":", &state)) &&
              (centerX = strtok_r(NULL, ":", &state)) &&
              (centerY = strtok_r(NULL, ":", &state)) &&
              (width = strtok_r(NULL, ":", &state)) &&
              (height = strtok_r(NULL, ":", &state)))) {
            LOG("  failed to read bound params");
            break;
        }

        // NB: these coordinates are in *screen* space, not input
        // space.  That means the values in /sys/board_config make
        // assumptions about how the raw input events are mapped
        // ... le sigh.
        VirtualKeyDefinition def;
        def.scanCode = atoi(scanCode);
        def.centerX = atoi(centerX);
        def.centerY = atoi(centerY);
        def.width = atoi(width);
        def.height = atoi(height);
        outVirtualKeyDefinitions.push(def);

        LOG("  configured vbutton code=%d at <x=%d,y=%d,w=%d,h=%d>",
            def.scanCode, def.centerX, def.centerY, def.width, def.height);
    }
    mConfig.setDisplayInfo(0, false, gScreenBounds.width, gScreenBounds.height, nsScreenGonk::GetRotation());
}

void
GeckoInputReaderPolicy::getInputDeviceCalibration(const String8& deviceName,            InputDeviceCalibration& outCalibration)
void GeckoInputReaderPolicy::getReaderConfiguration(InputReaderConfiguration* outConfig)
{
    outCalibration.clear();
    *outConfig = mConfig;
}

void
GeckoInputReaderPolicy::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames)
{
    outExcludedDeviceNames.clear();
}

// GeckoInputDispatcher
void
@@ -511,8 +405,8 @@ GeckoInputDispatcher::dispatchOnce()
        }
        sendMouseEvent(msg,
                       data.timeMs,
                       data.motion.touches[0].coords.x,
                       data.motion.touches[0].coords.y);
                       data.motion.touches[0].coords.getX(),
                       data.motion.touches[0].coords.getY());
        break;
    }
    case UserInputData::KEY_DATA:
@@ -525,7 +419,7 @@ GeckoInputDispatcher::dispatchOnce()


void
GeckoInputDispatcher::notifyConfigurationChanged(nsecs_t eventTime)
GeckoInputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs*)
{
}

@@ -536,25 +430,16 @@ nanosecsToMillisecs(nsecs_t nsecs)
}

void
GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
                                int32_t deviceId,
                                int32_t source,
                                uint32_t policyFlags,
                                int32_t action,
                                int32_t flags,
                                int32_t keyCode,
                                int32_t scanCode,
                                int32_t metaState,
                                nsecs_t downTime)
GeckoInputDispatcher::notifyKey(const NotifyKeyArgs* args)
{
    UserInputData data;
    data.timeMs = nanosecsToMillisecs(eventTime);
    data.timeMs = nanosecsToMillisecs(args->eventTime);
    data.type = UserInputData::KEY_DATA;
    data.action = action;
    data.flags = flags;
    data.metaState = metaState;
    data.key.keyCode = keyCode;
    data.key.scanCode = scanCode;
    data.action = args->action;
    data.flags = args->flags;
    data.metaState = args->metaState;
    data.key.keyCode = args->keyCode;
    data.key.scanCode = args->scanCode;
    {
        MutexAutoLock lock(mQueueLock);
        mEventQueue.push(data);
@@ -562,34 +447,22 @@ GeckoInputDispatcher::notifyKey(nsecs_t eventTime,
    gAppShell->NotifyNativeEvent();
}


void
GeckoInputDispatcher::notifyMotion(nsecs_t eventTime,
                                   int32_t deviceId,
                                   int32_t source,
                                   uint32_t policyFlags,
                                   int32_t action,
                                   int32_t flags,
                                   int32_t metaState,
                                   int32_t edgeFlags,
                                   uint32_t pointerCount,
                                   const int32_t* pointerIds,
                                   const PointerCoords* pointerCoords,
                                   float xPrecision,
                                   float yPrecision,
                                   nsecs_t downTime)
GeckoInputDispatcher::notifyMotion(const NotifyMotionArgs* args)
{
    UserInputData data;
    data.timeMs = nanosecsToMillisecs(eventTime);
    data.timeMs = nanosecsToMillisecs(args->eventTime);
    data.type = UserInputData::MOTION_DATA;
    data.action = action;
    data.flags = flags;
    data.metaState = metaState;
    MOZ_ASSERT(pointerCount <= MAX_POINTERS);
    data.motion.touchCount = pointerCount;
    for (int32_t i = 0; i < pointerCount; ++i) {
    data.action = args->action;
    data.flags = args->flags;
    data.metaState = args->metaState;
    MOZ_ASSERT(args->pointerCount <= MAX_POINTERS);
    data.motion.touchCount = args->pointerCount;
    for (uint32_t i = 0; i < args->pointerCount; ++i) {
        Touch& touch = data.motion.touches[i];
        touch.id = pointerIds[i];
        memcpy(&touch.coords, &pointerCoords[i], sizeof(*pointerCoords));
        touch.id = args->pointerProperties[i].id;
        memcpy(&touch.coords, &args->pointerCoords[i], sizeof(*args->pointerCoords));
    }
    {
        MutexAutoLock lock(mQueueLock);
@@ -604,32 +477,31 @@ GeckoInputDispatcher::notifyMotion(nsecs_t eventTime,
    gAppShell->NotifyNativeEvent();
}

void
GeckoInputDispatcher::notifySwitch(nsecs_t when,
                                   int32_t switchCode,
                                   int32_t switchValue,
                                   uint32_t policyFlags)


void GeckoInputDispatcher::notifySwitch(const NotifySwitchArgs* args)
{
}

void GeckoInputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args)
{
}

int32_t
GeckoInputDispatcher::injectInputEvent(const InputEvent* event,
                                       int32_t injectorPid,
                                       int32_t injectorUid,
                                       int32_t syncMode,
                                       int32_t timeoutMillis)
int32_t GeckoInputDispatcher::injectInputEvent(
    const InputEvent* event,
    int32_t injectorPid, int32_t injectorUid, int32_t syncMode,
    int32_t timeoutMillis, uint32_t policyFlags)
{
    return INPUT_EVENT_INJECTION_SUCCEEDED;
}

void
GeckoInputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows)
GeckoInputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles)
{
}

void
GeckoInputDispatcher::setFocusedApplication(const InputApplication* inputApplication)
GeckoInputDispatcher::setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle)
{
}

@@ -640,7 +512,7 @@ GeckoInputDispatcher::setInputDispatchMode(bool enabled, bool frozen)

status_t
GeckoInputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
                                           bool monitor)
                                           const sp<InputWindowHandle>& inputWindowHandle, bool monitor)
{
    return OK;
}
@@ -747,16 +619,26 @@ nsAppShell::Init()
    rv = AddFdHandler(signalfds[0], pipeHandler, "");
    NS_ENSURE_SUCCESS(rv, rv);

    // Delay initializing input devices until the screen has been
    // initialized (and we know the resolution).
    return rv;
}

void
nsAppShell::InitInputDevices()
{
    mEventHub = new EventHub();
    mReaderPolicy = new GeckoInputReaderPolicy();
    mReaderPolicy->setDisplayInfo();
    mDispatcher = new GeckoInputDispatcher();

    mReader = new InputReader(mEventHub, mReaderPolicy, mDispatcher);
    mReaderThread = new InputReaderThread(mReader);

    status_t result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    NS_ENSURE_FALSE(result, NS_ERROR_UNEXPECTED);
    return rv;
    if (result) {
        LOG("Failed to initialize InputReader thread, bad things are going to happen...");
    }
}

nsresult
@@ -820,3 +702,8 @@ nsAppShell::NotifyNativeEvent()
    write(signalfds[1], "w", 1);
}

/*static*/ void
nsAppShell::NotifyScreenInitialized()
{
    gAppShell->InitInputDevices();
}
+3 −0
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ public:

    void NotifyNativeEvent();

    static void NotifyScreenInitialized();

protected:
    virtual ~nsAppShell();

@@ -105,6 +107,7 @@ protected:
private:
    nsresult AddFdHandler(int fd, FdHandlerCallback handlerFunc,
                          const char* deviceName);
    void InitInputDevices();

    // This is somewhat racy but is perfectly safe given how the callback works
    bool mNativeCallbackRequest;
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ nsWindow::nsWindow()
            }
        }
        sVirtualBounds = gScreenBounds;

        nsAppShell::NotifyScreenInitialized();
    }
}