summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/CameraService.cpp48
-rw-r--r--services/camera/libcameraservice/CameraService.h10
-rw-r--r--services/input/Android.mk1
-rw-r--r--services/input/InputDispatcher.cpp143
-rw-r--r--services/input/InputDispatcher.h36
-rw-r--r--services/input/InputListener.cpp162
-rw-r--r--services/input/InputListener.h175
-rw-r--r--services/input/InputReader.cpp3022
-rw-r--r--services/input/InputReader.h553
-rw-r--r--services/input/PointerController.cpp4
-rw-r--r--services/input/tests/InputReader_test.cpp1906
-rw-r--r--services/java/com/android/server/BackupManagerService.java57
-rw-r--r--services/java/com/android/server/NetworkManagementService.java41
-rw-r--r--services/java/com/android/server/TextServicesManagerService.java36
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java5
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java78
-rw-r--r--services/surfaceflinger/Android.mk2
-rw-r--r--services/surfaceflinger/Layer.cpp1
-rw-r--r--services/surfaceflinger/SurfaceTextureLayer.cpp26
-rw-r--r--services/surfaceflinger/SurfaceTextureLayer.h2
-rw-r--r--services/tests/servicestests/AndroidManifest.xml4
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java207
-rw-r--r--services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java2
25 files changed, 4105 insertions, 2434 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index b03649e..e193be0 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -350,10 +350,9 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
dataCallbackTimestamp,
(void *)cameraId);
- // Enable zoom, error, and focus messages by default
- enableMsgType(CAMERA_MSG_ERROR |
- CAMERA_MSG_ZOOM |
- CAMERA_MSG_FOCUS);
+ // Enable zoom, error, focus, and metadata messages by default
+ enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
+ CAMERA_MSG_PREVIEW_METADATA);
// Callback is disabled by default
mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
@@ -460,10 +459,10 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
static void disconnectWindow(const sp<ANativeWindow>& window) {
if (window != 0) {
- status_t result = native_window_disconnect(window.get(),
+ status_t result = native_window_api_disconnect(window.get(),
NATIVE_WINDOW_API_CAMERA);
if (result != NO_ERROR) {
- LOGW("native_window_disconnect failed: %s (%d)", strerror(-result),
+ LOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
result);
}
}
@@ -526,9 +525,9 @@ status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
}
if (window != 0) {
- result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
+ result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
if (result != NO_ERROR) {
- LOGE("native_window_connect failed: %s (%d)", strerror(-result),
+ LOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
result);
return result;
}
@@ -995,15 +994,15 @@ void CameraService::Client::dataCallback(int32_t msgType,
if (client == 0) return;
if (!client->lockIfMessageWanted(msgType)) return;
- if (dataPtr == 0) {
+ if (dataPtr == 0 && metadata == NULL) {
LOGE("Null data returned in data callback");
client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
return;
}
- switch (msgType) {
+ switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
case CAMERA_MSG_PREVIEW_FRAME:
- client->handlePreviewData(dataPtr);
+ client->handlePreviewData(msgType, dataPtr, metadata);
break;
case CAMERA_MSG_POSTVIEW_FRAME:
client->handlePostview(dataPtr);
@@ -1015,7 +1014,7 @@ void CameraService::Client::dataCallback(int32_t msgType,
client->handleCompressedPicture(dataPtr);
break;
default:
- client->handleGenericData(msgType, dataPtr);
+ client->handleGenericData(msgType, dataPtr, metadata);
break;
}
}
@@ -1055,7 +1054,9 @@ void CameraService::Client::handleShutter(void) {
}
// preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
+void CameraService::Client::handlePreviewData(int32_t msgType,
+ const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata) {
ssize_t offset;
size_t size;
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
@@ -1087,11 +1088,11 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) {
// Is the received frame copied out or not?
if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
LOG2("frame is copied");
- copyFrameAndPostCopiedFrame(c, heap, offset, size);
+ copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
} else {
LOG2("frame is forwarded");
mLock.unlock();
- c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
+ c->dataCallback(msgType, mem, metadata);
}
} else {
mLock.unlock();
@@ -1105,7 +1106,7 @@ void CameraService::Client::handlePostview(const sp<IMemory>& mem) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
+ c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
}
}
@@ -1120,7 +1121,7 @@ void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
}
}
@@ -1131,7 +1132,7 @@ void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
+ c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
}
}
@@ -1146,11 +1147,11 @@ void CameraService::Client::handleGenericNotify(int32_t msgType,
}
void CameraService::Client::handleGenericData(int32_t msgType,
- const sp<IMemory>& dataPtr) {
+ const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
sp<ICameraClient> c = mCameraClient;
mLock.unlock();
if (c != 0) {
- c->dataCallback(msgType, dataPtr);
+ c->dataCallback(msgType, dataPtr, metadata);
}
}
@@ -1164,8 +1165,9 @@ void CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
}
void CameraService::Client::copyFrameAndPostCopiedFrame(
- const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap,
- size_t offset, size_t size) {
+ int32_t msgType, const sp<ICameraClient>& client,
+ const sp<IMemoryHeap>& heap, size_t offset, size_t size,
+ camera_frame_metadata_t *metadata) {
LOG2("copyFrameAndPostCopiedFrame");
// It is necessary to copy out of pmem before sending this to
// the callback. For efficiency, reuse the same MemoryHeapBase
@@ -1197,7 +1199,7 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(
}
mLock.unlock();
- client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
+ client->dataCallback(msgType, frame, metadata);
}
int CameraService::Client::getOrientation(int degrees, bool mirror) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index af7f06e..57abf83 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -147,18 +147,22 @@ private:
static sp<Client> getClientFromCookie(void* user);
// handlers for messages
void handleShutter(void);
- void handlePreviewData(const sp<IMemory>& mem);
+ void handlePreviewData(int32_t msgType, const sp<IMemory>& mem,
+ camera_frame_metadata_t *metadata);
void handlePostview(const sp<IMemory>& mem);
void handleRawPicture(const sp<IMemory>& mem);
void handleCompressedPicture(const sp<IMemory>& mem);
void handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
- void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
+ void handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr,
+ camera_frame_metadata_t *metadata);
void handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
void copyFrameAndPostCopiedFrame(
+ int32_t msgType,
const sp<ICameraClient>& client,
const sp<IMemoryHeap>& heap,
- size_t offset, size_t size);
+ size_t offset, size_t size,
+ camera_frame_metadata_t *metadata);
int getOrientation(int orientation, bool mirror);
diff --git a/services/input/Android.mk b/services/input/Android.mk
index e36507a..afbe546 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -19,6 +19,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
EventHub.cpp \
InputDispatcher.cpp \
+ InputListener.cpp \
InputManager.cpp \
InputReader.cpp \
InputWindow.cpp \
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index af13945..ce9e14f 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -2550,16 +2550,16 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
return splitMotionEntry;
}
-void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
+void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
- LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
+ LOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
#endif
bool needWake;
{ // acquire lock
AutoMutex _l(mLock);
- ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(eventTime);
+ ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
needWake = enqueueInboundEventLocked(newEntry);
} // release lock
@@ -2568,19 +2568,21 @@ void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
}
}
-void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
"flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
- eventTime, deviceId, source, policyFlags, action, flags,
- keyCode, scanCode, metaState, downTime);
+ args->eventTime, args->deviceId, args->source, args->policyFlags,
+ args->action, args->flags, args->keyCode, args->scanCode,
+ args->metaState, args->downTime);
#endif
- if (! validateKeyEvent(action)) {
+ if (!validateKeyEvent(args->action)) {
return;
}
+ uint32_t policyFlags = args->policyFlags;
+ int32_t flags = args->flags;
+ int32_t metaState = args->metaState;
if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
policyFlags |= POLICY_FLAG_VIRTUAL;
flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
@@ -2604,8 +2606,9 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so
policyFlags |= POLICY_FLAG_TRUSTED;
KeyEvent event;
- event.initialize(deviceId, source, action, flags, keyCode, scanCode,
- metaState, 0, downTime, eventTime);
+ event.initialize(args->deviceId, args->source, args->action,
+ flags, args->keyCode, args->scanCode, metaState, 0,
+ args->downTime, args->eventTime);
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
@@ -2629,9 +2632,10 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so
}
int32_t repeatCount = 0;
- KeyEntry* newEntry = new KeyEntry(eventTime,
- deviceId, source, policyFlags, action, flags, keyCode, scanCode,
- metaState, repeatCount, downTime);
+ KeyEntry* newEntry = new KeyEntry(args->eventTime,
+ args->deviceId, args->source, policyFlags,
+ args->action, flags, args->keyCode, args->scanCode,
+ metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
@@ -2642,43 +2646,39 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t so
}
}
-void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) {
+void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
"action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
"xPrecision=%f, yPrecision=%f, downTime=%lld",
- eventTime, deviceId, source, policyFlags, action, flags,
- metaState, buttonState, edgeFlags,
- xPrecision, yPrecision, downTime);
- for (uint32_t i = 0; i < pointerCount; i++) {
+ args->eventTime, args->deviceId, args->source, args->policyFlags,
+ args->action, args->flags, args->metaState, args->buttonState,
+ args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
+ for (uint32_t i = 0; i < args->pointerCount; i++) {
LOGD(" Pointer %d: id=%d, toolType=%d, "
"x=%f, y=%f, pressure=%f, size=%f, "
"touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
"orientation=%f",
- i, pointerProperties[i].id,
- pointerProperties[i].toolType,
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
- pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
+ i, args->pointerProperties[i].id,
+ args->pointerProperties[i].toolType,
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
}
#endif
- if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
+ if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
return;
}
+ uint32_t policyFlags = args->policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+ mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
bool needWake;
{ // acquire lock
@@ -2688,10 +2688,11 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
mLock.unlock();
MotionEvent event;
- event.initialize(deviceId, source, action, flags, edgeFlags, metaState,
- buttonState, 0, 0,
- xPrecision, yPrecision, downTime, eventTime,
- pointerCount, pointerProperties, pointerCoords);
+ event.initialize(args->deviceId, args->source, args->action, args->flags,
+ args->edgeFlags, args->metaState, args->buttonState, 0, 0,
+ args->xPrecision, args->yPrecision,
+ args->downTime, args->eventTime,
+ args->pointerCount, args->pointerProperties, args->pointerCoords);
policyFlags |= POLICY_FLAG_FILTERED;
if (!mPolicy->filterInputEvent(&event, policyFlags)) {
@@ -2702,8 +2703,8 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
}
// Attempt batching and streaming of move events.
- if (action == AMOTION_EVENT_ACTION_MOVE
- || action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ if (args->action == AMOTION_EVENT_ACTION_MOVE
+ || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
// BATCHING CASE
//
// Try to append a move sample to the tail of the inbound queue for this device.
@@ -2716,20 +2717,22 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
}
MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
- if (motionEntry->deviceId != deviceId
- || motionEntry->source != source) {
+ if (motionEntry->deviceId != args->deviceId
+ || motionEntry->source != args->source) {
// Keep looking for this device and source.
continue;
}
- if (!motionEntry->canAppendSamples(action, pointerCount, pointerProperties)) {
+ if (!motionEntry->canAppendSamples(args->action,
+ args->pointerCount, args->pointerProperties)) {
// Last motion event in the queue for this device and source is
// not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}
// Do the batching magic.
- batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
+ batchMotionLocked(motionEntry, args->eventTime,
+ args->metaState, args->pointerCoords,
"most recent motion event for this device and source in the inbound queue");
mLock.unlock();
return; // done!
@@ -2744,15 +2747,18 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
&& (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
&& mPendingEvent->type == EventEntry::TYPE_MOTION) {
MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
- if (motionEntry->deviceId == deviceId && motionEntry->source == source) {
- if (!motionEntry->canAppendSamples(action, pointerCount, pointerProperties)) {
+ if (motionEntry->deviceId == args->deviceId
+ && motionEntry->source == args->source) {
+ if (!motionEntry->canAppendSamples(args->action,
+ args->pointerCount, args->pointerProperties)) {
// Pending motion event is for this device and source but it is
// not compatible for appending new samples. Stop here.
goto NoBatchingOrStreaming;
}
// Do the batching magic.
- batchMotionLocked(motionEntry, eventTime, metaState, pointerCoords,
+ batchMotionLocked(motionEntry, args->eventTime,
+ args->metaState, args->pointerCoords,
"pending motion event");
mLock.unlock();
return; // done!
@@ -2799,16 +2805,16 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
MotionEntry* motionEntry = static_cast<MotionEntry*>(
dispatchEntry->eventEntry);
- if (motionEntry->action != action
- || motionEntry->deviceId != deviceId
- || motionEntry->source != source
- || motionEntry->pointerCount != pointerCount
+ if (motionEntry->action != args->action
+ || motionEntry->deviceId != args->deviceId
+ || motionEntry->source != args->source
+ || motionEntry->pointerCount != args->pointerCount
|| motionEntry->isInjected()) {
// The motion event is not compatible with this move.
continue;
}
- if (action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
+ if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
if (mLastHoverWindowHandle == NULL) {
#if DEBUG_BATCHING
LOGD("Not streaming hover move because there is no "
@@ -2818,8 +2824,8 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
}
sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked(
- pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
- pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
+ args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
+ args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
if (mLastHoverWindowHandle != hoverWindowHandle) {
#if DEBUG_BATCHING
LOGD("Not streaming hover move because the last hovered window "
@@ -2834,7 +2840,7 @@ void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t
// Hurray! This foreground target is currently dispatching a move event
// that we can stream onto. Append the motion sample and resume dispatch.
- motionEntry->appendSample(eventTime, pointerCoords);
+ motionEntry->appendSample(args->eventTime, args->pointerCoords);
#if DEBUG_BATCHING
LOGD("Appended motion sample onto batch for most recently dispatched "
"motion event for this device and source in the outbound queues. "
@@ -2854,10 +2860,11 @@ NoBatchingOrStreaming:;
}
// Just enqueue a new motion event.
- MotionEntry* newEntry = new MotionEntry(eventTime,
- deviceId, source, policyFlags, action, flags, metaState, buttonState, edgeFlags,
- xPrecision, yPrecision, downTime,
- pointerCount, pointerProperties, pointerCoords);
+ MotionEntry* newEntry = new MotionEntry(args->eventTime,
+ args->deviceId, args->source, policyFlags,
+ args->action, args->flags, args->metaState, args->buttonState,
+ args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
+ args->pointerCount, args->pointerProperties, args->pointerCoords);
needWake = enqueueInboundEventLocked(newEntry);
mLock.unlock();
@@ -2898,15 +2905,17 @@ void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
#endif
}
-void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
- uint32_t policyFlags) {
+void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
- LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
- switchCode, switchValue, policyFlags);
+ LOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
+ args->eventTime, args->policyFlags,
+ args->switchCode, args->switchValue);
#endif
+ uint32_t policyFlags = args->policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
- mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
+ mPolicy->notifySwitch(args->eventTime,
+ args->switchCode, args->switchValue, policyFlags);
}
int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 1d39b2e..01c7b35 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -34,6 +34,7 @@
#include "InputWindow.h"
#include "InputApplication.h"
+#include "InputListener.h"
namespace android {
@@ -270,7 +271,7 @@ public:
/* Notifies the system about input events generated by the input reader.
* The dispatcher is expected to be mostly asynchronous. */
-class InputDispatcherInterface : public virtual RefBase {
+class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
protected:
InputDispatcherInterface() { }
virtual ~InputDispatcherInterface() { }
@@ -288,23 +289,6 @@ public:
*/
virtual void dispatchOnce() = 0;
- /* Notifies the dispatcher about new events.
- *
- * These methods should only be called on the input reader thread.
- */
- virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
- int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
- virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) = 0;
- virtual void notifySwitch(nsecs_t when,
- int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
-
/* Injects an input event and optionally waits for sync.
* The synchronization mode determines whether the method blocks while waiting for
* input injection to proceed.
@@ -389,18 +373,10 @@ public:
virtual void dispatchOnce();
- virtual void notifyConfigurationChanged(nsecs_t eventTime);
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_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, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- 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 int32_t injectInputEvent(const InputEvent* event,
int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
diff --git a/services/input/InputListener.cpp b/services/input/InputListener.cpp
new file mode 100644
index 0000000..4f9fe90
--- /dev/null
+++ b/services/input/InputListener.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "InputListener"
+
+//#define LOG_NDEBUG 0
+
+#include "InputListener.h"
+
+#include <cutils/log.h>
+
+namespace android {
+
+// --- NotifyConfigurationChangedArgs ---
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(nsecs_t eventTime) :
+ eventTime(eventTime) {
+}
+
+NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
+ const NotifyConfigurationChangedArgs& other) :
+ eventTime(other.eventTime) {
+}
+
+void NotifyConfigurationChangedArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyConfigurationChanged(this);
+}
+
+
+// --- NotifyKeyArgs ---
+
+NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+ int32_t metaState, nsecs_t downTime) :
+ eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+ action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
+ metaState(metaState), downTime(downTime) {
+}
+
+NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
+ eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+ policyFlags(other.policyFlags),
+ action(other.action), flags(other.flags),
+ keyCode(other.keyCode), scanCode(other.scanCode),
+ metaState(other.metaState), downTime(other.downTime) {
+}
+
+void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyKey(this);
+}
+
+
+// --- NotifyMotionArgs ---
+
+NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
+ uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime) :
+ eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+ action(action), flags(flags), metaState(metaState), buttonState(buttonState),
+ edgeFlags(edgeFlags), pointerCount(pointerCount),
+ xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ this->pointerProperties[i].copyFrom(pointerProperties[i]);
+ this->pointerCoords[i].copyFrom(pointerCoords[i]);
+ }
+}
+
+NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
+ eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
+ policyFlags(other.policyFlags),
+ action(other.action), flags(other.flags),
+ metaState(other.metaState), buttonState(other.buttonState),
+ edgeFlags(other.edgeFlags), pointerCount(other.pointerCount),
+ xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].copyFrom(other.pointerProperties[i]);
+ pointerCoords[i].copyFrom(other.pointerCoords[i]);
+ }
+}
+
+void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifyMotion(this);
+}
+
+
+// --- NotifySwitchArgs ---
+
+NotifySwitchArgs::NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+ int32_t switchCode, int32_t switchValue) :
+ eventTime(eventTime), policyFlags(policyFlags),
+ switchCode(switchCode), switchValue(switchValue) {
+}
+
+NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
+ eventTime(other.eventTime), policyFlags(other.policyFlags),
+ switchCode(other.switchCode), switchValue(other.switchValue) {
+}
+
+void NotifySwitchArgs::notify(const sp<InputListenerInterface>& listener) const {
+ listener->notifySwitch(this);
+}
+
+
+// --- QueuedInputListener ---
+
+QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
+ mInnerListener(innerListener) {
+}
+
+QueuedInputListener::~QueuedInputListener() {
+ size_t count = mArgsQueue.size();
+ for (size_t i = 0; i < count; i++) {
+ delete mArgsQueue[i];
+ }
+}
+
+void QueuedInputListener::notifyConfigurationChanged(
+ const NotifyConfigurationChangedArgs* args) {
+ mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
+}
+
+void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
+ mArgsQueue.push(new NotifyKeyArgs(*args));
+}
+
+void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
+ mArgsQueue.push(new NotifyMotionArgs(*args));
+}
+
+void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
+ mArgsQueue.push(new NotifySwitchArgs(*args));
+}
+
+void QueuedInputListener::flush() {
+ size_t count = mArgsQueue.size();
+ for (size_t i = 0; i < count; i++) {
+ NotifyArgs* args = mArgsQueue[i];
+ args->notify(mInnerListener);
+ delete args;
+ }
+ mArgsQueue.clear();
+}
+
+
+} // namespace android
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
new file mode 100644
index 0000000..3fef132
--- /dev/null
+++ b/services/input/InputListener.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 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_LISTENER_H
+#define _UI_INPUT_LISTENER_H
+
+#include <ui/Input.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class InputListenerInterface;
+
+
+/* Superclass of all input event argument objects */
+struct NotifyArgs {
+ virtual ~NotifyArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const = 0;
+};
+
+
+/* Describes a configuration change event. */
+struct NotifyConfigurationChangedArgs : public NotifyArgs {
+ nsecs_t eventTime;
+
+ inline NotifyConfigurationChangedArgs() { }
+
+ NotifyConfigurationChangedArgs(nsecs_t eventTime);
+
+ NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
+
+ virtual ~NotifyConfigurationChangedArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a key event. */
+struct NotifyKeyArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ int32_t deviceId;
+ uint32_t source;
+ uint32_t policyFlags;
+ int32_t action;
+ int32_t flags;
+ int32_t keyCode;
+ int32_t scanCode;
+ int32_t metaState;
+ nsecs_t downTime;
+
+ inline NotifyKeyArgs() { }
+
+ NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+ int32_t metaState, nsecs_t downTime);
+
+ NotifyKeyArgs(const NotifyKeyArgs& other);
+
+ virtual ~NotifyKeyArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a motion event. */
+struct NotifyMotionArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ int32_t deviceId;
+ uint32_t source;
+ uint32_t policyFlags;
+ int32_t action;
+ int32_t flags;
+ int32_t metaState;
+ int32_t buttonState;
+ int32_t edgeFlags;
+ uint32_t pointerCount;
+ PointerProperties pointerProperties[MAX_POINTERS];
+ PointerCoords pointerCoords[MAX_POINTERS];
+ float xPrecision;
+ float yPrecision;
+ nsecs_t downTime;
+
+ inline NotifyMotionArgs() { }
+
+ NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
+ int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
+ int32_t edgeFlags, uint32_t pointerCount,
+ const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
+ float xPrecision, float yPrecision, nsecs_t downTime);
+
+ NotifyMotionArgs(const NotifyMotionArgs& other);
+
+ virtual ~NotifyMotionArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/* Describes a switch event. */
+struct NotifySwitchArgs : public NotifyArgs {
+ nsecs_t eventTime;
+ uint32_t policyFlags;
+ int32_t switchCode;
+ int32_t switchValue;
+
+ inline NotifySwitchArgs() { }
+
+ NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
+ int32_t switchCode, int32_t switchValue);
+
+ NotifySwitchArgs(const NotifySwitchArgs& other);
+
+ virtual ~NotifySwitchArgs() { }
+
+ virtual void notify(const sp<InputListenerInterface>& listener) const;
+};
+
+
+/*
+ * The interface used by the InputReader to notify the InputListener about input events.
+ */
+class InputListenerInterface : public virtual RefBase {
+protected:
+ InputListenerInterface() { }
+ virtual ~InputListenerInterface() { }
+
+public:
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) = 0;
+ virtual void notifyKey(const NotifyKeyArgs* args) = 0;
+ virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
+ virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
+};
+
+
+/*
+ * An implementation of the listener interface that queues up and defers dispatch
+ * of decoded events until flushed.
+ */
+class QueuedInputListener : public InputListenerInterface {
+protected:
+ virtual ~QueuedInputListener();
+
+public:
+ QueuedInputListener(const sp<InputListenerInterface>& innerListener);
+
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
+ virtual void notifyKey(const NotifyKeyArgs* args);
+ virtual void notifyMotion(const NotifyMotionArgs* args);
+ virtual void notifySwitch(const NotifySwitchArgs* args);
+
+ void flush();
+
+private:
+ sp<InputListenerInterface> mInnerListener;
+ Vector<NotifyArgs*> mArgsQueue;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_LISTENER_H
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index db312ad..8786c24 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -180,8 +180,9 @@ static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
|| (action == AKEY_EVENT_ACTION_UP
&& (lastButtonState & buttonState)
&& !(currentButtonState & buttonState))) {
- context->getDispatcher()->notifyKey(when, deviceId, source, policyFlags,
+ NotifyKeyArgs args(when, deviceId, source, policyFlags,
action, 0, keyCode, 0, context->getGlobalMetaState(), when);
+ context->getListener()->notifyKey(&args);
}
}
@@ -201,13 +202,19 @@ static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
- refreshConfiguration(0);
- updateGlobalMetaState();
- updateInputConfiguration();
+ mQueuedListener = new QueuedInputListener(listener);
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ refreshConfigurationLocked(0);
+ updateGlobalMetaStateLocked();
+ updateInputConfigurationLocked();
+ } // release lock
}
InputReader::~InputReader() {
@@ -217,39 +224,52 @@ InputReader::~InputReader() {
}
void InputReader::loopOnce() {
- uint32_t changes;
+ int32_t timeoutMillis;
{ // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
+
+ uint32_t changes = mConfigurationChangesToRefresh;
+ if (changes) {
+ mConfigurationChangesToRefresh = 0;
+ refreshConfigurationLocked(changes);
+ }
- changes = mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh = 0;
+ timeoutMillis = -1;
+ if (mNextTimeout != LLONG_MAX) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
+ }
} // release lock
- if (changes) {
- refreshConfiguration(changes);
- }
+ size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- int32_t timeoutMillis = -1;
- if (mNextTimeout != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
- }
+ { // acquire lock
+ AutoMutex _l(mLock);
- size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- if (count) {
- processEvents(mEventBuffer, count);
- }
- if (!count || timeoutMillis == 0) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ if (count) {
+ processEventsLocked(mEventBuffer, count);
+ }
+ if (!count || timeoutMillis == 0) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
#if DEBUG_RAW_EVENTS
- LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
+ LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
#endif
- mNextTimeout = LLONG_MAX;
- timeoutExpired(now);
- }
+ mNextTimeout = LLONG_MAX;
+ timeoutExpiredLocked(now);
+ }
+ } // release lock
+
+ // Flush queued events out to the listener.
+ // This must happen outside of the lock because the listener could potentially call
+ // back into the InputReader's methods, such as getScanCodeState, or become blocked
+ // on another thread similarly waiting to acquire the InputReader lock thereby
+ // resulting in a deadlock. This situation is actually quite plausible because the
+ // listener is actually the input dispatcher, which calls into the window manager,
+ // which occasionally calls into the input reader.
+ mQueuedListener->flush();
}
-void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
+void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
@@ -265,17 +285,17 @@ void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
#if DEBUG_RAW_EVENTS
LOGD("BatchSize: %d Count: %d", batchSize, count);
#endif
- processEventsForDevice(deviceId, rawEvent, batchSize);
+ processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
- addDevice(rawEvent->deviceId);
+ addDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED:
- removeDevice(rawEvent->deviceId);
+ removeDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
- handleConfigurationChanged(rawEvent->when);
+ handleConfigurationChangedLocked(rawEvent->when);
break;
default:
LOG_ASSERT(false); // can't happen
@@ -287,11 +307,11 @@ void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
}
}
-void InputReader::addDevice(int32_t deviceId) {
+void InputReader::addDeviceLocked(int32_t deviceId) {
String8 name = mEventHub->getDeviceName(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
- InputDevice* device = createDevice(deviceId, name, classes);
+ InputDevice* device = createDeviceLocked(deviceId, name, classes);
device->configure(&mConfig, 0);
if (device->isIgnored()) {
@@ -301,39 +321,23 @@ void InputReader::addDevice(int32_t deviceId) {
device->getSources());
}
- bool added = false;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- mDevices.add(deviceId, device);
- added = true;
- }
- } // release device registry writer lock
-
- if (! added) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ mDevices.add(deviceId, device);
+ } else {
LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
delete device;
return;
}
}
-void InputReader::removeDevice(int32_t deviceId) {
- bool removed = false;
+void InputReader::removeDeviceLocked(int32_t deviceId) {
InputDevice* device = NULL;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- device = mDevices.valueAt(deviceIndex);
- mDevices.removeItemsAt(deviceIndex, 1);
- removed = true;
- }
- } // release device registry writer lock
-
- if (! removed) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ device = mDevices.valueAt(deviceIndex);
+ mDevices.removeItemsAt(deviceIndex, 1);
+ } else {
LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
return;
}
@@ -351,8 +355,9 @@ void InputReader::removeDevice(int32_t deviceId) {
delete device;
}
-InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
- InputDevice* device = new InputDevice(this, deviceId, name);
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes) {
+ InputDevice* device = new InputDevice(&mContext, deviceId, name);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -404,52 +409,45 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui
return device;
}
-void InputReader::processEventsForDevice(int32_t deviceId,
+void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- LOGW("Discarding event for unknown deviceId %d.", deviceId);
- return;
- }
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ LOGW("Discarding event for unknown deviceId %d.", deviceId);
+ return;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- //LOGD("Discarding event for ignored deviceId %d.", deviceId);
- return;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ //LOGD("Discarding event for ignored deviceId %d.", deviceId);
+ return;
+ }
- device->process(rawEvents, count);
- } // release device registry reader lock
+ device->process(rawEvents, count);
}
-void InputReader::timeoutExpired(nsecs_t when) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (!device->isIgnored()) {
- device->timeoutExpired(when);
- }
+void InputReader::timeoutExpiredLocked(nsecs_t when) {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ device->timeoutExpired(when);
}
- } // release device registry reader lock
+ }
}
-void InputReader::handleConfigurationChanged(nsecs_t when) {
+void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
// Reset global meta state because it depends on the list of all configured devices.
- updateGlobalMetaState();
+ updateGlobalMetaStateLocked();
// Update input configuration.
- updateInputConfiguration();
+ updateInputConfigurationLocked();
// Enqueue configuration changed.
- mDispatcher->notifyConfigurationChanged(when);
+ NotifyConfigurationChangedArgs args(when);
+ mQueuedListener->notifyConfigurationChanged(&args);
}
-void InputReader::refreshConfiguration(uint32_t changes) {
+void InputReader::refreshConfigurationLocked(uint32_t changes) {
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
@@ -459,84 +457,60 @@ void InputReader::refreshConfiguration(uint32_t changes) {
if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
mEventHub->requestReopenDevices();
} else {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->configure(&mConfig, changes);
- }
- } // release device registry reader lock
- }
- }
-}
-
-void InputReader::updateGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
-
- mGlobalMetaState = 0;
-
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
for (size_t i = 0; i < mDevices.size(); i++) {
InputDevice* device = mDevices.valueAt(i);
- mGlobalMetaState |= device->getMetaState();
+ device->configure(&mConfig, changes);
}
- } // release device registry reader lock
- } // release state lock
+ }
+ }
}
-int32_t InputReader::getGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+void InputReader::updateGlobalMetaStateLocked() {
+ mGlobalMetaState = 0;
- return mGlobalMetaState;
- } // release state lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ mGlobalMetaState |= device->getMetaState();
+ }
}
-void InputReader::updateInputConfiguration() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
-
- int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
- int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
- int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+int32_t InputReader::getGlobalMetaStateLocked() {
+ return mGlobalMetaState;
+}
- InputDeviceInfo deviceInfo;
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->getDeviceInfo(& deviceInfo);
- uint32_t sources = deviceInfo.getSources();
+void InputReader::updateInputConfigurationLocked() {
+ int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
+ int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
+ int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
+ InputDeviceInfo deviceInfo;
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->getDeviceInfo(& deviceInfo);
+ uint32_t sources = deviceInfo.getSources();
- if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
- touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
- }
- if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
- navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
- } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
- navigationConfig = InputConfiguration::NAVIGATION_DPAD;
- }
- if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
- keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
- }
- }
- } // release device registry reader lock
+ if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
+ touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
+ }
+ if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
+ navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
+ } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
+ navigationConfig = InputConfiguration::NAVIGATION_DPAD;
+ }
+ if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
+ keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
+ }
+ }
- mInputConfiguration.touchScreen = touchScreenConfig;
- mInputConfiguration.keyboard = keyboardConfig;
- mInputConfiguration.navigation = navigationConfig;
- } // release state lock
+ mInputConfiguration.touchScreen = touchScreenConfig;
+ mInputConfiguration.keyboard = keyboardConfig;
+ mInputConfiguration.navigation = navigationConfig;
}
-void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
mDisableVirtualKeysTimeout = time;
}
-bool InputReader::shouldDropVirtualKey(nsecs_t now,
+bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
InputDevice* device, int32_t keyCode, int32_t scanCode) {
if (now < mDisableVirtualKeysTimeout) {
LOGI("Dropping virtual key from device %s because virtual keys are "
@@ -550,153 +524,141 @@ bool InputReader::shouldDropVirtualKey(nsecs_t now,
}
}
-void InputReader::fadePointer() {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->fadePointer();
- }
- } // release device registry reader lock
+void InputReader::fadePointerLocked() {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->fadePointer();
+ }
}
-void InputReader::requestTimeoutAtTime(nsecs_t when) {
+void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
if (when < mNextTimeout) {
mNextTimeout = when;
}
}
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- *outConfiguration = mInputConfiguration;
- } // release state lock
+ *outConfiguration = mInputConfiguration;
}
status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ AutoMutex _l(mLock);
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- return NAME_NOT_FOUND;
- }
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ return NAME_NOT_FOUND;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- return NAME_NOT_FOUND;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ return NAME_NOT_FOUND;
+ }
- device->getDeviceInfo(outDeviceInfo);
- return OK;
- } // release device registy reader lock
+ device->getDeviceInfo(outDeviceInfo);
+ return OK;
}
void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
- outDeviceIds.clear();
+ AutoMutex _l(mLock);
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ outDeviceIds.clear();
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored()) {
- outDeviceIds.add(device->getId());
- }
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ outDeviceIds.add(device->getId());
}
- } // release device registy reader lock
+ }
}
int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t keyCode) {
- return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
}
int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t scanCode) {
- return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
}
int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
- return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
}
-int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- int32_t result = AKEY_STATE_UNKNOWN;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- }
+ int32_t result = AKEY_STATE_UNKNOWN;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
}
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- if (result >= AKEY_STATE_DOWN) {
- return result;
- }
+ }
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
+ if (result >= AKEY_STATE_DOWN) {
+ return result;
}
}
}
- return result;
- } // release device registy reader lock
+ }
+ return result;
}
bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ AutoMutex _l(mLock);
+
memset(outFlags, 0, numCodes);
- return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+ return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
}
-bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
- bool result = false;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
+bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ bool result = false;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
}
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result |= device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
+ }
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result |= device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
}
}
- return result;
- } // release device registy reader lock
+ }
+ return result;
}
void InputReader::requestRefreshConfiguration(uint32_t changes) {
- if (changes) {
- bool needWake;
- { // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- needWake = !mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh |= changes;
- } // release lock
+ if (changes) {
+ bool needWake = !mConfigurationChangesToRefresh;
+ mConfigurationChangesToRefresh |= changes;
if (needWake) {
mEventHub->wake();
@@ -705,18 +667,16 @@ void InputReader::requestRefreshConfiguration(uint32_t changes) {
}
void InputReader::dump(String8& dump) {
+ AutoMutex _l(mLock);
+
mEventHub->dump(dump);
dump.append("\n");
dump.append("Input Reader State:\n");
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- mDevices.valueAt(i)->dump(dump);
- }
- } // release device registy reader lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ mDevices.valueAt(i)->dump(dump);
+ }
dump.append(INDENT "Configuration:\n");
dump.append(INDENT2 "ExcludedDeviceNames: [");
@@ -772,6 +732,56 @@ void InputReader::dump(String8& dump) {
}
+// --- InputReader::ContextImpl ---
+
+InputReader::ContextImpl::ContextImpl(InputReader* reader) :
+ mReader(reader) {
+}
+
+void InputReader::ContextImpl::updateGlobalMetaState() {
+ // lock is already held by the input loop
+ mReader->updateGlobalMetaStateLocked();
+}
+
+int32_t InputReader::ContextImpl::getGlobalMetaState() {
+ // lock is already held by the input loop
+ return mReader->getGlobalMetaStateLocked();
+}
+
+void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
+ // lock is already held by the input loop
+ mReader->disableVirtualKeysUntilLocked(time);
+}
+
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ // lock is already held by the input loop
+ return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+}
+
+void InputReader::ContextImpl::fadePointer() {
+ // lock is already held by the input loop
+ mReader->fadePointerLocked();
+}
+
+void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
+ // lock is already held by the input loop
+ mReader->requestTimeoutAtTimeLocked(when);
+}
+
+InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
+ return mReader->mPolicy.get();
+}
+
+InputListenerInterface* InputReader::ContextImpl::getListener() {
+ return mReader->mQueuedListener.get();
+}
+
+EventHubInterface* InputReader::ContextImpl::getEventHub() {
+ return mReader->mEventHub.get();
+}
+
+
// --- InputReaderThread ---
InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
@@ -1170,6 +1180,96 @@ bool TouchButtonAccumulator::isHovering() const {
}
+// --- RawPointerAxes ---
+
+RawPointerAxes::RawPointerAxes() {
+ clear();
+}
+
+void RawPointerAxes::clear() {
+ x.clear();
+ y.clear();
+ pressure.clear();
+ touchMajor.clear();
+ touchMinor.clear();
+ toolMajor.clear();
+ toolMinor.clear();
+ orientation.clear();
+ distance.clear();
+ trackingId.clear();
+ slot.clear();
+}
+
+
+// --- RawPointerData ---
+
+RawPointerData::RawPointerData() {
+ clear();
+}
+
+void RawPointerData::clear() {
+ pointerCount = 0;
+ clearIdBits();
+}
+
+void RawPointerData::copyFrom(const RawPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointers[i] = other.pointers[i];
+
+ int id = pointers[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
+ float x = 0, y = 0;
+ uint32_t count = touchingIdBits.count();
+ if (count) {
+ for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const Pointer& pointer = pointerForId(id);
+ x += pointer.x;
+ y += pointer.y;
+ }
+ x /= count;
+ y /= count;
+ }
+ *outX = x;
+ *outY = y;
+}
+
+
+// --- CookedPointerData ---
+
+CookedPointerData::CookedPointerData() {
+ clear();
+}
+
+void CookedPointerData::clear() {
+ pointerCount = 0;
+ hoveringIdBits.clear();
+ touchingIdBits.clear();
+}
+
+void CookedPointerData::copyFrom(const CookedPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].copyFrom(other.pointerProperties[i]);
+ pointerCoords[i].copyFrom(other.pointerCoords[i]);
+
+ int id = pointerProperties[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+
// --- SingleTouchMotionAccumulator ---
SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
@@ -1298,6 +1398,10 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
slot->mInUse = true;
slot->mAbsMTPressure = rawEvent->value;
break;
+ case ABS_MT_DISTANCE:
+ slot->mInUse = true;
+ slot->mAbsMTDistance = rawEvent->value;
+ break;
case ABS_MT_TOOL_TYPE:
slot->mInUse = true;
slot->mAbsMTToolType = rawEvent->value;
@@ -1338,8 +1442,8 @@ void MultiTouchMotionAccumulator::Slot::clear() {
mAbsMTOrientation = 0;
mAbsMTTrackingId = -1;
mAbsMTPressure = 0;
- mAbsMTToolType = 0;
mAbsMTDistance = 0;
+ mAbsMTToolType = 0;
}
int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
@@ -1404,6 +1508,10 @@ int32_t InputMapper::getMetaState() {
void InputMapper::fadePointer() {
}
+status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
+ return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+}
+
void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name) {
if (axis.valid) {
@@ -1437,7 +1545,8 @@ void SwitchInputMapper::process(const RawEvent* rawEvent) {
}
void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
- getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
+ NotifySwitchArgs args(when, 0, switchCode, switchValue);
+ getListener()->notifySwitch(&args);
}
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
@@ -1451,15 +1560,15 @@ KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
uint32_t source, int32_t keyboardType) :
InputMapper(device), mSource(source),
mKeyboardType(keyboardType) {
- initializeLocked();
+ initialize();
}
KeyboardInputMapper::~KeyboardInputMapper() {
}
-void KeyboardInputMapper::initializeLocked() {
- mLocked.metaState = AMETA_NONE;
- mLocked.downTime = 0;
+void KeyboardInputMapper::initialize() {
+ mMetaState = AMETA_NONE;
+ mDownTime = 0;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -1473,15 +1582,12 @@ void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
}
void KeyboardInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Keyboard Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
- dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
- dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Keyboard Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
+ dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
+ dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
@@ -1493,10 +1599,7 @@ void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint
configureParameters();
// Reset LEDs.
- {
- AutoMutex _l(mLock);
- resetLedStateLocked();
- }
+ resetLedState();
}
}
@@ -1520,27 +1623,16 @@ void KeyboardInputMapper::dumpParameters(String8& dump) {
}
void KeyboardInputMapper::reset() {
- for (;;) {
- int32_t keyCode, scanCode;
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Synthesize key up event on reset if keys are currently down.
- if (mLocked.keyDowns.isEmpty()) {
- initializeLocked();
- resetLedStateLocked();
- break; // done
- }
-
- const KeyDown& keyDown = mLocked.keyDowns.top();
- keyCode = keyDown.keyCode;
- scanCode = keyDown.scanCode;
- } // release lock
-
+ // Synthesize key up event on reset if keys are currently down.
+ while (!mKeyDowns.isEmpty()) {
+ const KeyDown& keyDown = mKeyDowns.top();
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- processKey(when, false, keyCode, scanCode, 0);
+ processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
}
+ initialize();
+ resetLedState();
+
InputMapper::reset();
getContext()->updateGlobalMetaState();
}
@@ -1567,72 +1659,66 @@ bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
int32_t scanCode, uint32_t policyFlags) {
- int32_t newMetaState;
- nsecs_t downTime;
- bool metaStateChanged = false;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (down) {
- // Rotate key codes according to orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
- int32_t orientation;
- if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
- }
- keyCode = rotateKeyCode(keyCode, orientation);
+ if (down) {
+ // Rotate key codes according to orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
+ int32_t orientation;
+ if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
}
- // Add key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- } else {
- // key down
- if ((policyFlags & POLICY_FLAG_VIRTUAL)
- && mContext->shouldDropVirtualKey(when,
- getDevice(), keyCode, scanCode)) {
- return;
- }
-
- mLocked.keyDowns.push();
- KeyDown& keyDown = mLocked.keyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
- }
+ keyCode = rotateKeyCode(keyCode, orientation);
+ }
- mLocked.downTime = when;
+ // Add key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key repeat, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
} else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- mLocked.keyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- LOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
+ // key down
+ if ((policyFlags & POLICY_FLAG_VIRTUAL)
+ && mContext->shouldDropVirtualKey(when,
+ getDevice(), keyCode, scanCode)) {
return;
}
+
+ mKeyDowns.push();
+ KeyDown& keyDown = mKeyDowns.editTop();
+ keyDown.keyCode = keyCode;
+ keyDown.scanCode = scanCode;
}
- int32_t oldMetaState = mLocked.metaState;
- newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mLocked.metaState = newMetaState;
- metaStateChanged = true;
- updateLedStateLocked(false);
+ mDownTime = when;
+ } else {
+ // Remove key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key up, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+ mKeyDowns.removeAt(size_t(keyDownIndex));
+ } else {
+ // key was not actually down
+ LOGI("Dropping key up from device %s because the key was not down. "
+ "keyCode=%d, scanCode=%d",
+ getDeviceName().string(), keyCode, scanCode);
+ return;
}
+ }
- downTime = mLocked.downTime;
- } // release lock
+ bool metaStateChanged = false;
+ int32_t oldMetaState = mMetaState;
+ int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
+ if (oldMetaState != newMetaState) {
+ mMetaState = newMetaState;
+ metaStateChanged = true;
+ updateLedState(false);
+ }
+
+ nsecs_t downTime = mDownTime;
// Key down on external an keyboard should wake the device.
// We don't do this for internal keyboards to prevent them from waking up in your pocket.
@@ -1652,15 +1738,16 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
getContext()->fadePointer();
}
- getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags,
+ NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
+ getListener()->notifyKey(&args);
}
-ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
- size_t n = mLocked.keyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
+ size_t n = mKeyDowns.size();
for (size_t i = 0; i < n; i++) {
- if (mLocked.keyDowns[i].scanCode == scanCode) {
+ if (mKeyDowns[i].scanCode == scanCode) {
return i;
}
}
@@ -1681,38 +1768,35 @@ bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numC
}
int32_t KeyboardInputMapper::getMetaState() {
- { // acquire lock
- AutoMutex _l(mLock);
- return mLocked.metaState;
- } // release lock
+ return mMetaState;
}
-void KeyboardInputMapper::resetLedStateLocked() {
- initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
- initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
- initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
+void KeyboardInputMapper::resetLedState() {
+ initializeLedState(mCapsLockLedState, LED_CAPSL);
+ initializeLedState(mNumLockLedState, LED_NUML);
+ initializeLedState(mScrollLockLedState, LED_SCROLLL);
- updateLedStateLocked(true);
+ updateLedState(true);
}
-void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
+void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
ledState.on = false;
}
-void KeyboardInputMapper::updateLedStateLocked(bool reset) {
- updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL,
+void KeyboardInputMapper::updateLedState(bool reset) {
+ updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
AMETA_CAPS_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML,
+ updateLedStateForModifier(mNumLockLedState, LED_NUML,
AMETA_NUM_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL,
+ updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
AMETA_SCROLL_LOCK_ON, reset);
}
-void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState,
+void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
int32_t led, int32_t modifier, bool reset) {
if (ledState.avail) {
- bool desiredState = (mLocked.metaState & modifier) != 0;
+ bool desiredState = (mMetaState & modifier) != 0;
if (reset || ledState.on != desiredState) {
getEventHub()->setLedState(getDeviceId(), led, desiredState);
ledState.on = desiredState;
@@ -1725,7 +1809,7 @@ void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState&
CursorInputMapper::CursorInputMapper(InputDevice* device) :
InputMapper(device) {
- initializeLocked();
+ initialize();
}
CursorInputMapper::~CursorInputMapper() {
@@ -1759,24 +1843,21 @@ void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
}
void CursorInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Cursor Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
- dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
- dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
- dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
- dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeVWheel()));
- dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeHWheel()));
- dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
- dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
- dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState);
- dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState)));
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Cursor Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeVWheel()));
+ dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeHWheel()));
+ dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+ dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
+ dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
+ dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
@@ -1859,38 +1940,27 @@ void CursorInputMapper::dumpParameters(String8& dump) {
toString(mParameters.orientationAware));
}
-void CursorInputMapper::initializeLocked() {
+void CursorInputMapper::initialize() {
mCursorButtonAccumulator.clearButtons();
mCursorMotionAccumulator.clearRelativeAxes();
- mLocked.buttonState = 0;
- mLocked.downTime = 0;
+ mButtonState = 0;
+ mDownTime = 0;
}
void CursorInputMapper::reset() {
- for (;;) {
- int32_t buttonState;
- { // acquire lock
- AutoMutex _l(mLock);
-
- buttonState = mLocked.buttonState;
- if (!buttonState) {
- initializeLocked();
- break; // done
- }
- } // release lock
+ // Reset velocity.
+ mPointerVelocityControl.reset();
+ mWheelXVelocityControl.reset();
+ mWheelYVelocityControl.reset();
- // Reset velocity.
- mPointerVelocityControl.reset();
- mWheelXVelocityControl.reset();
- mWheelYVelocityControl.reset();
+ // Synthesize button up event on reset.
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCursorButtonAccumulator.clearButtons();
+ mCursorMotionAccumulator.clearRelativeAxes();
+ sync(when);
- // Synthesize button up event on reset.
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCursorButtonAccumulator.clearButtons();
- mCursorMotionAccumulator.clearRelativeAxes();
- sync(when);
- }
+ initialize();
InputMapper::reset();
}
@@ -1905,98 +1975,84 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
}
void CursorInputMapper::sync(nsecs_t when) {
- int32_t motionEventAction;
- int32_t lastButtonState, currentButtonState;
- PointerProperties pointerProperties;
- PointerCoords pointerCoords;
- nsecs_t downTime;
- float vscroll, hscroll;
- { // acquire lock
- AutoMutex _l(mLock);
-
- lastButtonState = mLocked.buttonState;
- currentButtonState = mCursorButtonAccumulator.getButtonState();
- mLocked.buttonState = currentButtonState;
-
- bool wasDown = isPointerDown(lastButtonState);
- bool down = isPointerDown(currentButtonState);
- bool downChanged;
- if (!wasDown && down) {
- mLocked.downTime = when;
- downChanged = true;
- } else if (wasDown && !down) {
- downChanged = true;
- } else {
- downChanged = false;
- }
- downTime = mLocked.downTime;
-
- if (downChanged) {
- motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else if (down || mPointerController == NULL) {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
- }
-
- float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
- float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ int32_t lastButtonState = mButtonState;
+ int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
+ mButtonState = currentButtonState;
+
+ bool wasDown = isPointerDown(lastButtonState);
+ bool down = isPointerDown(currentButtonState);
+ bool downChanged;
+ if (!wasDown && down) {
+ mDownTime = when;
+ downChanged = true;
+ } else if (wasDown && !down) {
+ downChanged = true;
+ } else {
+ downChanged = false;
+ }
+ nsecs_t downTime = mDownTime;
+ bool buttonsChanged = currentButtonState != lastButtonState;
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
- && (deltaX != 0.0f || deltaY != 0.0f)) {
- // Rotate motion based on display orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- int32_t orientation;
- if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
- }
+ float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
+ float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ bool moved = deltaX != 0 || deltaY != 0;
- rotateDelta(orientation, &deltaX, &deltaY);
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
+ && (deltaX != 0.0f || deltaY != 0.0f)) {
+ // Rotate motion based on display orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
}
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
+ rotateDelta(orientation, &deltaX, &deltaY);
+ }
- pointerCoords.clear();
+ PointerProperties pointerProperties;
+ pointerProperties.clear();
+ pointerProperties.id = 0;
+ pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
- vscroll = mCursorMotionAccumulator.getRelativeVWheel();
- hscroll = mCursorMotionAccumulator.getRelativeHWheel();
+ PointerCoords pointerCoords;
+ pointerCoords.clear();
- mWheelYVelocityControl.move(when, NULL, &vscroll);
- mWheelXVelocityControl.move(when, &hscroll, NULL);
+ float vscroll = mCursorMotionAccumulator.getRelativeVWheel();
+ float hscroll = mCursorMotionAccumulator.getRelativeHWheel();
+ bool scrolled = vscroll != 0 || hscroll != 0;
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
+ mWheelYVelocityControl.move(when, NULL, &vscroll);
+ mWheelXVelocityControl.move(when, &hscroll, NULL);
- if (mPointerController != NULL) {
- if (deltaX != 0 || deltaY != 0 || vscroll != 0 || hscroll != 0
- || currentButtonState != lastButtonState) {
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerVelocityControl.move(when, &deltaX, &deltaY);
- if (deltaX != 0 || deltaY != 0) {
- mPointerController->move(deltaX, deltaY);
- }
+ if (mPointerController != NULL) {
+ if (moved || scrolled || buttonsChanged) {
+ mPointerController->setPresentation(
+ PointerControllerInterface::PRESENTATION_POINTER);
- if (currentButtonState != lastButtonState) {
- mPointerController->setButtonState(currentButtonState);
- }
+ if (moved) {
+ mPointerController->move(deltaX, deltaY);
+ }
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ if (buttonsChanged) {
+ mPointerController->setButtonState(currentButtonState);
}
- float x, y;
- mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- } else {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
}
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
- } // release lock
+ float x, y;
+ mPointerController->getPosition(&x, &y);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ } else {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ }
+
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
// Moving an external trackball or mouse should wake the device.
// We don't do this for internal cursor devices to prevent them from waking up
@@ -2012,29 +2068,43 @@ void CursorInputMapper::sync(nsecs_t when) {
policyFlags, lastButtonState, currentButtonState);
// Send motion event.
- int32_t metaState = mContext->getGlobalMetaState();
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- motionEventAction, 0, metaState, currentButtonState, 0,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
-
- // Send hover move after UP to tell the application that the mouse is hovering now.
- if (motionEventAction == AMOTION_EVENT_ACTION_UP
- && mPointerController != NULL) {
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ if (downChanged || moved || scrolled || buttonsChanged) {
+ int32_t metaState = mContext->getGlobalMetaState();
+ int32_t motionEventAction;
+ if (downChanged) {
+ motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+ } else if (down || mPointerController == NULL) {
+ motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ } else {
+ motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
+ }
+
+ NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ motionEventAction, 0, metaState, currentButtonState, 0,
1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
- }
+ getListener()->notifyMotion(&args);
+
+ // Send hover move after UP to tell the application that the mouse is hovering now.
+ if (motionEventAction == AMOTION_EVENT_ACTION_UP
+ && mPointerController != NULL) {
+ NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+ metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&hoverArgs);
+ }
- // Send scroll events.
- if (vscroll != 0 || hscroll != 0) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+ // Send scroll events.
+ if (scrolled) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&scrollArgs);
+ }
}
// Synthesize key up from buttons if needed.
@@ -2053,24 +2123,18 @@ int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCod
}
void CursorInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
// --- TouchInputMapper ---
TouchInputMapper::TouchInputMapper(InputDevice* device) :
- InputMapper(device) {
- mLocked.surfaceOrientation = -1;
- mLocked.surfaceWidth = -1;
- mLocked.surfaceHeight = -1;
-
- initializeLocked();
+ InputMapper(device),
+ mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
+ initialize();
}
TouchInputMapper::~TouchInputMapper() {
@@ -2083,126 +2147,148 @@ uint32_t TouchInputMapper::getSources() {
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Ensure surface information is up to date so that orientation changes are
- // noticed immediately.
- if (!configureSurfaceLocked()) {
- return;
- }
+ // Ensure surface information is up to date so that orientation changes are
+ // noticed immediately.
+ if (!configureSurface()) {
+ return;
+ }
- info->addMotionRange(mLocked.orientedRanges.x);
- info->addMotionRange(mLocked.orientedRanges.y);
+ info->addMotionRange(mOrientedRanges.x);
+ info->addMotionRange(mOrientedRanges.y);
- if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(mLocked.orientedRanges.pressure);
- }
+ if (mOrientedRanges.havePressure) {
+ info->addMotionRange(mOrientedRanges.pressure);
+ }
- if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(mLocked.orientedRanges.size);
- }
+ if (mOrientedRanges.haveSize) {
+ info->addMotionRange(mOrientedRanges.size);
+ }
- if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(mLocked.orientedRanges.touchMajor);
- info->addMotionRange(mLocked.orientedRanges.touchMinor);
- }
+ if (mOrientedRanges.haveTouchSize) {
+ info->addMotionRange(mOrientedRanges.touchMajor);
+ info->addMotionRange(mOrientedRanges.touchMinor);
+ }
- if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(mLocked.orientedRanges.toolMajor);
- info->addMotionRange(mLocked.orientedRanges.toolMinor);
- }
+ if (mOrientedRanges.haveToolSize) {
+ info->addMotionRange(mOrientedRanges.toolMajor);
+ info->addMotionRange(mOrientedRanges.toolMinor);
+ }
- if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(mLocked.orientedRanges.orientation);
- }
+ if (mOrientedRanges.haveOrientation) {
+ info->addMotionRange(mOrientedRanges.orientation);
+ }
- if (mLocked.orientedRanges.haveDistance) {
- info->addMotionRange(mLocked.orientedRanges.distance);
- }
+ if (mOrientedRanges.haveDistance) {
+ info->addMotionRange(mOrientedRanges.distance);
+ }
- if (mPointerController != NULL) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
- minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
- minY, maxY, 0.0f, 0.0f);
- }
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
- 0.0f, 1.0f, 0.0f, 0.0f);
+ if (mPointerController != NULL) {
+ float minX, minY, maxX, maxY;
+ if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
+ minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
+ minY, maxY, 0.0f, 0.0f);
}
- } // release lock
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
+ 0.0f, 1.0f, 0.0f, 0.0f);
+ }
}
void TouchInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Touch Input Mapper:\n");
- dumpParameters(dump);
- dumpVirtualKeysLocked(dump);
- dumpRawAxes(dump);
- dumpCalibration(dump);
- dumpSurfaceLocked(dump);
-
- dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
- dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
- dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
- dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
- dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
- dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
- dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
- dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
- dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
- dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
- dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale);
- dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mLocked.distanceScale);
-
- dump.appendFormat(INDENT3 "Last Touch:\n");
- dump.appendFormat(INDENT4 "Button State: 0x%08x\n", mLastTouch.buttonState);
- dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount);
- for (uint32_t i = 0; i < mLastTouch.pointerCount; i++) {
- const PointerData& pointer = mLastTouch.pointers[i];
- dump.appendFormat(INDENT5 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
- "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
- "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
- pointer.id, pointer.x, pointer.y, pointer.pressure,
- pointer.touchMajor, pointer.touchMinor, pointer.toolMajor, pointer.toolMinor,
- pointer.orientation, pointer.distance,
- pointer.toolType, toString(pointer.isHovering));
- }
-
- if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
- dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
- mLocked.pointerGestureXMovementScale);
- dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
- mLocked.pointerGestureYMovementScale);
- dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
- mLocked.pointerGestureXZoomScale);
- dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
- mLocked.pointerGestureYZoomScale);
- dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
- mLocked.pointerGestureMaxSwipeWidth);
- }
- } // release lock
-}
-
-void TouchInputMapper::initializeLocked() {
- mCurrentTouch.clear();
- mLastTouch.clear();
+ dump.append(INDENT2 "Touch Input Mapper:\n");
+ dumpParameters(dump);
+ dumpVirtualKeys(dump);
+ dumpRawPointerAxes(dump);
+ dumpCalibration(dump);
+ dumpSurface(dump);
+
+ dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+ dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mToolSizeLinearScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mToolSizeLinearBias);
+ dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mToolSizeAreaScale);
+ dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mToolSizeAreaBias);
+ dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
+ dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
+ dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
+ dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
+
+ dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
+
+ dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
+ mLastRawPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
+ const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
+ "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
+ "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
+ pointer.id, pointer.x, pointer.y, pointer.pressure,
+ pointer.touchMajor, pointer.touchMinor,
+ pointer.toolMajor, pointer.toolMinor,
+ pointer.orientation, pointer.distance,
+ pointer.toolType, toString(pointer.isHovering));
+ }
+
+ dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
+ mLastCookedPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
+ const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
+ const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
+ "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
+ "orientation=%0.3f, distance=%0.3f, toolType=%d, isHovering=%s\n", i,
+ pointerProperties.id,
+ pointerCoords.getX(),
+ pointerCoords.getY(),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
+ pointerProperties.toolType,
+ toString(mLastCookedPointerData.isHovering(i)));
+ }
+
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
+ dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
+ dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
+ mPointerGestureXMovementScale);
+ dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
+ mPointerGestureYMovementScale);
+ dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
+ mPointerGestureXZoomScale);
+ dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
+ mPointerGestureYZoomScale);
+ dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
+ mPointerGestureMaxSwipeWidth);
+ }
+}
+
+void TouchInputMapper::initialize() {
+ mCurrentRawPointerData.clear();
+ mLastRawPointerData.clear();
+ mCurrentCookedPointerData.clear();
+ mLastCookedPointerData.clear();
+ mCurrentButtonState = 0;
+ mLastButtonState = 0;
+ mSentHoverEnter = false;
mDownTime = 0;
- mLocked.currentVirtualKey.down = false;
+ mCurrentVirtualKey.down = false;
- mLocked.orientedRanges.havePressure = false;
- mLocked.orientedRanges.haveSize = false;
- mLocked.orientedRanges.haveTouchSize = false;
- mLocked.orientedRanges.haveToolSize = false;
- mLocked.orientedRanges.haveOrientation = false;
- mLocked.orientedRanges.haveDistance = false;
+ mOrientedRanges.havePressure = false;
+ mOrientedRanges.haveSize = false;
+ mOrientedRanges.haveTouchSize = false;
+ mOrientedRanges.haveToolSize = false;
+ mOrientedRanges.haveOrientation = false;
+ mOrientedRanges.haveDistance = false;
mPointerGesture.reset();
}
@@ -2235,18 +2321,14 @@ void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_
}
// Configure absolute axis information.
- configureRawAxes();
+ configureRawPointerAxes();
// Prepare input device calibration.
parseCalibration();
resolveCalibration();
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Configure surface dimensions and orientation.
- configureSurfaceLocked();
- } // release lock
+ // Configure surface dimensions and orientation.
+ configureSurface();
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
@@ -2359,38 +2441,28 @@ void TouchInputMapper::dumpParameters(String8& dump) {
toString(mParameters.orientationAware));
}
-void TouchInputMapper::configureRawAxes() {
- mRawAxes.x.clear();
- mRawAxes.y.clear();
- mRawAxes.pressure.clear();
- mRawAxes.touchMajor.clear();
- mRawAxes.touchMinor.clear();
- mRawAxes.toolMajor.clear();
- mRawAxes.toolMinor.clear();
- mRawAxes.orientation.clear();
- mRawAxes.distance.clear();
- mRawAxes.trackingId.clear();
- mRawAxes.slot.clear();
-}
-
-void TouchInputMapper::dumpRawAxes(String8& dump) {
- dump.append(INDENT3 "Raw Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.distance, "Distance");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.trackingId, "TrackingId");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.slot, "Slot");
-}
-
-bool TouchInputMapper::configureSurfaceLocked() {
+void TouchInputMapper::configureRawPointerAxes() {
+ mRawPointerAxes.clear();
+}
+
+void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
+ dump.append(INDENT3 "Raw Touch Axes:\n");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
+}
+
+bool TouchInputMapper::configureSurface() {
// Ensure we have valid X and Y axes.
- if (!mRawAxes.x.valid || !mRawAxes.y.valid) {
+ if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! "
"The device will be inoperable.", getDeviceName().string());
return false;
@@ -2398,27 +2470,27 @@ bool TouchInputMapper::configureSurfaceLocked() {
// Update orientation and dimensions if needed.
int32_t orientation = DISPLAY_ORIENTATION_0;
- int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
if (mParameters.associatedDisplayId >= 0) {
// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
mParameters.associatedDisplayIsExternal,
- &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight,
- &mLocked.associatedDisplayOrientation)) {
+ &mAssociatedDisplayWidth, &mAssociatedDisplayHeight,
+ &mAssociatedDisplayOrientation)) {
return false;
}
// A touch screen inherits the dimensions of the display.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
- width = mLocked.associatedDisplayWidth;
- height = mLocked.associatedDisplayHeight;
+ width = mAssociatedDisplayWidth;
+ height = mAssociatedDisplayHeight;
}
// The device inherits the orientation of the display if it is orientation aware.
if (mParameters.orientationAware) {
- orientation = mLocked.associatedDisplayOrientation;
+ orientation = mAssociatedDisplayOrientation;
}
}
@@ -2427,118 +2499,120 @@ bool TouchInputMapper::configureSurfaceLocked() {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
}
- bool orientationChanged = mLocked.surfaceOrientation != orientation;
+ bool orientationChanged = mSurfaceOrientation != orientation;
if (orientationChanged) {
- mLocked.surfaceOrientation = orientation;
+ mSurfaceOrientation = orientation;
}
- bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
+ bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
if (sizeChanged) {
LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d",
getDeviceId(), getDeviceName().string(), width, height);
- mLocked.surfaceWidth = width;
- mLocked.surfaceHeight = height;
+ mSurfaceWidth = width;
+ mSurfaceHeight = height;
// Configure X and Y factors.
- mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1);
- mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1);
- mLocked.xPrecision = 1.0f / mLocked.xScale;
- mLocked.yPrecision = 1.0f / mLocked.yScale;
+ mXScale = float(width) / (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1);
+ mYScale = float(height) / (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1);
+ mXPrecision = 1.0f / mXScale;
+ mYPrecision = 1.0f / mYScale;
- mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
- mLocked.orientedRanges.x.source = mTouchSource;
- mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
- mLocked.orientedRanges.y.source = mTouchSource;
+ mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
+ mOrientedRanges.x.source = mTouchSource;
+ mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
+ mOrientedRanges.y.source = mTouchSource;
- configureVirtualKeysLocked();
+ configureVirtualKeys();
// Scale factor for terms that are not oriented in a particular axis.
// If the pixels are square then xScale == yScale otherwise we fake it
// by choosing an average.
- mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
+ mGeometricScale = avg(mXScale, mYScale);
// Size of diagonal axis.
float diagonalSize = hypotf(width, height);
// TouchMajor and TouchMinor factors.
if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
- mLocked.orientedRanges.haveTouchSize = true;
+ mOrientedRanges.haveTouchSize = true;
- mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
- mLocked.orientedRanges.touchMajor.source = mTouchSource;
- mLocked.orientedRanges.touchMajor.min = 0;
- mLocked.orientedRanges.touchMajor.max = diagonalSize;
- mLocked.orientedRanges.touchMajor.flat = 0;
- mLocked.orientedRanges.touchMajor.fuzz = 0;
+ mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
+ mOrientedRanges.touchMajor.source = mTouchSource;
+ mOrientedRanges.touchMajor.min = 0;
+ mOrientedRanges.touchMajor.max = diagonalSize;
+ mOrientedRanges.touchMajor.flat = 0;
+ mOrientedRanges.touchMajor.fuzz = 0;
- mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
- mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
+ mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+ mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
}
// ToolMajor and ToolMinor factors.
- mLocked.toolSizeLinearScale = 0;
- mLocked.toolSizeLinearBias = 0;
- mLocked.toolSizeAreaScale = 0;
- mLocked.toolSizeAreaBias = 0;
+ mToolSizeLinearScale = 0;
+ mToolSizeLinearBias = 0;
+ mToolSizeAreaScale = 0;
+ mToolSizeAreaBias = 0;
if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeLinearScale = float(min(width, height))
- / mRawAxes.toolMajor.maxValue;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeLinearScale = float(min(width, height))
+ / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
} else if (mCalibration.toolSizeCalibration ==
Calibration::TOOL_SIZE_CALIBRATION_AREA) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
} else {
- mLocked.toolSizeLinearScale = min(width, height);
+ mToolSizeLinearScale = min(width, height);
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
if (mCalibration.haveToolSizeAreaScale) {
- mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ mToolSizeAreaScale = mCalibration.toolSizeAreaScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeAreaScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeAreaBias) {
- mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
+ mToolSizeAreaBias = mCalibration.toolSizeAreaBias;
}
}
- mLocked.orientedRanges.haveToolSize = true;
+ mOrientedRanges.haveToolSize = true;
- mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
- mLocked.orientedRanges.toolMajor.source = mTouchSource;
- mLocked.orientedRanges.toolMajor.min = 0;
- mLocked.orientedRanges.toolMajor.max = diagonalSize;
- mLocked.orientedRanges.toolMajor.flat = 0;
- mLocked.orientedRanges.toolMajor.fuzz = 0;
+ mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
+ mOrientedRanges.toolMajor.source = mTouchSource;
+ mOrientedRanges.toolMajor.min = 0;
+ mOrientedRanges.toolMajor.max = diagonalSize;
+ mOrientedRanges.toolMajor.flat = 0;
+ mOrientedRanges.toolMajor.fuzz = 0;
- mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
- mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
+ mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
+ mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
}
// Pressure factors.
- mLocked.pressureScale = 0;
+ mPressureScale = 0;
if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
RawAbsoluteAxisInfo rawPressureAxis;
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_PRESSURE:
- rawPressureAxis = mRawAxes.pressure;
+ rawPressureAxis = mRawPointerAxes.pressure;
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- rawPressureAxis = mRawAxes.touchMajor;
+ rawPressureAxis = mRawPointerAxes.touchMajor;
break;
default:
rawPressureAxis.clear();
@@ -2548,84 +2622,84 @@ bool TouchInputMapper::configureSurfaceLocked() {
|| mCalibration.pressureCalibration
== Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
if (mCalibration.havePressureScale) {
- mLocked.pressureScale = mCalibration.pressureScale;
+ mPressureScale = mCalibration.pressureScale;
} else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
- mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+ mPressureScale = 1.0f / rawPressureAxis.maxValue;
}
}
- mLocked.orientedRanges.havePressure = true;
+ mOrientedRanges.havePressure = true;
- mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
- mLocked.orientedRanges.pressure.source = mTouchSource;
- mLocked.orientedRanges.pressure.min = 0;
- mLocked.orientedRanges.pressure.max = 1.0;
- mLocked.orientedRanges.pressure.flat = 0;
- mLocked.orientedRanges.pressure.fuzz = 0;
+ mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
+ mOrientedRanges.pressure.source = mTouchSource;
+ mOrientedRanges.pressure.min = 0;
+ mOrientedRanges.pressure.max = 1.0;
+ mOrientedRanges.pressure.flat = 0;
+ mOrientedRanges.pressure.fuzz = 0;
}
// Size factors.
- mLocked.sizeScale = 0;
+ mSizeScale = 0;
if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
- if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
}
- mLocked.orientedRanges.haveSize = true;
+ mOrientedRanges.haveSize = true;
- mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
- mLocked.orientedRanges.size.source = mTouchSource;
- mLocked.orientedRanges.size.min = 0;
- mLocked.orientedRanges.size.max = 1.0;
- mLocked.orientedRanges.size.flat = 0;
- mLocked.orientedRanges.size.fuzz = 0;
+ mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
+ mOrientedRanges.size.source = mTouchSource;
+ mOrientedRanges.size.min = 0;
+ mOrientedRanges.size.max = 1.0;
+ mOrientedRanges.size.flat = 0;
+ mOrientedRanges.size.fuzz = 0;
}
// Orientation
- mLocked.orientationScale = 0;
+ mOrientationScale = 0;
if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
if (mCalibration.orientationCalibration
== Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
- if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
- mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+ if (mRawPointerAxes.orientation.valid && mRawPointerAxes.orientation.maxValue != 0) {
+ mOrientationScale = float(M_PI_2) / mRawPointerAxes.orientation.maxValue;
}
}
- mLocked.orientedRanges.haveOrientation = true;
+ mOrientedRanges.haveOrientation = true;
- mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
- mLocked.orientedRanges.orientation.source = mTouchSource;
- mLocked.orientedRanges.orientation.min = - M_PI_2;
- mLocked.orientedRanges.orientation.max = M_PI_2;
- mLocked.orientedRanges.orientation.flat = 0;
- mLocked.orientedRanges.orientation.fuzz = 0;
+ mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+ mOrientedRanges.orientation.source = mTouchSource;
+ mOrientedRanges.orientation.min = - M_PI_2;
+ mOrientedRanges.orientation.max = M_PI_2;
+ mOrientedRanges.orientation.flat = 0;
+ mOrientedRanges.orientation.fuzz = 0;
}
// Distance
- mLocked.distanceScale = 0;
+ mDistanceScale = 0;
if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
if (mCalibration.distanceCalibration
== Calibration::DISTANCE_CALIBRATION_SCALED) {
if (mCalibration.haveDistanceScale) {
- mLocked.distanceScale = mCalibration.distanceScale;
+ mDistanceScale = mCalibration.distanceScale;
} else {
- mLocked.distanceScale = 1.0f;
+ mDistanceScale = 1.0f;
}
}
- mLocked.orientedRanges.haveDistance = true;
+ mOrientedRanges.haveDistance = true;
- mLocked.orientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
- mLocked.orientedRanges.distance.source = mTouchSource;
- mLocked.orientedRanges.distance.min =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.max =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.flat = 0;
- mLocked.orientedRanges.distance.fuzz =
- mRawAxes.distance.fuzz * mLocked.distanceScale;
+ mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
+ mOrientedRanges.distance.source = mTouchSource;
+ mOrientedRanges.distance.min =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.max =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.flat = 0;
+ mOrientedRanges.distance.fuzz =
+ mRawPointerAxes.distance.fuzz * mDistanceScale;
}
}
@@ -2633,78 +2707,77 @@ bool TouchInputMapper::configureSurfaceLocked() {
// Compute oriented surface dimensions, precision, scales and ranges.
// Note that the maximum value reported is an inclusive maximum value so it is one
// unit less than the total width or height of surface.
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
case DISPLAY_ORIENTATION_270:
- mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
- mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
-
- mLocked.orientedXPrecision = mLocked.yPrecision;
- mLocked.orientedYPrecision = mLocked.xPrecision;
-
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.yScale;
-
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.xScale;
+ mOrientedSurfaceWidth = mSurfaceHeight;
+ mOrientedSurfaceHeight = mSurfaceWidth;
+
+ mOrientedXPrecision = mYPrecision;
+ mOrientedYPrecision = mXPrecision;
+
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mYScale;
+
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mXScale;
break;
default:
- mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
- mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
-
- mLocked.orientedXPrecision = mLocked.xPrecision;
- mLocked.orientedYPrecision = mLocked.yPrecision;
-
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.xScale;
-
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.yScale;
+ mOrientedSurfaceWidth = mSurfaceWidth;
+ mOrientedSurfaceHeight = mSurfaceHeight;
+
+ mOrientedXPrecision = mXPrecision;
+ mOrientedYPrecision = mYPrecision;
+
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mXScale;
+
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mYScale;
break;
}
// Compute pointer gesture detection parameters.
- // TODO: These factors should not be hardcoded.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- int32_t rawWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t rawHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
float rawDiagonal = hypotf(rawWidth, rawHeight);
- float displayDiagonal = hypotf(mLocked.associatedDisplayWidth,
- mLocked.associatedDisplayHeight);
+ float displayDiagonal = hypotf(mAssociatedDisplayWidth,
+ mAssociatedDisplayHeight);
// Scale movements such that one whole swipe of the touch pad covers a
// given area relative to the diagonal size of the display when no acceleration
// is applied.
// Assume that the touch pad has a square aspect ratio such that movements in
// X and Y of the same number of raw units cover the same physical distance.
- mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
+ mPointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale;
+ mPointerGestureYMovementScale = mPointerGestureXMovementScale;
// Scale zooms to cover a smaller range of the display than movements do.
// This value determines the area around the pointer that is affected by freeform
// pointer gestures.
- mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
+ mPointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale;
+ mPointerGestureYZoomScale = mPointerGestureXZoomScale;
// Max width between pointers to detect a swipe gesture is more than some fraction
// of the diagonal axis of the touch pad. Touches that are wider than this are
// translated into freeform gestures.
- mLocked.pointerGestureMaxSwipeWidth =
+ mPointerGestureMaxSwipeWidth =
mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
// Reset the current pointer gesture.
@@ -2720,35 +2793,35 @@ bool TouchInputMapper::configureSurfaceLocked() {
return true;
}
-void TouchInputMapper::dumpSurfaceLocked(String8& dump) {
- dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
- dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
- dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
+void TouchInputMapper::dumpSurface(String8& dump) {
+ dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
+ dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+ dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
-void TouchInputMapper::configureVirtualKeysLocked() {
+void TouchInputMapper::configureVirtualKeys() {
Vector<VirtualKeyDefinition> virtualKeyDefinitions;
getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
- mLocked.virtualKeys.clear();
+ mVirtualKeys.clear();
if (virtualKeyDefinitions.size() == 0) {
return;
}
- mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+ mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
- int32_t touchScreenLeft = mRawAxes.x.minValue;
- int32_t touchScreenTop = mRawAxes.y.minValue;
- int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
+ int32_t touchScreenTop = mRawPointerAxes.y.minValue;
+ int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
const VirtualKeyDefinition& virtualKeyDefinition =
virtualKeyDefinitions[i];
- mLocked.virtualKeys.add();
- VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+ mVirtualKeys.add();
+ VirtualKey& virtualKey = mVirtualKeys.editTop();
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
@@ -2757,7 +2830,7 @@ void TouchInputMapper::configureVirtualKeysLocked() {
& keyCode, & flags)) {
LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
- mLocked.virtualKeys.pop(); // drop the key
+ mVirtualKeys.pop(); // drop the key
continue;
}
@@ -2769,22 +2842,22 @@ void TouchInputMapper::configureVirtualKeysLocked() {
int32_t halfHeight = virtualKeyDefinition.height / 2;
virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
}
}
-void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
- if (!mLocked.virtualKeys.isEmpty()) {
+void TouchInputMapper::dumpVirtualKeys(String8& dump) {
+ if (!mVirtualKeys.isEmpty()) {
dump.append(INDENT3 "Virtual Keys:\n");
- for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
+ for (size_t i = 0; i < mVirtualKeys.size(); i++) {
+ const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
"hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
i, virtualKey.scanCode, virtualKey.keyCode,
@@ -2927,22 +3000,22 @@ void TouchInputMapper::resolveCalibration() {
// Pressure
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_DEFAULT:
- if (mRawAxes.pressure.valid) {
+ if (mRawPointerAxes.pressure.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
- } else if (mRawAxes.touchMajor.valid) {
+ } else if (mRawPointerAxes.touchMajor.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
}
break;
case Calibration::PRESSURE_SOURCE_PRESSURE:
- if (! mRawAxes.pressure.valid) {
+ if (! mRawPointerAxes.pressure.valid) {
LOGW("Calibration property touch.pressure.source is 'pressure' but "
"the pressure axis is not available.");
}
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- if (! mRawAxes.touchMajor.valid) {
+ if (! mRawPointerAxes.touchMajor.valid) {
LOGW("Calibration property touch.pressure.source is 'touch' but "
"the touchMajor axis is not available.");
}
@@ -2968,7 +3041,7 @@ void TouchInputMapper::resolveCalibration() {
// Tool Size
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
} else {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
@@ -2997,7 +3070,7 @@ void TouchInputMapper::resolveCalibration() {
// Size
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
} else {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
@@ -3011,7 +3084,7 @@ void TouchInputMapper::resolveCalibration() {
// Orientation
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
- if (mRawAxes.orientation.valid) {
+ if (mRawPointerAxes.orientation.valid) {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
} else {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
@@ -3025,7 +3098,7 @@ void TouchInputMapper::resolveCalibration() {
// Distance
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_DEFAULT:
- if (mRawAxes.distance.valid) {
+ if (mRawPointerAxes.distance.valid) {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
} else {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
@@ -3177,24 +3250,20 @@ void TouchInputMapper::dumpCalibration(String8& dump) {
}
void TouchInputMapper::reset() {
- // Synthesize touch up event if touch is currently down.
+ // Synthesize touch up event.
// This will also take care of finishing virtual key processing if needed.
- if (mLastTouch.pointerCount != 0) {
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCurrentTouch.clear();
- syncTouch(when, true);
- }
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
+ syncTouch(when, true);
- { // acquire lock
- AutoMutex _l(mLock);
- initializeLocked();
+ initialize();
- if (mPointerController != NULL
- && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- mPointerController->clearSpots();
- }
- } // release lock
+ if (mPointerController != NULL
+ && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->clearSpots();
+ }
InputMapper::reset();
}
@@ -3202,25 +3271,37 @@ void TouchInputMapper::reset() {
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
#if DEBUG_RAW_EVENTS
if (!havePointerIds) {
- LOGD("syncTouch: pointerCount=%d, no pointer ids", mCurrentTouch.pointerCount);
+ LOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount);
} else {
- LOGD("syncTouch: pointerCount=%d, up=0x%08x, down=0x%08x, move=0x%08x, "
- "last=0x%08x, current=0x%08x", mCurrentTouch.pointerCount,
- mLastTouch.idBits.value & ~mCurrentTouch.idBits.value,
- mCurrentTouch.idBits.value & ~mLastTouch.idBits.value,
- mLastTouch.idBits.value & mCurrentTouch.idBits.value,
- mLastTouch.idBits.value, mCurrentTouch.idBits.value);
+ LOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
+ "hovering ids 0x%08x -> 0x%08x",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount,
+ mLastRawPointerData.touchingIdBits.value,
+ mCurrentRawPointerData.touchingIdBits.value,
+ mLastRawPointerData.hoveringIdBits.value,
+ mCurrentRawPointerData.hoveringIdBits.value);
}
#endif
+ // Configure the surface now, if possible.
+ if (!configureSurface()) {
+ mLastRawPointerData.clear();
+ mLastCookedPointerData.clear();
+ mLastButtonState = 0;
+ return;
+ }
+
// Preprocess pointer data.
if (!havePointerIds) {
- calculatePointerIds();
+ assignPointerIds();
}
- // Handle initial down events.
+ // Handle policy on initial down or hover events.
uint32_t policyFlags = 0;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (mLastRawPointerData.pointerCount == 0 && mCurrentRawPointerData.pointerCount != 0) {
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
// If this is a touch screen, hide the pointer on an initial down.
getContext()->fadePointer();
@@ -3235,40 +3316,31 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
}
}
- // Synthesize key down from buttons if needed.
+ // Synthesize key down from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
-
- // Send motion events.
- TouchResult touchResult;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount == 0
- && mLastTouch.buttonState == mCurrentTouch.buttonState) {
- // Drop spurious syncs.
- touchResult = DROP_STROKE;
- } else {
- // Process touches and virtual keys.
- touchResult = consumeOffScreenTouches(when, policyFlags);
- if (touchResult == DISPATCH_TOUCH) {
- suppressSwipeOntoVirtualKeys(when);
- if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
- dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
- }
- dispatchTouches(when, policyFlags);
- }
+ policyFlags, mLastButtonState, mCurrentButtonState);
+
+ if (consumeRawTouches(when, policyFlags)) {
+ mCurrentRawPointerData.clear();
}
- // Synthesize key up from buttons if needed.
+ if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
+ dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
+ }
+
+ cookPointerData();
+ dispatchHoverExit(when, policyFlags);
+ dispatchTouches(when, policyFlags);
+ dispatchHoverEnterAndMove(when, policyFlags);
+
+ // Synthesize key up from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
+ policyFlags, mLastButtonState, mCurrentButtonState);
// Copy current touch to last touch in preparation for the next cycle.
- // Keep the button state so we can track edge-triggered button state changes.
- if (touchResult == DROP_STROKE) {
- mLastTouch.clear();
- mLastTouch.buttonState = mCurrentTouch.buttonState;
- } else {
- mLastTouch.copyFrom(mCurrentTouch);
- }
+ mLastRawPointerData.copyFrom(mCurrentRawPointerData);
+ mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
+ mLastButtonState = mCurrentButtonState;
}
void TouchInputMapper::timeoutExpired(nsecs_t when) {
@@ -3277,125 +3349,88 @@ void TouchInputMapper::timeoutExpired(nsecs_t when) {
}
}
-TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
- nsecs_t when, uint32_t policyFlags) {
- int32_t keyEventAction, keyEventFlags;
- int32_t keyCode, scanCode, downTime;
- TouchResult touchResult;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Update surface size and orientation, including virtual key positions.
- if (! configureSurfaceLocked()) {
- return DROP_STROKE;
- }
-
- // Check for virtual key press.
- if (mLocked.currentVirtualKey.down) {
- if (mCurrentTouch.pointerCount == 0) {
- // Pointer went up while virtual key was down.
- mLocked.currentVirtualKey.down = false;
+bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
+ // Check for release of a virtual key.
+ if (mCurrentVirtualKey.down) {
+ if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer went up while virtual key was down.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
+ return true;
+ }
- if (mCurrentTouch.pointerCount == 1) {
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
- // Pointer is still within the space of the virtual key.
- return SKIP_TOUCH;
- }
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+ // Pointer is still within the space of the virtual key.
+ return true;
}
+ }
- // Pointer left virtual key area or another pointer also went down.
- // Send key cancellation and drop the stroke so subsequent motions will be
- // considered fresh downs. This is useful when the user swipes away from the
- // virtual key area into the main display surface.
- mLocked.currentVirtualKey.down = false;
+ // Pointer left virtual key area or another pointer also went down.
+ // Send key cancellation but do not consume the touch yet.
+ // This is useful when the user swipes through from the virtual key area
+ // into the main display surface.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
- | AKEY_EVENT_FLAG_CANCELED;
-
- // Check whether the pointer moved inside the display area where we should
- // start a new stroke.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (isPointInsideSurfaceLocked(x, y)) {
- mLastTouch.clear();
- touchResult = DISPATCH_TOUCH;
- } else {
- touchResult = DROP_STROKE;
- }
- } else {
- if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
- // Pointer just went down. Handle off-screen touches, if needed.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (! isPointInsideSurfaceLocked(x, y)) {
- // If exactly one pointer went down, check for virtual key hit.
- // Otherwise we will drop the entire stroke.
- if (mCurrentTouch.pointerCount == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey) {
- if (mContext->shouldDropVirtualKey(when, getDevice(),
- virtualKey->keyCode, virtualKey->scanCode)) {
- return DROP_STROKE;
- }
-
- mLocked.currentVirtualKey.down = true;
- mLocked.currentVirtualKey.downTime = when;
- mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
- mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+ | AKEY_EVENT_FLAG_CANCELED);
+ }
+ }
+
+ if (mLastRawPointerData.touchingIdBits.isEmpty()
+ && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer just went down. Check for virtual key press or off-screen touches.
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ if (!isPointInsideSurface(pointer.x, pointer.y)) {
+ // If exactly one pointer went down, check for virtual key hit.
+ // Otherwise we will drop the entire stroke.
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey) {
+ mCurrentVirtualKey.down = true;
+ mCurrentVirtualKey.downTime = when;
+ mCurrentVirtualKey.keyCode = virtualKey->keyCode;
+ mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+ mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
+ when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
+
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
- LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode,
- mLocked.currentVirtualKey.scanCode);
+ LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+ mCurrentVirtualKey.keyCode,
+ mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_DOWN;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
- | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
- }
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_DOWN,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
- return DROP_STROKE;
}
}
- return DISPATCH_TOUCH;
+ return true;
}
+ }
- DispatchVirtualKey:
- // Collect remaining state needed to dispatch virtual key.
- keyCode = mLocked.currentVirtualKey.keyCode;
- scanCode = mLocked.currentVirtualKey.scanCode;
- downTime = mLocked.currentVirtualKey.downTime;
- } // release lock
-
- // Dispatch virtual key.
- int32_t metaState = mContext->getGlobalMetaState();
- policyFlags |= POLICY_FLAG_VIRTUAL;
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
- return touchResult;
-}
-
-void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
// Disable all virtual key touches that happen within a short time interval of the
- // most recent touch. The idea is to filter out stray virtual key presses when
- // interacting with the touch screen.
+ // most recent touch within the screen area. The idea is to filter out stray
+ // virtual key presses when interacting with the touch screen.
//
// Problems we're trying to solve:
//
@@ -3407,37 +3442,44 @@ void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
// area and accidentally triggers a virtual key. This often happens when virtual keys
// are layed out below the screen near to where the on screen keyboard's space bar
// is displayed.
- if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+ if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
+ return false;
}
-void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
- if (currentPointerCount == 0 && lastPointerCount == 0) {
- return; // nothing to do!
- }
+void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags) {
+ int32_t keyCode = mCurrentVirtualKey.keyCode;
+ int32_t scanCode = mCurrentVirtualKey.scanCode;
+ nsecs_t downTime = mCurrentVirtualKey.downTime;
+ int32_t metaState = mContext->getGlobalMetaState();
+ policyFlags |= POLICY_FLAG_VIRTUAL;
- // Update current touch coordinates.
- float xPrecision, yPrecision;
- prepareTouches(&xPrecision, &yPrecision);
+ NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+ getListener()->notifyKey(&args);
+}
- // Dispatch motions.
- BitSet32 currentIdBits = mCurrentTouch.idBits;
- BitSet32 lastIdBits = mLastTouch.idBits;
+void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
+ BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
+ BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
if (currentIdBits == lastIdBits) {
- // No pointer id changes so this is a move event.
- // The dispatcher takes care of batching moves so we don't have to deal with that here.
- dispatchMotion(when, policyFlags, mTouchSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, currentIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ if (!currentIdBits.isEmpty()) {
+ // No pointer id changes so this is a move event.
+ // The listener takes care of batching moves so we don't have to deal with that here.
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ currentIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
} else {
// There may be pointers going up and pointers going down and pointers moving
// all at the same time.
@@ -3449,23 +3491,28 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
bool moveNeeded = updateMovedPointers(
- mCurrentTouchProperties, mCurrentTouchCoords, mCurrentTouch.idToIndex,
- mLastTouchProperties, mLastTouchCoords, mLastTouch.idToIndex,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
moveIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
// Dispatch pointer up events.
while (!upIdBits.isEmpty()) {
- uint32_t upId = upIdBits.firstMarkedBit();
- upIdBits.clearBit(upId);
+ uint32_t upId = upIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
- mLastTouchProperties, mLastTouchCoords,
- mLastTouch.idToIndex, dispatchedIdBits, upId,
- xPrecision, yPrecision, mDownTime);
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ dispatchedIdBits, upId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
dispatchedIdBits.clearBit(upId);
}
@@ -3476,15 +3523,16 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
LOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
// Dispatch pointer down events using the new pointer locations.
while (!downIdBits.isEmpty()) {
- uint32_t downId = downIdBits.firstMarkedBit();
- downIdBits.clearBit(downId);
+ uint32_t downId = downIdBits.clearFirstMarkedBit();
dispatchedIdBits.markBit(downId);
if (dispatchedIdBits.count() == 1) {
@@ -3494,49 +3542,88 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, downId,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, downId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
}
+}
- // Update state for next time.
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- mLastTouchProperties[i].copyFrom(mCurrentTouchProperties[i]);
- mLastTouchCoords[i].copyFrom(mCurrentTouchCoords[i]);
+void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
+ if (mSentHoverEnter &&
+ (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
+ || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ mLastCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = false;
}
}
-void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
+ if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
+ && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ if (!mSentHoverEnter) {
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = true;
+ }
- AutoMutex _l(mLock);
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
+}
+
+void TouchInputMapper::cookPointerData() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+
+ mCurrentCookedPointerData.clear();
+ mCurrentCookedPointerData.pointerCount = currentPointerCount;
+ mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
+ mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
- // Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display or surface coordinates (PointerCoords) and adjust for display orientation.
+ // Walk through the the active pointers and map device coordinates onto
+ // surface coordinates and adjust for display orientation.
for (uint32_t i = 0; i < currentPointerCount; i++) {
- const PointerData& in = mCurrentTouch.pointers[i];
+ const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
// ToolMajor and ToolMinor
float toolMajor, toolMinor;
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
- toolMajor = in.toolMajor * mLocked.geometricScale;
- if (mRawAxes.toolMinor.valid) {
- toolMinor = in.toolMinor * mLocked.geometricScale;
+ toolMajor = in.toolMajor * mGeometricScale;
+ if (mRawPointerAxes.toolMinor.valid) {
+ toolMinor = in.toolMinor * mGeometricScale;
} else {
toolMinor = toolMajor;
}
break;
case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
toolMajor = in.toolMajor != 0
- ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
+ ? in.toolMajor * mToolSizeLinearScale + mToolSizeLinearBias
: 0;
- if (mRawAxes.toolMinor.valid) {
+ if (mRawPointerAxes.toolMinor.valid) {
toolMinor = in.toolMinor != 0
- ? in.toolMinor * mLocked.toolSizeLinearScale
- + mLocked.toolSizeLinearBias
+ ? in.toolMinor * mToolSizeLinearScale
+ + mToolSizeLinearBias
: 0;
} else {
toolMinor = toolMajor;
@@ -3545,8 +3632,8 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
case Calibration::TOOL_SIZE_CALIBRATION_AREA:
if (in.toolMajor != 0) {
float diameter = sqrtf(in.toolMajor
- * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
- toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
+ * mToolSizeAreaScale + mToolSizeAreaBias);
+ toolMajor = diameter * mToolSizeLinearScale + mToolSizeLinearBias;
} else {
toolMajor = 0;
}
@@ -3559,8 +3646,9 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
}
if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
- toolMajor /= currentPointerCount;
- toolMinor /= currentPointerCount;
+ uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
+ toolMajor /= touchingCount;
+ toolMinor /= touchingCount;
}
// Pressure
@@ -3580,10 +3668,10 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
switch (mCalibration.pressureCalibration) {
case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
- pressure = rawPressure * mLocked.pressureScale;
+ pressure = rawPressure * mPressureScale;
break;
default:
- pressure = 1;
+ pressure = in.isHovering ? 0 : 1;
break;
}
@@ -3591,9 +3679,9 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float touchMajor, touchMinor;
switch (mCalibration.touchSizeCalibration) {
case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
- touchMajor = in.touchMajor * mLocked.geometricScale;
- if (mRawAxes.touchMinor.valid) {
- touchMinor = in.touchMinor * mLocked.geometricScale;
+ touchMajor = in.touchMajor * mGeometricScale;
+ if (mRawPointerAxes.touchMinor.valid) {
+ touchMinor = in.touchMinor * mGeometricScale;
} else {
touchMinor = touchMajor;
}
@@ -3619,10 +3707,10 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float size;
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_NORMALIZED: {
- float rawSize = mRawAxes.toolMinor.valid
+ float rawSize = mRawPointerAxes.toolMinor.valid
? avg(in.toolMajor, in.toolMinor)
: in.toolMajor;
- size = rawSize * mLocked.sizeScale;
+ size = rawSize * mSizeScale;
break;
}
default:
@@ -3634,7 +3722,7 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float orientation;
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
- orientation = in.orientation * mLocked.orientationScale;
+ orientation = in.orientation * mOrientationScale;
break;
case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
@@ -3659,7 +3747,7 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float distance;
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_SCALED:
- distance = in.distance * mLocked.distanceScale;
+ distance = in.distance * mDistanceScale;
break;
default:
distance = 0;
@@ -3668,35 +3756,35 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
// X and Y
// Adjust coords for surface orientation.
float x, y;
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
- y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
+ x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
+ y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
orientation -= M_PI_2;
if (orientation < - M_PI_2) {
orientation += M_PI;
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
- y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
+ x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
+ y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
- y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
+ x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
+ y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
orientation += M_PI_2;
if (orientation > M_PI_2) {
orientation -= M_PI;
}
break;
default:
- x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
- y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
+ x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
+ y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
break;
}
// Write output coords.
- PointerCoords& out = mCurrentTouchCoords[i];
+ PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
out.clear();
out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
@@ -3707,19 +3795,18 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
- if (distance != 0) {
- out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
- }
+ out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
// Write output properties.
- PointerProperties& properties = mCurrentTouchProperties[i];
+ PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
+ uint32_t id = in.id;
properties.clear();
- properties.id = mCurrentTouch.pointers[i].id;
- properties.toolType = mCurrentTouch.pointers[i].toolType;
- }
+ properties.id = id;
+ properties.toolType = in.toolType;
- *outXPrecision = mLocked.orientedXPrecision;
- *outYPrecision = mLocked.orientedYPrecision;
+ // Write id index.
+ mCurrentCookedPointerData.idToIndex[id] = i;
+ }
}
void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
@@ -3782,7 +3869,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
// Send events!
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
@@ -3803,7 +3890,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
movedGestureIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
}
@@ -3830,8 +3917,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
& ~mPointerGesture.currentGestureIdBits.value;
}
while (!upGestureIdBits.isEmpty()) {
- uint32_t id = upGestureIdBits.firstMarkedBit();
- upGestureIdBits.clearBit(id);
+ uint32_t id = upGestureIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mPointerSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0,
@@ -3861,8 +3947,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
& ~dispatchedGestureIdBits.value);
while (!downGestureIdBits.isEmpty()) {
- uint32_t id = downGestureIdBits.firstMarkedBit();
- downGestureIdBits.clearBit(id);
+ uint32_t id = downGestureIdBits.clearFirstMarkedBit();
dispatchedGestureIdBits.markBit(id);
if (dispatchedGestureIdBits.count() == 1) {
@@ -3906,10 +3991,11 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- getDispatcher()->notifyMotion(when, getDeviceId(), mPointerSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mPointerSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime);
+ getListener()->notifyMotion(&args);
}
// Update state.
@@ -3919,8 +4005,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
} else {
mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
mPointerGesture.lastGestureProperties[index].copyFrom(
mPointerGesture.currentGestureProperties[index]);
@@ -3936,8 +4021,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
*outCancelPreviousGesture = false;
*outFinishPreviousGesture = false;
- AutoMutex _l(mLock);
-
// Handle TAP timeout.
if (isTimeout) {
#if DEBUG_GESTURES
@@ -3973,16 +4056,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
{
VelocityTracker::Position positions[MAX_POINTERS];
uint32_t count = 0;
- for (BitSet32 idBits(mCurrentTouch.idBits); !idBits.isEmpty(); count++) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- uint32_t index = mCurrentTouch.idToIndex[id];
- positions[count].x = mCurrentTouch.pointers[index].x
- * mLocked.pointerGestureXMovementScale;
- positions[count].y = mCurrentTouch.pointers[index].y
- * mLocked.pointerGestureYMovementScale;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); count++) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ positions[count].x = pointer.x * mPointerGestureXMovementScale;
+ positions[count].y = pointer.y * mPointerGestureYMovementScale;
}
- mPointerGesture.velocityTracker.addMovement(when, mCurrentTouch.idBits, positions);
+ mPointerGesture.velocityTracker.addMovement(when,
+ mCurrentRawPointerData.touchingIdBits, positions);
}
// Pick a new active touch id if needed.
@@ -3994,20 +4075,25 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
int32_t activeTouchId = lastActiveTouchId;
if (activeTouchId < 0) {
- if (!mCurrentTouch.idBits.isEmpty()) {
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
activeTouchChanged = true;
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
mPointerGesture.firstTouchTime = when;
}
- } else if (!mCurrentTouch.idBits.hasBit(activeTouchId)) {
+ } else if (!mCurrentRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
activeTouchChanged = true;
- if (!mCurrentTouch.idBits.isEmpty()) {
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
} else {
activeTouchId = mPointerGesture.activeTouchId = -1;
}
}
+ uint32_t currentTouchingPointerCount = mCurrentRawPointerData.touchingIdBits.count();
+ uint32_t lastTouchingPointerCount = mLastRawPointerData.touchingIdBits.count();
+
// Determine whether we are in quiet time.
bool isQuietTime = false;
if (activeTouchId < 0) {
@@ -4018,14 +4104,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
|| mPointerGesture.lastGestureMode == PointerGesture::SWIPE
|| mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
- && mCurrentTouch.pointerCount < 2) {
+ && currentTouchingPointerCount < 2) {
// Enter quiet time when exiting swipe or freeform state.
// This is to prevent accidentally entering the hover state and flinging the
// pointer when finishing a swipe and there is still one pointer left onscreen.
isQuietTime = true;
} else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
- && mCurrentTouch.pointerCount >= 2
- && !isPointerDown(mCurrentTouch.buttonState)) {
+ && currentTouchingPointerCount >= 2
+ && !isPointerDown(mCurrentButtonState)) {
// Enter quiet time when releasing the button and there are still two or more
// fingers down. This may indicate that one finger was used to press the button
// but it has not gone up yet.
@@ -4053,7 +4139,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
- } else if (isPointerDown(mCurrentTouch.buttonState)) {
+ } else if (isPointerDown(mCurrentButtonState)) {
// Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
// The pointer follows the active touch point.
// Emit DOWN, MOVE, UP events at the pointer location.
@@ -4069,7 +4155,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// being dragged.
#if DEBUG_GESTURES
LOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
- "currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount);
+ "currentTouchingPointerCount=%d", activeTouchId, currentTouchingPointerCount);
#endif
// Reset state when just starting.
if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
@@ -4079,11 +4165,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Switch pointers if needed.
// Find the fastest pointer and follow it.
- if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) {
+ if (activeTouchId >= 0 && currentTouchingPointerCount > 1) {
int32_t bestId = -1;
float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t id = mCurrentTouch.pointers[i].id;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
float vx, vy;
if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
float speed = hypotf(vx, vy);
@@ -4103,17 +4189,15 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
- if (activeTouchId >= 0 && mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
- float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
- float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ if (activeTouchId >= 0 && mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
+ float deltaX = (currentPointer.x - lastPointer.x) * mPointerGestureXMovementScale;
+ float deltaY = (currentPointer.y - lastPointer.y) * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4138,7 +4222,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- } else if (mCurrentTouch.pointerCount == 0) {
+ } else if (currentTouchingPointerCount == 0) {
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
*outFinishPreviousGesture = true;
@@ -4149,7 +4233,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
bool tapped = false;
if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
|| mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
- && mLastTouch.pointerCount == 1) {
+ && lastTouchingPointerCount == 1) {
if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
float x, y;
mPointerController->getPosition(&x, &y);
@@ -4209,7 +4293,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
mPointerGesture.currentGestureIdBits.clear();
}
- } else if (mCurrentTouch.pointerCount == 1) {
+ } else if (currentTouchingPointerCount == 1) {
// Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
// The pointer follows the active touch point.
// When in HOVER, emit HOVER_MOVE events at the pointer location.
@@ -4241,17 +4325,17 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
}
- if (mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
+ if (mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
+ * mPointerGestureXMovementScale;
float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4294,7 +4378,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
down ? 1.0f : 0.0f);
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (lastTouchingPointerCount == 0 && currentTouchingPointerCount != 0) {
mPointerGesture.resetTap();
mPointerGesture.tapDownTime = when;
mPointerGesture.tapX = x;
@@ -4322,7 +4406,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
&& mPointerGesture.lastGestureMode != PointerGesture::SWIPE
&& mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
*outFinishPreviousGesture = true;
- } else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) {
+ } else if (!settled && currentTouchingPointerCount > lastTouchingPointerCount) {
// Additional pointers have gone down but not yet settled.
// Reset the gesture.
#if DEBUG_GESTURES
@@ -4350,33 +4434,31 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
+ mConfig.pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
- mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
+ mCurrentRawPointerData.getCentroidOfTouchingPointers(
+ &mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
mPointerController->getPosition(&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);
}
// Clear the reference deltas for fingers not yet included in the reference calculation.
- for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value);
- !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits.value
+ & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
mPointerGesture.referenceDeltas[id].dx = 0;
mPointerGesture.referenceDeltas[id].dy = 0;
}
- mPointerGesture.referenceIdBits = mCurrentTouch.idBits;
+ mPointerGesture.referenceIdBits = mCurrentRawPointerData.touchingIdBits;
// Add delta for all fingers and calculate a common movement delta.
float commonDeltaX = 0, commonDeltaY = 0;
- BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value);
+ BitSet32 commonIdBits(mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value);
for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
bool first = (idBits == commonIdBits);
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
- const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]];
- const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]];
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
+ const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx += cpd.x - lpd.x;
delta.dy += cpd.y - lpd.y;
@@ -4395,12 +4477,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
float dist[MAX_POINTER_ID + 1];
int32_t distOverThreshold = 0;
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale,
- delta.dy * mLocked.pointerGestureYZoomScale);
+ dist[id] = hypotf(delta.dx * mPointerGestureXZoomScale,
+ delta.dy * mPointerGestureYZoomScale);
if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
distOverThreshold += 1;
}
@@ -4409,71 +4489,74 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Only transition when at least two pointers have moved further than
// the minimum distance threshold.
if (distOverThreshold >= 2) {
- float d;
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
// There are more than two pointers, switch to FREEFORM.
#if DEBUG_GESTURES
LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else if (((d = distance(
- mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y,
- mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y))
- > mLocked.pointerGestureMaxSwipeWidth)) {
- // There are two pointers but they are too far apart for a SWIPE,
- // switch to FREEFORM.
+ } else {
+ // There are exactly two pointers.
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ uint32_t id1 = idBits.clearFirstMarkedBit();
+ uint32_t id2 = idBits.firstMarkedBit();
+ const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
+ const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
+ float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
+ if (mutualDistance > mPointerGestureMaxSwipeWidth) {
+ // There are two pointers but they are too far apart for a SWIPE,
+ // switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
- d, mLocked.pointerGestureMaxSwipeWidth);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
+ mutualDistance, mPointerGestureMaxSwipeWidth);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else {
- // There are two pointers. Wait for both pointers to start moving
- // before deciding whether this is a SWIPE or FREEFORM gesture.
- uint32_t id1 = mCurrentTouch.pointers[0].id;
- uint32_t id2 = mCurrentTouch.pointers[1].id;
- float dist1 = dist[id1];
- float dist2 = dist[id2];
- if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
- && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
- // Calculate the dot product of the displacement vectors.
- // When the vectors are oriented in approximately the same direction,
- // the angle betweeen them is near zero and the cosine of the angle
- // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
- PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
- PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
- float dx1 = delta1.dx * mLocked.pointerGestureXZoomScale;
- float dy1 = delta1.dy * mLocked.pointerGestureYZoomScale;
- float dx2 = delta2.dx * mLocked.pointerGestureXZoomScale;
- float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale;
- float dot = dx1 * dx2 + dy1 * dy2;
- float cosine = dot / (dist1 * dist2); // denominator always > 0
- if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
- // Pointers are moving in the same direction. Switch to SWIPE.
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ } else {
+ // There are two pointers. Wait for both pointers to start moving
+ // before deciding whether this is a SWIPE or FREEFORM gesture.
+ float dist1 = dist[id1];
+ float dist2 = dist[id2];
+ if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
+ && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
+ // Calculate the dot product of the displacement vectors.
+ // When the vectors are oriented in approximately the same direction,
+ // the angle betweeen them is near zero and the cosine of the angle
+ // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
+ PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
+ PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
+ float dx1 = delta1.dx * mPointerGestureXZoomScale;
+ float dy1 = delta1.dy * mPointerGestureYZoomScale;
+ float dx2 = delta2.dx * mPointerGestureXZoomScale;
+ float dy2 = delta2.dy * mPointerGestureYZoomScale;
+ float dot = dx1 * dx2 + dy1 * dy2;
+ float cosine = dot / (dist1 * dist2); // denominator always > 0
+ if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
+ // Pointers are moving in the same direction. Switch to SWIPE.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to SWIPE, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f >= %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+ LOGD("Gestures: PRESS transitioned to SWIPE, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f >= %0.3f",
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
#endif
- mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
- } else {
- // Pointers are moving in different directions. Switch to FREEFORM.
+ mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
+ } else {
+ // Pointers are moving in different directions. Switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, "
- "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
- "cosine %0.3f < %0.3f",
- dist1, mConfig.pointerGestureMultitouchMinDistance,
- dist2, mConfig.pointerGestureMultitouchMinDistance,
- cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, "
+ "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
+ "cosine %0.3f < %0.3f",
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ }
}
}
}
@@ -4481,10 +4564,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
} else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
// Switch from SWIPE to FREEFORM if additional pointers go down.
// Cancel previous gesture.
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
#if DEBUG_GESTURES
LOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
@@ -4496,9 +4579,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
&& (commonDeltaX || commonDeltaY)) {
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx = 0;
delta.dy = 0;
@@ -4507,10 +4588,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.referenceTouchX += commonDeltaX;
mPointerGesture.referenceTouchY += commonDeltaY;
- commonDeltaX *= mLocked.pointerGestureXMovementScale;
- commonDeltaY *= mLocked.pointerGestureYMovementScale;
+ commonDeltaX *= mPointerGestureXMovementScale;
+ commonDeltaY *= mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &commonDeltaX, &commonDeltaY);
+ rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
mPointerGesture.referenceGestureX += commonDeltaX;
@@ -4524,7 +4605,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4546,7 +4627,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4568,15 +4649,16 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
} else {
// Otherwise, assume we mapped all touches from the previous frame.
// Reuse all mappings that are still applicable.
- mappedTouchIdBits.value = mLastTouch.idBits.value & mCurrentTouch.idBits.value;
+ mappedTouchIdBits.value = mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value;
usedGestureIdBits = mPointerGesture.lastGestureIdBits;
// Check whether we need to choose a new active gesture id because the
// current went went up.
- for (BitSet32 upTouchIdBits(mLastTouch.idBits.value & ~mCurrentTouch.idBits.value);
+ for (BitSet32 upTouchIdBits(mLastRawPointerData.touchingIdBits.value
+ & ~mCurrentRawPointerData.touchingIdBits.value);
!upTouchIdBits.isEmpty(); ) {
- uint32_t upTouchId = upTouchIdBits.firstMarkedBit();
- upTouchIdBits.clearBit(upTouchId);
+ uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
mPointerGesture.activeGestureId = -1;
@@ -4593,12 +4675,12 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.activeGestureId);
#endif
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t touchId = mCurrentTouch.pointers[i].id;
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ for (uint32_t i = 0; i < currentTouchingPointerCount; i++) {
+ uint32_t touchId = idBits.clearFirstMarkedBit();
uint32_t gestureId;
if (!mappedTouchIdBits.hasBit(touchId)) {
- gestureId = usedGestureIdBits.firstUnmarkedBit();
- usedGestureIdBits.markBit(gestureId);
+ gestureId = usedGestureIdBits.markFirstUnmarkedBit();
mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM "
@@ -4616,11 +4698,13 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureIdBits.markBit(gestureId);
mPointerGesture.currentGestureIdToIndex[gestureId] = i;
- float deltaX = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX)
- * mLocked.pointerGestureXZoomScale;
- float deltaY = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY)
- * mLocked.pointerGestureYZoomScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ const RawPointerData::Pointer& pointer =
+ mCurrentRawPointerData.pointerForId(touchId);
+ float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
+ * mPointerGestureXZoomScale;
+ float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
+ * mPointerGestureYZoomScale;
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.currentGestureProperties[i].clear();
mPointerGesture.currentGestureProperties[i].id = gestureId;
@@ -4646,7 +4730,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
- mPointerController->setButtonState(mCurrentTouch.buttonState);
+ mPointerController->setButtonState(mCurrentButtonState);
#if DEBUG_GESTURES
LOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
@@ -4656,8 +4740,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
@@ -4669,8 +4752,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
}
for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
@@ -4694,8 +4776,7 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = idToIndex[id];
pointerProperties[pointerCount].copyFrom(properties[index]);
pointerCoords[pointerCount].copyFrom(coords[index]);
@@ -4723,9 +4804,10 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
}
}
- getDispatcher()->notifyMotion(when, getDeviceId(), source, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
action, flags, metaState, buttonState, edgeFlags,
pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
+ getListener()->notifyMotion(&args);
}
bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
@@ -4734,9 +4816,7 @@ bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties
BitSet32 idBits) const {
bool changed = false;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t inIndex = inIdToIndex[id];
uint32_t outIndex = outIdToIndex[id];
@@ -4759,24 +4839,21 @@ bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties
}
void TouchInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
-bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
- return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
- && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
+bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+ return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
}
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
int32_t x, int32_t y) {
- size_t numVirtualKeys = mLocked.virtualKeys.size();
+ size_t numVirtualKeys = mVirtualKeys.size();
for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+ const VirtualKey& virtualKey = mVirtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -4795,43 +4872,59 @@ const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
return NULL;
}
-void TouchInputMapper::calculatePointerIds() {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::assignPointerIds() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+ uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
+
+ mCurrentRawPointerData.clearIdBits();
if (currentPointerCount == 0) {
// No pointers to assign.
- mCurrentTouch.idBits.clear();
- } else if (lastPointerCount == 0) {
+ return;
+ }
+
+ if (lastPointerCount == 0) {
// All pointers are new.
- mCurrentTouch.idBits.clear();
for (uint32_t i = 0; i < currentPointerCount; i++) {
- mCurrentTouch.pointers[i].id = i;
- mCurrentTouch.idToIndex[i] = i;
- mCurrentTouch.idBits.markBit(i);
+ uint32_t id = i;
+ mCurrentRawPointerData.pointers[i].id = id;
+ mCurrentRawPointerData.idToIndex[id] = i;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
}
- } else if (currentPointerCount == 1 && lastPointerCount == 1) {
+ return;
+ }
+
+ if (currentPointerCount == 1 && lastPointerCount == 1
+ && mCurrentRawPointerData.pointers[0].toolType
+ == mLastRawPointerData.pointers[0].toolType) {
// Only one pointer and no change in count so it must have the same id as before.
- uint32_t id = mLastTouch.pointers[0].id;
- mCurrentTouch.pointers[0].id = id;
- mCurrentTouch.idToIndex[id] = 0;
- mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
- } else {
- // General case.
- // We build a heap of squared euclidean distances between current and last pointers
- // associated with the current and last pointer indices. Then, we find the best
- // match (by distance) for each current pointer.
- PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
-
- uint32_t heapSize = 0;
- for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
- currentPointerIndex++) {
- for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
- lastPointerIndex++) {
- int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
- - mLastTouch.pointers[lastPointerIndex].x;
- int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
- - mLastTouch.pointers[lastPointerIndex].y;
+ uint32_t id = mLastRawPointerData.pointers[0].id;
+ mCurrentRawPointerData.pointers[0].id = id;
+ mCurrentRawPointerData.idToIndex[id] = 0;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
+ return;
+ }
+
+ // General case.
+ // We build a heap of squared euclidean distances between current and last pointers
+ // associated with the current and last pointer indices. Then, we find the best
+ // match (by distance) for each current pointer.
+ // The pointers must have the same tool type but it is possible for them to
+ // transition from hovering to touching or vice-versa while retaining the same id.
+ PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+
+ uint32_t heapSize = 0;
+ for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+ currentPointerIndex++) {
+ for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+ lastPointerIndex++) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointers[currentPointerIndex];
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointers[lastPointerIndex];
+ if (currentPointer.toolType == lastPointer.toolType) {
+ int64_t deltaX = currentPointer.x - lastPointer.x;
+ int64_t deltaY = currentPointer.y - lastPointer.y;
uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
@@ -4842,193 +4935,174 @@ void TouchInputMapper::calculatePointerIds() {
heapSize += 1;
}
}
+ }
- // Heapify
- for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
- startIndex -= 1;
- for (uint32_t parentIndex = startIndex; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
+ // Heapify
+ for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
+ startIndex -= 1;
+ for (uint32_t parentIndex = startIndex; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
+ break;
+ }
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
}
+
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
}
+ }
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
+ LOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
+ }
#endif
- // Pull matches out by increasing order of distance.
- // To avoid reassigning pointers that have already been matched, the loop keeps track
- // of which last and current pointers have been matched using the matchedXXXBits variables.
- // It also tracks the used pointer id bits.
- BitSet32 matchedLastBits(0);
- BitSet32 matchedCurrentBits(0);
- BitSet32 usedIdBits(0);
- bool first = true;
- for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
- for (;;) {
- if (first) {
- // The first time through the loop, we just consume the root element of
- // the heap (the one with smallest distance).
- first = false;
- } else {
- // Previous iterations consumed the root element of the heap.
- // Pop root element off of the heap (sift down).
- heapSize -= 1;
- LOG_ASSERT(heapSize > 0);
-
- // Sift down.
- heap[0] = heap[heapSize];
- for (uint32_t parentIndex = 0; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
+ // Pull matches out by increasing order of distance.
+ // To avoid reassigning pointers that have already been matched, the loop keeps track
+ // of which last and current pointers have been matched using the matchedXXXBits variables.
+ // It also tracks the used pointer id bits.
+ BitSet32 matchedLastBits(0);
+ BitSet32 matchedCurrentBits(0);
+ BitSet32 usedIdBits(0);
+ bool first = true;
+ for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
+ while (heapSize > 0) {
+ if (first) {
+ // The first time through the loop, we just consume the root element of
+ // the heap (the one with smallest distance).
+ first = false;
+ } else {
+ // Previous iterations consumed the root element of the heap.
+ // Pop root element off of the heap (sift down).
+ heap[0] = heap[heapSize];
+ for (uint32_t parentIndex = 0; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
+ break;
+ }
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
}
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
+ }
+
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
+ LOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
}
+#endif
+ }
- uint32_t currentPointerIndex = heap[0].currentPointerIndex;
- if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+ heapSize -= 1;
- uint32_t lastPointerIndex = heap[0].lastPointerIndex;
- if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+ uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+ if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
- matchedCurrentBits.markBit(currentPointerIndex);
- matchedLastBits.markBit(lastPointerIndex);
+ uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+ if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
- uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
+ matchedCurrentBits.markBit(currentPointerIndex);
+ matchedLastBits.markBit(lastPointerIndex);
+
+ uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
+ usedIdBits.markBit(id);
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
- lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+ LOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+ lastPointerIndex, currentPointerIndex, id, heap[0].distance);
#endif
- break;
- }
+ break;
}
+ }
- // Assign fresh ids to new pointers.
- if (currentPointerCount > lastPointerCount) {
- for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
- uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
- uint32_t id = usedIdBits.firstUnmarkedBit();
+ // Assign fresh ids to pointers that were not matched in the process.
+ for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
+ uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
+ uint32_t id = usedIdBits.markFirstUnmarkedBit();
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
- currentPointerIndex, id);
+ LOGD("assignPointerIds - assigned: cur=%d, id=%d",
+ currentPointerIndex, id);
#endif
-
- if (--i == 0) break; // done
- matchedCurrentBits.markBit(currentPointerIndex);
- }
- }
-
- // Fix id bits.
- mCurrentTouch.idBits = usedIdBits;
}
}
int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
- return AKEY_STATE_VIRTUAL;
- }
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.keyCode == keyCode) {
- return AKEY_STATE_UP;
- }
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.keyCode == keyCode) {
+ return AKEY_STATE_UP;
}
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
- return AKEY_STATE_VIRTUAL;
- }
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.scanCode == scanCode) {
- return AKEY_STATE_UP;
- }
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.scanCode == scanCode) {
+ return AKEY_STATE_UP;
}
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
- for (size_t i = 0; i < numCodes; i++) {
- if (virtualKey.keyCode == keyCodes[i]) {
- outFlags[i] = 1;
- }
+ for (size_t i = 0; i < numCodes; i++) {
+ if (virtualKey.keyCode == keyCodes[i]) {
+ outFlags[i] = 1;
}
}
- } // release lock
+ }
return true;
}
@@ -5067,21 +5141,18 @@ void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
}
void SingleTouchInputMapper::sync(nsecs_t when) {
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
if (mTouchButtonAccumulator.isActive()) {
- uint32_t buttonState = mTouchButtonAccumulator.getButtonState();
- bool isHovering = mTouchButtonAccumulator.isHovering();
- if (mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0) {
- isHovering = true;
- }
+ mCurrentRawPointerData.pointerCount = 1;
+ mCurrentRawPointerData.idToIndex[0] = 0;
- mCurrentTouch.pointerCount = 1;
- mCurrentTouch.idToIndex[0] = 0;
- mCurrentTouch.idBits.markBit(0);
- mCurrentTouch.buttonState = buttonState;
+ bool isHovering = mTouchButtonAccumulator.isHovering()
+ || mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0;
+ mCurrentRawPointerData.markIdBit(0, isHovering);
- PointerData& outPointer = mCurrentTouch.pointers[0];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
outPointer.id = 0;
outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
@@ -5097,21 +5168,24 @@ void SingleTouchInputMapper::sync(nsecs_t when) {
outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
}
outPointer.isHovering = isHovering;
+
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
}
syncTouch(when, true);
}
-void SingleTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void SingleTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_DISTANCE, & mRawAxes.distance);
+ getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
}
@@ -5172,8 +5246,9 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
size_t outCount = 0;
bool havePointerIds = true;
+ BitSet32 newPointerIdBits;
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
const MultiTouchMotionAccumulator::Slot* inSlot =
@@ -5191,7 +5266,7 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
break; // too many fingers!
}
- PointerData& outPointer = mCurrentTouch.pointers[outCount];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
outPointer.x = inSlot->getX();
outPointer.y = inSlot->getY();
outPointer.pressure = inSlot->getPressure();
@@ -5210,8 +5285,9 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
}
}
- outPointer.isHovering = mTouchButtonAccumulator.isHovering()
+ bool isHovering = mTouchButtonAccumulator.isHovering()
|| inSlot->getDistance() > 0;
+ outPointer.isHovering = isHovering;
// Assign pointer id using tracking id if available.
if (havePointerIds) {
@@ -5219,37 +5295,37 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
int32_t id = -1;
if (trackingId >= 0) {
for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
- uint32_t n = idBits.firstMarkedBit();
- idBits.clearBit(n);
-
+ uint32_t n = idBits.clearFirstMarkedBit();
if (mPointerTrackingIdMap[n] == trackingId) {
id = n;
}
}
if (id < 0 && !mPointerIdBits.isFull()) {
- id = mPointerIdBits.firstUnmarkedBit();
- mPointerIdBits.markBit(id);
+ id = mPointerIdBits.markFirstUnmarkedBit();
mPointerTrackingIdMap[id] = trackingId;
}
}
if (id < 0) {
havePointerIds = false;
- mCurrentTouch.idBits.clear();
+ mCurrentRawPointerData.clearIdBits();
+ newPointerIdBits.clear();
} else {
outPointer.id = id;
- mCurrentTouch.idToIndex[id] = outCount;
- mCurrentTouch.idBits.markBit(id);
+ mCurrentRawPointerData.idToIndex[id] = outCount;
+ mCurrentRawPointerData.markIdBit(id, isHovering);
+ newPointerIdBits.markBit(id);
}
}
outCount += 1;
}
- mCurrentTouch.pointerCount = outCount;
- mCurrentTouch.buttonState = mTouchButtonAccumulator.getButtonState();
+ mCurrentRawPointerData.pointerCount = outCount;
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
- mPointerIdBits = mCurrentTouch.idBits;
+ mPointerIdBits = newPointerIdBits;
syncTouch(when, havePointerIds);
@@ -5258,26 +5334,27 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
}
}
-void MultiTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void MultiTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, &mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, &mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, &mRawAxes.touchMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, &mRawAxes.touchMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, &mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, &mRawAxes.toolMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, &mRawAxes.orientation);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, &mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_DISTANCE, &mRawAxes.distance);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TRACKING_ID, &mRawAxes.trackingId);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_SLOT, &mRawAxes.slot);
-
- if (mRawAxes.trackingId.valid
- && mRawAxes.slot.valid && mRawAxes.slot.minValue == 0 && mRawAxes.slot.maxValue > 0) {
- size_t slotCount = mRawAxes.slot.maxValue + 1;
+ getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
+ getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
+ getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
+ getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
+ getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
+
+ if (mRawPointerAxes.trackingId.valid
+ && mRawPointerAxes.slot.valid
+ && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
+ size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
if (slotCount > MAX_SLOTS) {
LOGW("MultiTouch Device %s reported %d slots but the framework "
"only supports a maximum of %d slots at this time.",
@@ -5364,7 +5441,7 @@ void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint
// Collect all axes.
for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
RawAbsoluteAxisInfo rawAxisInfo;
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ getAbsoluteAxisInfo(abs, &rawAxisInfo);
if (rawAxisInfo.valid) {
// Map axis.
AxisInfo axisInfo;
@@ -5581,9 +5658,10 @@ void JoystickInputMapper::sync(nsecs_t when, bool force) {
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, 0);
+ getListener()->notifyMotion(&args);
}
bool JoystickInputMapper::filterAxes(bool force) {
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index ee6990b..f5d095d 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -18,8 +18,8 @@
#define _UI_INPUT_READER_H
#include "EventHub.h"
-#include "InputDispatcher.h"
#include "PointerController.h"
+#include "InputListener.h"
#include <ui/Input.h>
#include <ui/DisplayInfo.h>
@@ -164,6 +164,9 @@ struct InputReaderConfiguration {
*
* The actual implementation is partially supported by callbacks into the DVM
* via JNI. This interface is also mocked in the unit tests.
+ *
+ * These methods must NOT re-enter the input reader since they may be called while
+ * holding the input reader lock.
*/
class InputReaderPolicyInterface : public virtual RefBase {
protected:
@@ -195,7 +198,7 @@ public:
};
-/* Processes raw input events and sends cooked event data to an input dispatcher. */
+/* Processes raw input events and sends cooked event data to an input listener. */
class InputReaderInterface : public virtual RefBase {
protected:
InputReaderInterface() { }
@@ -270,25 +273,27 @@ public:
virtual void requestTimeoutAtTime(nsecs_t when) = 0;
virtual InputReaderPolicyInterface* getPolicy() = 0;
- virtual InputDispatcherInterface* getDispatcher() = 0;
+ virtual InputListenerInterface* getListener() = 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
+ * that it sends to the input listener. 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.
+ * The InputReader owns a collection of InputMappers. Most of the work it does happens
+ * on the input reader thread but the InputReader can receive queries from other system
+ * components running on arbitrary threads. To keep things manageable, the InputReader
+ * uses a single Mutex to guard its state. The Mutex may be held while calling into the
+ * EventHub or the InputReaderPolicy but it is never held while calling into the
+ * InputListener.
*/
-class InputReader : public InputReaderInterface, protected InputReaderContext {
+class InputReader : public InputReaderInterface {
public:
InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher);
+ const sp<InputListenerInterface>& listener);
virtual ~InputReader();
virtual void dump(String8& dump);
@@ -313,74 +318,80 @@ public:
virtual void requestRefreshConfiguration(uint32_t changes);
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);
+ // These members are protected so they can be instrumented by test cases.
+ virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes);
+
+ class ContextImpl : public InputReaderContext {
+ InputReader* mReader;
+
+ public:
+ ContextImpl(InputReader* reader);
+
+ virtual void updateGlobalMetaState();
+ virtual int32_t getGlobalMetaState();
+ virtual void disableVirtualKeysUntil(nsecs_t time);
+ virtual bool shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode);
+ virtual void fadePointer();
+ virtual void requestTimeoutAtTime(nsecs_t when);
+ virtual InputReaderPolicyInterface* getPolicy();
+ virtual InputListenerInterface* getListener();
+ virtual EventHubInterface* getEventHub();
+ } mContext;
+
+ friend class ContextImpl;
private:
+ Mutex mLock;
+
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
- sp<InputDispatcherInterface> mDispatcher;
+ sp<QueuedInputListener> mQueuedListener;
InputReaderConfiguration mConfig;
- virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
- virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
- virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
-
// The event queue.
static const int EVENT_BUFFER_SIZE = 256;
RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
- // 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 processEvents(const RawEvent* rawEvents, size_t count);
+ void processEventsLocked(const RawEvent* rawEvents, size_t count);
- void addDevice(int32_t deviceId);
- void removeDevice(int32_t deviceId);
- void processEventsForDevice(int32_t deviceId, const RawEvent* rawEvents, size_t count);
- void timeoutExpired(nsecs_t when);
+ void addDeviceLocked(int32_t deviceId);
+ void removeDeviceLocked(int32_t deviceId);
+ void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
+ void timeoutExpiredLocked(nsecs_t when);
- void handleConfigurationChanged(nsecs_t when);
+ void handleConfigurationChangedLocked(nsecs_t when);
- // state management for all devices
- Mutex mStateLock;
+ int32_t mGlobalMetaState;
+ void updateGlobalMetaStateLocked();
+ int32_t getGlobalMetaStateLocked();
- int32_t mGlobalMetaState; // guarded by mStateLock
- virtual void updateGlobalMetaState();
- virtual int32_t getGlobalMetaState();
+ void fadePointerLocked();
- virtual void fadePointer();
-
- InputConfiguration mInputConfiguration; // guarded by mStateLock
- void updateInputConfiguration();
+ InputConfiguration mInputConfiguration;
+ void updateInputConfigurationLocked();
- nsecs_t mDisableVirtualKeysTimeout; // only accessed by reader thread
- virtual void disableVirtualKeysUntil(nsecs_t time);
- virtual bool shouldDropVirtualKey(nsecs_t now,
+ nsecs_t mDisableVirtualKeysTimeout;
+ void disableVirtualKeysUntilLocked(nsecs_t time);
+ bool shouldDropVirtualKeyLocked(nsecs_t now,
InputDevice* device, int32_t keyCode, int32_t scanCode);
- nsecs_t mNextTimeout; // only accessed by reader thread, not guarded
- virtual void requestTimeoutAtTime(nsecs_t when);
+ nsecs_t mNextTimeout;
+ void requestTimeoutAtTimeLocked(nsecs_t when);
- uint32_t mConfigurationChangesToRefresh; // guarded by mStateLock
- void refreshConfiguration(uint32_t changes);
+ uint32_t mConfigurationChangesToRefresh;
+ void refreshConfigurationLocked(uint32_t changes);
// 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,
+ int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc);
- bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+ bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags);
};
@@ -530,6 +541,93 @@ private:
};
+/* Raw axis information from the driver. */
+struct RawPointerAxes {
+ RawAbsoluteAxisInfo x;
+ RawAbsoluteAxisInfo y;
+ RawAbsoluteAxisInfo pressure;
+ RawAbsoluteAxisInfo touchMajor;
+ RawAbsoluteAxisInfo touchMinor;
+ RawAbsoluteAxisInfo toolMajor;
+ RawAbsoluteAxisInfo toolMinor;
+ RawAbsoluteAxisInfo orientation;
+ RawAbsoluteAxisInfo distance;
+ RawAbsoluteAxisInfo trackingId;
+ RawAbsoluteAxisInfo slot;
+
+ RawPointerAxes();
+ void clear();
+};
+
+
+/* Raw data for a collection of pointers including a pointer id mapping table. */
+struct RawPointerData {
+ struct Pointer {
+ 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;
+ int32_t distance;
+ int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
+ bool isHovering;
+ };
+
+ uint32_t pointerCount;
+ Pointer pointers[MAX_POINTERS];
+ BitSet32 hoveringIdBits, touchingIdBits;
+ uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+ RawPointerData();
+ void clear();
+ void copyFrom(const RawPointerData& other);
+ void getCentroidOfTouchingPointers(float* outX, float* outY) const;
+
+ inline void markIdBit(uint32_t id, bool isHovering) {
+ if (isHovering) {
+ hoveringIdBits.markBit(id);
+ } else {
+ touchingIdBits.markBit(id);
+ }
+ }
+
+ inline void clearIdBits() {
+ hoveringIdBits.clear();
+ touchingIdBits.clear();
+ }
+
+ inline const Pointer& pointerForId(uint32_t id) const {
+ return pointers[idToIndex[id]];
+ }
+
+ inline bool isHovering(uint32_t pointerIndex) {
+ return pointers[pointerIndex].isHovering;
+ }
+};
+
+
+/* Cooked data for a collection of pointers including a pointer id mapping table. */
+struct CookedPointerData {
+ uint32_t pointerCount;
+ PointerProperties pointerProperties[MAX_POINTERS];
+ PointerCoords pointerCoords[MAX_POINTERS];
+ BitSet32 hoveringIdBits, touchingIdBits;
+ uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+ CookedPointerData();
+ void clear();
+ void copyFrom(const CookedPointerData& other);
+
+ inline bool isHovering(uint32_t pointerIndex) {
+ return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
+ }
+};
+
+
/* Keeps track of the state of single-touch protocol. */
class SingleTouchMotionAccumulator {
public:
@@ -590,8 +688,8 @@ public:
int32_t mAbsMTOrientation;
int32_t mAbsMTTrackingId;
int32_t mAbsMTPressure;
- int32_t mAbsMTToolType;
int32_t mAbsMTDistance;
+ int32_t mAbsMTToolType;
Slot();
void clearIfInUse();
@@ -632,7 +730,7 @@ public:
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 InputListenerInterface* getListener() { return mContext->getListener(); }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
virtual uint32_t getSources() = 0;
@@ -657,6 +755,8 @@ protected:
InputDevice* mDevice;
InputReaderContext* mContext;
+ status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
+
static void dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name);
};
@@ -707,27 +807,25 @@ private:
uint32_t mSource;
int32_t mKeyboardType;
+ Vector<KeyDown> mKeyDowns; // keys that are down
+ int32_t mMetaState;
+ nsecs_t mDownTime; // time of most recent key down
+
+ struct LedState {
+ bool avail; // led is available
+ bool on; // we think the led is currently on
+ };
+ LedState mCapsLockLedState;
+ LedState mNumLockLedState;
+ LedState mScrollLockLedState;
+
// 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 initialize();
void configureParameters();
void dumpParameters(String8& dump);
@@ -737,12 +835,12 @@ private:
void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
uint32_t policyFlags);
- ssize_t findKeyDownLocked(int32_t scanCode);
+ ssize_t findKeyDown(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,
+ void resetLedState();
+ void initializeLedState(LedState& ledState, int32_t led);
+ void updateLedState(bool reset);
+ void updateLedStateForModifier(LedState& ledState, int32_t led,
int32_t modifier, bool reset);
};
@@ -767,8 +865,6 @@ 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 {
@@ -801,12 +897,10 @@ private:
sp<PointerControllerInterface> mPointerController;
- struct LockedState {
- int32_t buttonState;
- nsecs_t downTime;
- } mLocked;
+ int32_t mButtonState;
+ nsecs_t mDownTime;
- void initializeLocked();
+ void initialize();
void configureParameters();
void dumpParameters(String8& dump);
@@ -835,8 +929,6 @@ public:
virtual void timeoutExpired(nsecs_t when);
protected:
- Mutex mLock;
-
struct VirtualKey {
int32_t keyCode;
int32_t scanCode;
@@ -853,82 +945,6 @@ protected:
}
};
- // 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;
- int32_t distance;
- int32_t toolType; // AMOTION_EVENT_TOOL_TYPE constant
- bool isHovering;
-
- 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
- && distance == other.distance
- && toolType == other.toolType
- && isHovering == other.isHovering;
- }
- 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];
- int32_t buttonState;
-
- void copyFrom(const TouchData& other) {
- pointerCount = other.pointerCount;
- idBits = other.idBits;
- buttonState = other.buttonState;
-
- 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();
- buttonState = 0;
- }
-
- void getCentroid(float* outX, float* outY) {
- float x = 0, y = 0;
- if (pointerCount != 0) {
- for (uint32_t i = 0; i < pointerCount; i++) {
- x += pointers[i].x;
- y += pointers[i].y;
- }
- x /= pointerCount;
- y /= pointerCount;
- }
- *outX = x;
- *outY = y;
- }
- };
-
// Input sources supported by the device.
uint32_t mTouchSource; // sources when reporting touch data
uint32_t mPointerSource; // sources when reporting pointer gestures
@@ -1038,29 +1054,23 @@ protected:
float distanceScale;
} 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;
- RawAbsoluteAxisInfo distance;
- RawAbsoluteAxisInfo trackingId;
- RawAbsoluteAxisInfo slot;
- } mRawAxes;
-
- // Current and previous touch sample data.
- TouchData mCurrentTouch;
- PointerProperties mCurrentTouchProperties[MAX_POINTERS];
- PointerCoords mCurrentTouchCoords[MAX_POINTERS];
-
- TouchData mLastTouch;
- PointerProperties mLastTouchProperties[MAX_POINTERS];
- PointerCoords mLastTouchCoords[MAX_POINTERS];
+ // Raw pointer axis information from the driver.
+ RawPointerAxes mRawPointerAxes;
+
+ // Raw pointer sample data.
+ RawPointerData mCurrentRawPointerData;
+ RawPointerData mLastRawPointerData;
+
+ // Cooked pointer sample data.
+ CookedPointerData mCurrentCookedPointerData;
+ CookedPointerData mLastCookedPointerData;
+
+ // Button state.
+ int32_t mCurrentButtonState;
+ int32_t mLastButtonState;
+
+ // True if we sent a HOVER_ENTER event.
+ bool mSentHoverEnter;
// The time the primary pointer last went down.
nsecs_t mDownTime;
@@ -1068,113 +1078,106 @@ protected:
// The pointer controller, or null if the device is not a pointer.
sp<PointerControllerInterface> mPointerController;
- struct LockedState {
- Vector<VirtualKey> virtualKeys;
-
- // The surface orientation and width and height set by configureSurfaceLocked().
- int32_t surfaceOrientation;
- int32_t surfaceWidth, surfaceHeight;
+ Vector<VirtualKey> mVirtualKeys;
- // The associated display orientation and width and height set by configureSurfaceLocked().
- int32_t associatedDisplayOrientation;
- int32_t associatedDisplayWidth, associatedDisplayHeight;
+ virtual void configureParameters();
+ virtual void dumpParameters(String8& dump);
+ virtual void configureRawPointerAxes();
+ virtual void dumpRawPointerAxes(String8& dump);
+ virtual bool configureSurface();
+ virtual void dumpSurface(String8& dump);
+ virtual void configureVirtualKeys();
+ virtual void dumpVirtualKeys(String8& dump);
+ virtual void parseCalibration();
+ virtual void resolveCalibration();
+ virtual void dumpCalibration(String8& dump);
- // Translation and scaling factors, orientation-independent.
- float xScale;
- float xPrecision;
+ void syncTouch(nsecs_t when, bool havePointerIds);
- float yScale;
- float yPrecision;
+private:
+ // The surface orientation and width and height set by configureSurface().
+ int32_t mSurfaceOrientation;
+ int32_t mSurfaceWidth;
+ int32_t mSurfaceHeight;
- float geometricScale;
+ // The associated display orientation and width and height set by configureSurface().
+ int32_t mAssociatedDisplayOrientation;
+ int32_t mAssociatedDisplayWidth;
+ int32_t mAssociatedDisplayHeight;
- float toolSizeLinearScale;
- float toolSizeLinearBias;
- float toolSizeAreaScale;
- float toolSizeAreaBias;
+ // Translation and scaling factors, orientation-independent.
+ float mXScale;
+ float mXPrecision;
- float pressureScale;
+ float mYScale;
+ float mYPrecision;
- float sizeScale;
+ float mGeometricScale;
- float orientationScale;
+ float mToolSizeLinearScale;
+ float mToolSizeLinearBias;
+ float mToolSizeAreaScale;
+ float mToolSizeAreaBias;
- float distanceScale;
+ float mPressureScale;
- // Oriented motion ranges for input device info.
- struct OrientedRanges {
- InputDeviceInfo::MotionRange x;
- InputDeviceInfo::MotionRange y;
+ float mSizeScale;
- bool havePressure;
- InputDeviceInfo::MotionRange pressure;
+ float mOrientationScale;
- bool haveSize;
- InputDeviceInfo::MotionRange size;
+ float mDistanceScale;
- bool haveTouchSize;
- InputDeviceInfo::MotionRange touchMajor;
- InputDeviceInfo::MotionRange touchMinor;
+ // Oriented motion ranges for input device info.
+ struct OrientedRanges {
+ InputDeviceInfo::MotionRange x;
+ InputDeviceInfo::MotionRange y;
- bool haveToolSize;
- InputDeviceInfo::MotionRange toolMajor;
- InputDeviceInfo::MotionRange toolMinor;
+ bool havePressure;
+ InputDeviceInfo::MotionRange pressure;
- bool haveOrientation;
- InputDeviceInfo::MotionRange orientation;
+ bool haveSize;
+ InputDeviceInfo::MotionRange size;
- bool haveDistance;
- InputDeviceInfo::MotionRange distance;
- } orientedRanges;
+ bool haveTouchSize;
+ InputDeviceInfo::MotionRange touchMajor;
+ InputDeviceInfo::MotionRange touchMinor;
- // Oriented dimensions and precision.
- float orientedSurfaceWidth, orientedSurfaceHeight;
- float orientedXPrecision, orientedYPrecision;
+ bool haveToolSize;
+ InputDeviceInfo::MotionRange toolMajor;
+ InputDeviceInfo::MotionRange toolMinor;
- struct CurrentVirtualKeyState {
- bool down;
- nsecs_t downTime;
- int32_t keyCode;
- int32_t scanCode;
- } currentVirtualKey;
+ bool haveOrientation;
+ InputDeviceInfo::MotionRange orientation;
- // Scale factor for gesture based pointer movements.
- float pointerGestureXMovementScale;
- float pointerGestureYMovementScale;
+ bool haveDistance;
+ InputDeviceInfo::MotionRange distance;
+ } mOrientedRanges;
- // Scale factor for gesture based zooming and other freeform motions.
- float pointerGestureXZoomScale;
- float pointerGestureYZoomScale;
+ // Oriented dimensions and precision.
+ float mOrientedSurfaceWidth;
+ float mOrientedSurfaceHeight;
+ float mOrientedXPrecision;
+ float mOrientedYPrecision;
- // The maximum swipe width.
- float pointerGestureMaxSwipeWidth;
- } mLocked;
+ struct CurrentVirtualKeyState {
+ bool down;
+ bool ignored;
+ nsecs_t downTime;
+ int32_t keyCode;
+ int32_t scanCode;
+ } mCurrentVirtualKey;
- 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);
+ // Scale factor for gesture based pointer movements.
+ float mPointerGestureXMovementScale;
+ float mPointerGestureYMovementScale;
- 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
- };
+ // Scale factor for gesture based zooming and other freeform motions.
+ float mPointerGestureXZoomScale;
+ float mPointerGestureYZoomScale;
- void syncTouch(nsecs_t when, bool havePointerIds);
+ // The maximum swipe width.
+ float mPointerGestureMaxSwipeWidth;
-private:
struct PointerDistanceHeapElement {
uint32_t currentPointerIndex : 8;
uint32_t lastPointerIndex : 8;
@@ -1319,11 +1322,17 @@ private:
}
} mPointerGesture;
- void initializeLocked();
+ void initialize();
+
+ bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
+ void dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags);
- TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
void dispatchTouches(nsecs_t when, uint32_t policyFlags);
- void prepareTouches(float* outXPrecision, float* outYPrecision);
+ void dispatchHoverExit(nsecs_t when, uint32_t policyFlags);
+ void dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags);
+ void cookPointerData();
+
void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
bool preparePointerGestures(nsecs_t when,
bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout);
@@ -1346,12 +1355,10 @@ private:
PointerProperties* outProperties, PointerCoords* outCoords,
const uint32_t* outIdToIndex, BitSet32 idBits) const;
- void suppressSwipeOntoVirtualKeys(nsecs_t when);
-
- bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
- const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
+ bool isPointInsideSurface(int32_t x, int32_t y);
+ const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
- void calculatePointerIds();
+ void assignPointerIds();
};
@@ -1364,7 +1371,7 @@ public:
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureRawAxes();
+ virtual void configureRawPointerAxes();
private:
CursorButtonAccumulator mCursorButtonAccumulator;
@@ -1386,7 +1393,7 @@ public:
virtual void process(const RawEvent* rawEvent);
protected:
- virtual void configureRawAxes();
+ virtual void configureRawPointerAxes();
private:
CursorButtonAccumulator mCursorButtonAccumulator;
diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp
index 12c7cba..1d1730d 100644
--- a/services/input/PointerController.cpp
+++ b/services/input/PointerController.cpp
@@ -261,9 +261,7 @@ void PointerController::setSpots(const PointerCoords* spotCoords,
// Add or move spots for fingers that are down.
for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
const PointerCoords& c = spotCoords[spotIdToIndex[id]];
const SpriteIcon& icon = c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE) > 0
? mResources.spotTouch : mResources.spotHover;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 8533743..4a866a8 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -48,13 +48,16 @@ static inline float avg(float x, float y) {
class FakePointerController : public PointerControllerInterface {
bool mHaveBounds;
float mMinX, mMinY, mMaxX, mMaxY;
+ float mX, mY;
+ int32_t mButtonState;
protected:
virtual ~FakePointerController() { }
public:
FakePointerController() :
- mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0) {
+ mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
+ mButtonState(0) {
}
void setBounds(float minX, float minY, float maxX, float maxY) {
@@ -65,31 +68,40 @@ public:
mMaxY = maxY;
}
-private:
- virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
- *outMinX = mMinX;
- *outMinY = mMinY;
- *outMaxX = mMaxX;
- *outMaxY = mMaxY;
- return mHaveBounds;
- }
-
- virtual void move(float deltaX, float deltaY) {
+ virtual void setPosition(float x, float y) {
+ mX = x;
+ mY = y;
}
virtual void setButtonState(int32_t buttonState) {
+ mButtonState = buttonState;
}
virtual int32_t getButtonState() const {
- return 0;
+ return mButtonState;
}
- virtual void setPosition(float x, float y) {
+ virtual void getPosition(float* outX, float* outY) const {
+ *outX = mX;
+ *outY = mY;
}
- virtual void getPosition(float* outX, float* outY) const {
- *outX = 0;
- *outY = 0;
+private:
+ virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
+ *outMinX = mMinX;
+ *outMinY = mMinY;
+ *outMaxX = mMaxX;
+ *outMaxY = mMaxY;
+ return mHaveBounds;
+ }
+
+ virtual void move(float deltaX, float deltaY) {
+ mX += deltaX;
+ if (mX < mMinX) mX = mMinX;
+ if (mX > mMaxX) mX = mMaxX;
+ mY += deltaY;
+ if (mY < mMinY) mY = mMinY;
+ if (mY > mMaxY) mY = mMaxY;
}
virtual void fade(Transition transition) {
@@ -186,221 +198,84 @@ private:
};
-// --- FakeInputDispatcher ---
-
-class FakeInputDispatcher : public InputDispatcherInterface {
-public:
- struct NotifyConfigurationChangedArgs {
- NotifyConfigurationChangedArgs() : eventTime(0) { }
-
- nsecs_t eventTime;
- };
-
- struct NotifyKeyArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t keyCode;
- int32_t scanCode;
- int32_t metaState;
- nsecs_t downTime;
- };
-
- struct NotifyMotionArgs {
- nsecs_t eventTime;
- int32_t deviceId;
- uint32_t source;
- uint32_t policyFlags;
- int32_t action;
- int32_t flags;
- int32_t metaState;
- int32_t buttonState;
- int32_t edgeFlags;
- uint32_t pointerCount;
- Vector<PointerProperties> pointerProperties;
- Vector<PointerCoords> pointerCoords;
- float xPrecision;
- float yPrecision;
- nsecs_t downTime;
- };
-
- struct NotifySwitchArgs {
- nsecs_t when;
- int32_t switchCode;
- int32_t switchValue;
- uint32_t policyFlags;
- };
+// --- FakeInputListener ---
+class FakeInputListener : public InputListenerInterface {
private:
- List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgs;
- List<NotifyKeyArgs> mNotifyKeyArgs;
- List<NotifyMotionArgs> mNotifyMotionArgs;
- List<NotifySwitchArgs> mNotifySwitchArgs;
+ List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
+ List<NotifyKeyArgs> mNotifyKeyArgsQueue;
+ List<NotifyMotionArgs> mNotifyMotionArgsQueue;
+ List<NotifySwitchArgs> mNotifySwitchArgsQueue;
protected:
- virtual ~FakeInputDispatcher() { }
+ virtual ~FakeInputListener() { }
public:
- FakeInputDispatcher() {
+ FakeInputListener() {
}
- void assertNotifyConfigurationChangedWasCalled(NotifyConfigurationChangedArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyConfigurationChangedArgs.empty())
+ void assertNotifyConfigurationChangedWasCalled(
+ NotifyConfigurationChangedArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
<< "Expected notifyConfigurationChanged() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyConfigurationChangedArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
}
- mNotifyConfigurationChangedArgs.erase(mNotifyConfigurationChangedArgs.begin());
+ mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
}
- void assertNotifyKeyWasCalled(NotifyKeyArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyKeyArgs.empty())
+ void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
<< "Expected notifyKey() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyKeyArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyKeyArgsQueue.begin();
}
- mNotifyKeyArgs.erase(mNotifyKeyArgs.begin());
+ mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
}
void assertNotifyKeyWasNotCalled() {
- ASSERT_TRUE(mNotifyKeyArgs.empty())
+ ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
<< "Expected notifyKey() to not have been called.";
}
- void assertNotifyMotionWasCalled(NotifyMotionArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifyMotionArgs.empty())
+ void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
<< "Expected notifyMotion() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifyMotionArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifyMotionArgsQueue.begin();
}
- mNotifyMotionArgs.erase(mNotifyMotionArgs.begin());
+ mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
}
void assertNotifyMotionWasNotCalled() {
- ASSERT_TRUE(mNotifyMotionArgs.empty())
+ ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
<< "Expected notifyMotion() to not have been called.";
}
- void assertNotifySwitchWasCalled(NotifySwitchArgs* outArgs = NULL) {
- ASSERT_FALSE(mNotifySwitchArgs.empty())
+ void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
+ ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
<< "Expected notifySwitch() to have been called.";
- if (outArgs) {
- *outArgs = *mNotifySwitchArgs.begin();
+ if (outEventArgs) {
+ *outEventArgs = *mNotifySwitchArgsQueue.begin();
}
- mNotifySwitchArgs.erase(mNotifySwitchArgs.begin());
+ mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
}
private:
- virtual void notifyConfigurationChanged(nsecs_t eventTime) {
- NotifyConfigurationChangedArgs args;
- args.eventTime = eventTime;
- mNotifyConfigurationChangedArgs.push_back(args);
- }
-
- virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
- int32_t scanCode, int32_t metaState, nsecs_t downTime) {
- NotifyKeyArgs args;
- args.eventTime = eventTime;
- args.deviceId = deviceId;
- args.source = source;
- args.policyFlags = policyFlags;
- args.action = action;
- args.flags = flags;
- args.keyCode = keyCode;
- args.scanCode = scanCode;
- args.metaState = metaState;
- args.downTime = downTime;
- mNotifyKeyArgs.push_back(args);
- }
-
- virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, uint32_t source,
- uint32_t policyFlags, int32_t action, int32_t flags,
- int32_t metaState, int32_t buttonState, int32_t edgeFlags,
- uint32_t pointerCount, const PointerProperties* pointerProperties,
- const PointerCoords* pointerCoords,
- float xPrecision, float yPrecision, nsecs_t downTime) {
- NotifyMotionArgs args;
- args.eventTime = eventTime;
- args.deviceId = deviceId;
- args.source = source;
- args.policyFlags = policyFlags;
- args.action = action;
- args.flags = flags;
- args.metaState = metaState;
- args.buttonState = buttonState;
- args.edgeFlags = edgeFlags;
- args.pointerCount = pointerCount;
- args.pointerProperties.clear();
- args.pointerProperties.appendArray(pointerProperties, pointerCount);
- args.pointerCoords.clear();
- args.pointerCoords.appendArray(pointerCoords, pointerCount);
- args.xPrecision = xPrecision;
- args.yPrecision = yPrecision;
- args.downTime = downTime;
- mNotifyMotionArgs.push_back(args);
- }
-
- virtual void notifySwitch(nsecs_t when,
- int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
- NotifySwitchArgs args;
- args.when = when;
- args.switchCode = switchCode;
- args.switchValue = switchValue;
- args.policyFlags = policyFlags;
- mNotifySwitchArgs.push_back(args);
- }
-
- virtual void dump(String8& dump) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual void dispatchOnce() {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual int32_t injectInputEvent(const InputEvent* event,
- int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
- uint32_t policyFlags) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return INPUT_EVENT_INJECTION_FAILED;
- }
-
- virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
- ADD_FAILURE() << "Should never be called by input reader.";
+ virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
+ mNotifyConfigurationChangedArgsQueue.push_back(*args);
}
- virtual void setFocusedApplication(
- const sp<InputApplicationHandle>& inputApplicationHandle) {
- ADD_FAILURE() << "Should never be called by input reader.";
+ virtual void notifyKey(const NotifyKeyArgs* args) {
+ mNotifyKeyArgsQueue.push_back(*args);
}
- virtual void setInputDispatchMode(bool enabled, bool frozen) {
- ADD_FAILURE() << "Should never be called by input reader.";
+ virtual void notifyMotion(const NotifyMotionArgs* args) {
+ mNotifyMotionArgsQueue.push_back(*args);
}
- virtual void setInputFilterEnabled(bool enabled) {
- ADD_FAILURE() << "Should never be called by input reader.";
- }
-
- virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
- const sp<InputChannel>& toChannel) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
- }
-
- virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
- const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
- }
-
- virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) {
- ADD_FAILURE() << "Should never be called by input reader.";
- return 0;
+ virtual void notifySwitch(const NotifySwitchArgs* args) {
+ mNotifySwitchArgsQueue.push_back(*args);
}
};
@@ -551,6 +426,10 @@ public:
event.value = value;
event.flags = flags;
mEvents.push_back(event);
+
+ if (type == EV_ABS) {
+ setAbsoluteAxisValue(deviceId, scanCode, value);
+ }
}
void assertQueueIsEmpty() {
@@ -765,15 +644,15 @@ private:
class FakeInputReaderContext : public InputReaderContext {
sp<EventHubInterface> mEventHub;
sp<InputReaderPolicyInterface> mPolicy;
- sp<InputDispatcherInterface> mDispatcher;
+ sp<InputListenerInterface> mListener;
int32_t mGlobalMetaState;
bool mUpdateGlobalMetaStateWasCalled;
public:
FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ mEventHub(eventHub), mPolicy(policy), mListener(listener),
mGlobalMetaState(0) {
}
@@ -806,8 +685,8 @@ private:
return mPolicy.get();
}
- virtual InputDispatcherInterface* getDispatcher() {
- return mDispatcher.get();
+ virtual InputListenerInterface* getListener() {
+ return mListener.get();
}
virtual void disableVirtualKeysUntil(nsecs_t time) {
@@ -969,8 +848,8 @@ class InstrumentedInputReader : public InputReader {
public:
InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- InputReader(eventHub, policy, dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ InputReader(eventHub, policy, listener),
mNextDevice(NULL) {
}
@@ -984,14 +863,19 @@ public:
mNextDevice = device;
}
+ InputDevice* newDevice(int32_t deviceId, const String8& name) {
+ return new InputDevice(&mContext, deviceId, name);
+ }
+
protected:
- virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+ virtual InputDevice* createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes) {
if (mNextDevice) {
InputDevice* device = mNextDevice;
mNextDevice = NULL;
return device;
}
- return InputReader::createDevice(deviceId, name, classes);
+ return InputReader::createDeviceLocked(deviceId, name, classes);
}
friend class InputReaderTest;
@@ -1002,7 +886,7 @@ protected:
class InputReaderTest : public testing::Test {
protected:
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
sp<FakeInputReaderPolicy> mFakePolicy;
sp<FakeEventHub> mFakeEventHub;
sp<InstrumentedInputReader> mReader;
@@ -1010,15 +894,15 @@ protected:
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
+ mFakeListener = new FakeInputListener();
- mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeListener);
}
virtual void TearDown() {
mReader.clear();
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1038,7 +922,7 @@ protected:
FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
const String8& name, uint32_t classes, uint32_t sources,
const PropertyMap* configuration) {
- InputDevice* device = new InputDevice(mReader.get(), deviceId, name);
+ InputDevice* device = mReader->newDevice(deviceId, name);
FakeInputMapper* mapper = new FakeInputMapper(device, sources);
device->addMapper(mapper);
mReader->setNextDevice(device);
@@ -1304,8 +1188,9 @@ TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, NULL);
- FakeInputDispatcher::NotifyConfigurationChangedArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyConfigurationChangedWasCalled(&args));
+ NotifyConfigurationChangedArgs args;
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
}
@@ -1339,7 +1224,7 @@ protected:
sp<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
FakeInputReaderContext* mFakeContext;
InputDevice* mDevice;
@@ -1347,8 +1232,8 @@ protected:
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
- mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mFakeListener = new FakeInputListener();
+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
@@ -1358,7 +1243,7 @@ protected:
delete mDevice;
delete mFakeContext;
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1509,15 +1394,15 @@ protected:
sp<FakeEventHub> mFakeEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
- sp<FakeInputDispatcher> mFakeDispatcher;
+ sp<FakeInputListener> mFakeListener;
FakeInputReaderContext* mFakeContext;
InputDevice* mDevice;
virtual void SetUp() {
mFakeEventHub = new FakeEventHub();
mFakePolicy = new FakeInputReaderPolicy();
- mFakeDispatcher = new FakeInputDispatcher();
- mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+ mFakeListener = new FakeInputListener();
+ mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
@@ -1526,7 +1411,7 @@ protected:
virtual void TearDown() {
delete mDevice;
delete mFakeContext;
- mFakeDispatcher.clear();
+ mFakeListener.clear();
mFakePolicy.clear();
mFakeEventHub.clear();
}
@@ -1570,7 +1455,7 @@ protected:
static void assertPointerCoords(const PointerCoords& coords,
float x, float y, float pressure, float size,
float touchMajor, float touchMinor, float toolMajor, float toolMinor,
- float orientation) {
+ float orientation, float distance) {
ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
@@ -1580,6 +1465,14 @@ protected:
ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
+ ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
+ }
+
+ static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
+ float actualX, actualY;
+ controller->getPosition(&actualX, &actualY);
+ ASSERT_NEAR(x, actualX, 1);
+ ASSERT_NEAR(y, actualY, 1);
}
};
@@ -1617,9 +1510,9 @@ TEST_F(SwitchInputMapperTest, Process) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 0, 1, 0);
- FakeInputDispatcher::NotifySwitchArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifySwitchWasCalled(&args));
- ASSERT_EQ(ARBITRARY_TIME, args.when);
+ NotifySwitchArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(SW_LID, args.switchCode);
ASSERT_EQ(1, args.switchValue);
ASSERT_EQ(uint32_t(0), args.policyFlags);
@@ -1636,16 +1529,16 @@ protected:
void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
ASSERT_EQ(originalScanCode, args.scanCode);
ASSERT_EQ(rotatedKeyCode, args.keyCode);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(originalScanCode, args.scanCode);
ASSERT_EQ(rotatedKeyCode, args.keyCode);
@@ -1668,8 +1561,8 @@ TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
// Key down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
@@ -1684,7 +1577,7 @@ TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
// Key up.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
@@ -1705,16 +1598,16 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp)
// Key down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Key up.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since no keys still down, should not synthesize any key ups.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
@@ -1725,18 +1618,18 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
// Metakey down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Key down.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since two keys are still down, should synthesize two key ups in reverse order.
mapper->reset();
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
@@ -1747,7 +1640,7 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
ASSERT_EQ(uint32_t(0), args.policyFlags);
ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
@@ -1759,7 +1652,7 @@ TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
// And that's it.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
@@ -1773,8 +1666,8 @@ TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
// Metakey down.
process(mapper, ARBITRARY_TIME, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
@@ -1782,21 +1675,21 @@ TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
// Key down.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
// Key up.
process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
EV_KEY, KEY_A, AKEYCODE_A, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
// Metakey up.
process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_NONE, args.metaState);
ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
@@ -1876,13 +1769,13 @@ TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
// Special case: if orientation changes while key is down, we still emit the same keycode
// in the key up as we did in the key down.
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
mFakePolicy->setDisplayInfo(DISPLAY_ID,
DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_ORIENTATION_270);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 1, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
@@ -1891,7 +1784,7 @@ TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
DISPLAY_WIDTH, DISPLAY_HEIGHT,
DISPLAY_ORIENTATION_180);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
@@ -2034,17 +1927,17 @@ const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper,
int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, originalX, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, originalY, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
@@ -2120,13 +2013,13 @@ TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaStat
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
// Mostly testing non x/y behavior here so we don't need to check again elsewhere.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
@@ -2140,7 +2033,7 @@ TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaStat
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
@@ -2148,7 +2041,7 @@ TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaStat
// Button release. Should have same down time.
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
@@ -2162,7 +2055,7 @@ TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaStat
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
@@ -2173,23 +2066,23 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Motion in X but not Y.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Motion in Y but not X.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
@@ -2197,23 +2090,23 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
- // Button press without following sync.
+ // Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
- // Button release without following sync.
+ // Button release.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
@@ -2221,36 +2114,36 @@ TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Combined X, Y and Button.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Move X, Y a bit while pressed.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 2, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
- 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Release Button.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) {
@@ -2258,22 +2151,24 @@ TEST_F(CursorInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButto
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
// Button release.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
// Reset. Should not synthesize button up since button is not pressed.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(CursorInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) {
@@ -2281,20 +2176,20 @@ TEST_F(CursorInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) {
addConfigurationProperty("cursor.mode", "navigation");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Button press.
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
// Reset. Should synthesize button up.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
}
TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
@@ -2366,6 +2261,203 @@ TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions)
ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, 1, -1, -1));
}
+TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+ addConfigurationProperty("cursor.mode", "pointer");
+ addMapperAndConfigure(mapper);
+
+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+ mFakePointerController->setPosition(100, 200);
+ mFakePointerController->setButtonState(0);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ // press BTN_LEFT, release BTN_LEFT
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ mFakePointerController->getButtonState());
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ // press BTN_BACK, release BTN_BACK
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0, 1, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0, 0, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(0, mFakePointerController->getButtonState());
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ 100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+}
+
+TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
+ CursorInputMapper* mapper = new CursorInputMapper(mDevice);
+ addConfigurationProperty("cursor.mode", "pointer");
+ addMapperAndConfigure(mapper);
+
+ mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
+ mFakePointerController->setPosition(100, 200);
+ mFakePointerController->setButtonState(0);
+
+ NotifyMotionArgs args;
+
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 10, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 20, 0);
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+ 110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+ ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
+}
+
// --- TouchInputMapperTest ---
@@ -2383,8 +2475,12 @@ protected:
static const int32_t RAW_PRESSURE_MAX;
static const int32_t RAW_ORIENTATION_MIN;
static const int32_t RAW_ORIENTATION_MAX;
+ static const int32_t RAW_DISTANCE_MIN;
+ static const int32_t RAW_DISTANCE_MAX;
static const int32_t RAW_ID_MIN;
static const int32_t RAW_ID_MAX;
+ static const int32_t RAW_SLOT_MIN;
+ static const int32_t RAW_SLOT_MAX;
static const float X_PRECISION;
static const float Y_PRECISION;
@@ -2398,6 +2494,9 @@ protected:
ORIENTATION = 1 << 4,
MINOR = 1 << 5,
ID = 1 << 6,
+ DISTANCE = 1 << 7,
+ SLOT = 1 << 8,
+ TOOL_TYPE = 1 << 9,
};
void prepareDisplay(int32_t orientation);
@@ -2420,8 +2519,12 @@ const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN;
const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
+const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
+const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
@@ -2470,6 +2573,8 @@ protected:
void processUp(SingleTouchInputMapper* mappery);
void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
+ void processDistance(SingleTouchInputMapper* mapper, int32_t distance);
+ void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value);
void processSync(SingleTouchInputMapper* mapper);
};
@@ -2492,6 +2597,10 @@ void SingleTouchInputMapperTest::prepareAxes(int axes) {
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
}
+ if (axes & DISTANCE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ }
}
void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
@@ -2519,6 +2628,16 @@ void SingleTouchInputMapperTest::processToolMajor(
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, 0, toolMajor, 0);
}
+void SingleTouchInputMapperTest::processDistance(
+ SingleTouchInputMapper* mapper, int32_t distance) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, 0, distance, 0);
+}
+
+void SingleTouchInputMapperTest::processKey(
+ SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, 0, value, 0);
+}
+
void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
}
@@ -2581,14 +2700,14 @@ TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
// Virtual key is up.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
}
@@ -2610,14 +2729,14 @@ TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
// Virtual key is up.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
}
@@ -2656,13 +2775,13 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) {
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since key is down, synthesize key up.
mapper->reset();
- FakeInputDispatcher::NotifyKeyArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ NotifyKeyArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
//ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2689,18 +2808,18 @@ TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens
int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Release virtual key.
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
// Reset. Since no key is down, nothing happens.
mapper->reset();
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
@@ -2714,7 +2833,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyKeyArgs args;
+ NotifyKeyArgs args;
// Press virtual key.
int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
@@ -2722,7 +2841,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2738,7 +2857,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2751,7 +2870,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNor
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Should not have sent any motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
@@ -2765,7 +2884,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyKeyArgs keyArgs;
+ NotifyKeyArgs keyArgs;
// Press virtual key.
int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
@@ -2773,7 +2892,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
@@ -2791,7 +2910,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
@@ -2804,8 +2923,8 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ NotifyMotionArgs motionArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2819,7 +2938,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2829,7 +2948,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2843,7 +2962,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2852,7 +2971,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2866,14 +2985,14 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfB
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
@@ -2887,7 +3006,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Initially go down out of bounds.
int32_t x = -10;
@@ -2895,7 +3014,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
// Move into the display area. Should generate a pointer down.
x = 50;
@@ -2903,7 +3022,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2917,7 +3036,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2926,7 +3045,7 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2940,14 +3059,14 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMoves
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
@@ -2961,7 +3080,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Down.
int32_t x = 100;
@@ -2969,7 +3088,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
processDown(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -2983,7 +3102,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -2994,7 +3113,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
processMove(mapper, x, y);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3008,7 +3127,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3017,7 +3136,7 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3031,14 +3150,14 @@ TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
@@ -3049,20 +3168,20 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotate
addConfigurationProperty("touch.orientationAware", "0");
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Rotation 90.
prepareDisplay(DISPLAY_ORIENTATION_90);
processDown(mapper, toRawX(50), toRawY(75));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
@@ -3072,59 +3191,59 @@ TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions)
prepareAxes(POSITION);
addMapperAndConfigure(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
+ NotifyMotionArgs args;
// Rotation 0.
prepareDisplay(DISPLAY_ORIENTATION_0);
processDown(mapper, toRawX(50), toRawY(75));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 90.
prepareDisplay(DISPLAY_ORIENTATION_90);
processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 180.
prepareDisplay(DISPLAY_ORIENTATION_180);
processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
// Rotation 270.
prepareDisplay(DISPLAY_ORIENTATION_270);
processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
processUp(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
}
TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
@@ -3132,7 +3251,7 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
prepareButtons();
- prepareAxes(POSITION | PRESSURE | TOOL);
+ prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE);
addMapperAndConfigure(mapper);
// These calculations are based on the input device calibration documentation.
@@ -3140,6 +3259,7 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
int32_t rawY = 200;
int32_t rawPressure = 10;
int32_t rawToolMajor = 12;
+ int32_t rawDistance = 0;
float x = toDisplayX(rawX);
float y = toDisplayY(rawY);
@@ -3147,16 +3267,388 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
float size = float(rawToolMajor) / RAW_TOOL_MAX;
float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size;
float touch = min(tool * pressure, tool);
+ float distance = float(rawDistance);
processDown(mapper, rawX, rawY);
processPressure(mapper, rawPressure);
processToolMajor(mapper, rawToolMajor);
+ processDistance(mapper, rawDistance);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, distance));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ processDown(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+
+ // press BTN_LEFT, release BTN_LEFT
+ processKey(mapper, BTN_LEFT, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_LEFT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ processKey(mapper, BTN_RIGHT, 1);
+ processKey(mapper, BTN_MIDDLE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+
+ processKey(mapper, BTN_RIGHT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_MIDDLE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_BACK, release BTN_BACK
+ processKey(mapper, BTN_BACK, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_BACK, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ processKey(mapper, BTN_SIDE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_SIDE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ processKey(mapper, BTN_FORWARD, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_FORWARD, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ processKey(mapper, BTN_EXTRA, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_EXTRA, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_STYLUS, release BTN_STYLUS
+ processKey(mapper, BTN_STYLUS, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_STYLUS2, release BTN_STYLUS2
+ processKey(mapper, BTN_STYLUS2, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS2, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // release touch
+ processUp(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // default tool type is finger
+ processDown(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // eraser
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus trumps finger
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // eraser trumps stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // back to default tool type
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION);
+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, AKEYCODE_UNKNOWN, 0);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processMove(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // move a little
+ processMove(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // down when BTN_TOUCH is pressed, pressure defaults to 1
+ processKey(mapper, BTN_TOUCH, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when BTN_TOUCH is released, hover restored
+ processKey(mapper, BTN_TOUCH, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // exit hover when pointer goes away
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenAbsDistanceIsPresent_HoversIfItsValueIsGreaterThanZero) {
+ SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareButtons();
+ prepareAxes(POSITION | DISTANCE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because distance is 1, pressure defaults to 0
+ processDown(mapper, 100, 200);
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // move a little
+ processMove(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // down when distance goes to 0, pressure defaults to 1
+ processDistance(mapper, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when distance goes to 1, hover restored
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // exit hover when pointer goes away
+ processUp(mapper);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
}
@@ -3173,7 +3665,11 @@ protected:
void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
+ void processDistance(MultiTouchInputMapper* mapper, int32_t distance);
void processId(MultiTouchInputMapper* mapper, int32_t id);
+ void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
+ void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
+ void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
void processMTSync(MultiTouchInputMapper* mapper);
void processSync(MultiTouchInputMapper* mapper);
};
@@ -3209,10 +3705,23 @@ void MultiTouchInputMapperTest::prepareAxes(int axes) {
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
}
+ if (axes & DISTANCE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
+ RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
+ }
if (axes & ID) {
mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
RAW_ID_MIN, RAW_ID_MAX, 0, 0);
}
+ if (axes & SLOT) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
+ RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
+ mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
+ }
+ if (axes & TOOL_TYPE) {
+ mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
+ 0, MT_TOOL_MAX, 0, 0);
+ }
}
void MultiTouchInputMapperTest::processPosition(
@@ -3251,11 +3760,31 @@ void MultiTouchInputMapperTest::processPressure(
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, 0, pressure, 0);
}
+void MultiTouchInputMapperTest::processDistance(
+ MultiTouchInputMapper* mapper, int32_t distance) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, 0, distance, 0);
+}
+
void MultiTouchInputMapperTest::processId(
MultiTouchInputMapper* mapper, int32_t id) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, 0, id, 0);
}
+void MultiTouchInputMapperTest::processSlot(
+ MultiTouchInputMapper* mapper, int32_t slot) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, 0, slot, 0);
+}
+
+void MultiTouchInputMapperTest::processToolType(
+ MultiTouchInputMapper* mapper, int32_t toolType) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, 0, toolType, 0);
+}
+
+void MultiTouchInputMapperTest::processKey(
+ MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
+ process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, 0, value, 0);
+}
+
void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0, 0, 0);
}
@@ -3275,7 +3804,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Two fingers down at once.
int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
@@ -3285,7 +3814,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3299,12 +3828,12 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3321,9 +3850,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3336,7 +3865,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3352,9 +3881,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3365,7 +3894,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3382,14 +3911,14 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3403,7 +3932,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3414,7 +3943,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3428,7 +3957,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3441,7 +3970,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3458,9 +3987,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3471,7 +4000,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3488,14 +4017,14 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3509,7 +4038,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
@@ -3518,7 +4047,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
@@ -3532,14 +4061,14 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackin
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
@@ -3552,7 +4081,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
- FakeInputDispatcher::NotifyMotionArgs motionArgs;
+ NotifyMotionArgs motionArgs;
// Two fingers down at once.
int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
@@ -3564,15 +4093,15 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3581,9 +4110,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Move.
x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
@@ -3595,7 +4124,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
@@ -3603,9 +4132,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// First finger up.
x2 += 15; y2 -= 20;
@@ -3614,7 +4143,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3623,17 +4152,17 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Move.
x2 += 20; y2 -= 25;
@@ -3642,13 +4171,13 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// New finger down.
int32_t x3 = 700, y3 = 300;
@@ -3660,7 +4189,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3669,9 +4198,9 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
// Second finger up.
x3 += 30; y3 -= 20;
@@ -3680,7 +4209,7 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
motionArgs.action);
ASSERT_EQ(size_t(2), motionArgs.pointerCount);
@@ -3689,40 +4218,211 @@ TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingId
ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
- toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
// Last finger up.
processMTSync(mapper);
processSync(mapper);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
ASSERT_EQ(size_t(1), motionArgs.pointerCount);
ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
- toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
// Should not have sent any more keys or motions.
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ prepareVirtualKeys();
+ addMapperAndConfigure(mapper);
+
+ mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+ NotifyMotionArgs motionArgs;
+
+ // Two fingers down at once.
+ int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+ processPosition(mapper, x1, y1);
+ processId(mapper, 1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processId(mapper, 2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Move.
+ x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
+ processSlot(mapper, 0);
+ processPosition(mapper, x1, y1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // First finger up.
+ x2 += 15; y2 -= 20;
+ processSlot(mapper, 0);
+ processId(mapper, -1);
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Move.
+ x2 += 20; y2 -= 25;
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // New finger down.
+ int32_t x3 = 700, y3 = 300;
+ processPosition(mapper, x2, y2);
+ processSlot(mapper, 0);
+ processId(mapper, 3);
+ processPosition(mapper, x3, y3);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Second finger up.
+ x3 += 30; y3 -= 20;
+ processSlot(mapper, 1);
+ processId(mapper, -1);
+ processSlot(mapper, 0);
+ processPosition(mapper, x3, y3);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+ toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Last finger up.
+ processId(mapper, -1);
+ processSync(mapper);
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+ ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // Should not have sent any more keys or motions.
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
addConfigurationProperty("touch.deviceType", "touchScreen");
prepareDisplay(DISPLAY_ORIENTATION_0);
- prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR);
+ prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
addMapperAndConfigure(mapper);
// These calculations are based on the input device calibration documentation.
@@ -3733,6 +4433,7 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
int32_t rawToolMajor = 9;
int32_t rawToolMinor = 8;
int32_t rawPressure = 11;
+ int32_t rawDistance = 0;
int32_t rawOrientation = 3;
int32_t id = 5;
@@ -3745,6 +4446,7 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
float touchMajor = min(toolMajor * pressure, toolMajor);
float touchMinor = min(toolMinor * pressure, toolMinor);
float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
+ float distance = float(rawDistance);
processPosition(mapper, rawX, rawY);
processTouchMajor(mapper, rawTouchMajor);
@@ -3753,15 +4455,16 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
processToolMinor(mapper, rawToolMinor);
processPressure(mapper, rawPressure);
processOrientation(mapper, rawOrientation);
+ processDistance(mapper, rawDistance);
processId(mapper, id);
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(0, args.pointerProperties[0].id);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation));
+ x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation, distance));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
@@ -3800,10 +4503,10 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration)
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0));
+ x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) {
@@ -3850,18 +4553,18 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinear
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
args.action);
ASSERT_EQ(size_t(2), args.pointerCount);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, 0));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
- x2, y2, pressure, size, touch, touch, tool, tool, 0));
+ x2, y2, pressure, size, touch, touch, tool, tool, 0, 0));
}
TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) {
@@ -3899,10 +4602,395 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibrat
processMTSync(mapper);
processSync(mapper);
- FakeInputDispatcher::NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+ NotifyMotionArgs args;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
- x, y, pressure, size, touch, touch, tool, tool, 0));
+ x, y, pressure, size, touch, touch, tool, tool, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+ NotifyKeyArgs keyArgs;
+
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
+
+ // press BTN_LEFT, release BTN_LEFT
+ processKey(mapper, BTN_LEFT, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_LEFT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
+ processKey(mapper, BTN_RIGHT, 1);
+ processKey(mapper, BTN_MIDDLE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
+ motionArgs.buttonState);
+
+ processKey(mapper, BTN_RIGHT, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_MIDDLE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_BACK, release BTN_BACK
+ processKey(mapper, BTN_BACK, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_BACK, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_SIDE, release BTN_SIDE
+ processKey(mapper, BTN_SIDE, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_SIDE, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
+
+ // press BTN_FORWARD, release BTN_FORWARD
+ processKey(mapper, BTN_FORWARD, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_FORWARD, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_EXTRA, release BTN_EXTRA
+ processKey(mapper, BTN_EXTRA, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ processKey(mapper, BTN_EXTRA, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
+ ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+ ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
+
+ // press BTN_STYLUS, release BTN_STYLUS
+ processKey(mapper, BTN_STYLUS, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // press BTN_STYLUS2, release BTN_STYLUS2
+ processKey(mapper, BTN_STYLUS2, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
+
+ processKey(mapper, BTN_STYLUS2, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(0, motionArgs.buttonState);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+
+ // release touch
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_EQ(0, motionArgs.buttonState);
}
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // default tool type is finger
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // eraser
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // finger
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // stylus trumps finger
+ processKey(mapper, BTN_TOOL_PEN, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // eraser trumps stylus
+ processKey(mapper, BTN_TOOL_RUBBER, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
+
+ // MT tool type trumps BTN tool types: MT_TOOL_FINGER
+ processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // MT tool type trumps BTN tool types: MT_TOOL_PEN
+ processToolType(mapper, MT_TOOL_PEN);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
+
+ // back to default tool type
+ processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
+ processKey(mapper, BTN_TOOL_RUBBER, 0);
+ processKey(mapper, BTN_TOOL_PEN, 0);
+ processKey(mapper, BTN_TOOL_FINGER, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT);
+ mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, AKEYCODE_UNKNOWN, 0);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // move a little
+ processPosition(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // down when BTN_TOUCH is pressed, pressure defaults to 1
+ processKey(mapper, BTN_TOUCH, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when BTN_TOUCH is released, hover restored
+ processKey(mapper, BTN_TOUCH, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+
+ // exit hover when pointer goes away
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTDistanceIsPresent_HoversIfItsValueIsGreaterThanZero) {
+ MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT | DISTANCE);
+ addMapperAndConfigure(mapper);
+
+ NotifyMotionArgs motionArgs;
+
+ // initially hovering because distance is 1, pressure defaults to 0
+ processId(mapper, 1);
+ processPosition(mapper, 100, 200);
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // move a little
+ processPosition(mapper, 150, 250);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // down when distance goes to 0, pressure defaults to 1
+ processDistance(mapper, 0);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ // up when distance goes to 1, hover restored
+ processDistance(mapper, 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+
+ // exit hover when pointer goes away
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
+ ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+ toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 1));
+}
+
+
} // namespace android
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index bdd8938..2e3d6dd 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -129,6 +129,7 @@ import javax.crypto.spec.SecretKeySpec;
class BackupManagerService extends IBackupManager.Stub {
private static final String TAG = "BackupManagerService";
private static final boolean DEBUG = true;
+ private static final boolean MORE_DEBUG = false;
// Name and current contents version of the full-backup manifest file
static final String BACKUP_MANIFEST_FILENAME = "_manifest";
@@ -851,10 +852,10 @@ class BackupManagerService extends IBackupManager.Stub {
info = mPackageManager.getPackageInfo(pkg, 0);
mEverStoredApps.add(pkg);
temp.writeUTF(pkg);
- if (DEBUG) Slog.v(TAG, " + " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " + " + pkg);
} catch (NameNotFoundException e) {
// nope, this package was uninstalled; don't include it
- if (DEBUG) Slog.v(TAG, " - " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " - " + pkg);
}
}
} catch (EOFException e) {
@@ -1246,7 +1247,7 @@ class BackupManagerService extends IBackupManager.Stub {
private void addPackageParticipantsLockedInner(String packageName,
List<PackageInfo> targetPkgs) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
Slog.v(TAG, "Adding " + targetPkgs.size() + " backup participants:");
for (PackageInfo p : targetPkgs) {
Slog.v(TAG, " " + p + " agent=" + p.applicationInfo.backupAgentName
@@ -1296,7 +1297,7 @@ class BackupManagerService extends IBackupManager.Stub {
private void removePackageParticipantsLockedInner(String packageName,
List<String> allPackageNames) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
Slog.v(TAG, "removePackageParticipantsLockedInner (" + packageName
+ ") removing " + allPackageNames.size() + " entries");
for (String p : allPackageNames) {
@@ -1320,7 +1321,7 @@ class BackupManagerService extends IBackupManager.Stub {
// We can't just remove(app) because the instances are different.
for (ApplicationInfo entry: set) {
if (entry.packageName.equals(pkg)) {
- if (DEBUG) Slog.v(TAG, " removing participant " + pkg);
+ if (MORE_DEBUG) Slog.v(TAG, " removing participant " + pkg);
set.remove(entry);
removeEverBackedUp(pkg);
break;
@@ -1403,7 +1404,8 @@ class BackupManagerService extends IBackupManager.Stub {
// Remove our awareness of having ever backed up the given package
void removeEverBackedUp(String packageName) {
- if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName + ", new set:");
+ if (DEBUG) Slog.v(TAG, "Removing backed-up knowledge of " + packageName);
+ if (MORE_DEBUG) Slog.v(TAG, "New set:");
synchronized (mEverStoredApps) {
// Rewrite the file and rename to overwrite. If we reboot in the middle,
@@ -1416,7 +1418,7 @@ class BackupManagerService extends IBackupManager.Stub {
mEverStoredApps.remove(packageName);
for (String s : mEverStoredApps) {
known.writeUTF(s);
- if (DEBUG) Slog.v(TAG, " " + s);
+ if (MORE_DEBUG) Slog.v(TAG, " " + s);
}
known.close();
known = null;
@@ -1460,7 +1462,7 @@ class BackupManagerService extends IBackupManager.Stub {
if (DEBUG) Slog.v(TAG, "Ancestral packages: " + mAncestralPackages.size());
for (String pkgName : mAncestralPackages) {
af.writeUTF(pkgName);
- if (DEBUG) Slog.v(TAG, " " + pkgName);
+ if (MORE_DEBUG) Slog.v(TAG, " " + pkgName);
}
}
af.close();
@@ -1523,7 +1525,7 @@ class BackupManagerService extends IBackupManager.Stub {
try {
PackageInfo info = mPackageManager.getPackageInfo(packageName, 0);
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA) == 0) {
- if (DEBUG) Slog.i(TAG, "allowClearUserData=false so not wiping "
+ if (MORE_DEBUG) Slog.i(TAG, "allowClearUserData=false so not wiping "
+ packageName);
return;
}
@@ -1593,13 +1595,13 @@ class BackupManagerService extends IBackupManager.Stub {
}
}
mBackupHandler.removeMessages(MSG_TIMEOUT);
- if (DEBUG) Slog.v(TAG, "operation " + Integer.toHexString(token)
+ if (MORE_DEBUG) Slog.v(TAG, "operation " + Integer.toHexString(token)
+ " complete: finalState=" + finalState);
return finalState == OP_ACKNOWLEDGED;
}
void prepareOperationTimeout(int token, long interval) {
- if (DEBUG) Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+ if (MORE_DEBUG) Slog.v(TAG, "starting timeout: token=" + Integer.toHexString(token)
+ " interval=" + interval);
synchronized (mCurrentOpLock) {
mCurrentOperations.put(token, OP_PENDING);
@@ -1937,7 +1939,7 @@ class BackupManagerService extends IBackupManager.Stub {
BackupDataOutput output = new BackupDataOutput(
mPipe.getFileDescriptor());
- if (DEBUG) Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
+ if (MORE_DEBUG) Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
writeAppManifest(mPackage, mManifestFile, mSendApk);
FullBackup.backupToTar(mPackage.packageName, null, null,
mFilesDir.getAbsolutePath(),
@@ -1948,7 +1950,7 @@ class BackupManagerService extends IBackupManager.Stub {
writeApkToBackup(mPackage, output);
}
- if (DEBUG) Slog.d(TAG, "Calling doFullBackup()");
+ if (DEBUG) Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
prepareOperationTimeout(mToken, TIMEOUT_FULL_BACKUP_INTERVAL);
mAgent.doFullBackup(mPipe, mToken, mBackupManagerBinder);
} catch (IOException e) {
@@ -2285,7 +2287,7 @@ class BackupManagerService extends IBackupManager.Stub {
// check for .obb and save those too
final File obbDir = Environment.getExternalStorageAppObbDirectory(pkg.packageName);
if (obbDir != null) {
- if (DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
+ if (MORE_DEBUG) Log.i(TAG, "obb dir: " + obbDir.getAbsolutePath());
File[] obbFiles = obbDir.listFiles();
if (obbFiles != null) {
final String obbDirName = obbDir.getAbsolutePath();
@@ -2374,10 +2376,10 @@ class BackupManagerService extends IBackupManager.Stub {
// The agent was running with a stub Application object, so shut it down.
if (app.uid != Process.SYSTEM_UID
&& app.uid != Process.PHONE_UID) {
- if (DEBUG) Slog.d(TAG, "Backup complete, killing host process");
+ if (MORE_DEBUG) Slog.d(TAG, "Backup complete, killing host process");
mActivityManager.killApplicationProcess(app.processName, app.uid);
} else {
- if (DEBUG) Slog.d(TAG, "Not killing after restore: " + app.processName);
+ if (MORE_DEBUG) Slog.d(TAG, "Not killing after restore: " + app.processName);
}
} catch (RemoteException e) {
Slog.d(TAG, "Lost app trying to shut down");
@@ -2600,7 +2602,7 @@ class BackupManagerService extends IBackupManager.Stub {
didRestore = restoreOneFile(in, buffer);
} while (didRestore);
- if (DEBUG) Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
+ if (MORE_DEBUG) Slog.v(TAG, "Done consuming input tarfile, total bytes=" + mBytes);
} catch (IOException e) {
Slog.e(TAG, "Unable to read restore input");
} finally {
@@ -2624,7 +2626,7 @@ class BackupManagerService extends IBackupManager.Stub {
}
sendEndRestore();
mWakelock.release();
- if (DEBUG) Slog.d(TAG, "Full restore pass complete.");
+ Slog.d(TAG, "Full restore pass complete.");
}
}
@@ -2722,7 +2724,7 @@ class BackupManagerService extends IBackupManager.Stub {
try {
info = readTarHeaders(instream);
if (info != null) {
- if (DEBUG) {
+ if (MORE_DEBUG) {
dumpFileMetadata(info);
}
@@ -2910,7 +2912,6 @@ class BackupManagerService extends IBackupManager.Stub {
boolean pipeOkay = true;
FileOutputStream pipe = new FileOutputStream(
mPipes[1].getFileDescriptor());
- if (DEBUG) Slog.d(TAG, "Piping data to agent");
while (toCopy > 0) {
int toRead = (toCopy > buffer.length)
? buffer.length : (int)toCopy;
@@ -3629,7 +3630,7 @@ class BackupManagerService extends IBackupManager.Stub {
// Allow unsigned apps, but not signed on one device and unsigned on the other
// !!! TODO: is this the right policy?
Signature[] deviceSigs = target.signatures;
- if (DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs
+ if (MORE_DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs
+ " device=" + deviceSigs);
if ((storedSigs == null || storedSigs.length == 0)
&& (deviceSigs == null || deviceSigs.length == 0)) {
@@ -4189,7 +4190,7 @@ class BackupManagerService extends IBackupManager.Stub {
// in the set; we want to avoid touching the disk redundantly.
writeToJournalLocked(packageName);
- if (DEBUG) {
+ if (MORE_DEBUG) {
int numKeys = mPendingBackups.size();
Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:");
for (BackupRequest b : mPendingBackups.values()) {
@@ -4387,7 +4388,7 @@ class BackupManagerService extends IBackupManager.Stub {
}
Binder.restoreCallingIdentity(oldId);
}
- if (DEBUG) Slog.d(TAG, "Full backup done; returning to caller");
+ if (MORE_DEBUG) Slog.d(TAG, "Full backup done; returning to caller");
}
public void fullRestore(ParcelFileDescriptor fd) {
@@ -4446,7 +4447,7 @@ class BackupManagerService extends IBackupManager.Stub {
}
void startConfirmationTimeout(int token, FullParams params) {
- if (DEBUG) Slog.d(TAG, "Posting conf timeout msg after "
+ if (MORE_DEBUG) Slog.d(TAG, "Posting conf timeout msg after "
+ TIMEOUT_FULL_CONFIRMATION + " millis");
Message msg = mBackupHandler.obtainMessage(MSG_FULL_CONFIRMATION_TIMEOUT,
token, 0, params);
@@ -4625,7 +4626,7 @@ class BackupManagerService extends IBackupManager.Stub {
public String getCurrentTransport() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"getCurrentTransport");
- if (DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + mCurrentTransport);
+ if (MORE_DEBUG) Slog.v(TAG, "... getCurrentTransport() returning " + mCurrentTransport);
return mCurrentTransport;
}
@@ -4682,7 +4683,7 @@ class BackupManagerService extends IBackupManager.Stub {
if (transport != null) {
try {
final Intent intent = transport.configurationIntent();
- if (DEBUG) Slog.d(TAG, "getConfigurationIntent() returning config intent "
+ if (MORE_DEBUG) Slog.d(TAG, "getConfigurationIntent() returning config intent "
+ intent);
return intent;
} catch (RemoteException e) {
@@ -4708,7 +4709,7 @@ class BackupManagerService extends IBackupManager.Stub {
if (transport != null) {
try {
final String text = transport.currentDestinationString();
- if (DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
+ if (MORE_DEBUG) Slog.d(TAG, "getDestinationString() returning " + text);
return text;
} catch (RemoteException e) {
/* fall through to return null */
@@ -4853,7 +4854,7 @@ class BackupManagerService extends IBackupManager.Stub {
// completed the given outstanding asynchronous backup/restore operation.
public void opComplete(int token) {
synchronized (mCurrentOpLock) {
- if (DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token));
+ if (MORE_DEBUG) Slog.v(TAG, "opComplete: " + Integer.toHexString(token));
mCurrentOperations.put(token, OP_ACKNOWLEDGED);
mCurrentOpLock.notifyAll();
}
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 39d2b1c..a59b6c0 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -21,6 +21,8 @@ import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.TAG_NONE;
import static android.net.NetworkStats.UID_ALL;
import static android.provider.Settings.Secure.NETSTATS_ENABLED;
+import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
+import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -54,7 +56,6 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -89,8 +90,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
private static final String KEY_IFACE = "iface";
private static final String KEY_TAG_HEX = "acct_tag_hex";
private static final String KEY_UID = "uid_tag_int";
- private static final String KEY_RX = "rx_bytes";
- private static final String KEY_TX = "tx_bytes";
+ private static final String KEY_RX_BYTES = "rx_bytes";
+ private static final String KEY_RX_PACKETS = "rx_packets";
+ private static final String KEY_TX_BYTES = "tx_bytes";
+ private static final String KEY_TX_PACKETS = "tx_packets";
class NetdResponseCode {
/* Keep in sync with system/netd/ResponseCode.h */
@@ -203,8 +206,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
Slog.d(TAG, "not enabling bandwidth control");
}
- SystemProperties.set(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
- mBandwidthControlEnabled ? "1" : "0");
+ SystemProperties.set(PROP_QTAGUID_ENABLED, mBandwidthControlEnabled ? "1" : "0");
}
public void registerObserver(INetworkManagementEventObserver obs) {
@@ -1249,6 +1251,9 @@ class NetworkManagementService extends INetworkManagementService.Stub {
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
final NetworkStats.Entry entry = new NetworkStats.Entry();
+ // TODO: remove knownLines check once 5087722 verified
+ final HashSet<String> knownLines = Sets.newHashSet();
+
final ArrayList<String> keys = Lists.newArrayList();
final ArrayList<String> values = Lists.newArrayList();
final HashMap<String, String> parsed = Maps.newHashMap();
@@ -1266,14 +1271,18 @@ class NetworkManagementService extends INetworkManagementService.Stub {
splitLine(line, values);
parseLine(keys, values, parsed);
+ if (!knownLines.add(line)) {
+ throw new IllegalStateException("encountered duplicate proc entry");
+ }
+
try {
- // TODO: add rxPackets/txPackets once kernel exports
entry.iface = parsed.get(KEY_IFACE);
- entry.tag = NetworkManagementSocketTagger.kernelToTag(
- parsed.get(KEY_TAG_HEX));
- entry.uid = Integer.parseInt(parsed.get(KEY_UID));
- entry.rxBytes = Long.parseLong(parsed.get(KEY_RX));
- entry.txBytes = Long.parseLong(parsed.get(KEY_TX));
+ entry.tag = kernelToTag(parsed.get(KEY_TAG_HEX));
+ entry.uid = getParsedInt(parsed, KEY_UID);
+ entry.rxBytes = getParsedLong(parsed, KEY_RX_BYTES);
+ entry.rxPackets = getParsedLong(parsed, KEY_RX_PACKETS);
+ entry.txBytes = getParsedLong(parsed, KEY_TX_BYTES);
+ entry.txPackets = getParsedLong(parsed, KEY_TX_PACKETS);
if (limitUid == UID_ALL || limitUid == entry.uid) {
stats.addValues(entry);
@@ -1291,6 +1300,16 @@ class NetworkManagementService extends INetworkManagementService.Stub {
return stats;
}
+ private static int getParsedInt(HashMap<String, String> parsed, String key) {
+ final String value = parsed.get(key);
+ return value != null ? Integer.parseInt(value) : 0;
+ }
+
+ private static long getParsedLong(HashMap<String, String> parsed, String key) {
+ final String value = parsed.get(key);
+ return value != null ? Long.parseLong(value) : 0;
+ }
+
/**
* Build {@link NetworkStats} with detailed UID statistics.
*
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index 837778e..e97df84 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -80,7 +80,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
// Set the current spell checker if there is one or more spell checkers
// available. In this case, "sci" is the first one in the available spell
// checkers.
- setCurrentSpellCheckerLocked(sci);
+ setCurrentSpellCheckerLocked(sci.getId());
}
}
}
@@ -95,12 +95,14 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
if (sci == null) return;
final String packageName = sci.getPackageName();
final int change = isPackageDisappearing(packageName);
- if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
- // Package disappearing
- setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
- } else if (isPackageModified(packageName)) {
- // Package modified
- setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
+ if (// Package disappearing
+ change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
+ // Package modified
+ || isPackageModified(packageName)) {
+ sci = findAvailSpellCheckerLocked(null, packageName);
+ if (sci != null) {
+ setCurrentSpellCheckerLocked(sci.getId());
+ }
}
}
}
@@ -177,20 +179,20 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
@Override
- public void getSpellCheckerService(SpellCheckerInfo info, String locale,
+ public void getSpellCheckerService(String sciId, String locale,
ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
if (!mSystemReady) {
return;
}
- if (info == null || tsListener == null || scListener == null) {
+ if (TextUtils.isEmpty(sciId) || tsListener == null || scListener == null) {
Slog.e(TAG, "getSpellCheckerService: Invalid input.");
return;
}
- final String sciId = info.getId();
synchronized(mSpellCheckerMap) {
if (!mSpellCheckerMap.containsKey(sciId)) {
return;
}
+ final SpellCheckerInfo sci = mSpellCheckerMap.get(sciId);
final int uid = Binder.getCallingUid();
if (mSpellCheckerBindGroups.containsKey(sciId)) {
final SpellCheckerBindGroup bindGroup = mSpellCheckerBindGroups.get(sciId);
@@ -234,7 +236,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
final long ident = Binder.clearCallingIdentity();
try {
- startSpellCheckerServiceInnerLocked(info, locale, tsListener, scListener, uid);
+ startSpellCheckerServiceInnerLocked(sci, locale, tsListener, scListener, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -290,7 +292,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
}
@Override
- public void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ public void setCurrentSpellChecker(String sciId) {
synchronized(mSpellCheckerMap) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SECURE_SETTINGS)
@@ -299,19 +301,19 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
"Requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
- setCurrentSpellCheckerLocked(sci);
+ setCurrentSpellCheckerLocked(sciId);
}
}
- private void setCurrentSpellCheckerLocked(SpellCheckerInfo sci) {
+ private void setCurrentSpellCheckerLocked(String sciId) {
if (DBG) {
- Slog.w(TAG, "setCurrentSpellChecker: " + sci.getId());
+ Slog.w(TAG, "setCurrentSpellChecker: " + sciId);
}
- if (sci == null || !mSpellCheckerMap.containsKey(sci.getId())) return;
+ if (TextUtils.isEmpty(sciId) || !mSpellCheckerMap.containsKey(sciId)) return;
final long ident = Binder.clearCallingIdentity();
try {
Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.SPELL_CHECKER_SERVICE, sci == null ? "" : sci.getId());
+ Settings.Secure.SPELL_CHECKER_SERVICE, sciId);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index c129b97..2460fd6 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -68,7 +68,6 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import com.android.internal.content.PackageMonitor;
-import com.android.internal.service.wallpaper.ImageWallpaper;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
@@ -150,8 +149,8 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
* Name of the component used to display bitmap wallpapers from either the gallery or
* built-in wallpapers.
*/
- ComponentName mImageWallpaperComponent = new ComponentName("android",
- ImageWallpaper.class.getName());
+ ComponentName mImageWallpaperComponent = new ComponentName("com.android.systemui",
+ "com.android.systemui.ImageWallpaper");
WallpaperConnection mWallpaperConnection;
long mLastDiedTime;
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 6cc01f4..24188ca 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -17,6 +17,8 @@
package com.android.server.net;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
+import static android.Manifest.permission.MODIFY_NETWORK_ACCOUNTING;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.READ_NETWORK_USAGE_HISTORY;
import static android.content.Intent.ACTION_SHUTDOWN;
@@ -56,6 +58,7 @@ import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
+import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -65,6 +68,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.provider.Settings;
import android.telephony.TelephonyManager;
+import android.util.Log;
import android.util.LongSparseArray;
import android.util.NtpTrustedTime;
import android.util.Slog;
@@ -150,9 +154,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** Set of currently active ifaces. */
private HashMap<String, NetworkIdentitySet> mActiveIfaces = Maps.newHashMap();
- /** Set of historical stats for known networks. */
+ /** Set of historical network layer stats for known networks. */
private HashMap<NetworkIdentitySet, NetworkStatsHistory> mNetworkStats = Maps.newHashMap();
- /** Set of historical stats for known UIDs. */
+ /** Set of historical network layer stats for known UIDs. */
private HashMap<NetworkIdentitySet, LongSparseArray<NetworkStatsHistory>> mUidStats =
Maps.newHashMap();
@@ -164,6 +168,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStats mLastUidSnapshot;
+ /** Data layer operation counters for splicing into other structures. */
+ private NetworkStats mOperations = new NetworkStats(0L, 10);
+ private NetworkStats mLastOperationsSnapshot;
+
private final HandlerThread mHandlerThread;
private final Handler mHandler;
@@ -381,9 +389,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
entry.uid = uid;
entry.tag = tag;
entry.rxBytes = historyEntry.rxBytes;
+ entry.rxPackets = historyEntry.rxPackets;
entry.txBytes = historyEntry.txBytes;
+ entry.txPackets = historyEntry.txPackets;
+ entry.operations = historyEntry.operations;
- if (entry.rxBytes > 0 || entry.txBytes > 0) {
+ if (entry.rxBytes > 0 || entry.rxPackets > 0 || entry.txBytes > 0
+ || entry.txPackets > 0 || entry.operations > 0) {
stats.combineValues(entry);
}
}
@@ -396,6 +408,41 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
@Override
+ public NetworkStats getDataLayerSnapshotForUid(int uid) throws RemoteException {
+ if (Binder.getCallingUid() != uid) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+ }
+
+ // TODO: switch to data layer stats once kernel exports
+ // for now, read network layer stats and flatten across all ifaces
+ final NetworkStats networkLayer = mNetworkManager.getNetworkStatsUidDetail(uid);
+ final NetworkStats dataLayer = new NetworkStats(
+ networkLayer.getElapsedRealtime(), networkLayer.size());
+
+ NetworkStats.Entry entry = null;
+ for (int i = 0; i < networkLayer.size(); i++) {
+ entry = networkLayer.getValues(i, entry);
+ entry.iface = IFACE_ALL;
+ dataLayer.combineValues(entry);
+ }
+
+ // splice in operation counts
+ dataLayer.spliceOperationsFrom(mOperations);
+ return dataLayer;
+ }
+
+ @Override
+ public void incrementOperationCount(int uid, int tag, int operationCount) {
+ if (Binder.getCallingUid() != uid) {
+ mContext.enforceCallingOrSelfPermission(MODIFY_NETWORK_ACCOUNTING, TAG);
+ }
+
+ synchronized (mStatsLock) {
+ mOperations.combineValues(IFACE_ALL, uid, tag, 0L, 0L, 0L, 0L, operationCount);
+ }
+ }
+
+ @Override
public void forceUpdate() {
mContext.enforceCallingOrSelfPermission(READ_NETWORK_USAGE_HISTORY, TAG);
@@ -533,7 +580,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final NetworkStats uidSnapshot;
try {
networkSnapshot = mNetworkManager.getNetworkStatsSummary();
- uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsDetail() : null;
+ uidSnapshot = detailedPoll ? mNetworkManager.getNetworkStatsUidDetail(UID_ALL) : null;
} catch (IllegalStateException e) {
Slog.w(TAG, "problem reading network stats: " + e);
return;
@@ -592,7 +639,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
final NetworkStatsHistory history = findOrCreateNetworkStatsLocked(ident);
- history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
+ history.recordData(timeStart, currentTime, entry);
}
// trim any history beyond max
@@ -615,9 +662,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
ensureUidStatsLoadedLocked();
final NetworkStats delta = computeStatsDelta(mLastUidSnapshot, uidSnapshot);
+ final NetworkStats operationsDelta = computeStatsDelta(
+ mLastOperationsSnapshot, mOperations);
final long timeStart = currentTime - delta.getElapsedRealtime();
NetworkStats.Entry entry = null;
+ NetworkStats.Entry operationsEntry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
final NetworkIdentitySet ident = mActiveIfaces.get(entry.iface);
@@ -625,9 +675,16 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
continue;
}
+ // splice in operation counts since last poll
+ final int j = operationsDelta.findIndex(IFACE_ALL, entry.uid, entry.tag);
+ if (j != -1) {
+ operationsEntry = operationsDelta.getValues(j, operationsEntry);
+ entry.operations = operationsEntry.operations;
+ }
+
final NetworkStatsHistory history = findOrCreateUidStatsLocked(
ident, entry.uid, entry.tag);
- history.recordData(timeStart, currentTime, entry.rxBytes, entry.txBytes);
+ history.recordData(timeStart, currentTime, entry);
}
// trim any history beyond max
@@ -648,6 +705,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
mLastUidSnapshot = uidSnapshot;
+ mLastOperationsSnapshot = mOperations;
+ mOperations = new NetworkStats(0L, 10);
}
/**
@@ -980,7 +1039,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
final int tag = unpackTag(packed);
final NetworkStatsHistory history = uidStats.valueAt(i);
pw.print(" UID="); pw.print(uid);
- pw.print(" tag="); pw.println(tag);
+ pw.print(" tag=0x"); pw.println(Integer.toHexString(tag));
history.dump(" ", pw, fullHistory);
}
}
@@ -1028,7 +1087,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
if (before != null) {
return current.subtractClamped(before);
} else {
- return current;
+ // this is first snapshot; to prevent from double-counting we only
+ // observe traffic occuring between known snapshots.
+ return new NetworkStats(0L, 10);
}
}
@@ -1114,5 +1175,4 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
return DAY_IN_MILLIS;
}
}
-
}
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index f67c82e..b178e49 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -22,7 +22,7 @@ ifeq ($(TARGET_BOARD_PLATFORM), omap3)
LOCAL_CFLAGS += -DNO_RGBX_8888
endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
- LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+ LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
endif
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 63062cc..886bb2a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -105,6 +105,7 @@ void Layer::onFrameQueued() {
// in the purgatory list
void Layer::onRemoved()
{
+ mSurfaceTexture->abandon();
}
sp<ISurface> Layer::createSurface()
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
index 91e010f..5973e76 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.cpp
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -86,6 +86,32 @@ status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
return res;
}
+status_t SurfaceTextureLayer::connect(int api) {
+ status_t err = SurfaceTexture::connect(api);
+ if (err == NO_ERROR) {
+ switch(api) {
+ case NATIVE_WINDOW_API_MEDIA:
+ case NATIVE_WINDOW_API_CAMERA:
+ // Camera preview and videos are rate-limited on the producer
+ // side. If enabled for this build, we use async mode to always
+ // show the most recent frame at the cost of requiring an
+ // additional buffer.
+#ifndef NEVER_DEFAULT_TO_ASYNC_MODE
+ err = setSynchronousMode(false);
+ break;
+#endif
+ // fall through to set synchronous mode when not defaulting to
+ // async mode.
+ deafult:
+ err = setSynchronousMode(true);
+ break;
+ }
+ if (err != NO_ERROR) {
+ disconnect(api);
+ }
+ }
+ return err;
+}
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h
index 29a9cbe..5d328b7 100644
--- a/services/surfaceflinger/SurfaceTextureLayer.h
+++ b/services/surfaceflinger/SurfaceTextureLayer.h
@@ -50,6 +50,8 @@ protected:
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
uint32_t format, uint32_t usage);
+
+ virtual status_t connect(int api);
};
// ---------------------------------------------------------------------------
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 1620405..60be35a 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -26,10 +26,12 @@
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
<uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+ <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 56ef995..f628977 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -50,10 +50,9 @@ public class NetworkManagementServiceTest extends AndroidTestCase {
public void setUp() throws Exception {
super.setUp();
- final File canonicalFilesDir = getContext().getFilesDir().getCanonicalFile();
- mTestProc = new File(canonicalFilesDir, "proc");
+ mTestProc = new File(getContext().getFilesDir(), "proc");
if (mTestProc.exists()) {
- Files.deleteRecursively(mTestProc);
+ IoUtils.deleteContents(mTestProc);
}
mService = NetworkManagementService.createForTest(mContext, mTestProc, true);
@@ -64,7 +63,7 @@ public class NetworkManagementServiceTest extends AndroidTestCase {
mService = null;
if (mTestProc.exists()) {
- Files.deleteRecursively(mTestProc);
+ IoUtils.deleteContents(mTestProc);
}
super.tearDown();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index aab09ca..91fef22 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -197,9 +197,6 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
expect(mPowerManager.isScreenOn()).andReturn(true).atLeastOnce();
expectTime(System.currentTimeMillis());
- // default behavior is background data enabled
- expect(mConnManager.getBackgroundDataSetting()).andReturn(true);
-
replay();
mService.systemReady();
verifyAndReset();
@@ -471,7 +468,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
// pretend that 512 bytes total have happened
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 256L, 2L, 256L, 2L, 11);
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
.andReturn(stats).atLeastOnce();
@@ -547,7 +544,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 0L, 0L, 0L, 0L, 0);
state = new NetworkState[] { buildWifi() };
{
@@ -574,7 +571,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1536L, 15L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1536L, 15L, 0L, 0L, 11);
{
expectTime(currentTime);
@@ -595,7 +592,7 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase {
elapsedRealtime += MINUTE_IN_MILLIS;
currentTime = TIME_MAR_10 + elapsedRealtime;
stats = new NetworkStats(elapsedRealtime, 1)
- .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 5120L, 512L, 0L, 0L);
+ .addValues(TEST_IFACE, UID_ALL, TAG_NONE, 5120L, 512L, 0L, 0L, 22);
{
expectTime(currentTime);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
index bd80af9..cf69fd5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java
@@ -160,22 +160,25 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 1L, 2048L, 2L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 1L, 2048L, 2L, 0);
verifyAndReset();
// and bump forward again, with counters going higher. this is
@@ -185,13 +188,13 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4096L, 4L, 8192L, 8L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4096L, 8192L);
+ assertNetworkTotal(sTemplateWifi, 4096L, 4L, 8192L, 8L, 0);
verifyAndReset();
}
@@ -211,26 +214,32 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
// verify service has empty history for wifi
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 1024L, 8L, 2048L, 16L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 2)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 2)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 128L, 1L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 20);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
verifyAndReset();
// graceful shutdown system, which should trigger persist of stats, and
@@ -241,7 +250,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// we persisted them to file.
expectDefaultSettings();
replay();
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
verifyAndReset();
assertStatsFilesExist(true);
@@ -254,9 +263,9 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mService.systemReady();
// after systemReady(), we should have historical stats loaded again
- assertNetworkTotal(sTemplateWifi, 1024L, 2048L);
- assertUidTotal(sTemplateWifi, UID_RED, 512L, 256L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 128L);
+ assertNetworkTotal(sTemplateWifi, 1024L, 8L, 2048L, 16L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 512L, 4L, 256L, 2L, 20);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 128L, 1L, 128L, 1L, 10);
verifyAndReset();
}
@@ -278,20 +287,23 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// modify some number on wifi, and trigger poll event
elapsedRealtime += 2 * HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 512L, 4L, 512L, 4L));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
history = mService.getHistoryForNetwork(sTemplateWifi);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(HOUR_IN_MILLIS, history.getBucketDuration());
assertEquals(2, history.size());
verifyAndReset();
@@ -301,14 +313,14 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectSettings(0L, 30 * MINUTE_IN_MILLIS, WEEK_IN_MILLIS);
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify identical stats, but spread across 4 buckets now
history = mService.getHistoryForNetwork(sTemplateWifi);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 512L);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, 512L, 4L, 512L, 4L, 0);
assertEquals(30 * MINUTE_IN_MILLIS, history.getBucketDuration());
assertEquals(4, history.size());
verifyAndReset();
@@ -328,25 +340,32 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic on first network
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 2048L, 16L, 512L, 4L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 3)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 3)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 1536L, 12L, 512L, 4L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 512L, 4L, 0L, 0L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 15);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 10);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+ assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+ assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
verifyAndReset();
// now switch networks; this also tests that we're okay with interfaces
@@ -356,7 +375,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkState(buildMobile3gState(IMSI_2));
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -369,22 +388,24 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 128L, 1L, 1024L, 8L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 128L, 1L, 1024L, 8L));
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify original history still intact
- assertNetworkTotal(sTemplateImsi1, 2048L, 512L);
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 512L);
- assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 0L);
+ assertNetworkTotal(sTemplateImsi1, 2048L, 16L, 512L, 4L, 0);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 512L, 4L, 15);
+ assertUidTotal(sTemplateImsi1, UID_BLUE, 512L, 4L, 0L, 0L, 5);
// and verify new history also recorded under different template, which
// verifies that we didn't cross the streams.
- assertNetworkTotal(sTemplateImsi2, 128L, 1024L);
- assertNetworkTotal(sTemplateWifi, 0L, 0L);
- assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1024L);
+ assertNetworkTotal(sTemplateImsi2, 128L, 1L, 1024L, 8L, 0);
+ assertNetworkTotal(sTemplateWifi, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateImsi2, UID_BLUE, 128L, 1L, 1024L, 8L, 10);
verifyAndReset();
}
@@ -402,25 +423,32 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_ALL, TAG_NONE, 4128L, 258L, 544L, 34L));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 16L, 1L, 16L, 1L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 4096L, 258L, 512L, 32L)
.addValues(TEST_IFACE, UID_GREEN, TAG_NONE, 16L, 1L, 16L, 1L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+ mService.incrementOperationCount(UID_GREEN, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertNetworkTotal(sTemplateWifi, 4128L, 544L);
- assertUidTotal(sTemplateWifi, UID_RED, 16L, 16L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 512L);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
+ assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 16L, 1L, 16L, 1L, 10);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 4096L, 258L, 512L, 32L, 15);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5);
verifyAndReset();
// now pretend two UIDs are uninstalled, which should migrate stats to
@@ -435,11 +463,11 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
// existing uid and total should remain unchanged; but removed UID
// should be gone completely.
- assertNetworkTotal(sTemplateWifi, 4128L, 544L);
- assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L);
- assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 16L);
- assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 528L);
+ assertNetworkTotal(sTemplateWifi, 4128L, 258L, 544L, 34L, 0);
+ assertUidTotal(sTemplateWifi, UID_RED, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 0L, 0L, 0L, 0L, 0);
+ assertUidTotal(sTemplateWifi, UID_GREEN, 16L, 1L, 16L, 1L, 5);
+ assertUidTotal(sTemplateWifi, UID_REMOVED, 4112L, 259L, 528L, 33L, 25);
verifyAndReset();
}
@@ -457,20 +485,26 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 1024L, 8L, 1024L, 8L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 512L, 4L, 512L, 4L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 10);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 1024L);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1024L, 8L, 1024L, 8L, 10);
verifyAndReset();
// now switch over to 4g network
@@ -479,7 +513,7 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectDefaultSettings();
expectNetworkState(buildMobile4gState());
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
replay();
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
@@ -491,14 +525,16 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 512L, 4L, 256L, 2L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify that ALL_MOBILE template combines both
- assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 1280L);
+ assertUidTotal(sTemplateImsi1, UID_RED, 1536L, 12L, 1280L, 10L, 15);
verifyAndReset();
@@ -537,32 +573,41 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
mServiceContext.sendBroadcast(new Intent(CONNECTIVITY_ACTION));
verifyAndReset();
+ // bootstrap with full polling event to prime stats
+ performBootstrapPoll(TEST_START, elapsedRealtime);
+
// create some traffic for two apps
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L)
.addValues(TEST_IFACE, UID_RED, 0xF00D, 10L, 1L, 10L, 1L)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L));
+ mService.incrementOperationCount(UID_RED, TAG_NONE, 5);
+ mService.incrementOperationCount(UID_RED, 0xF00D, 1);
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 10);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
// verify service recorded history
- assertUidTotal(sTemplateWifi, UID_RED, 50L, 50L);
- assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 512L);
+ assertUidTotal(sTemplateWifi, UID_RED, 50L, 5L, 50L, 5L, 5);
+ assertUidTotal(sTemplateWifi, UID_BLUE, 1024L, 8L, 512L, 4L, 10);
verifyAndReset();
-
+
// now create more traffic in next hour, but only for one app
elapsedRealtime += HOUR_IN_MILLIS;
expectTime(TEST_START + elapsedRealtime);
expectDefaultSettings();
expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
- expectNetworkStatsDetail(new NetworkStats(elapsedRealtime, 1)
+ expectNetworkStatsUidDetail(new NetworkStats(elapsedRealtime, 1)
.addValues(TEST_IFACE, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L));
+ mService.incrementOperationCount(UID_BLUE, TAG_NONE, 15);
+
replay();
mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
@@ -570,28 +615,32 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
NetworkStats stats = mService.getSummaryForAllUid(
sTemplateWifi, Long.MIN_VALUE, Long.MAX_VALUE, true);
assertEquals(3, stats.size());
- assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L);
- assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L);
- assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L);
+ assertValues(stats, 0, IFACE_ALL, UID_RED, TAG_NONE, 50L, 5L, 50L, 5L, 5);
+ assertValues(stats, 1, IFACE_ALL, UID_RED, 0xF00D, 10L, 1L, 10L, 1L, 1);
+ assertValues(stats, 2, IFACE_ALL, UID_BLUE, TAG_NONE, 2048L, 16L, 1024L, 8L, 15);
// now verify that recent history only contains one uid
final long currentTime = TEST_START + elapsedRealtime;
stats = mService.getSummaryForAllUid(
sTemplateWifi, currentTime - HOUR_IN_MILLIS, currentTime, true);
assertEquals(1, stats.size());
- assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L);
+ assertValues(stats, 0, IFACE_ALL, UID_BLUE, TAG_NONE, 1024L, 8L, 512L, 4L, 5);
verifyAndReset();
}
- private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long txBytes) {
+ private void assertNetworkTotal(NetworkTemplate template, long rxBytes, long rxPackets,
+ long txBytes, long txPackets, int operations) {
final NetworkStatsHistory history = mService.getHistoryForNetwork(template);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
}
- private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long txBytes) {
+ private void assertUidTotal(NetworkTemplate template, int uid, long rxBytes, long rxPackets,
+ long txBytes, long txPackets, int operations) {
final NetworkStatsHistory history = mService.getHistoryForUid(template, uid, TAG_NONE);
- assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, txBytes);
+ assertValues(history, Long.MIN_VALUE, Long.MAX_VALUE, rxBytes, rxPackets, txBytes,
+ txPackets, operations);
}
private void expectSystemReady() throws Exception {
@@ -611,8 +660,8 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expect(mNetManager.getNetworkStatsSummary()).andReturn(summary).atLeastOnce();
}
- private void expectNetworkStatsDetail(NetworkStats detail) throws Exception {
- expect(mNetManager.getNetworkStatsDetail()).andReturn(detail).atLeastOnce();
+ private void expectNetworkStatsUidDetail(NetworkStats detail) throws Exception {
+ expect(mNetManager.getNetworkStatsUidDetail(eq(UID_ALL))).andReturn(detail).atLeastOnce();
}
private void expectDefaultSettings() throws Exception {
@@ -639,6 +688,17 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
expect(mTime.getCacheCertainty()).andReturn(0L).anyTimes();
}
+ private void performBootstrapPoll(long testStart, long elapsedRealtime) throws Exception {
+ expectTime(testStart + elapsedRealtime);
+ expectDefaultSettings();
+ expectNetworkStatsSummary(buildEmptyStats(elapsedRealtime));
+ expectNetworkStatsUidDetail(buildEmptyStats(elapsedRealtime));
+
+ replay();
+ mServiceContext.sendBroadcast(new Intent(ACTION_NETWORK_STATS_POLL));
+ verifyAndReset();
+ }
+
private void assertStatsFilesExist(boolean exist) {
final File networkFile = new File(mStatsDir, "netstats.bin");
final File uidFile = new File(mStatsDir, "netstats_uid.bin");
@@ -652,23 +712,26 @@ public class NetworkStatsServiceTest extends AndroidTestCase {
}
private static void assertValues(NetworkStats stats, int i, String iface, int uid, int tag,
- long rxBytes, long rxPackets, long txBytes, long txPackets) {
+ long rxBytes, long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStats.Entry entry = stats.getValues(i, null);
- assertEquals(iface, entry.iface);
- assertEquals(uid, entry.uid);
- assertEquals(tag, entry.tag);
- assertEquals(rxBytes, entry.rxBytes);
- // TODO: enable testing packet counts once stored in history
-// assertEquals(rxPackets, entry.rxPackets);
- assertEquals(txBytes, entry.txBytes);
-// assertEquals(txPackets, entry.txPackets);
+ assertEquals("unexpected iface", iface, entry.iface);
+ assertEquals("unexpected uid", uid, entry.uid);
+ assertEquals("unexpected tag", tag, entry.tag);
+ assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
+ assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
}
- private static void assertValues(
- NetworkStatsHistory stats, long start, long end, long rxBytes, long txBytes) {
+ private static void assertValues(NetworkStatsHistory stats, long start, long end, long rxBytes,
+ long rxPackets, long txBytes, long txPackets, int operations) {
final NetworkStatsHistory.Entry entry = stats.getValues(start, end, null);
assertEquals("unexpected rxBytes", rxBytes, entry.rxBytes);
+ assertEquals("unexpected rxPackets", rxPackets, entry.rxPackets);
assertEquals("unexpected txBytes", txBytes, entry.txBytes);
+ assertEquals("unexpected txPackets", txPackets, entry.txPackets);
+ assertEquals("unexpected operations", operations, entry.operations);
}
private static NetworkState buildWifiState() {
diff --git a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
index 50c18f0..c0870c7 100644
--- a/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ThrottleServiceTest.java
@@ -289,7 +289,7 @@ public class ThrottleServiceTest extends AndroidTestCase {
public void expectGetInterfaceCounter(long rx, long tx) throws Exception {
// TODO: provide elapsedRealtime mock to match TimeAuthority
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1);
- stats.addValues(TEST_IFACE, NetworkStats.UID_ALL, NetworkStats.TAG_NONE, rx, 0L, tx, 0L);
+ stats.addValues(TEST_IFACE, NetworkStats.UID_ALL, NetworkStats.TAG_NONE, rx, 0L, tx, 0L, 0);
expect(mMockNMService.getNetworkStatsSummary()).andReturn(stats).atLeastOnce();
}