Merge "Installd: Refactor in preparation for OTA"
diff --git a/include/android/input.h b/include/android/input.h
index 5ab4e29..5eeb7fc 100644
--- a/include/android/input.h
+++ b/include/android/input.h
@@ -644,6 +644,13 @@
*/
AMOTION_EVENT_AXIS_TILT = 25,
/**
+ * Axis constant: Generic scroll axis of a motion event.
+ *
+ * - This is used for scroll axis motion events that can't be classified as strictly
+ * vertical or horizontal. The movement of a rotating scroller is an example of this.
+ */
+ AMOTION_EVENT_AXIS_SCROLL = 26,
+ /**
* Axis constant: Generic 1 axis of a motion event.
* The interpretation of a generic axis is device-specific.
*/
@@ -817,6 +824,8 @@
AINPUT_SOURCE_TOUCH_NAVIGATION = 0x00200000 | AINPUT_SOURCE_CLASS_NONE,
/** joystick */
AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
+ /** rotary encoder */
+ AINPUT_SOURCE_ROTARY_ENCODER = 0x00400000 | AINPUT_SOURCE_CLASS_NONE,
/** any */
AINPUT_SOURCE_ANY = 0xffffff00,
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index ef01745..9271ed8 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -809,15 +809,6 @@
mCore->validateConsistencyLocked();
} // Autolock scope
- // Wait without lock held
- if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
- // Waiting here allows for two full buffers to be queued but not a
- // third. In the event that frames take varying time, this makes a
- // small trade-off in favor of latency rather than throughput.
- mLastQueueBufferFence->waitForever("Throttling EGL Production");
- mLastQueueBufferFence = fence;
- }
-
// Don't send the GraphicBuffer through the callback, and don't send
// the slot number, since the consumer shouldn't need it
item.mGraphicBuffer.clear();
@@ -841,6 +832,15 @@
mCallbackCondition.broadcast();
}
+ // Wait without lock held
+ if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+ // Waiting here allows for two full buffers to be queued but not a
+ // third. In the event that frames take varying time, this makes a
+ // small trade-off in favor of latency rather than throughput.
+ mLastQueueBufferFence->waitForever("Throttling EGL Production");
+ mLastQueueBufferFence = fence;
+ }
+
return NO_ERROR;
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 5e02ef1..3f9e332 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -101,11 +101,12 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
- GLES2/gl2.cpp.arm \
+LOCAL_SRC_FILES:= \
+ GLES2/gl2.cpp \
#
LOCAL_CLANG := false
+LOCAL_ARM_MODE := arm
LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
LOCAL_MODULE:= libGLESv2
@@ -120,14 +121,32 @@
# TODO: This is to work around b/20093774. Remove after root cause is fixed
LOCAL_LDFLAGS_arm += -Wl,--hash-style,both
-# Symlink libGLESv3.so -> libGLESv2.so
-# Platform modules should link against libGLESv2.so (-lGLESv2), but NDK apps
-# will be linked against libGLESv3.so.
-# Note we defer the evaluation of the LOCAL_POST_INSTALL_CMD,
-# so $(LOCAL_INSTALLED_MODULE) will be expanded to correct value,
-# even for both 32-bit and 64-bit installed files in multilib build.
-LOCAL_POST_INSTALL_CMD = \
- $(hide) ln -sf $(notdir $(LOCAL_INSTALLED_MODULE)) $(dir $(LOCAL_INSTALLED_MODULE))libGLESv3.so
+include $(BUILD_SHARED_LIBRARY)
+
+###############################################################################
+# Build the wrapper OpenGL ES 3.x library (this is just different name for v2)
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ GLES2/gl2.cpp \
+#
+
+LOCAL_CLANG := false
+LOCAL_ARM_MODE := arm
+LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
+LOCAL_MODULE:= libGLESv3
+LOCAL_SHARED_LIBRARIES += libdl
+# we need to access the private Bionic header <bionic_tls.h>
+LOCAL_C_INCLUDES += bionic/libc/private
+
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv3\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -fvisibility=hidden
+
+# TODO: This is to work around b/20093774. Remove after root cause is fixed
+LOCAL_LDFLAGS_arm += -Wl,--hash-style,both
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index 5859606..2a53dec 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -1191,6 +1191,15 @@
device->classes |= INPUT_DEVICE_CLASS_CURSOR;
}
+ // See if this is a rotary encoder type device.
+ String8 deviceType = String8();
+ if (device->configuration &&
+ device->configuration->tryGetProperty(String8("device.type"), deviceType)) {
+ if (!deviceType.compare(String8("rotaryEncoder"))) {
+ device->classes |= INPUT_DEVICE_CLASS_ROTARY_ENCODER;
+ }
+ }
+
// See if this is a touch pad.
// Is this a new modern multi-touch driver?
if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h
index 0f94c77..6869253 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -137,6 +137,9 @@
/* The input device is an external stylus (has data we want to fuse with touch data). */
INPUT_DEVICE_CLASS_EXTERNAL_STYLUS = 0x00000800,
+ /* The input device has a rotary encoder */
+ INPUT_DEVICE_CLASS_ROTARY_ENCODER = 0x00001000,
+
/* The input device is virtual (not a real device, not part of UI configuration). */
INPUT_DEVICE_CLASS_VIRTUAL = 0x40000000,
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index e10a101..2aee8ad 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -450,6 +450,11 @@
device->addMapper(new SwitchInputMapper(device));
}
+ // Scroll wheel-like devices.
+ if (classes & INPUT_DEVICE_CLASS_ROTARY_ENCODER) {
+ device->addMapper(new RotaryEncoderInputMapper(device));
+ }
+
// Vibrator-like devices.
if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
device->addMapper(new VibratorInputMapper(device));
@@ -2728,6 +2733,92 @@
}
}
+// --- RotaryEncoderInputMapper ---
+
+RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) :
+ InputMapper(device) {
+ mSource = AINPUT_SOURCE_ROTARY_ENCODER;
+}
+
+RotaryEncoderInputMapper::~RotaryEncoderInputMapper() {
+}
+
+uint32_t RotaryEncoderInputMapper::getSources() {
+ return mSource;
+}
+
+void RotaryEncoderInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+ InputMapper::populateDeviceInfo(info);
+
+ if (mRotaryEncoderScrollAccumulator.haveRelativeVWheel()) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_SCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
+ }
+}
+
+void RotaryEncoderInputMapper::dump(String8& dump) {
+ dump.append(INDENT2 "Rotary Encoder Input Mapper:\n");
+ dump.appendFormat(INDENT3 "HaveWheel: %s\n",
+ toString(mRotaryEncoderScrollAccumulator.haveRelativeVWheel()));
+}
+
+void RotaryEncoderInputMapper::configure(nsecs_t when,
+ const InputReaderConfiguration* config, uint32_t changes) {
+ InputMapper::configure(when, config, changes);
+ if (!changes) {
+ mRotaryEncoderScrollAccumulator.configure(getDevice());
+ }
+}
+
+void RotaryEncoderInputMapper::reset(nsecs_t when) {
+ mRotaryEncoderScrollAccumulator.reset(getDevice());
+
+ InputMapper::reset(when);
+}
+
+void RotaryEncoderInputMapper::process(const RawEvent* rawEvent) {
+ mRotaryEncoderScrollAccumulator.process(rawEvent);
+
+ if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
+ sync(rawEvent->when);
+ }
+}
+
+void RotaryEncoderInputMapper::sync(nsecs_t when) {
+ PointerCoords pointerCoords;
+ pointerCoords.clear();
+
+ PointerProperties pointerProperties;
+ pointerProperties.clear();
+ pointerProperties.id = 0;
+ pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
+
+ float scroll = mRotaryEncoderScrollAccumulator.getRelativeVWheel();
+ bool scrolled = scroll != 0;
+
+ // This is not a pointer, so it's not associated with a display.
+ int32_t displayId = ADISPLAY_ID_NONE;
+
+ // Moving the rotary encoder should wake the device (if specified).
+ uint32_t policyFlags = 0;
+ if (scrolled && getDevice()->isExternal()) {
+ policyFlags |= POLICY_FLAG_WAKE;
+ }
+
+ // Send motion event.
+ if (scrolled) {
+ int32_t metaState = mContext->getGlobalMetaState();
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_SCROLL, scroll);
+
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_SCROLL, 0, 0, metaState, 0,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ displayId, 1, &pointerProperties, &pointerCoords,
+ 0, 0, 0);
+ getListener()->notifyMotion(&scrollArgs);
+ }
+
+ mRotaryEncoderScrollAccumulator.finishSync();
+}
// --- TouchInputMapper ---
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 3a5c76f..1de9d19 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1231,6 +1231,26 @@
};
+class RotaryEncoderInputMapper : public InputMapper {
+public:
+ RotaryEncoderInputMapper(InputDevice* device);
+ virtual ~RotaryEncoderInputMapper();
+
+ virtual uint32_t getSources();
+ virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+ virtual void dump(String8& dump);
+ virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
+ virtual void reset(nsecs_t when);
+ virtual void process(const RawEvent* rawEvent);
+
+private:
+ CursorScrollAccumulator mRotaryEncoderScrollAccumulator;
+
+ int32_t mSource;
+
+ void sync(nsecs_t when);
+};
+
class TouchInputMapper : public InputMapper {
public:
TouchInputMapper(InputDevice* device);