From 66db68948c83f1940fa66d76d28208b49bed7815 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Thu, 22 Apr 2010 18:58:52 -0700 Subject: Native input dispatch rewrite work in progress. The old dispatch mechanism has been left in place and continues to be used by default for now. To enable native input dispatch, edit the ENABLE_NATIVE_DISPATCH constant in WindowManagerPolicy. Includes part of the new input event NDK API. Some details TBD. To wire up input dispatch, as the ViewRoot adds a window to the window session it receives an InputChannel object as an output argument. The InputChannel encapsulates the file descriptors for a shared memory region and two pipe end-points. The ViewRoot then provides the InputChannel to the InputQueue. Behind the scenes, InputQueue simply attaches handlers to the native PollLoop object that underlies the MessageQueue. This way MessageQueue doesn't need to know anything about input dispatch per-se, it just exposes (in native code) a PollLoop that other components can use to monitor file descriptor state changes. There can be zero or more targets for any given input event. Each input target is specified by its input channel and some parameters including flags, an X/Y coordinate offset, and the dispatch timeout. An input target can request either synchronous dispatch (for foreground apps) or asynchronous dispatch (fire-and-forget for wallpapers and "outside" targets). Currently, finding the appropriate input targets for an event requires a call back into the WindowManagerServer from native code. In the future this will be refactored to avoid most of these callbacks except as required to handle pending focus transitions. End-to-end event dispatch mostly works! To do: event injection, rate limiting, ANRs, testing, optimization, etc. Change-Id: I8c36b2b9e0a2d27392040ecda0f51b636456de25 --- include/utils/BitSet.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 include/utils/BitSet.h (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h new file mode 100644 index 0000000..19c8bf0 --- /dev/null +++ b/include/utils/BitSet.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef UTILS_BITSET_H +#define UTILS_BITSET_H + +#include + +/* + * Contains some bit manipulation helpers. + */ + +namespace android { + +// A simple set of 32 bits that can be individually marked or cleared. +struct BitSet32 { + uint32_t value; + + inline BitSet32() : value(0) { } + explicit inline BitSet32(uint32_t value) : value(value) { } + + // Gets the value associated with a particular bit index. + static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; } + + // Clears the bit set. + inline void clear() { value = 0; } + + // Returns true if the bit set does not contain any marked bits. + inline bool isEmpty() const { return ! value; } + + // Returns true if the specified bit is marked. + inline bool hasBit(uint32_t n) const { return value & valueForBit(n); } + + // Marks the specified bit. + inline void markBit(uint32_t n) { value |= valueForBit(n); } + + // Clears the specified bit. + inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); } + + // Finds the first marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t firstMarkedBit() const { return __builtin_clz(value); } + + // Finds the first unmarked bit in the set. + // Result is undefined if all bits are marked. + inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); } + + inline bool operator== (const BitSet32& other) const { return value == other.value; } + inline bool operator!= (const BitSet32& other) const { return value != other.value; } +}; + +} // namespace android + +#endif // UTILS_BITSET_H -- cgit v1.1 From 7d90df8dc30e7b22aea030f7dca01095529cc6b1 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Sun, 26 Sep 2010 22:20:12 -0700 Subject: Add suuport for splitting touch events across windows. This feature is currently used to enable dragging the start and end selection handles of a TextView at the same time. Could be used for other things later. Deleted some dead code in ArrowKeyMovementMethod and CursorControllers. Change-Id: I930accd97ca1ca1917aab8a807db2c950fc7b409 --- include/utils/BitSet.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index 19c8bf0..f5dbcd9 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -38,6 +38,9 @@ struct BitSet32 { // Clears the bit set. inline void clear() { value = 0; } + // Returns the number of marked bits in the set. + inline uint32_t count() const { return __builtin_popcount(value); } + // Returns true if the bit set does not contain any marked bits. inline bool isEmpty() const { return ! value; } -- cgit v1.1 From 9ae794de4685c080d92d8c2a09d195a0d71ae2a8 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 9 Mar 2011 17:39:48 -0800 Subject: Use touch pad gestures to manipulate the pointer. 1. Single finger tap performs a click. 2. Single finger movement moves the pointer (hovers). 3. Button press plus movement performs click or drag. While dragging, the pointer follows the finger that is moving fastest. This is important if there are additional fingers down on the touch pad for the purpose of applying force to an integrated button underneath. 4. Two fingers near each other moving in the same direction are coalesced as a swipe gesture under the pointer. 5. Two or more fingers moving in arbitrary directions are transformed into touches in the vicinity of the pointer. This makes scale/zoom and rotate gestures possible. Added a native VelocityTracker implementation to enable intelligent switching of the active pointer during drags. Change-Id: I5ada57e7f2bdb9b0a791843eb354a8c706b365dc --- include/utils/BitSet.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index f5dbcd9..f03825a 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -61,6 +61,12 @@ struct BitSet32 { // Result is undefined if all bits are marked. inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); } + // Gets the index of the specified bit in the set, which is the number of + // marked bits that appear before the specified bit. + inline uint32_t getIndexOfBit(uint32_t n) const { + return __builtin_popcount(value & ~(0xffffffffUL >> n)); + } + inline bool operator== (const BitSet32& other) const { return value == other.value; } inline bool operator!= (const BitSet32& other) const { return value != other.value; } }; -- cgit v1.1 From 5e35370a3bd941d8e797b9e9beb1b378e00157d5 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Mon, 14 Mar 2011 19:39:54 -0700 Subject: Improve VelocityTracker numerical stability. Replaced VelocityTracker with a faster and more accurate native implementation. This avoids the duplicate maintenance overhead of having two implementations. The new algorithm requires that the sample duration be at least 10ms in order to contribute to the velocity calculation. This ensures that the velocity is not severely overestimated when samples arrive in bursts. The new algorithm computes the exponentially weighted moving average using weights based on the relative duration of successive sample periods. The new algorithm is also more careful about how it handles individual pointers going down or up and their effects on the collected movement traces. The intent is to preserve the last known velocity of pointers as they go up while also ensuring that other motion samples do not count twice in that case. Bug: 4086785 Change-Id: I2632321232c64d6b8faacdb929e33f60e64dcdd3 --- include/utils/BitSet.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index f03825a..de748b5 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -61,6 +61,10 @@ struct BitSet32 { // Result is undefined if all bits are marked. inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); } + // Finds the last marked bit in the set. + // Result is undefined if all bits are unmarked. + inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); } + // Gets the index of the specified bit in the set, which is the number of // marked bits that appear before the specified bit. inline uint32_t getIndexOfBit(uint32_t n) const { -- cgit v1.1 From 82e14f67803d3457b639a8aea772a6490b34165c Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 1 Jul 2011 17:59:27 -0700 Subject: Workaround apps that make assumptions about pointer ids. Modified the touch input mapper to assign pointer ids sequentially starting from 0 instead of using the tracking id or slot index supplied by the driver. Applications should not depend on this ordering but some do. (sigh) Bug: 4980884 Change-Id: I0dfeb3ac27c57a7102a13c960c760e2a02eb7669 --- include/utils/BitSet.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index de748b5..600017e 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -44,6 +44,9 @@ struct BitSet32 { // Returns true if the bit set does not contain any marked bits. inline bool isEmpty() const { return ! value; } + // Returns true if the bit set does not contain any unmarked bits. + inline bool isFull() const { return value == 0xffffffff; } + // Returns true if the specified bit is marked. inline bool hasBit(uint32_t n) const { return value & valueForBit(n); } -- cgit v1.1 From 4ccb2fc8e129236f2832fc18b1ba0f8bbac5abbc Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Wed, 27 Jul 2011 16:04:54 -0700 Subject: Refactor input reader to add stylus support. Bug: 5064702 Introduced the concept of an InputListener to further decouple the InputReader from the InputDispatcher. The InputListener exposes just the minimum interface that the InputReader needs to communicate with the outside world. The InputReader passes arguments to the InputListener by reference, which makes it easy to queue them up. Consolidated all of the InputReader locks into one simple global Mutex. The reason this wasn't done before was due to potential re-entrance in outbound calls to the InputDispatcher. To fix this, the InputReader now queues up all of the events it wants to send using a QueuedInputListener, then flushes them outside of the critical section after all of the event processing is finished. Removing all of the InputMapper locks greatly simplifies the implementation. Added tests for new stylus features such as buttons, tool types, and hovering. Added some helpers to BitSet32 to handle common code patterns like finding the first marked bit and clearing it. Fixed a bug in VelocityTracker where the wrong pointer trace could get cleared when handling ACTION_POINTER_DOWN. Oops. Changed PointerCoords so it no longer stores useless zero axis values. Removed editAxisValue because it is not very useful when all zero value axes are absent and therefore cannot be edited in place. Added dispatch of stylus hover events. Added support for distance and tool types. Change-Id: I4cf14d134fcb1db7d10be5f2af7b37deef8f8468 --- include/utils/BitSet.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index 600017e..9452e86 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -68,6 +68,30 @@ struct BitSet32 { // Result is undefined if all bits are unmarked. inline uint32_t lastMarkedBit() const { return 31 - __builtin_ctz(value); } + // Finds the first marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearFirstMarkedBit() { + uint32_t n = firstMarkedBit(); + clearBit(n); + return n; + } + + // Finds the first unmarked bit in the set and marks it. Returns the bit index. + // Result is undefined if all bits are marked. + inline uint32_t markFirstUnmarkedBit() { + uint32_t n = firstUnmarkedBit(); + markBit(n); + return n; + } + + // Finds the last marked bit in the set and clears it. Returns the bit index. + // Result is undefined if all bits are unmarked. + inline uint32_t clearLastMarkedBit() { + uint32_t n = lastMarkedBit(); + clearBit(n); + return n; + } + // Gets the index of the specified bit in the set, which is the number of // marked bits that appear before the specified bit. inline uint32_t getIndexOfBit(uint32_t n) const { -- cgit v1.1 From 9a0a76df1e961ef4621e81814d8bf891a09bef66 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 16 Mar 2012 14:45:49 -0700 Subject: Add traits to common utils data structures. Many of our basic data structures are trivially movable using memcpy() even if they are not trivially constructable, destructable or copyable. It's worth taking advantage of this *ahem* trait. Adding trivial_move_trait to String16 reduces appt running time on frameworks/base/core/res by 40%! Change-Id: I630a1a027e2d0ded96856e4ca042ea82906289fe --- include/utils/BitSet.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index 9452e86..e189d0c 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -18,6 +18,7 @@ #define UTILS_BITSET_H #include +#include /* * Contains some bit manipulation helpers. @@ -102,6 +103,8 @@ struct BitSet32 { inline bool operator!= (const BitSet32& other) const { return value != other.value; } }; +ANDROID_BASIC_TYPES_TRAITS(BitSet32) + } // namespace android #endif // UTILS_BITSET_H -- cgit v1.1 From d614ee455705047fd27db0ad7f3013e6ea64204d Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Tue, 21 May 2013 14:11:34 -0700 Subject: Added bitwise-or and bitwise-and to BitSet Change-Id: I9bbf41f9d2d4a2593b0e6d7d8be7e283f985bade --- include/utils/BitSet.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/utils/BitSet.h') diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h index e189d0c..19c03d1 100644 --- a/include/utils/BitSet.h +++ b/include/utils/BitSet.h @@ -101,6 +101,20 @@ struct BitSet32 { inline bool operator== (const BitSet32& other) const { return value == other.value; } inline bool operator!= (const BitSet32& other) const { return value != other.value; } + inline BitSet32 operator& (const BitSet32& other) const { + return BitSet32(value & other.value); + } + inline BitSet32& operator&= (const BitSet32& other) { + value &= other.value; + return *this; + } + inline BitSet32 operator| (const BitSet32& other) const { + return BitSet32(value | other.value); + } + inline BitSet32& operator|= (const BitSet32& other) { + value |= other.value; + return *this; + } }; ANDROID_BASIC_TYPES_TRAITS(BitSet32) -- cgit v1.1