Mouse pointer integration.
Added support for loading the pointer icon from a resource. Moved the system server related bits of the input manager out of libui and into libinput since they do not need to be linked into applications. Change-Id: Iec11e0725b3add2b905c51f8ea2c3b4b0d1a2d67
This commit is contained in:
parent
d95aaf3982
commit
4125036157
|
@ -37,6 +37,15 @@ struct DisplayInfo {
|
|||
float ydpi;
|
||||
};
|
||||
|
||||
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
|
||||
enum {
|
||||
DISPLAY_ORIENTATION_0 = 0,
|
||||
DISPLAY_ORIENTATION_90 = 1,
|
||||
DISPLAY_ORIENTATION_180 = 2,
|
||||
DISPLAY_ORIENTATION_270 = 3
|
||||
};
|
||||
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_COMPOSER_DISPLAY_INFO_H
|
||||
|
|
|
@ -1,327 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2005 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//
|
||||
#ifndef _RUNTIME_EVENT_HUB_H
|
||||
#define _RUNTIME_EVENT_HUB_H
|
||||
|
||||
#include <ui/Input.h>
|
||||
#include <ui/Keyboard.h>
|
||||
#include <ui/KeyLayoutMap.h>
|
||||
#include <ui/KeyCharacterMap.h>
|
||||
#include <ui/VirtualKeyMap.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/List.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/PropertyMap.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
/* These constants are not defined in linux/input.h but they are part of the multitouch
|
||||
* input protocol. */
|
||||
|
||||
#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
|
||||
#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */
|
||||
#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */
|
||||
#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */
|
||||
#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */
|
||||
#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
|
||||
#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
|
||||
#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device (finger, pen, ...) */
|
||||
#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */
|
||||
#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */
|
||||
#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */
|
||||
|
||||
#define MT_TOOL_FINGER 0 /* Identifies a finger */
|
||||
#define MT_TOOL_PEN 1 /* Identifies a pen */
|
||||
|
||||
#define SYN_MT_REPORT 2
|
||||
|
||||
/* Convenience constants. */
|
||||
|
||||
#define BTN_FIRST 0x100 // first button scancode
|
||||
#define BTN_LAST 0x15f // last button scancode
|
||||
|
||||
struct pollfd;
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* A raw event as retrieved from the EventHub.
|
||||
*/
|
||||
struct RawEvent {
|
||||
nsecs_t when;
|
||||
int32_t deviceId;
|
||||
int32_t type;
|
||||
int32_t scanCode;
|
||||
int32_t keyCode;
|
||||
int32_t value;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/* Describes an absolute axis. */
|
||||
struct RawAbsoluteAxisInfo {
|
||||
bool valid; // true if the information is valid, false otherwise
|
||||
|
||||
int32_t minValue; // minimum value
|
||||
int32_t maxValue; // maximum value
|
||||
int32_t flat; // center flat position, eg. flat == 8 means center is between -8 and 8
|
||||
int32_t fuzz; // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
|
||||
|
||||
inline int32_t getRange() { return maxValue - minValue; }
|
||||
|
||||
inline void clear() {
|
||||
valid = false;
|
||||
minValue = 0;
|
||||
maxValue = 0;
|
||||
flat = 0;
|
||||
fuzz = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Input device classes.
|
||||
*/
|
||||
enum {
|
||||
/* The input device is a keyboard. */
|
||||
INPUT_DEVICE_CLASS_KEYBOARD = 0x00000001,
|
||||
|
||||
/* The input device is an alpha-numeric keyboard (not just a dial pad). */
|
||||
INPUT_DEVICE_CLASS_ALPHAKEY = 0x00000002,
|
||||
|
||||
/* The input device is a touchscreen (either single-touch or multi-touch). */
|
||||
INPUT_DEVICE_CLASS_TOUCHSCREEN = 0x00000004,
|
||||
|
||||
/* The input device is a cursor device such as a trackball or mouse. */
|
||||
INPUT_DEVICE_CLASS_CURSOR = 0x00000008,
|
||||
|
||||
/* The input device is a multi-touch touchscreen. */
|
||||
INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
|
||||
|
||||
/* The input device is a directional pad (implies keyboard, has DPAD keys). */
|
||||
INPUT_DEVICE_CLASS_DPAD = 0x00000020,
|
||||
|
||||
/* The input device is a gamepad (implies keyboard, has BUTTON keys). */
|
||||
INPUT_DEVICE_CLASS_GAMEPAD = 0x00000040,
|
||||
|
||||
/* The input device has switches. */
|
||||
INPUT_DEVICE_CLASS_SWITCH = 0x00000080,
|
||||
};
|
||||
|
||||
/*
|
||||
* Grand Central Station for events.
|
||||
*
|
||||
* The event hub aggregates input events received across all known input
|
||||
* devices on the system, including devices that may be emulated by the simulator
|
||||
* environment. In addition, the event hub generates fake input events to indicate
|
||||
* when devices are added or removed.
|
||||
*
|
||||
* The event hub provies a stream of input events (via the getEvent function).
|
||||
* It also supports querying the current actual state of input devices such as identifying
|
||||
* which keys are currently down. Finally, the event hub keeps track of the capabilities of
|
||||
* individual input devices, such as their class and the set of key codes that they support.
|
||||
*/
|
||||
class EventHubInterface : public virtual RefBase {
|
||||
protected:
|
||||
EventHubInterface() { }
|
||||
virtual ~EventHubInterface() { }
|
||||
|
||||
public:
|
||||
// Synthetic raw event type codes produced when devices are added or removed.
|
||||
enum {
|
||||
// Sent when a device is added.
|
||||
DEVICE_ADDED = 0x10000000,
|
||||
// Sent when a device is removed.
|
||||
DEVICE_REMOVED = 0x20000000,
|
||||
// Sent when all added/removed devices from the most recent scan have been reported.
|
||||
// This event is always sent at least once.
|
||||
FINISHED_DEVICE_SCAN = 0x30000000,
|
||||
};
|
||||
|
||||
virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
|
||||
|
||||
virtual String8 getDeviceName(int32_t deviceId) const = 0;
|
||||
|
||||
virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0;
|
||||
|
||||
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
|
||||
RawAbsoluteAxisInfo* outAxisInfo) const = 0;
|
||||
|
||||
virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
|
||||
int32_t* outKeycode, uint32_t* outFlags) const = 0;
|
||||
|
||||
// exclude a particular device from opening
|
||||
// this can be used to ignore input devices for sensors
|
||||
virtual void addExcludedDevice(const char* deviceName) = 0;
|
||||
|
||||
/*
|
||||
* Wait for the next event to become available and return it.
|
||||
* After returning, the EventHub holds onto a wake lock until the next call to getEvent.
|
||||
* This ensures that the device will not go to sleep while the event is being processed.
|
||||
* If the device needs to remain awake longer than that, then the caller is responsible
|
||||
* for taking care of it (say, by poking the power manager user activity timer).
|
||||
*/
|
||||
virtual bool getEvent(RawEvent* outEvent) = 0;
|
||||
|
||||
/*
|
||||
* Query current input state.
|
||||
*/
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
|
||||
virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
|
||||
|
||||
/*
|
||||
* Examine key input devices for specific framework keycode support
|
||||
*/
|
||||
virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
|
||||
uint8_t* outFlags) const = 0;
|
||||
|
||||
virtual bool hasLed(int32_t deviceId, int32_t led) const = 0;
|
||||
virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
|
||||
|
||||
virtual void getVirtualKeyDefinitions(int32_t deviceId,
|
||||
Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
|
||||
|
||||
virtual void dump(String8& dump) = 0;
|
||||
};
|
||||
|
||||
class EventHub : public EventHubInterface
|
||||
{
|
||||
public:
|
||||
EventHub();
|
||||
|
||||
status_t errorCheck() const;
|
||||
|
||||
virtual uint32_t getDeviceClasses(int32_t deviceId) const;
|
||||
|
||||
virtual String8 getDeviceName(int32_t deviceId) const;
|
||||
|
||||
virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const;
|
||||
|
||||
virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
|
||||
RawAbsoluteAxisInfo* outAxisInfo) const;
|
||||
|
||||
virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
|
||||
int32_t* outKeycode, uint32_t* outFlags) const;
|
||||
|
||||
virtual void addExcludedDevice(const char* deviceName);
|
||||
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
|
||||
virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
|
||||
|
||||
virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags) const;
|
||||
|
||||
virtual bool getEvent(RawEvent* outEvent);
|
||||
|
||||
virtual bool hasLed(int32_t deviceId, int32_t led) const;
|
||||
virtual void setLedState(int32_t deviceId, int32_t led, bool on);
|
||||
|
||||
virtual void getVirtualKeyDefinitions(int32_t deviceId,
|
||||
Vector<VirtualKeyDefinition>& outVirtualKeys) const;
|
||||
|
||||
virtual void dump(String8& dump);
|
||||
|
||||
protected:
|
||||
virtual ~EventHub();
|
||||
|
||||
private:
|
||||
bool openPlatformInput(void);
|
||||
|
||||
int openDevice(const char *devicePath);
|
||||
int closeDevice(const char *devicePath);
|
||||
int scanDir(const char *dirname);
|
||||
int readNotify(int nfd);
|
||||
|
||||
status_t mError;
|
||||
|
||||
struct Device {
|
||||
Device* next;
|
||||
|
||||
int fd;
|
||||
const int32_t id;
|
||||
const String8 path;
|
||||
const InputDeviceIdentifier identifier;
|
||||
|
||||
uint32_t classes;
|
||||
uint8_t* keyBitmask;
|
||||
String8 configurationFile;
|
||||
PropertyMap* configuration;
|
||||
VirtualKeyMap* virtualKeyMap;
|
||||
KeyMap keyMap;
|
||||
|
||||
Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
|
||||
~Device();
|
||||
|
||||
void close();
|
||||
};
|
||||
|
||||
Device* getDeviceLocked(int32_t deviceId) const;
|
||||
bool hasKeycodeLocked(Device* device, int keycode) const;
|
||||
|
||||
int32_t getScanCodeStateLocked(Device* device, int32_t scanCode) const;
|
||||
int32_t getKeyCodeStateLocked(Device* device, int32_t keyCode) const;
|
||||
int32_t getSwitchStateLocked(Device* device, int32_t sw) const;
|
||||
bool markSupportedKeyCodesLocked(Device* device, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags) const;
|
||||
|
||||
void loadConfiguration(Device* device);
|
||||
status_t loadVirtualKeyMap(Device* device);
|
||||
status_t loadKeyMap(Device* device);
|
||||
void setKeyboardProperties(Device* device, bool builtInKeyboard);
|
||||
void clearKeyboardProperties(Device* device, bool builtInKeyboard);
|
||||
|
||||
// Protect all internal state.
|
||||
mutable Mutex mLock;
|
||||
|
||||
// The actual id of the built-in keyboard, or -1 if none.
|
||||
// EventHub remaps the built-in keyboard to id 0 externally as required by the API.
|
||||
int32_t mBuiltInKeyboardId;
|
||||
|
||||
int32_t mNextDeviceId;
|
||||
|
||||
// Parallel arrays of fds and devices.
|
||||
// First index is reserved for inotify.
|
||||
Vector<struct pollfd> mFds;
|
||||
Vector<Device*> mDevices;
|
||||
|
||||
Device *mOpeningDevices;
|
||||
Device *mClosingDevices;
|
||||
|
||||
bool mOpened;
|
||||
bool mNeedToSendFinishedDeviceScan;
|
||||
List<String8> mExcludedDevices;
|
||||
|
||||
// device ids that report particular switches.
|
||||
#ifdef EV_SW
|
||||
int32_t mSwitches[SW_MAX + 1];
|
||||
#endif
|
||||
|
||||
static const int INPUT_BUFFER_SIZE = 64;
|
||||
struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
|
||||
size_t mInputBufferIndex;
|
||||
size_t mInputBufferCount;
|
||||
size_t mInputFdIndex;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // _RUNTIME_EVENT_HUB_H
|
File diff suppressed because it is too large
Load Diff
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UI_INPUT_MANAGER_H
|
||||
#define _UI_INPUT_MANAGER_H
|
||||
|
||||
/**
|
||||
* Native input manager.
|
||||
*/
|
||||
|
||||
#include <ui/EventHub.h>
|
||||
#include <ui/Input.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class InputChannel;
|
||||
|
||||
class InputReaderInterface;
|
||||
class InputReaderPolicyInterface;
|
||||
class InputReaderThread;
|
||||
|
||||
class InputDispatcherInterface;
|
||||
class InputDispatcherPolicyInterface;
|
||||
class InputDispatcherThread;
|
||||
|
||||
/*
|
||||
* The input manager is the core of the system event processing.
|
||||
*
|
||||
* The input manager uses two threads.
|
||||
*
|
||||
* 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
|
||||
* applies policy, and posts messages to a queue managed by the DispatcherThread.
|
||||
* 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
|
||||
* into the InputDispatcherThread and never the reverse. Both classes may interact with the
|
||||
* InputDispatchPolicy, however.
|
||||
*
|
||||
* The InputManager class never makes any calls into Java itself. Instead, the
|
||||
* InputDispatchPolicy is responsible for performing all external interactions with the
|
||||
* system, including calling DVM services.
|
||||
*/
|
||||
class InputManagerInterface : public virtual RefBase {
|
||||
protected:
|
||||
InputManagerInterface() { }
|
||||
virtual ~InputManagerInterface() { }
|
||||
|
||||
public:
|
||||
/* Starts the input manager threads. */
|
||||
virtual status_t start() = 0;
|
||||
|
||||
/* Stops the input manager threads and waits for them to exit. */
|
||||
virtual status_t stop() = 0;
|
||||
|
||||
/* Gets the input reader. */
|
||||
virtual sp<InputReaderInterface> getReader() = 0;
|
||||
|
||||
/* Gets the input dispatcher. */
|
||||
virtual sp<InputDispatcherInterface> getDispatcher() = 0;
|
||||
};
|
||||
|
||||
class InputManager : public InputManagerInterface {
|
||||
protected:
|
||||
virtual ~InputManager();
|
||||
|
||||
public:
|
||||
InputManager(
|
||||
const sp<EventHubInterface>& eventHub,
|
||||
const sp<InputReaderPolicyInterface>& readerPolicy,
|
||||
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
|
||||
|
||||
// (used for testing purposes)
|
||||
InputManager(
|
||||
const sp<InputReaderInterface>& reader,
|
||||
const sp<InputDispatcherInterface>& dispatcher);
|
||||
|
||||
virtual status_t start();
|
||||
virtual status_t stop();
|
||||
|
||||
virtual sp<InputReaderInterface> getReader();
|
||||
virtual sp<InputDispatcherInterface> getDispatcher();
|
||||
|
||||
private:
|
||||
sp<InputReaderInterface> mReader;
|
||||
sp<InputReaderThread> mReaderThread;
|
||||
|
||||
sp<InputDispatcherInterface> mDispatcher;
|
||||
sp<InputDispatcherThread> mDispatcherThread;
|
||||
|
||||
void initialize();
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_INPUT_MANAGER_H
|
|
@ -1,953 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UI_INPUT_READER_H
|
||||
#define _UI_INPUT_READER_H
|
||||
|
||||
#include <ui/EventHub.h>
|
||||
#include <ui/Input.h>
|
||||
#include <ui/InputDispatcher.h>
|
||||
#include <ui/PointerController.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/threads.h>
|
||||
#include <utils/Timers.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
#include <utils/BitSet.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class InputDevice;
|
||||
class InputMapper;
|
||||
|
||||
|
||||
/*
|
||||
* Input reader policy interface.
|
||||
*
|
||||
* The input reader policy is used by the input reader to interact with the Window Manager
|
||||
* and other system components.
|
||||
*
|
||||
* The actual implementation is partially supported by callbacks into the DVM
|
||||
* via JNI. This interface is also mocked in the unit tests.
|
||||
*/
|
||||
class InputReaderPolicyInterface : public virtual RefBase {
|
||||
protected:
|
||||
InputReaderPolicyInterface() { }
|
||||
virtual ~InputReaderPolicyInterface() { }
|
||||
|
||||
public:
|
||||
/* Display orientations. */
|
||||
enum {
|
||||
ROTATION_0 = 0,
|
||||
ROTATION_90 = 1,
|
||||
ROTATION_180 = 2,
|
||||
ROTATION_270 = 3
|
||||
};
|
||||
|
||||
/* Gets information about the display with the specified id.
|
||||
* Returns true if the display info is available, false otherwise.
|
||||
*/
|
||||
virtual bool getDisplayInfo(int32_t displayId,
|
||||
int32_t* width, int32_t* height, int32_t* orientation) = 0;
|
||||
|
||||
/* Determines whether to turn on some hacks we have to improve the touch interaction with a
|
||||
* certain device whose screen currently is not all that good.
|
||||
*/
|
||||
virtual bool filterTouchEvents() = 0;
|
||||
|
||||
/* Determines whether to turn on some hacks to improve touch interaction with another device
|
||||
* where touch coordinate data can get corrupted.
|
||||
*/
|
||||
virtual bool filterJumpyTouchEvents() = 0;
|
||||
|
||||
/* Gets the excluded device names for the platform. */
|
||||
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
|
||||
|
||||
/* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
|
||||
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
|
||||
};
|
||||
|
||||
|
||||
/* Processes raw input events and sends cooked event data to an input dispatcher. */
|
||||
class InputReaderInterface : public virtual RefBase {
|
||||
protected:
|
||||
InputReaderInterface() { }
|
||||
virtual ~InputReaderInterface() { }
|
||||
|
||||
public:
|
||||
/* Dumps the state of the input reader.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager). */
|
||||
virtual void dump(String8& dump) = 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;
|
||||
|
||||
/* Gets the current input device configuration.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
|
||||
|
||||
/* Gets information about the specified input device.
|
||||
* Returns OK if the device information was obtained or NAME_NOT_FOUND if there
|
||||
* was no such device.
|
||||
*
|
||||
* This method may be called on any thread (usually by the input manager).
|
||||
*/
|
||||
virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
|
||||
|
||||
/* Gets the list of all registered device ids. */
|
||||
virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
|
||||
|
||||
/* Query current input state. */
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t scanCode) = 0;
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t keyCode) = 0;
|
||||
virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t sw) = 0;
|
||||
|
||||
/* Determine whether physical keys exist for the given framework-domain key codes. */
|
||||
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
|
||||
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
|
||||
};
|
||||
|
||||
|
||||
/* Internal interface used by individual input devices to access global input device state
|
||||
* and parameters maintained by the input reader.
|
||||
*/
|
||||
class InputReaderContext {
|
||||
public:
|
||||
InputReaderContext() { }
|
||||
virtual ~InputReaderContext() { }
|
||||
|
||||
virtual void updateGlobalMetaState() = 0;
|
||||
virtual int32_t getGlobalMetaState() = 0;
|
||||
|
||||
virtual InputReaderPolicyInterface* getPolicy() = 0;
|
||||
virtual InputDispatcherInterface* getDispatcher() = 0;
|
||||
virtual EventHubInterface* getEventHub() = 0;
|
||||
};
|
||||
|
||||
|
||||
/* The input reader reads raw event data from the event hub and processes it into input events
|
||||
* that it sends to the input dispatcher. Some functions of the input reader, such as early
|
||||
* event filtering in low power states, are controlled by a separate policy object.
|
||||
*
|
||||
* IMPORTANT INVARIANT:
|
||||
* Because the policy and dispatcher can potentially block or cause re-entrance into
|
||||
* the input reader, the input reader never calls into other components while holding
|
||||
* an exclusive internal lock whenever re-entrance can happen.
|
||||
*/
|
||||
class InputReader : public InputReaderInterface, protected InputReaderContext {
|
||||
public:
|
||||
InputReader(const sp<EventHubInterface>& eventHub,
|
||||
const sp<InputReaderPolicyInterface>& policy,
|
||||
const sp<InputDispatcherInterface>& dispatcher);
|
||||
virtual ~InputReader();
|
||||
|
||||
virtual void dump(String8& dump);
|
||||
|
||||
virtual void loopOnce();
|
||||
|
||||
virtual void getInputConfiguration(InputConfiguration* outConfiguration);
|
||||
|
||||
virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
|
||||
virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
|
||||
|
||||
virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t scanCode);
|
||||
virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t keyCode);
|
||||
virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
|
||||
int32_t sw);
|
||||
|
||||
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
|
||||
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
protected:
|
||||
// These methods are protected virtual so they can be overridden and instrumented
|
||||
// by test cases.
|
||||
virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
|
||||
|
||||
private:
|
||||
sp<EventHubInterface> mEventHub;
|
||||
sp<InputReaderPolicyInterface> mPolicy;
|
||||
sp<InputDispatcherInterface> mDispatcher;
|
||||
|
||||
virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
|
||||
virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
|
||||
virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
|
||||
|
||||
// This reader/writer lock guards the list of input devices.
|
||||
// The writer lock must be held whenever the list of input devices is modified
|
||||
// and then promptly released.
|
||||
// The reader lock must be held whenever the list of input devices is traversed or an
|
||||
// input device in the list is accessed.
|
||||
// This lock only protects the registry and prevents inadvertent deletion of device objects
|
||||
// that are in use. Individual devices are responsible for guarding their own internal state
|
||||
// as needed for concurrent operation.
|
||||
RWLock mDeviceRegistryLock;
|
||||
KeyedVector<int32_t, InputDevice*> mDevices;
|
||||
|
||||
// low-level input event decoding and device management
|
||||
void process(const RawEvent* rawEvent);
|
||||
|
||||
void addDevice(int32_t deviceId);
|
||||
void removeDevice(int32_t deviceId);
|
||||
void configureExcludedDevices();
|
||||
|
||||
void consumeEvent(const RawEvent* rawEvent);
|
||||
|
||||
void handleConfigurationChanged(nsecs_t when);
|
||||
|
||||
// state management for all devices
|
||||
Mutex mStateLock;
|
||||
|
||||
int32_t mGlobalMetaState;
|
||||
virtual void updateGlobalMetaState();
|
||||
virtual int32_t getGlobalMetaState();
|
||||
|
||||
InputConfiguration mInputConfiguration;
|
||||
void updateInputConfiguration();
|
||||
|
||||
// state queries
|
||||
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
||||
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
|
||||
GetStateFunc getStateFunc);
|
||||
bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
};
|
||||
|
||||
|
||||
/* Reads raw events from the event hub and processes them, endlessly. */
|
||||
class InputReaderThread : public Thread {
|
||||
public:
|
||||
InputReaderThread(const sp<InputReaderInterface>& reader);
|
||||
virtual ~InputReaderThread();
|
||||
|
||||
private:
|
||||
sp<InputReaderInterface> mReader;
|
||||
|
||||
virtual bool threadLoop();
|
||||
};
|
||||
|
||||
|
||||
/* Represents the state of a single input device. */
|
||||
class InputDevice {
|
||||
public:
|
||||
InputDevice(InputReaderContext* context, int32_t id, const String8& name);
|
||||
~InputDevice();
|
||||
|
||||
inline InputReaderContext* getContext() { return mContext; }
|
||||
inline int32_t getId() { return mId; }
|
||||
inline const String8& getName() { return mName; }
|
||||
inline uint32_t getSources() { return mSources; }
|
||||
|
||||
inline bool isIgnored() { return mMappers.isEmpty(); }
|
||||
|
||||
void dump(String8& dump);
|
||||
void addMapper(InputMapper* mapper);
|
||||
void configure();
|
||||
void reset();
|
||||
void process(const RawEvent* rawEvent);
|
||||
|
||||
void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
|
||||
int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
|
||||
bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
int32_t getMetaState();
|
||||
|
||||
inline const PropertyMap& getConfiguration() {
|
||||
return mConfiguration;
|
||||
}
|
||||
|
||||
private:
|
||||
InputReaderContext* mContext;
|
||||
int32_t mId;
|
||||
|
||||
Vector<InputMapper*> mMappers;
|
||||
|
||||
String8 mName;
|
||||
uint32_t mSources;
|
||||
|
||||
typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
||||
int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
|
||||
|
||||
PropertyMap mConfiguration;
|
||||
};
|
||||
|
||||
|
||||
/* An input mapper transforms raw input events into cooked event data.
|
||||
* A single input device can have multiple associated input mappers in order to interpret
|
||||
* different classes of events.
|
||||
*/
|
||||
class InputMapper {
|
||||
public:
|
||||
InputMapper(InputDevice* device);
|
||||
virtual ~InputMapper();
|
||||
|
||||
inline InputDevice* getDevice() { return mDevice; }
|
||||
inline int32_t getDeviceId() { return mDevice->getId(); }
|
||||
inline const String8 getDeviceName() { return mDevice->getName(); }
|
||||
inline InputReaderContext* getContext() { return mContext; }
|
||||
inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
|
||||
inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
|
||||
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
|
||||
|
||||
virtual uint32_t getSources() = 0;
|
||||
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
|
||||
virtual void dump(String8& dump);
|
||||
virtual void configure();
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent) = 0;
|
||||
|
||||
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
|
||||
virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
virtual int32_t getMetaState();
|
||||
|
||||
protected:
|
||||
InputDevice* mDevice;
|
||||
InputReaderContext* mContext;
|
||||
};
|
||||
|
||||
|
||||
class SwitchInputMapper : public InputMapper {
|
||||
public:
|
||||
SwitchInputMapper(InputDevice* device);
|
||||
virtual ~SwitchInputMapper();
|
||||
|
||||
virtual uint32_t getSources();
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
|
||||
|
||||
private:
|
||||
void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
|
||||
};
|
||||
|
||||
|
||||
class KeyboardInputMapper : public InputMapper {
|
||||
public:
|
||||
KeyboardInputMapper(InputDevice* device, uint32_t sources, int32_t keyboardType);
|
||||
virtual ~KeyboardInputMapper();
|
||||
|
||||
virtual uint32_t getSources();
|
||||
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
|
||||
virtual void dump(String8& dump);
|
||||
virtual void configure();
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
virtual int32_t getMetaState();
|
||||
|
||||
private:
|
||||
Mutex mLock;
|
||||
|
||||
struct KeyDown {
|
||||
int32_t keyCode;
|
||||
int32_t scanCode;
|
||||
};
|
||||
|
||||
uint32_t mSources;
|
||||
int32_t mKeyboardType;
|
||||
|
||||
// Immutable configuration parameters.
|
||||
struct Parameters {
|
||||
int32_t associatedDisplayId;
|
||||
bool orientationAware;
|
||||
} mParameters;
|
||||
|
||||
struct LockedState {
|
||||
Vector<KeyDown> keyDowns; // keys that are down
|
||||
int32_t metaState;
|
||||
nsecs_t downTime; // time of most recent key down
|
||||
|
||||
struct LedState {
|
||||
bool avail; // led is available
|
||||
bool on; // we think the led is currently on
|
||||
};
|
||||
LedState capsLockLedState;
|
||||
LedState numLockLedState;
|
||||
LedState scrollLockLedState;
|
||||
} mLocked;
|
||||
|
||||
void initializeLocked();
|
||||
|
||||
void configureParameters();
|
||||
void dumpParameters(String8& dump);
|
||||
|
||||
bool isKeyboardOrGamepadKey(int32_t scanCode);
|
||||
|
||||
void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
|
||||
uint32_t policyFlags);
|
||||
|
||||
ssize_t findKeyDownLocked(int32_t scanCode);
|
||||
|
||||
void resetLedStateLocked();
|
||||
void initializeLedStateLocked(LockedState::LedState& ledState, int32_t led);
|
||||
void updateLedStateLocked(bool reset);
|
||||
void updateLedStateForModifierLocked(LockedState::LedState& ledState, int32_t led,
|
||||
int32_t modifier, bool reset);
|
||||
};
|
||||
|
||||
|
||||
class CursorInputMapper : public InputMapper {
|
||||
public:
|
||||
CursorInputMapper(InputDevice* device);
|
||||
virtual ~CursorInputMapper();
|
||||
|
||||
virtual uint32_t getSources();
|
||||
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
|
||||
virtual void dump(String8& dump);
|
||||
virtual void configure();
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
|
||||
private:
|
||||
// Amount that trackball needs to move in order to generate a key event.
|
||||
static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
|
||||
|
||||
Mutex mLock;
|
||||
|
||||
// Immutable configuration parameters.
|
||||
struct Parameters {
|
||||
enum Mode {
|
||||
MODE_POINTER,
|
||||
MODE_NAVIGATION,
|
||||
};
|
||||
|
||||
Mode mode;
|
||||
int32_t associatedDisplayId;
|
||||
bool orientationAware;
|
||||
} mParameters;
|
||||
|
||||
struct Accumulator {
|
||||
enum {
|
||||
FIELD_BTN_MOUSE = 1,
|
||||
FIELD_REL_X = 2,
|
||||
FIELD_REL_Y = 4
|
||||
};
|
||||
|
||||
uint32_t fields;
|
||||
|
||||
bool btnMouse;
|
||||
int32_t relX;
|
||||
int32_t relY;
|
||||
|
||||
inline void clear() {
|
||||
fields = 0;
|
||||
}
|
||||
} mAccumulator;
|
||||
|
||||
int32_t mSources;
|
||||
float mXScale;
|
||||
float mYScale;
|
||||
float mXPrecision;
|
||||
float mYPrecision;
|
||||
sp<PointerControllerInterface> mPointerController;
|
||||
|
||||
struct LockedState {
|
||||
bool down;
|
||||
nsecs_t downTime;
|
||||
} mLocked;
|
||||
|
||||
void initializeLocked();
|
||||
|
||||
void configureParameters();
|
||||
void dumpParameters(String8& dump);
|
||||
|
||||
void sync(nsecs_t when);
|
||||
};
|
||||
|
||||
|
||||
class TouchInputMapper : public InputMapper {
|
||||
public:
|
||||
TouchInputMapper(InputDevice* device);
|
||||
virtual ~TouchInputMapper();
|
||||
|
||||
virtual uint32_t getSources();
|
||||
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
|
||||
virtual void dump(String8& dump);
|
||||
virtual void configure();
|
||||
virtual void reset();
|
||||
|
||||
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
|
||||
virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
|
||||
virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
|
||||
const int32_t* keyCodes, uint8_t* outFlags);
|
||||
|
||||
protected:
|
||||
Mutex mLock;
|
||||
|
||||
struct VirtualKey {
|
||||
int32_t keyCode;
|
||||
int32_t scanCode;
|
||||
uint32_t flags;
|
||||
|
||||
// computed hit box, specified in touch screen coords based on known display size
|
||||
int32_t hitLeft;
|
||||
int32_t hitTop;
|
||||
int32_t hitRight;
|
||||
int32_t hitBottom;
|
||||
|
||||
inline bool isHit(int32_t x, int32_t y) const {
|
||||
return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
|
||||
}
|
||||
};
|
||||
|
||||
// Raw data for a single pointer.
|
||||
struct PointerData {
|
||||
uint32_t id;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t pressure;
|
||||
int32_t touchMajor;
|
||||
int32_t touchMinor;
|
||||
int32_t toolMajor;
|
||||
int32_t toolMinor;
|
||||
int32_t orientation;
|
||||
|
||||
inline bool operator== (const PointerData& other) const {
|
||||
return id == other.id
|
||||
&& x == other.x
|
||||
&& y == other.y
|
||||
&& pressure == other.pressure
|
||||
&& touchMajor == other.touchMajor
|
||||
&& touchMinor == other.touchMinor
|
||||
&& toolMajor == other.toolMajor
|
||||
&& toolMinor == other.toolMinor
|
||||
&& orientation == other.orientation;
|
||||
}
|
||||
inline bool operator!= (const PointerData& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
// Raw data for a collection of pointers including a pointer id mapping table.
|
||||
struct TouchData {
|
||||
uint32_t pointerCount;
|
||||
PointerData pointers[MAX_POINTERS];
|
||||
BitSet32 idBits;
|
||||
uint32_t idToIndex[MAX_POINTER_ID + 1];
|
||||
|
||||
void copyFrom(const TouchData& other) {
|
||||
pointerCount = other.pointerCount;
|
||||
idBits = other.idBits;
|
||||
|
||||
for (uint32_t i = 0; i < pointerCount; i++) {
|
||||
pointers[i] = other.pointers[i];
|
||||
|
||||
int id = pointers[i].id;
|
||||
idToIndex[id] = other.idToIndex[id];
|
||||
}
|
||||
}
|
||||
|
||||
inline void clear() {
|
||||
pointerCount = 0;
|
||||
idBits.clear();
|
||||
}
|
||||
};
|
||||
|
||||
// Input sources supported by the device.
|
||||
int32_t mSources;
|
||||
|
||||
// Immutable configuration parameters.
|
||||
struct Parameters {
|
||||
enum DeviceType {
|
||||
DEVICE_TYPE_TOUCH_SCREEN,
|
||||
DEVICE_TYPE_TOUCH_PAD,
|
||||
};
|
||||
|
||||
DeviceType deviceType;
|
||||
int32_t associatedDisplayId;
|
||||
bool orientationAware;
|
||||
|
||||
bool useBadTouchFilter;
|
||||
bool useJumpyTouchFilter;
|
||||
bool useAveragingTouchFilter;
|
||||
} mParameters;
|
||||
|
||||
// Immutable calibration parameters in parsed form.
|
||||
struct Calibration {
|
||||
// Position
|
||||
bool haveXOrigin;
|
||||
int32_t xOrigin;
|
||||
bool haveYOrigin;
|
||||
int32_t yOrigin;
|
||||
bool haveXScale;
|
||||
float xScale;
|
||||
bool haveYScale;
|
||||
float yScale;
|
||||
|
||||
// Touch Size
|
||||
enum TouchSizeCalibration {
|
||||
TOUCH_SIZE_CALIBRATION_DEFAULT,
|
||||
TOUCH_SIZE_CALIBRATION_NONE,
|
||||
TOUCH_SIZE_CALIBRATION_GEOMETRIC,
|
||||
TOUCH_SIZE_CALIBRATION_PRESSURE,
|
||||
};
|
||||
|
||||
TouchSizeCalibration touchSizeCalibration;
|
||||
|
||||
// Tool Size
|
||||
enum ToolSizeCalibration {
|
||||
TOOL_SIZE_CALIBRATION_DEFAULT,
|
||||
TOOL_SIZE_CALIBRATION_NONE,
|
||||
TOOL_SIZE_CALIBRATION_GEOMETRIC,
|
||||
TOOL_SIZE_CALIBRATION_LINEAR,
|
||||
TOOL_SIZE_CALIBRATION_AREA,
|
||||
};
|
||||
|
||||
ToolSizeCalibration toolSizeCalibration;
|
||||
bool haveToolSizeLinearScale;
|
||||
float toolSizeLinearScale;
|
||||
bool haveToolSizeLinearBias;
|
||||
float toolSizeLinearBias;
|
||||
bool haveToolSizeAreaScale;
|
||||
float toolSizeAreaScale;
|
||||
bool haveToolSizeAreaBias;
|
||||
float toolSizeAreaBias;
|
||||
bool haveToolSizeIsSummed;
|
||||
bool toolSizeIsSummed;
|
||||
|
||||
// Pressure
|
||||
enum PressureCalibration {
|
||||
PRESSURE_CALIBRATION_DEFAULT,
|
||||
PRESSURE_CALIBRATION_NONE,
|
||||
PRESSURE_CALIBRATION_PHYSICAL,
|
||||
PRESSURE_CALIBRATION_AMPLITUDE,
|
||||
};
|
||||
enum PressureSource {
|
||||
PRESSURE_SOURCE_DEFAULT,
|
||||
PRESSURE_SOURCE_PRESSURE,
|
||||
PRESSURE_SOURCE_TOUCH,
|
||||
};
|
||||
|
||||
PressureCalibration pressureCalibration;
|
||||
PressureSource pressureSource;
|
||||
bool havePressureScale;
|
||||
float pressureScale;
|
||||
|
||||
// Size
|
||||
enum SizeCalibration {
|
||||
SIZE_CALIBRATION_DEFAULT,
|
||||
SIZE_CALIBRATION_NONE,
|
||||
SIZE_CALIBRATION_NORMALIZED,
|
||||
};
|
||||
|
||||
SizeCalibration sizeCalibration;
|
||||
|
||||
// Orientation
|
||||
enum OrientationCalibration {
|
||||
ORIENTATION_CALIBRATION_DEFAULT,
|
||||
ORIENTATION_CALIBRATION_NONE,
|
||||
ORIENTATION_CALIBRATION_INTERPOLATED,
|
||||
};
|
||||
|
||||
OrientationCalibration orientationCalibration;
|
||||
} mCalibration;
|
||||
|
||||
// Raw axis information from the driver.
|
||||
struct RawAxes {
|
||||
RawAbsoluteAxisInfo x;
|
||||
RawAbsoluteAxisInfo y;
|
||||
RawAbsoluteAxisInfo pressure;
|
||||
RawAbsoluteAxisInfo touchMajor;
|
||||
RawAbsoluteAxisInfo touchMinor;
|
||||
RawAbsoluteAxisInfo toolMajor;
|
||||
RawAbsoluteAxisInfo toolMinor;
|
||||
RawAbsoluteAxisInfo orientation;
|
||||
} mRawAxes;
|
||||
|
||||
// Current and previous touch sample data.
|
||||
TouchData mCurrentTouch;
|
||||
TouchData mLastTouch;
|
||||
|
||||
// The time the primary pointer last went down.
|
||||
nsecs_t mDownTime;
|
||||
|
||||
struct LockedState {
|
||||
Vector<VirtualKey> virtualKeys;
|
||||
|
||||
// The surface orientation and width and height set by configureSurfaceLocked().
|
||||
int32_t surfaceOrientation;
|
||||
int32_t surfaceWidth, surfaceHeight;
|
||||
|
||||
// Translation and scaling factors, orientation-independent.
|
||||
int32_t xOrigin;
|
||||
float xScale;
|
||||
float xPrecision;
|
||||
|
||||
int32_t yOrigin;
|
||||
float yScale;
|
||||
float yPrecision;
|
||||
|
||||
float geometricScale;
|
||||
|
||||
float toolSizeLinearScale;
|
||||
float toolSizeLinearBias;
|
||||
float toolSizeAreaScale;
|
||||
float toolSizeAreaBias;
|
||||
|
||||
float pressureScale;
|
||||
|
||||
float sizeScale;
|
||||
|
||||
float orientationScale;
|
||||
|
||||
// Oriented motion ranges for input device info.
|
||||
struct OrientedRanges {
|
||||
InputDeviceInfo::MotionRange x;
|
||||
InputDeviceInfo::MotionRange y;
|
||||
|
||||
bool havePressure;
|
||||
InputDeviceInfo::MotionRange pressure;
|
||||
|
||||
bool haveSize;
|
||||
InputDeviceInfo::MotionRange size;
|
||||
|
||||
bool haveTouchSize;
|
||||
InputDeviceInfo::MotionRange touchMajor;
|
||||
InputDeviceInfo::MotionRange touchMinor;
|
||||
|
||||
bool haveToolSize;
|
||||
InputDeviceInfo::MotionRange toolMajor;
|
||||
InputDeviceInfo::MotionRange toolMinor;
|
||||
|
||||
bool haveOrientation;
|
||||
InputDeviceInfo::MotionRange orientation;
|
||||
} orientedRanges;
|
||||
|
||||
// Oriented dimensions and precision.
|
||||
float orientedSurfaceWidth, orientedSurfaceHeight;
|
||||
float orientedXPrecision, orientedYPrecision;
|
||||
|
||||
struct CurrentVirtualKeyState {
|
||||
bool down;
|
||||
nsecs_t downTime;
|
||||
int32_t keyCode;
|
||||
int32_t scanCode;
|
||||
} currentVirtualKey;
|
||||
} mLocked;
|
||||
|
||||
virtual void configureParameters();
|
||||
virtual void dumpParameters(String8& dump);
|
||||
virtual void configureRawAxes();
|
||||
virtual void dumpRawAxes(String8& dump);
|
||||
virtual bool configureSurfaceLocked();
|
||||
virtual void dumpSurfaceLocked(String8& dump);
|
||||
virtual void configureVirtualKeysLocked();
|
||||
virtual void dumpVirtualKeysLocked(String8& dump);
|
||||
virtual void parseCalibration();
|
||||
virtual void resolveCalibration();
|
||||
virtual void dumpCalibration(String8& dump);
|
||||
|
||||
enum TouchResult {
|
||||
// Dispatch the touch normally.
|
||||
DISPATCH_TOUCH,
|
||||
// Do not dispatch the touch, but keep tracking the current stroke.
|
||||
SKIP_TOUCH,
|
||||
// Do not dispatch the touch, and drop all information associated with the current stoke
|
||||
// so the next movement will appear as a new down.
|
||||
DROP_STROKE
|
||||
};
|
||||
|
||||
void syncTouch(nsecs_t when, bool havePointerIds);
|
||||
|
||||
private:
|
||||
/* Maximum number of historical samples to average. */
|
||||
static const uint32_t AVERAGING_HISTORY_SIZE = 5;
|
||||
|
||||
/* Slop distance for jumpy pointer detection.
|
||||
* The vertical range of the screen divided by this is our epsilon value. */
|
||||
static const uint32_t JUMPY_EPSILON_DIVISOR = 212;
|
||||
|
||||
/* Number of jumpy points to drop for touchscreens that need it. */
|
||||
static const uint32_t JUMPY_TRANSITION_DROPS = 3;
|
||||
static const uint32_t JUMPY_DROP_LIMIT = 3;
|
||||
|
||||
/* Maximum squared distance for averaging.
|
||||
* If moving farther than this, turn of averaging to avoid lag in response. */
|
||||
static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75;
|
||||
|
||||
struct AveragingTouchFilterState {
|
||||
// Individual history tracks are stored by pointer id
|
||||
uint32_t historyStart[MAX_POINTERS];
|
||||
uint32_t historyEnd[MAX_POINTERS];
|
||||
struct {
|
||||
struct {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t pressure;
|
||||
} pointers[MAX_POINTERS];
|
||||
} historyData[AVERAGING_HISTORY_SIZE];
|
||||
} mAveragingTouchFilter;
|
||||
|
||||
struct JumpyTouchFilterState {
|
||||
uint32_t jumpyPointsDropped;
|
||||
} mJumpyTouchFilter;
|
||||
|
||||
struct PointerDistanceHeapElement {
|
||||
uint32_t currentPointerIndex : 8;
|
||||
uint32_t lastPointerIndex : 8;
|
||||
uint64_t distance : 48; // squared distance
|
||||
};
|
||||
|
||||
void initializeLocked();
|
||||
|
||||
TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
|
||||
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
|
||||
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
|
||||
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
|
||||
int32_t motionEventAction);
|
||||
|
||||
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
|
||||
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
|
||||
|
||||
bool applyBadTouchFilter();
|
||||
bool applyJumpyTouchFilter();
|
||||
void applyAveragingTouchFilter();
|
||||
void calculatePointerIds();
|
||||
};
|
||||
|
||||
|
||||
class SingleTouchInputMapper : public TouchInputMapper {
|
||||
public:
|
||||
SingleTouchInputMapper(InputDevice* device);
|
||||
virtual ~SingleTouchInputMapper();
|
||||
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
protected:
|
||||
virtual void configureRawAxes();
|
||||
|
||||
private:
|
||||
struct Accumulator {
|
||||
enum {
|
||||
FIELD_BTN_TOUCH = 1,
|
||||
FIELD_ABS_X = 2,
|
||||
FIELD_ABS_Y = 4,
|
||||
FIELD_ABS_PRESSURE = 8,
|
||||
FIELD_ABS_TOOL_WIDTH = 16
|
||||
};
|
||||
|
||||
uint32_t fields;
|
||||
|
||||
bool btnTouch;
|
||||
int32_t absX;
|
||||
int32_t absY;
|
||||
int32_t absPressure;
|
||||
int32_t absToolWidth;
|
||||
|
||||
inline void clear() {
|
||||
fields = 0;
|
||||
}
|
||||
} mAccumulator;
|
||||
|
||||
bool mDown;
|
||||
int32_t mX;
|
||||
int32_t mY;
|
||||
int32_t mPressure;
|
||||
int32_t mToolWidth;
|
||||
|
||||
void initialize();
|
||||
|
||||
void sync(nsecs_t when);
|
||||
};
|
||||
|
||||
|
||||
class MultiTouchInputMapper : public TouchInputMapper {
|
||||
public:
|
||||
MultiTouchInputMapper(InputDevice* device);
|
||||
virtual ~MultiTouchInputMapper();
|
||||
|
||||
virtual void reset();
|
||||
virtual void process(const RawEvent* rawEvent);
|
||||
|
||||
protected:
|
||||
virtual void configureRawAxes();
|
||||
|
||||
private:
|
||||
struct Accumulator {
|
||||
enum {
|
||||
FIELD_ABS_MT_POSITION_X = 1,
|
||||
FIELD_ABS_MT_POSITION_Y = 2,
|
||||
FIELD_ABS_MT_TOUCH_MAJOR = 4,
|
||||
FIELD_ABS_MT_TOUCH_MINOR = 8,
|
||||
FIELD_ABS_MT_WIDTH_MAJOR = 16,
|
||||
FIELD_ABS_MT_WIDTH_MINOR = 32,
|
||||
FIELD_ABS_MT_ORIENTATION = 64,
|
||||
FIELD_ABS_MT_TRACKING_ID = 128,
|
||||
FIELD_ABS_MT_PRESSURE = 256,
|
||||
};
|
||||
|
||||
uint32_t pointerCount;
|
||||
struct Pointer {
|
||||
uint32_t fields;
|
||||
|
||||
int32_t absMTPositionX;
|
||||
int32_t absMTPositionY;
|
||||
int32_t absMTTouchMajor;
|
||||
int32_t absMTTouchMinor;
|
||||
int32_t absMTWidthMajor;
|
||||
int32_t absMTWidthMinor;
|
||||
int32_t absMTOrientation;
|
||||
int32_t absMTTrackingId;
|
||||
int32_t absMTPressure;
|
||||
|
||||
inline void clear() {
|
||||
fields = 0;
|
||||
}
|
||||
} pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
|
||||
|
||||
inline void clear() {
|
||||
pointerCount = 0;
|
||||
pointers[0].clear();
|
||||
}
|
||||
} mAccumulator;
|
||||
|
||||
void initialize();
|
||||
|
||||
void sync(nsecs_t when);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_INPUT_READER_H
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _UI_POINTER_CONTROLLER_H
|
||||
#define _UI_POINTER_CONTROLLER_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
enum {
|
||||
POINTER_BUTTON_1 = 1 << 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for tracking a single (mouse) pointer.
|
||||
*
|
||||
* The pointer controller is responsible for providing synchronization and for tracking
|
||||
* display orientation changes if needed.
|
||||
*/
|
||||
class PointerControllerInterface : public virtual RefBase {
|
||||
protected:
|
||||
PointerControllerInterface() { }
|
||||
virtual ~PointerControllerInterface() { }
|
||||
|
||||
public:
|
||||
/* Gets the bounds of the region that the pointer can traverse.
|
||||
* Returns true if the bounds are available. */
|
||||
virtual bool getBounds(float* outMinX, float* outMinY,
|
||||
float* outMaxX, float* outMaxY) const = 0;
|
||||
|
||||
/* Move the pointer. */
|
||||
virtual void move(float deltaX, float deltaY) = 0;
|
||||
|
||||
/* Sets a mask that indicates which buttons are pressed. */
|
||||
virtual void setButtonState(uint32_t buttonState) = 0;
|
||||
|
||||
/* Gets a mask that indicates which buttons are pressed. */
|
||||
virtual uint32_t getButtonState() const = 0;
|
||||
|
||||
/* Sets the absolute location of the pointer. */
|
||||
virtual void setPosition(float x, float y) = 0;
|
||||
|
||||
/* Gets the absolute location of the pointer. */
|
||||
virtual void getPosition(float* outX, float* outY) const = 0;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // _UI_POINTER_CONTROLLER_H
|
|
@ -43,16 +43,12 @@ include $(CLEAR_VARS)
|
|||
LOCAL_SRC_FILES:= \
|
||||
$(commonSources) \
|
||||
EGLUtils.cpp \
|
||||
EventHub.cpp \
|
||||
EventRecurrence.cpp \
|
||||
FramebufferNativeWindow.cpp \
|
||||
GraphicBuffer.cpp \
|
||||
GraphicBufferAllocator.cpp \
|
||||
GraphicBufferMapper.cpp \
|
||||
GraphicLog.cpp \
|
||||
InputDispatcher.cpp \
|
||||
InputManager.cpp \
|
||||
InputReader.cpp \
|
||||
InputTransport.cpp \
|
||||
PixelFormat.cpp \
|
||||
Rect.cpp \
|
||||
|
|
1092
libs/ui/EventHub.cpp
1092
libs/ui/EventHub.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,83 +0,0 @@
|
|||
//
|
||||
// Copyright 2010 The Android Open Source Project
|
||||
//
|
||||
// The input manager.
|
||||
//
|
||||
#define LOG_TAG "InputManager"
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
|
||||
#include <cutils/log.h>
|
||||
#include <ui/InputManager.h>
|
||||
#include <ui/InputReader.h>
|
||||
#include <ui/InputDispatcher.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
InputManager::InputManager(
|
||||
const sp<EventHubInterface>& eventHub,
|
||||
const sp<InputReaderPolicyInterface>& readerPolicy,
|
||||
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
|
||||
mDispatcher = new InputDispatcher(dispatcherPolicy);
|
||||
mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
|
||||
initialize();
|
||||
}
|
||||
|
||||
InputManager::InputManager(
|
||||
const sp<InputReaderInterface>& reader,
|
||||
const sp<InputDispatcherInterface>& dispatcher) :
|
||||
mReader(reader),
|
||||
mDispatcher(dispatcher) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
InputManager::~InputManager() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void InputManager::initialize() {
|
||||
mReaderThread = new InputReaderThread(mReader);
|
||||
mDispatcherThread = new InputDispatcherThread(mDispatcher);
|
||||
}
|
||||
|
||||
status_t InputManager::start() {
|
||||
status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
|
||||
if (result) {
|
||||
LOGE("Could not start InputDispatcher thread due to error %d.", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
|
||||
if (result) {
|
||||
LOGE("Could not start InputReader thread due to error %d.", result);
|
||||
|
||||
mDispatcherThread->requestExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t InputManager::stop() {
|
||||
status_t result = mReaderThread->requestExitAndWait();
|
||||
if (result) {
|
||||
LOGW("Could not stop InputReader thread due to error %d.", result);
|
||||
}
|
||||
|
||||
result = mDispatcherThread->requestExitAndWait();
|
||||
if (result) {
|
||||
LOGW("Could not stop InputDispatcher thread due to error %d.", result);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
sp<InputReaderInterface> InputManager::getReader() {
|
||||
return mReader;
|
||||
}
|
||||
|
||||
sp<InputDispatcherInterface> InputManager::getDispatcher() {
|
||||
return mDispatcher;
|
||||
}
|
||||
|
||||
} // namespace android
|
File diff suppressed because it is too large
Load Diff
|
@ -7,8 +7,6 @@ ifneq ($(TARGET_SIMULATOR),true)
|
|||
# Build the unit tests.
|
||||
test_src_files := \
|
||||
InputChannel_test.cpp \
|
||||
InputReader_test.cpp \
|
||||
InputDispatcher_test.cpp \
|
||||
InputPublisherAndConsumer_test.cpp
|
||||
|
||||
shared_libraries := \
|
||||
|
|
|
@ -1,229 +0,0 @@
|
|||
//
|
||||
// Copyright 2010 The Android Open Source Project
|
||||
//
|
||||
|
||||
#include <ui/InputDispatcher.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// An arbitrary time value.
|
||||
static const nsecs_t ARBITRARY_TIME = 1234;
|
||||
|
||||
// An arbitrary device id.
|
||||
static const int32_t DEVICE_ID = 1;
|
||||
|
||||
// An arbitrary injector pid / uid pair that has permission to inject events.
|
||||
static const int32_t INJECTOR_PID = 999;
|
||||
static const int32_t INJECTOR_UID = 1001;
|
||||
|
||||
|
||||
// --- FakeInputDispatcherPolicy ---
|
||||
|
||||
class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
|
||||
protected:
|
||||
virtual ~FakeInputDispatcherPolicy() {
|
||||
}
|
||||
|
||||
public:
|
||||
FakeInputDispatcherPolicy() {
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void notifyConfigurationChanged(nsecs_t when) {
|
||||
}
|
||||
|
||||
virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
|
||||
const sp<InputChannel>& inputChannel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
|
||||
}
|
||||
|
||||
virtual nsecs_t getKeyRepeatTimeout() {
|
||||
return 500 * 1000000LL;
|
||||
}
|
||||
|
||||
virtual nsecs_t getKeyRepeatDelay() {
|
||||
return 50 * 1000000LL;
|
||||
}
|
||||
|
||||
virtual int32_t getMaxEventsPerSecond() {
|
||||
return 60;
|
||||
}
|
||||
|
||||
virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
|
||||
}
|
||||
|
||||
virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
|
||||
}
|
||||
|
||||
virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
|
||||
const KeyEvent* keyEvent, uint32_t policyFlags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
|
||||
const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void notifySwitch(nsecs_t when,
|
||||
int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
|
||||
}
|
||||
|
||||
virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
|
||||
}
|
||||
|
||||
virtual bool checkInjectEventsPermissionNonReentrant(
|
||||
int32_t injectorPid, int32_t injectorUid) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --- InputDispatcherTest ---
|
||||
|
||||
class InputDispatcherTest : public testing::Test {
|
||||
protected:
|
||||
sp<FakeInputDispatcherPolicy> mFakePolicy;
|
||||
sp<InputDispatcher> mDispatcher;
|
||||
|
||||
virtual void SetUp() {
|
||||
mFakePolicy = new FakeInputDispatcherPolicy();
|
||||
mDispatcher = new InputDispatcher(mFakePolicy);
|
||||
}
|
||||
|
||||
virtual void TearDown() {
|
||||
mFakePolicy.clear();
|
||||
mDispatcher.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
|
||||
KeyEvent event;
|
||||
|
||||
// Rejects undefined key actions.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
|
||||
/*action*/ -1, 0,
|
||||
AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject key events with undefined action.";
|
||||
|
||||
// Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
|
||||
AKEY_EVENT_ACTION_MULTIPLE, 0,
|
||||
AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject key events with ACTION_MULTIPLE.";
|
||||
}
|
||||
|
||||
TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
|
||||
MotionEvent event;
|
||||
int32_t pointerIds[MAX_POINTERS + 1];
|
||||
PointerCoords pointerCoords[MAX_POINTERS + 1];
|
||||
for (int i = 0; i <= MAX_POINTERS; i++) {
|
||||
pointerIds[i] = i;
|
||||
}
|
||||
|
||||
// Rejects undefined motion actions.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
/*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with undefined action.";
|
||||
|
||||
// Rejects pointer down with invalid index.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
|
||||
0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer down index too large.";
|
||||
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
|
||||
0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer down index too small.";
|
||||
|
||||
// Rejects pointer up with invalid index.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
|
||||
0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer up index too large.";
|
||||
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
|
||||
0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer up index too small.";
|
||||
|
||||
// Rejects motion events with invalid number of pointers.
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 0, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with 0 pointers.";
|
||||
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with more than MAX_POINTERS pointers.";
|
||||
|
||||
// Rejects motion events with invalid pointer ids.
|
||||
pointerIds[0] = -1;
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer ids less than 0.";
|
||||
|
||||
pointerIds[0] = MAX_POINTER_ID + 1;
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 1, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
|
||||
|
||||
// Rejects motion events with duplicate pointer ids.
|
||||
pointerIds[0] = 1;
|
||||
pointerIds[1] = 1;
|
||||
event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
|
||||
AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
|
||||
ARBITRARY_TIME, ARBITRARY_TIME,
|
||||
/*pointerCount*/ 2, pointerIds, pointerCoords);
|
||||
ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
|
||||
INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
|
||||
<< "Should reject motion events with duplicate pointer ids.";
|
||||
}
|
||||
|
||||
} // namespace android
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue