Merge "SF: Clear mCompositionInfo before recomputing visible layers"
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 4459cef..9b12a02 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -105,6 +105,8 @@
chmod 0666 /sys/kernel/tracing/events/mm_event/mm_event_record/enable
chmod 0666 /sys/kernel/debug/tracing/events/lowmemorykiller/lowmemory_kill/enable
chmod 0666 /sys/kernel/tracing/events/lowmemorykiller/lowmemory_kill/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/oom/oom_score_adj_update/enable
+ chmod 0666 /sys/kernel/tracing/events/oom/oom_score_adj_update/enable
# disk
chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_get_data_block/enable
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 72d1de9..dc7288e 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1100,7 +1100,7 @@
}
}
-// Runs dumpsys on services that must dump first and and will take less than 100ms to dump.
+// Runs dumpsys on services that must dump first and will take less than 100ms to dump.
static void RunDumpsysCritical() {
RunDumpsysText("DUMPSYS CRITICAL", IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL,
/* timeout= */ 5s, /* service_timeout= */ 500ms);
@@ -1864,17 +1864,6 @@
do_text_file = true;
} else {
do_text_file = false;
- // Since zip file is already created, it needs to be renamed.
- std::string new_path = ds.GetPath(".zip");
- if (ds.path_ != new_path) {
- MYLOGD("Renaming zip file from %s to %s\n", ds.path_.c_str(), new_path.c_str());
- if (rename(ds.path_.c_str(), new_path.c_str())) {
- MYLOGE("rename(%s, %s): %s\n", ds.path_.c_str(), new_path.c_str(),
- strerror(errno));
- } else {
- ds.path_ = new_path;
- }
- }
}
}
if (do_text_file) {
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 5e7f71d..35cbdb1 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -261,7 +261,7 @@
std::chrono::milliseconds timeout);
/*
- * Adds a text entry entry to the existing zip file.
+ * Adds a text entry to the existing zip file.
*/
bool AddTextZipEntry(const std::string& entry_name, const std::string& content);
diff --git a/include/input/Input.h b/include/input/Input.h
index d35354b..cc45aef 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -59,6 +59,12 @@
*/
AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED = 0x2,
+ /**
+ * This flag indicates that the event has been generated by a gesture generator. It
+ * provides a hint to the GestureDetector to not apply any touch slop.
+ */
+ AMOTION_EVENT_FLAG_IS_GENERATED_GESTURE = 0x8,
+
/* Motion event is inconsistent with previously sent motion events. */
AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
};
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index d906db3..dddbfb0 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -47,6 +47,13 @@
*
* Note that this structure is used for IPCs so its layout must be identical
* on 64 and 32 bit processes. This is tested in StructLayout_test.cpp.
+ *
+ * Since the struct must be aligned to an 8-byte boundary, there could be uninitialized bytes
+ * in-between the defined fields. This padding data should be explicitly accounted for by adding
+ * "empty" fields into the struct. This data is memset to zero before sending the struct across
+ * the socket. Adding the explicit fields ensures that the memset is not optimized away by the
+ * compiler. When a new field is added to the struct, the corresponding change
+ * in StructLayout_test should be made.
*/
struct InputMessage {
enum {
@@ -67,6 +74,7 @@
union Body {
struct Key {
uint32_t seq;
+ uint32_t empty1;
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
@@ -77,6 +85,7 @@
int32_t scanCode;
int32_t metaState;
int32_t repeatCount;
+ uint32_t empty2;
nsecs_t downTime __attribute__((aligned(8)));
inline size_t size() const {
@@ -86,6 +95,7 @@
struct Motion {
uint32_t seq;
+ uint32_t empty1;
nsecs_t eventTime __attribute__((aligned(8)));
int32_t deviceId;
int32_t source;
@@ -96,12 +106,14 @@
int32_t metaState;
int32_t buttonState;
int32_t edgeFlags;
+ uint32_t empty2;
nsecs_t downTime __attribute__((aligned(8)));
float xOffset;
float yOffset;
float xPrecision;
float yPrecision;
uint32_t pointerCount;
+ uint32_t empty3;
// Note that PointerCoords requires 8 byte alignment.
struct Pointer {
PointerProperties properties;
@@ -132,6 +144,7 @@
bool isValid(size_t actualSize) const;
size_t size() const;
+ void getSanitizedCopy(InputMessage* msg) const;
};
/*
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index e2c0cfa..c6fcaa4 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -163,7 +163,9 @@
ScopedAResource& operator=(ScopedAResource&&) = delete;
// move-constructing is okay
- ScopedAResource(ScopedAResource&&) = default;
+ ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) {
+ other.mT = DEFAULT;
+ }
private:
T mT;
diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp
index b715e43..add3ef0 100644
--- a/libs/gui/HdrMetadata.cpp
+++ b/libs/gui/HdrMetadata.cpp
@@ -15,6 +15,7 @@
*/
#include <gui/HdrMetadata.h>
+#include <limits>
namespace android {
@@ -26,6 +27,10 @@
if (validTypes & CTA861_3) {
size += sizeof(cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ size += sizeof(size_t);
+ size += hdr10plus.size();
+ }
return size;
}
@@ -41,6 +46,12 @@
if (validTypes & CTA861_3) {
FlattenableUtils::write(buffer, size, cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ size_t metadataSize = hdr10plus.size();
+ FlattenableUtils::write(buffer, size, metadataSize);
+ memcpy(buffer, hdr10plus.data(), metadataSize);
+ FlattenableUtils::advance(buffer, size, metadataSize);
+ }
return NO_ERROR;
}
@@ -62,6 +73,22 @@
}
FlattenableUtils::read(buffer, size, cta8613);
}
+ if (validTypes & HDR10PLUS) {
+ if (size < sizeof(size_t)) {
+ return NO_MEMORY;
+ }
+
+ size_t metadataSize;
+ FlattenableUtils::read(buffer, size, metadataSize);
+
+ if (size < metadataSize) {
+ return NO_MEMORY;
+ }
+
+ hdr10plus.resize(metadataSize);
+ memcpy(hdr10plus.data(), buffer, metadataSize);
+ FlattenableUtils::advance(buffer, size, metadataSize);
+ }
return NO_ERROR;
}
@@ -91,6 +118,10 @@
}
}
+ if ((validTypes & HDR10PLUS) == HDR10PLUS) {
+ if (hdr10plus != rhs.hdr10plus) return false;
+ }
+
return true;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index b505c6f..00e23f0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -965,6 +965,9 @@
case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
res = dispatchSetBuffersCta8613Metadata(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
+ res = dispatchSetBuffersHdr10PlusMetadata(args);
+ break;
case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
res = dispatchSetSurfaceDamage(args);
break;
@@ -1120,6 +1123,12 @@
return setBuffersCta8613Metadata(metadata);
}
+int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) {
+ const size_t size = va_arg(args, size_t);
+ const uint8_t* metadata = va_arg(args, const uint8_t*);
+ return setBuffersHdr10PlusMetadata(size, metadata);
+}
+
int Surface::dispatchSetSurfaceDamage(va_list args) {
android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
size_t numRects = va_arg(args, size_t);
@@ -1568,6 +1577,19 @@
return NO_ERROR;
}
+int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
+ ALOGV("Surface::setBuffersBlobMetadata");
+ Mutex::Autolock lock(mMutex);
+ if (size > 0) {
+ mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
+ mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
+ } else {
+ mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS;
+ mHdrMetadata.hdr10plus.clear();
+ }
+ return NO_ERROR;
+}
+
Dataspace Surface::getBuffersDataSpace() {
ALOGV("Surface::getBuffersDataSpace");
Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
index 9800602..1e9c3e7 100644
--- a/libs/gui/include/gui/HdrMetadata.h
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -17,6 +17,7 @@
#pragma once
#include <stdint.h>
+#include <vector>
#include <system/graphics.h>
#include <utils/Flattenable.h>
@@ -26,12 +27,15 @@
struct HdrMetadata : public LightFlattenable<HdrMetadata> {
enum Type : uint32_t {
SMPTE2086 = 1 << 0,
- CTA861_3 = 1 << 1,
+ CTA861_3 = 1 << 1,
+ HDR10PLUS = 1 << 2,
};
+
uint32_t validTypes{0};
android_smpte2086_metadata smpte2086{};
android_cta861_3_metadata cta8613{};
+ std::vector<uint8_t> hdr10plus{};
// LightFlattenable
bool isFixedSize() const { return false; }
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 32ee595..248e105 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -218,6 +218,7 @@
int dispatchSetBuffersDataSpace(va_list args);
int dispatchSetBuffersSmpte2086Metadata(va_list args);
int dispatchSetBuffersCta8613Metadata(va_list args);
+ int dispatchSetBuffersHdr10PlusMetadata(va_list args);
int dispatchSetSurfaceDamage(va_list args);
int dispatchSetSharedBufferMode(va_list args);
int dispatchSetAutoRefresh(va_list args);
@@ -249,6 +250,7 @@
virtual int setBuffersDataSpace(ui::Dataspace dataSpace);
virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata);
virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata);
+ virtual int setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata);
virtual int setCrop(Rect const* rect);
virtual int setUsage(uint64_t reqUsage);
virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d0600da..4ba7da3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -366,10 +366,17 @@
78.0,
62.0,
};
+
+ std::vector<uint8_t> hdr10plus;
+ hdr10plus.push_back(0xff);
+
int error = native_window_set_buffers_smpte2086_metadata(window.get(), &smpte2086);
ASSERT_EQ(error, NO_ERROR);
error = native_window_set_buffers_cta861_3_metadata(window.get(), &cta861_3);
ASSERT_EQ(error, NO_ERROR);
+ error = native_window_set_buffers_hdr10_plus_metadata(window.get(), hdr10plus.size(),
+ hdr10plus.data());
+ ASSERT_EQ(error, NO_ERROR);
}
TEST_F(SurfaceTest, DynamicSetBufferCount) {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index e93f3a4..f33b210 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -97,6 +97,106 @@
return sizeof(Header);
}
+/**
+ * There could be non-zero bytes in-between InputMessage fields. Force-initialize the entire
+ * memory to zero, then only copy the valid bytes on a per-field basis.
+ */
+void InputMessage::getSanitizedCopy(InputMessage* msg) const {
+ memset(msg, 0, sizeof(*msg));
+
+ // Write the header
+ msg->header.type = header.type;
+
+ // Write the body
+ switch(header.type) {
+ case InputMessage::TYPE_KEY: {
+ // uint32_t seq
+ msg->body.key.seq = body.key.seq;
+ // nsecs_t eventTime
+ msg->body.key.eventTime = body.key.eventTime;
+ // int32_t deviceId
+ msg->body.key.deviceId = body.key.deviceId;
+ // int32_t source
+ msg->body.key.source = body.key.source;
+ // int32_t displayId
+ msg->body.key.displayId = body.key.displayId;
+ // int32_t action
+ msg->body.key.action = body.key.action;
+ // int32_t flags
+ msg->body.key.flags = body.key.flags;
+ // int32_t keyCode
+ msg->body.key.keyCode = body.key.keyCode;
+ // int32_t scanCode
+ msg->body.key.scanCode = body.key.scanCode;
+ // int32_t metaState
+ msg->body.key.metaState = body.key.metaState;
+ // int32_t repeatCount
+ msg->body.key.repeatCount = body.key.repeatCount;
+ // nsecs_t downTime
+ msg->body.key.downTime = body.key.downTime;
+ break;
+ }
+ case InputMessage::TYPE_MOTION: {
+ // uint32_t seq
+ msg->body.motion.seq = body.motion.seq;
+ // nsecs_t eventTime
+ msg->body.motion.eventTime = body.motion.eventTime;
+ // int32_t deviceId
+ msg->body.motion.deviceId = body.motion.deviceId;
+ // int32_t source
+ msg->body.motion.source = body.motion.source;
+ // int32_t displayId
+ msg->body.motion.displayId = body.motion.displayId;
+ // int32_t action
+ msg->body.motion.action = body.motion.action;
+ // int32_t actionButton
+ msg->body.motion.actionButton = body.motion.actionButton;
+ // int32_t flags
+ msg->body.motion.flags = body.motion.flags;
+ // int32_t metaState
+ msg->body.motion.metaState = body.motion.metaState;
+ // int32_t buttonState
+ msg->body.motion.buttonState = body.motion.buttonState;
+ // int32_t edgeFlags
+ msg->body.motion.edgeFlags = body.motion.edgeFlags;
+ // nsecs_t downTime
+ msg->body.motion.downTime = body.motion.downTime;
+ // float xOffset
+ msg->body.motion.xOffset = body.motion.xOffset;
+ // float yOffset
+ msg->body.motion.yOffset = body.motion.yOffset;
+ // float xPrecision
+ msg->body.motion.xPrecision = body.motion.xPrecision;
+ // float yPrecision
+ msg->body.motion.yPrecision = body.motion.yPrecision;
+ // uint32_t pointerCount
+ msg->body.motion.pointerCount = body.motion.pointerCount;
+ //struct Pointer pointers[MAX_POINTERS]
+ for (size_t i = 0; i < body.motion.pointerCount; i++) {
+ // PointerProperties properties
+ msg->body.motion.pointers[i].properties.id = body.motion.pointers[i].properties.id;
+ msg->body.motion.pointers[i].properties.toolType =
+ body.motion.pointers[i].properties.toolType,
+ // PointerCoords coords
+ msg->body.motion.pointers[i].coords.bits = body.motion.pointers[i].coords.bits;
+ const uint32_t count = BitSet64::count(body.motion.pointers[i].coords.bits);
+ memcpy(&msg->body.motion.pointers[i].coords.values[0],
+ &body.motion.pointers[i].coords.values[0],
+ count * (sizeof(body.motion.pointers[i].coords.values[0])));
+ }
+ break;
+ }
+ case InputMessage::TYPE_FINISHED: {
+ msg->body.finished.seq = body.finished.seq;
+ msg->body.finished.handled = body.finished.handled;
+ break;
+ }
+ default: {
+ LOG_FATAL("Unexpected message type %i", header.type);
+ break;
+ }
+ }
+}
// --- InputChannel ---
@@ -160,10 +260,12 @@
}
status_t InputChannel::sendMessage(const InputMessage* msg) {
- size_t msgLength = msg->size();
+ const size_t msgLength = msg->size();
+ InputMessage cleanMsg;
+ msg->getSanitizedCopy(&cleanMsg);
ssize_t nWrite;
do {
- nWrite = ::send(mFd, msg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
+ nWrite = ::send(mFd, &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
} while (nWrite == -1 && errno == EINTR);
if (nWrite < 0) {
diff --git a/libs/input/tests/StructLayout_test.cpp b/libs/input/tests/StructLayout_test.cpp
index d19f3b8..12a6782 100644
--- a/libs/input/tests/StructLayout_test.cpp
+++ b/libs/input/tests/StructLayout_test.cpp
@@ -65,6 +65,9 @@
CHECK_OFFSET(InputMessage::Body::Motion, yPrecision, 76);
CHECK_OFFSET(InputMessage::Body::Motion, pointerCount, 80);
CHECK_OFFSET(InputMessage::Body::Motion, pointers, 88);
+
+ CHECK_OFFSET(InputMessage::Body::Finished, seq, 0);
+ CHECK_OFFSET(InputMessage::Body::Finished, handled, 4);
}
} // namespace android
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 197f73f..61590e0 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -202,7 +202,7 @@
* ANativeWindow.
*/
enum {
-// clang-format off
+ // clang-format off
NATIVE_WINDOW_SET_USAGE = 0, /* deprecated */
NATIVE_WINDOW_CONNECT = 1, /* deprecated */
NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
@@ -237,7 +237,8 @@
NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
-// clang-format on
+ NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
+ // clang-format on
};
/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
@@ -748,6 +749,27 @@
}
/*
+ * native_window_set_buffers_hdr10_plus_metadata(..., metadata)
+ * All buffers queued after this call will be associated with the
+ * HDR10+ dynamic metadata specified.
+ *
+ * metadata specifies additional dynamic information about the
+ * contents of the buffer that may affect how it is displayed. When
+ * it is nullptr, it means no such information is available. No
+ * HDR10+ dynamic emtadata is associated with the buffers by default.
+ *
+ * Parameter "size" refers to the length of the metadata blob pointed to
+ * by parameter "data". The metadata blob will adhere to the HDR10+ SEI
+ * message standard.
+ */
+static inline int native_window_set_buffers_hdr10_plus_metadata(struct ANativeWindow* window,
+ const size_t size,
+ const uint8_t* metadata) {
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA, size,
+ metadata);
+}
+
+/*
* native_window_set_buffers_transform(..., int transform)
* All buffers queued after this call will be displayed transformed according
* to the transform parameter specified.
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 7efc8bd..beaf9ee 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -50,7 +50,6 @@
"gl/GLExtensions.cpp",
"gl/GLFramebuffer.cpp",
"gl/GLImage.cpp",
- "gl/GLSurface.cpp",
"gl/Program.cpp",
"gl/ProgramCache.cpp",
],
diff --git a/libs/renderengine/gl/GLES20RenderEngine.cpp b/libs/renderengine/gl/GLES20RenderEngine.cpp
index 70a4322..d35762d 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.cpp
+++ b/libs/renderengine/gl/GLES20RenderEngine.cpp
@@ -41,7 +41,6 @@
#include "GLExtensions.h"
#include "GLFramebuffer.h"
#include "GLImage.h"
-#include "GLSurface.h"
#include "Program.h"
#include "ProgramCache.h"
@@ -275,6 +274,8 @@
// now figure out what version of GL did we actually get
// NOTE: a dummy surface is not needed if KHR_create_context is supported
+ // TODO(alecmouri): don't create this surface if EGL_KHR_surfaceless_context
+ // is supported.
EGLConfig dummyConfig = config;
if (dummyConfig == EGL_NO_CONFIG) {
@@ -301,10 +302,10 @@
break;
case GLES_VERSION_2_0:
case GLES_VERSION_3_0:
- engine = std::make_unique<GLES20RenderEngine>(featureFlags);
+ engine = std::make_unique<GLES20RenderEngine>(featureFlags, display, config, ctxt,
+ dummy);
break;
}
- engine->setEGLHandles(display, config, ctxt);
ALOGI("OpenGL ES informations:");
ALOGI("vendor : %s", extensions.getVendor());
@@ -314,9 +315,6 @@
ALOGI("GL_MAX_TEXTURE_SIZE = %zu", engine->getMaxTextureSize());
ALOGI("GL_MAX_VIEWPORT_DIMS = %zu", engine->getMaxViewportDims());
- eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- eglDestroySurface(display, dummy);
-
return engine;
}
@@ -359,11 +357,13 @@
return config;
}
-GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags)
+GLES20RenderEngine::GLES20RenderEngine(uint32_t featureFlags, EGLDisplay display, EGLConfig config,
+ EGLContext ctxt, EGLSurface dummy)
: renderengine::impl::RenderEngine(featureFlags),
- mEGLDisplay(EGL_NO_DISPLAY),
- mEGLConfig(nullptr),
- mEGLContext(EGL_NO_CONTEXT),
+ mEGLDisplay(display),
+ mEGLConfig(config),
+ mEGLContext(ctxt),
+ mDummySurface(dummy),
mVpWidth(0),
mVpHeight(0),
mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
@@ -422,10 +422,6 @@
return std::make_unique<GLFramebuffer>(*this);
}
-std::unique_ptr<Surface> GLES20RenderEngine::createSurface() {
- return std::make_unique<GLSurface>(*this);
-}
-
std::unique_ptr<Image> GLES20RenderEngine::createImage() {
return std::make_unique<GLImage>(*this);
}
@@ -438,31 +434,6 @@
return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
}
-bool GLES20RenderEngine::setCurrentSurface(const Surface& surface) {
- // Surface is an abstract interface. GLES20RenderEngine only ever
- // creates GLSurface's, so it is safe to just cast to the actual
- // type.
- bool success = true;
- const GLSurface& glSurface = static_cast<const GLSurface&>(surface);
- EGLSurface eglSurface = glSurface.getEGLSurface();
- if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) {
- success = eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext) == EGL_TRUE;
- if (success && glSurface.getAsync()) {
- eglSwapInterval(mEGLDisplay, 0);
- }
- if (success) {
- mSurfaceHeight = glSurface.getHeight();
- }
- }
-
- return success;
-}
-
-void GLES20RenderEngine::resetCurrentSurface() {
- eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- mSurfaceHeight = 0;
-}
-
base::unique_fd GLES20RenderEngine::flush() {
if (!GLExtensions::getInstance().hasNativeFenceSync()) {
return base::unique_fd();
@@ -576,7 +547,7 @@
void GLES20RenderEngine::setScissor(const Rect& region) {
// Invert y-coordinate to map to GL-space.
- int32_t canvasHeight = mRenderToFbo ? mFboHeight : mSurfaceHeight;
+ int32_t canvasHeight = mFboHeight;
int32_t glBottom = canvasHeight - region.bottom;
glScissor(region.left, glBottom, region.getWidth(), region.getHeight());
@@ -619,7 +590,6 @@
glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0);
- mRenderToFbo = true;
mFboHeight = glFramebuffer->getBufferHeight();
uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -631,17 +601,10 @@
}
void GLES20RenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
- mRenderToFbo = false;
mFboHeight = 0;
// back to main framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Workaround for b/77935566 to force the EGL driver to release the
- // screenshot buffer
- setScissor(Rect::EMPTY_RECT);
- clearWithColor(0.0, 0.0, 0.0, 0.0);
- disableScissor();
}
void GLES20RenderEngine::checkErrors() const {
@@ -666,9 +629,7 @@
int32_t r = sourceCrop.right;
int32_t b = sourceCrop.bottom;
int32_t t = sourceCrop.top;
- if (mRenderToFbo) {
- std::swap(t, b);
- }
+ std::swap(t, b);
mat4 m = mat4::ortho(l, r, b, t, 0, 1);
// Apply custom rotation to the projection.
@@ -974,12 +935,6 @@
return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
}
-void GLES20RenderEngine::setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt) {
- mEGLDisplay = display;
- mEGLConfig = config;
- mEGLContext = ctxt;
-}
-
} // namespace gl
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/GLES20RenderEngine.h b/libs/renderengine/gl/GLES20RenderEngine.h
index 148df2f..6c50938 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.h
+++ b/libs/renderengine/gl/GLES20RenderEngine.h
@@ -40,24 +40,21 @@
namespace gl {
class GLImage;
-class GLSurface;
class GLES20RenderEngine : public impl::RenderEngine {
public:
static std::unique_ptr<GLES20RenderEngine> create(int hwcFormat, uint32_t featureFlags);
static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig);
- GLES20RenderEngine(uint32_t featureFlags); // See RenderEngine::FeatureFlag
+ GLES20RenderEngine(uint32_t featureFlags, // See RenderEngine::FeatureFlag
+ EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
~GLES20RenderEngine() override;
std::unique_ptr<Framebuffer> createFramebuffer() override;
- std::unique_ptr<Surface> createSurface() override;
std::unique_ptr<Image> createImage() override;
void primeCache() const override;
bool isCurrent() const override;
- bool setCurrentSurface(const Surface& surface) override;
- void resetCurrentSurface() override;
base::unique_fd flush() override;
bool finish() override;
bool waitFence(base::unique_fd fenceFd) override;
@@ -120,11 +117,12 @@
// with PQ or HLG transfer function.
bool isHdrDataSpace(const ui::Dataspace dataSpace) const;
bool needsXYZTransformMatrix() const;
- void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt);
+ void setEGLHandles(EGLDisplay display, EGLConfig config, EGLContext ctxt, EGLSurface dummy);
EGLDisplay mEGLDisplay;
EGLConfig mEGLConfig;
EGLContext mEGLContext;
+ EGLSurface mDummySurface;
GLuint mProtectedTexName;
GLint mMaxViewportDims[2];
GLint mMaxTextureSize;
@@ -145,8 +143,6 @@
mat4 mBt2020ToSrgb;
mat4 mBt2020ToDisplayP3;
- bool mRenderToFbo = false;
- int32_t mSurfaceHeight = 0;
int32_t mFboHeight = 0;
// Current dataspace of layer being rendered
diff --git a/libs/renderengine/gl/GLSurface.cpp b/libs/renderengine/gl/GLSurface.cpp
deleted file mode 100644
index 2d694e9..0000000
--- a/libs/renderengine/gl/GLSurface.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#include "GLSurface.h"
-
-#include <android/native_window.h>
-#include <log/log.h>
-#include <ui/PixelFormat.h>
-#include "GLES20RenderEngine.h"
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-GLSurface::GLSurface(const GLES20RenderEngine& engine)
- : mEGLDisplay(engine.getEGLDisplay()), mEGLConfig(engine.getEGLConfig()) {
- // RE does not assume any config when EGL_KHR_no_config_context is supported
- if (mEGLConfig == EGL_NO_CONFIG_KHR) {
- mEGLConfig =
- GLES20RenderEngine::chooseEglConfig(mEGLDisplay, PIXEL_FORMAT_RGBA_8888, false);
- }
-}
-
-GLSurface::~GLSurface() {
- setNativeWindow(nullptr);
-}
-
-void GLSurface::setNativeWindow(ANativeWindow* window) {
- if (mEGLSurface != EGL_NO_SURFACE) {
- eglDestroySurface(mEGLDisplay, mEGLSurface);
- mEGLSurface = EGL_NO_SURFACE;
- mSurfaceWidth = 0;
- mSurfaceHeight = 0;
- }
-
- mWindow = window;
- if (mWindow) {
- mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mWindow, nullptr);
- mSurfaceWidth = ANativeWindow_getWidth(window);
- mSurfaceHeight = ANativeWindow_getHeight(window);
- }
-}
-
-void GLSurface::swapBuffers() const {
- if (!eglSwapBuffers(mEGLDisplay, mEGLSurface)) {
- EGLint error = eglGetError();
-
- const char format[] = "eglSwapBuffers(%p, %p) failed with 0x%08x";
- if (mCritical || error == EGL_CONTEXT_LOST) {
- LOG_ALWAYS_FATAL(format, mEGLDisplay, mEGLSurface, error);
- } else {
- ALOGE(format, mEGLDisplay, mEGLSurface, error);
- }
- }
-}
-
-EGLint GLSurface::queryConfig(EGLint attrib) const {
- EGLint value;
- if (!eglGetConfigAttrib(mEGLDisplay, mEGLConfig, attrib, &value)) {
- value = 0;
- }
-
- return value;
-}
-
-int32_t GLSurface::queryRedSize() const {
- return queryConfig(EGL_RED_SIZE);
-}
-
-int32_t GLSurface::queryGreenSize() const {
- return queryConfig(EGL_GREEN_SIZE);
-}
-
-int32_t GLSurface::queryBlueSize() const {
- return queryConfig(EGL_BLUE_SIZE);
-}
-
-int32_t GLSurface::queryAlphaSize() const {
- return queryConfig(EGL_ALPHA_SIZE);
-}
-
-int32_t GLSurface::getWidth() const {
- return mSurfaceWidth;
-}
-
-int32_t GLSurface::getHeight() const {
- return mSurfaceHeight;
-}
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/gl/GLSurface.h b/libs/renderengine/gl/GLSurface.h
deleted file mode 100644
index 092d371..0000000
--- a/libs/renderengine/gl/GLSurface.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2018 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.
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include <EGL/egl.h>
-#include <android-base/macros.h>
-#include <renderengine/Surface.h>
-
-struct ANativeWindow;
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-class GLES20RenderEngine;
-
-class GLSurface final : public renderengine::Surface {
-public:
- GLSurface(const GLES20RenderEngine& engine);
- ~GLSurface() override;
-
- // renderengine::Surface implementation
- void setCritical(bool enable) override { mCritical = enable; }
- void setAsync(bool enable) override { mAsync = enable; }
-
- void setNativeWindow(ANativeWindow* window) override;
- void swapBuffers() const override;
-
- int32_t queryRedSize() const override;
- int32_t queryGreenSize() const override;
- int32_t queryBlueSize() const override;
- int32_t queryAlphaSize() const override;
-
- bool getAsync() const { return mAsync; }
- EGLSurface getEGLSurface() const { return mEGLSurface; }
-
- int32_t getWidth() const override;
- int32_t getHeight() const override;
-
-private:
- EGLint queryConfig(EGLint attrib) const;
-
- EGLDisplay mEGLDisplay;
- EGLConfig mEGLConfig;
-
- bool mCritical = false;
- bool mAsync = false;
-
- int32_t mSurfaceWidth = 0;
- int32_t mSurfaceHeight = 0;
-
- ANativeWindow* mWindow = nullptr;
- EGLSurface mEGLSurface = EGL_NO_SURFACE;
-
- DISALLOW_COPY_AND_ASSIGN(GLSurface);
-};
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index becb3c3..22891c4 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -48,7 +48,6 @@
class BindNativeBufferAsFramebuffer;
class Image;
class Mesh;
-class Surface;
class Texture;
namespace impl {
@@ -72,7 +71,6 @@
// used to support legacy behavior.
virtual std::unique_ptr<Framebuffer> createFramebuffer() = 0;
- virtual std::unique_ptr<Surface> createSurface() = 0;
virtual std::unique_ptr<Image> createImage() = 0;
virtual void primeCache() const = 0;
@@ -84,8 +82,6 @@
virtual bool useWaitSync() const = 0;
virtual bool isCurrent() const = 0;
- virtual bool setCurrentSurface(const Surface& surface) = 0;
- virtual void resetCurrentSurface() = 0;
// helpers
// flush submits RenderEngine command stream for execution and returns a
diff --git a/libs/renderengine/include/renderengine/Surface.h b/libs/renderengine/include/renderengine/Surface.h
deleted file mode 100644
index ba7331d..0000000
--- a/libs/renderengine/include/renderengine/Surface.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#pragma once
-
-#include <cstdint>
-
-struct ANativeWindow;
-
-namespace android {
-namespace renderengine {
-
-class Surface {
-public:
- virtual ~Surface() = default;
-
- virtual void setCritical(bool enable) = 0;
- virtual void setAsync(bool enable) = 0;
-
- virtual void setNativeWindow(ANativeWindow* window) = 0;
- virtual void swapBuffers() const = 0;
-
- virtual int32_t queryRedSize() const = 0;
- virtual int32_t queryGreenSize() const = 0;
- virtual int32_t queryBlueSize() const = 0;
- virtual int32_t queryAlphaSize() const = 0;
-
- virtual int32_t getWidth() const = 0;
- virtual int32_t getHeight() const = 0;
-};
-
-} // namespace renderengine
-} // namespace android
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 7e0175a..297e0c4 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -16,52 +16,53 @@
#if defined(__ANDROID__)
+#include <cutils/properties.h>
+#include "Loader.h"
#include "egl_angle_platform.h"
-#include <time.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include <EGL/Platform.h>
+#pragma GCC diagnostic pop
+
+#include <android/dlext.h>
+#include <dlfcn.h>
+#include <graphicsenv/GraphicsEnv.h>
+#include <time.h>
#include <log/log.h>
namespace angle {
-GetDisplayPlatformFunc AnglePlatformImpl::angleGetDisplayPlatform = nullptr;
-ResetDisplayPlatformFunc AnglePlatformImpl::angleResetDisplayPlatform = nullptr;
-// Initialize start time
-time_t AnglePlatformImpl::startTime = time(nullptr);
+static GetDisplayPlatformFunc angleGetDisplayPlatform = nullptr;
+static ResetDisplayPlatformFunc angleResetDisplayPlatform = nullptr;
-void AnglePlatformImpl::assignAnglePlatformMethods(PlatformMethods* platformMethods) {
- platformMethods->addTraceEvent = addTraceEvent;
- platformMethods->getTraceCategoryEnabledFlag = getTraceCategoryEnabledFlag;
- platformMethods->monotonicallyIncreasingTime = monotonicallyIncreasingTime;
- platformMethods->logError = logError;
- platformMethods->logWarning = logWarning;
- platformMethods->logInfo = logInfo;
-}
+static time_t startTime = time(nullptr);
-const unsigned char* AnglePlatformImpl::getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
- const char* /*categoryName*/) {
+static const unsigned char* getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
+ const char* /*categoryName*/) {
// Returning ptr to 'g' (non-zero) to ALWAYS enable tracing initially.
// This ptr is what will be passed into "category_group_enabled" of addTraceEvent
static const unsigned char traceEnabled = 'g';
return &traceEnabled;
}
-double AnglePlatformImpl::monotonicallyIncreasingTime(PlatformMethods* /*platform*/) {
+static double monotonicallyIncreasingTime(PlatformMethods* /*platform*/) {
return difftime(time(nullptr), startTime);
}
-void AnglePlatformImpl::logError(PlatformMethods* /*platform*/, const char* errorMessage) {
+static void logError(PlatformMethods* /*platform*/, const char* errorMessage) {
ALOGE("ANGLE Error:%s", errorMessage);
}
-void AnglePlatformImpl::logWarning(PlatformMethods* /*platform*/, const char* warningMessage) {
+static void logWarning(PlatformMethods* /*platform*/, const char* warningMessage) {
ALOGW("ANGLE Warn:%s", warningMessage);
}
-void AnglePlatformImpl::logInfo(PlatformMethods* /*platform*/, const char* infoMessage) {
+static void logInfo(PlatformMethods* /*platform*/, const char* infoMessage) {
ALOGD("ANGLE Info:%s", infoMessage);
}
-TraceEventHandle AnglePlatformImpl::addTraceEvent(
+static TraceEventHandle addTraceEvent(
PlatformMethods* /**platform*/, char phase, const unsigned char* /*category_group_enabled*/,
const char* name, unsigned long long /*id*/, double /*timestamp*/, int /*num_args*/,
const char** /*arg_names*/, const unsigned char* /*arg_types*/,
@@ -88,6 +89,58 @@
return result;
}
+static void assignAnglePlatformMethods(PlatformMethods* platformMethods) {
+ platformMethods->addTraceEvent = addTraceEvent;
+ platformMethods->getTraceCategoryEnabledFlag = getTraceCategoryEnabledFlag;
+ platformMethods->monotonicallyIncreasingTime = monotonicallyIncreasingTime;
+ platformMethods->logError = logError;
+ platformMethods->logWarning = logWarning;
+ platformMethods->logInfo = logInfo;
+}
+
+// Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace
+bool initializeAnglePlatform(EGLDisplay dpy) {
+ // Since we're inside libEGL, use dlsym to lookup fptr for ANGLEGetDisplayPlatform
+ android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = ns,
+ };
+ void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ angleGetDisplayPlatform =
+ reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
+
+ if (!angleGetDisplayPlatform) {
+ ALOGE("dlsym lookup of ANGLEGetDisplayPlatform in libEGL_angle failed!");
+ return false;
+ }
+
+ angleResetDisplayPlatform =
+ reinterpret_cast<ResetDisplayPlatformFunc>(
+ eglGetProcAddress("ANGLEResetDisplayPlatform"));
+
+ PlatformMethods* platformMethods = nullptr;
+ if (!((angleGetDisplayPlatform)(dpy, g_PlatformMethodNames,
+ g_NumPlatformMethods, nullptr,
+ &platformMethods))) {
+ ALOGE("ANGLEGetDisplayPlatform call failed!");
+ return false;
+ }
+ if (platformMethods) {
+ assignAnglePlatformMethods(platformMethods);
+ } else {
+ ALOGE("In initializeAnglePlatform() platformMethods struct ptr is NULL. Not assigning "
+ "tracing function ptrs!");
+ }
+ return true;
+}
+
+void resetAnglePlatform(EGLDisplay dpy) {
+ if (angleResetDisplayPlatform) {
+ angleResetDisplayPlatform(dpy);
+ }
+}
+
}; // namespace angle
#endif // __ANDROID__
diff --git a/opengl/libs/EGL/egl_angle_platform.h b/opengl/libs/EGL/egl_angle_platform.h
index 7c6c8ed..6c24aa5 100644
--- a/opengl/libs/EGL/egl_angle_platform.h
+++ b/opengl/libs/EGL/egl_angle_platform.h
@@ -18,40 +18,15 @@
#if defined(__ANDROID__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#include <EGL/Platform.h>
-#pragma GCC diagnostic pop
+#include "egldefs.h"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-
#include "egl_trace.h"
namespace angle {
-class AnglePlatformImpl {
-public:
- static void assignAnglePlatformMethods(PlatformMethods* platformMethods);
- static GetDisplayPlatformFunc angleGetDisplayPlatform;
- static ResetDisplayPlatformFunc angleResetDisplayPlatform;
-
-private:
- static time_t startTime;
- static const unsigned char* getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
- const char* /*categoryName*/);
- static double monotonicallyIncreasingTime(PlatformMethods* /*platform*/);
- static void logError(PlatformMethods* /*platform*/, const char* errorMessage);
- static void logWarning(PlatformMethods* /*platform*/, const char* warningMessage);
- static void logInfo(PlatformMethods* /*platform*/, const char* infoMessage);
- static TraceEventHandle addTraceEvent(PlatformMethods* /**platform*/, char phase,
- const unsigned char* /*category_group_enabled*/,
- const char* name, unsigned long long /*id*/,
- double /*timestamp*/, int /*num_args*/,
- const char** /*arg_names*/,
- const unsigned char* /*arg_types*/,
- const unsigned long long* /*arg_values*/,
- unsigned char /*flags*/);
-};
+bool initializeAnglePlatform(EGLDisplay dpy);
+void resetAnglePlatform(EGLDisplay dpy);
}; // namespace angle
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index a065973..4433af0 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -164,43 +164,6 @@
return true;
}
-// Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace
-bool initializeAnglePlatform(EGLDisplay dpy) {
- // Since we're inside libEGL, use dlsym to lookup fptr for ANGLEGetDisplayPlatform
- android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = ns,
- };
- void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
- angle::AnglePlatformImpl::angleGetDisplayPlatform =
- reinterpret_cast<angle::GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
-
- if (!angle::AnglePlatformImpl::angleGetDisplayPlatform) {
- ALOGE("dlsym lookup of ANGLEGetDisplayPlatform in libEGL_angle failed!");
- return false;
- }
-
- angle::AnglePlatformImpl::angleResetDisplayPlatform =
- reinterpret_cast<angle::ResetDisplayPlatformFunc>(
- eglGetProcAddress("ANGLEResetDisplayPlatform"));
-
- angle::PlatformMethods* platformMethods = nullptr;
- if (!((angle::AnglePlatformImpl::angleGetDisplayPlatform)(dpy, angle::g_PlatformMethodNames,
- angle::g_NumPlatformMethods, nullptr,
- &platformMethods))) {
- ALOGE("ANGLEGetDisplayPlatform call failed!");
- return false;
- }
- if (platformMethods) {
- angle::AnglePlatformImpl::assignAnglePlatformMethods(platformMethods);
- } else {
- ALOGE("In initializeAnglePlatform() platformMethods struct ptr is NULL. Not assigning "
- "tracing function ptrs!");
- }
- return true;
-}
-
static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
const EGLAttrib* attrib_list, EGLint* error) {
EGLDisplay dpy = EGL_NO_DISPLAY;
@@ -228,7 +191,7 @@
if (dpy == EGL_NO_DISPLAY) {
ALOGE("eglGetPlatformDisplay failed!");
} else {
- if (!initializeAnglePlatform(dpy)) {
+ if (!angle::initializeAnglePlatform(dpy)) {
ALOGE("initializeAnglePlatform failed!");
}
}
@@ -505,8 +468,8 @@
egl_connection_t* const cnx = &gEGLImpl;
if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
// If we're using ANGLE reset any custom DisplayPlatform
- if (cnx->useAngle && angle::AnglePlatformImpl::angleResetDisplayPlatform) {
- (angle::AnglePlatformImpl::angleResetDisplayPlatform)(disp.dpy);
+ if (cnx->useAngle) {
+ angle::resetAnglePlatform(disp.dpy);
}
if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 7812cb2..4a8b613 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -18,24 +18,20 @@
cpp_std: "c++17",
srcs: [
- "EventHub.cpp",
"InputDispatcher.cpp",
- "InputListener.cpp",
"InputManager.cpp",
- "InputReader.cpp",
],
shared_libs: [
+ "libinputflinger_base",
+ "libinputreader",
"libbase",
"libbinder",
- "libcrypto",
"libcutils",
"libinput",
"liblog",
"libutils",
"libui",
- "libhardware_legacy",
- "libutils"
],
cflags: [
@@ -47,7 +43,91 @@
//-fvisibility=hidden
],
- export_include_dirs: ["."],
+ export_include_dirs: [
+ ".",
+ "include",
+ ],
+
+}
+
+
+cc_library_headers {
+ name: "libinputflinger_headers",
+
+ export_include_dirs: ["include"],
+}
+
+cc_library_shared {
+ name: "libinputreader",
+
+ cpp_std: "c++17",
+
+ srcs: [
+ "EventHub.cpp",
+ "InputReader.cpp",
+ "InputReaderFactory.cpp",
+ ],
+
+ shared_libs: [
+ "libinputflinger_base",
+ "libbase",
+ "libcrypto",
+ "libcutils",
+ "libinput",
+ "liblog",
+ "libutils",
+ "libui",
+ "libhardware_legacy",
+ "libutils"
+ ],
+
+ header_libs: [
+ "libinputflinger_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libinputflinger_headers",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
+}
+
+cc_library_shared {
+ name: "libinputflinger_base",
+
+ cpp_std: "c++17",
+
+ srcs: [
+ "InputListener.cpp",
+ "InputReaderBase.cpp",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libinput",
+ "liblog",
+ "libutils",
+ ],
+
+ header_libs: [
+ "libinputflinger_headers",
+ ],
+
+ export_header_lib_headers: [
+ "libinputflinger_headers",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Werror",
+ "-Wno-unused-parameter",
+ ],
}
subdirs = [
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 40ca6a7..388423c 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -19,6 +19,7 @@
//#define LOG_NDEBUG 0
#include "InputManager.h"
+#include "InputReaderFactory.h"
#include <log/log.h>
#include <unordered_map>
@@ -26,19 +27,10 @@
namespace android {
InputManager::InputManager(
- const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
mDispatcher = new InputDispatcher(dispatcherPolicy);
- mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
- initialize();
-}
-
-InputManager::InputManager(
- const sp<InputReaderInterface>& reader,
- const sp<InputDispatcherInterface>& dispatcher) :
- mReader(reader),
- mDispatcher(dispatcher) {
+ mReader = createInputReader(readerPolicy, mDispatcher);
initialize();
}
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index d0e4cb0..1173fa1 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -22,7 +22,7 @@
*/
#include "EventHub.h"
-#include "InputReader.h"
+#include "InputReaderBase.h"
#include "InputDispatcher.h"
#include <input/Input.h>
@@ -80,15 +80,9 @@
public:
InputManager(
- const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& readerPolicy,
const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
- // (used for testing purposes)
- InputManager(
- const sp<InputReaderInterface>& reader,
- const sp<InputDispatcherInterface>& dispatcher);
-
virtual status_t start();
virtual status_t stop();
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index e85e6ef..9dd14dc 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -254,47 +254,6 @@
}
-// --- InputReaderConfiguration ---
-
-std::optional<DisplayViewport> InputReaderConfiguration::getDisplayViewport(
- ViewportType viewportType, const std::string& uniqueDisplayId) const {
- for (const DisplayViewport& currentViewport : mDisplays) {
- if (currentViewport.type == viewportType) {
- if (uniqueDisplayId.empty() ||
- (!uniqueDisplayId.empty() && uniqueDisplayId == currentViewport.uniqueId)) {
- return std::make_optional(currentViewport);
- }
- }
- }
- return std::nullopt;
-}
-
-void InputReaderConfiguration::setDisplayViewports(const std::vector<DisplayViewport>& viewports) {
- mDisplays = viewports;
-}
-
-void InputReaderConfiguration::dump(std::string& dump) const {
- for (const DisplayViewport& viewport : mDisplays) {
- dumpViewport(dump, viewport);
- }
-}
-
-void InputReaderConfiguration::dumpViewport(std::string& dump, const DisplayViewport& viewport)
- const {
- dump += StringPrintf(INDENT4 "%s\n", viewport.toString().c_str());
-}
-
-
-// -- TouchAffineTransformation --
-void TouchAffineTransformation::applyTo(float& x, float& y) const {
- float newX, newY;
- newX = x * x_scale + y * x_ymix + x_offset;
- newY = x * y_xmix + y * y_scale + y_offset;
-
- x = newX;
- y = newY;
-}
-
// --- InputReader ---
@@ -987,21 +946,6 @@
}
-// --- InputReaderThread ---
-
-InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
- Thread(/*canCallJava*/ true), mReader(reader) {
-}
-
-InputReaderThread::~InputReaderThread() {
-}
-
-bool InputReaderThread::threadLoop() {
- mReader->loopOnce();
- return true;
-}
-
-
// --- InputDevice ---
InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index 9b0007a..1786fe8 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -20,6 +20,7 @@
#include "EventHub.h"
#include "PointerControllerInterface.h"
#include "InputListener.h"
+#include "InputReaderBase.h"
#include <input/DisplayViewport.h>
#include <input/Input.h>
@@ -28,314 +29,20 @@
#include <ui/DisplayInfo.h>
#include <utils/KeyedVector.h>
#include <utils/Condition.h>
-#include <utils/Thread.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
-#include <utils/RefBase.h>
#include <utils/BitSet.h>
-#include <utils/SortedVector.h>
#include <optional>
#include <stddef.h>
#include <unistd.h>
#include <vector>
-// Maximum supported size of a vibration pattern.
-// Must be at least 2.
-#define MAX_VIBRATE_PATTERN_SIZE 100
-
-// Maximum allowable delay value in a vibration pattern before
-// which the delay will be truncated.
-#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
-
namespace android {
class InputDevice;
class InputMapper;
-/*
- * Input reader configuration.
- *
- * Specifies various options that modify the behavior of the input reader.
- */
-struct InputReaderConfiguration {
- // Describes changes that have occurred.
- enum {
- // The pointer speed changed.
- CHANGE_POINTER_SPEED = 1 << 0,
-
- // The pointer gesture control changed.
- CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
-
- // The display size or orientation changed.
- CHANGE_DISPLAY_INFO = 1 << 2,
-
- // The visible touches option changed.
- CHANGE_SHOW_TOUCHES = 1 << 3,
-
- // The keyboard layouts must be reloaded.
- CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
-
- // The device name alias supplied by the may have changed for some devices.
- CHANGE_DEVICE_ALIAS = 1 << 5,
-
- // The location calibration matrix changed.
- CHANGE_TOUCH_AFFINE_TRANSFORMATION = 1 << 6,
-
- // The presence of an external stylus has changed.
- CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7,
-
- // The pointer capture mode has changed.
- CHANGE_POINTER_CAPTURE = 1 << 8,
-
- // The set of disabled input devices (disabledDevices) has changed.
- CHANGE_ENABLED_STATE = 1 << 9,
-
- // All devices must be reopened.
- CHANGE_MUST_REOPEN = 1 << 31,
- };
-
- // Gets the amount of time to disable virtual keys after the screen is touched
- // in order to filter out accidental virtual key presses due to swiping gestures
- // or taps near the edge of the display. May be 0 to disable the feature.
- nsecs_t virtualKeyQuietTime;
-
- // The excluded device names for the platform.
- // Devices with these names will be ignored.
- std::vector<std::string> excludedDeviceNames;
-
- // Velocity control parameters for mouse pointer movements.
- VelocityControlParameters pointerVelocityControlParameters;
-
- // Velocity control parameters for mouse wheel movements.
- VelocityControlParameters wheelVelocityControlParameters;
-
- // True if pointer gestures are enabled.
- bool pointerGesturesEnabled;
-
- // Quiet time between certain pointer gesture transitions.
- // Time to allow for all fingers or buttons to settle into a stable state before
- // starting a new gesture.
- nsecs_t pointerGestureQuietInterval;
-
- // The minimum speed that a pointer must travel for us to consider switching the active
- // touch pointer to it during a drag. This threshold is set to avoid switching due
- // to noise from a finger resting on the touch pad (perhaps just pressing it down).
- float pointerGestureDragMinSwitchSpeed; // in pixels per second
-
- // Tap gesture delay time.
- // The time between down and up must be less than this to be considered a tap.
- nsecs_t pointerGestureTapInterval;
-
- // Tap drag gesture delay time.
- // The time between the previous tap's up and the next down must be less than
- // this to be considered a drag. Otherwise, the previous tap is finished and a
- // new tap begins.
- //
- // Note that the previous tap will be held down for this entire duration so this
- // interval must be shorter than the long press timeout.
- nsecs_t pointerGestureTapDragInterval;
-
- // The distance in pixels that the pointer is allowed to move from initial down
- // to up and still be called a tap.
- float pointerGestureTapSlop; // in pixels
-
- // Time after the first touch points go down to settle on an initial centroid.
- // This is intended to be enough time to handle cases where the user puts down two
- // fingers at almost but not quite exactly the same time.
- nsecs_t pointerGestureMultitouchSettleInterval;
-
- // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
- // at least two pointers have moved at least this far from their starting place.
- float pointerGestureMultitouchMinDistance; // in pixels
-
- // The transition from PRESS to SWIPE gesture mode can only occur when the
- // cosine of the angle between the two vectors is greater than or equal to than this value
- // which indicates that the vectors are oriented in the same direction.
- // When the vectors are oriented in the exactly same direction, the cosine is 1.0.
- // (In exactly opposite directions, the cosine is -1.0.)
- float pointerGestureSwipeTransitionAngleCosine;
-
- // The transition from PRESS to SWIPE gesture mode can only occur when the
- // fingers are no more than this far apart relative to the diagonal size of
- // the touch pad. For example, a ratio of 0.5 means that the fingers must be
- // no more than half the diagonal size of the touch pad apart.
- float pointerGestureSwipeMaxWidthRatio;
-
- // The gesture movement speed factor relative to the size of the display.
- // Movement speed applies when the fingers are moving in the same direction.
- // Without acceleration, a full swipe of the touch pad diagonal in movement mode
- // will cover this portion of the display diagonal.
- float pointerGestureMovementSpeedRatio;
-
- // The gesture zoom speed factor relative to the size of the display.
- // Zoom speed applies when the fingers are mostly moving relative to each other
- // to execute a scale gesture or similar.
- // Without acceleration, a full swipe of the touch pad diagonal in zoom mode
- // will cover this portion of the display diagonal.
- float pointerGestureZoomSpeedRatio;
-
- // True to show the location of touches on the touch screen as spots.
- bool showTouches;
-
- // True if pointer capture is enabled.
- bool pointerCapture;
-
- // The set of currently disabled input devices.
- SortedVector<int32_t> disabledDevices;
-
- InputReaderConfiguration() :
- virtualKeyQuietTime(0),
- pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
- wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
- pointerGesturesEnabled(true),
- pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
- pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
- pointerGestureTapInterval(150 * 1000000LL), // 150 ms
- pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
- pointerGestureTapSlop(10.0f), // 10 pixels
- pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
- pointerGestureMultitouchMinDistance(15), // 15 pixels
- pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
- pointerGestureSwipeMaxWidthRatio(0.25f),
- pointerGestureMovementSpeedRatio(0.8f),
- pointerGestureZoomSpeedRatio(0.3f),
- showTouches(false) { }
-
- std::optional<DisplayViewport> getDisplayViewport(ViewportType viewportType,
- const std::string& uniqueDisplayId) const;
- void setDisplayViewports(const std::vector<DisplayViewport>& viewports);
-
-
- void dump(std::string& dump) const;
- void dumpViewport(std::string& dump, const DisplayViewport& viewport) const;
-
-private:
- std::vector<DisplayViewport> mDisplays;
-};
-
-
-struct TouchAffineTransformation {
- float x_scale;
- float x_ymix;
- float x_offset;
- float y_xmix;
- float y_scale;
- float y_offset;
-
- TouchAffineTransformation() :
- x_scale(1.0f), x_ymix(0.0f), x_offset(0.0f),
- y_xmix(0.0f), y_scale(1.0f), y_offset(0.0f) {
- }
-
- TouchAffineTransformation(float xscale, float xymix, float xoffset,
- float yxmix, float yscale, float yoffset) :
- x_scale(xscale), x_ymix(xymix), x_offset(xoffset),
- y_xmix(yxmix), y_scale(yscale), y_offset(yoffset) {
- }
-
- void applyTo(float& x, float& y) const;
-};
-
-
-/*
- * Input reader policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI. This interface is also mocked in the unit tests.
- *
- * 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:
- InputReaderPolicyInterface() { }
- virtual ~InputReaderPolicyInterface() { }
-
-public:
- /* Gets the input reader configuration. */
- virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
-
- /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
- virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
-
- /* Notifies the input reader policy that some input devices have changed
- * and provides information about all current input devices.
- */
- virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
-
- /* Gets the keyboard layout for a particular input device. */
- virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(
- const InputDeviceIdentifier& identifier) = 0;
-
- /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
- virtual std::string getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
-
- /* Gets the affine calibration associated with the specified device. */
- virtual TouchAffineTransformation getTouchAffineTransformation(
- const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
-};
-
-
-/* Processes raw input events and sends cooked event data to an input listener. */
-class InputReaderInterface : public virtual RefBase {
-protected:
- InputReaderInterface() { }
- virtual ~InputReaderInterface() { }
-
-public:
- /* Dumps the state of the input reader.
- *
- * This method may be called on any thread (usually by the input manager). */
- virtual void dump(std::string& dump) = 0;
-
- /* Called by the heatbeat to ensures that the reader has not deadlocked. */
- virtual void monitor() = 0;
-
- /* Returns true if the input device is enabled. */
- virtual bool isInputDeviceEnabled(int32_t deviceId) = 0;
-
- /* Runs a single iteration of the processing loop.
- * Nominally reads and processes one incoming message from the EventHub.
- *
- * This method should be called on the input reader thread.
- */
- virtual void loopOnce() = 0;
-
- /* Gets information about all input devices.
- *
- * This method may be called on any thread (usually by the input manager).
- */
- virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0;
-
- /* Query current input state. */
- virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t scanCode) = 0;
- virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
- int32_t keyCode) = 0;
- virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
- int32_t sw) = 0;
-
- /* Toggle Caps Lock */
- virtual void toggleCapsLockState(int32_t deviceId) = 0;
-
- /* Determine whether physical keys exist for the given framework-domain key codes. */
- virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
- size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
-
- /* Requests that a reconfiguration of all input devices.
- * The changes flag is a bitfield that indicates what has changed and whether
- * the input devices must all be reopened. */
- virtual void requestRefreshConfiguration(uint32_t changes) = 0;
-
- /* Controls the vibrator of a particular input device. */
- virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
- ssize_t repeat, int32_t token) = 0;
- virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;
-};
struct StylusState {
/* Time the stylus event was received. */
@@ -527,19 +234,6 @@
};
-/* Reads raw events from the event hub and processes them, endlessly. */
-class InputReaderThread : public Thread {
-public:
- explicit InputReaderThread(const sp<InputReaderInterface>& reader);
- virtual ~InputReaderThread();
-
-private:
- sp<InputReaderInterface> mReader;
-
- virtual bool threadLoop();
-};
-
-
/* Represents the state of a single input device. */
class InputDevice {
public:
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
new file mode 100644
index 0000000..17a116e
--- /dev/null
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 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 "InputReaderBase"
+
+//#define LOG_NDEBUG 0
+
+#include "InputReaderBase.h"
+
+#include <android/log.h>
+#include <android-base/stringprintf.h>
+
+#define INDENT " "
+#define INDENT2 " "
+#define INDENT3 " "
+#define INDENT4 " "
+#define INDENT5 " "
+
+using android::base::StringPrintf;
+
+namespace android {
+
+// --- InputReaderThread ---
+
+InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
+ Thread(/*canCallJava*/ true), mReader(reader) {
+}
+
+InputReaderThread::~InputReaderThread() {
+}
+
+bool InputReaderThread::threadLoop() {
+ mReader->loopOnce();
+ return true;
+}
+
+// --- InputReaderConfiguration ---
+
+std::optional<DisplayViewport> InputReaderConfiguration::getDisplayViewport(
+ ViewportType viewportType, const std::string& uniqueDisplayId) const {
+ for (const DisplayViewport& currentViewport : mDisplays) {
+ if (currentViewport.type == viewportType) {
+ if (uniqueDisplayId.empty() ||
+ (!uniqueDisplayId.empty() && uniqueDisplayId == currentViewport.uniqueId)) {
+ return std::make_optional(currentViewport);
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+void InputReaderConfiguration::setDisplayViewports(const std::vector<DisplayViewport>& viewports) {
+ mDisplays = viewports;
+}
+
+void InputReaderConfiguration::dump(std::string& dump) const {
+ for (const DisplayViewport& viewport : mDisplays) {
+ dumpViewport(dump, viewport);
+ }
+}
+
+void InputReaderConfiguration::dumpViewport(std::string& dump, const DisplayViewport& viewport)
+ const {
+ dump += StringPrintf(INDENT4 "%s\n", viewport.toString().c_str());
+}
+
+
+// -- TouchAffineTransformation --
+void TouchAffineTransformation::applyTo(float& x, float& y) const {
+ float newX, newY;
+ newX = x * x_scale + y * x_ymix + x_offset;
+ newY = x * y_xmix + y * y_scale + y_offset;
+
+ x = newX;
+ y = newY;
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/InputReaderFactory.cpp b/services/inputflinger/InputReaderFactory.cpp
new file mode 100644
index 0000000..3534f6b
--- /dev/null
+++ b/services/inputflinger/InputReaderFactory.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include "InputReaderFactory.h"
+#include "InputReader.h"
+
+namespace android {
+
+sp<InputReaderInterface> createInputReader(
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputListenerInterface>& listener) {
+ return new InputReader(new EventHub(), policy, listener);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/include/EventHub.h
similarity index 100%
rename from services/inputflinger/EventHub.h
rename to services/inputflinger/include/EventHub.h
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/include/InputListener.h
similarity index 100%
rename from services/inputflinger/InputListener.h
rename to services/inputflinger/include/InputListener.h
diff --git a/services/inputflinger/include/InputReaderBase.h b/services/inputflinger/include/InputReaderBase.h
new file mode 100644
index 0000000..fff8480
--- /dev/null
+++ b/services/inputflinger/include/InputReaderBase.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_READER_BASE_H
+#define _UI_INPUT_READER_BASE_H
+
+#include "PointerControllerInterface.h"
+
+#include <input/Input.h>
+#include <input/InputDevice.h>
+#include <input/DisplayViewport.h>
+#include <input/VelocityControl.h>
+#include <input/VelocityTracker.h>
+#include <utils/KeyedVector.h>
+#include <utils/Thread.h>
+#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
+
+#include <optional>
+#include <stddef.h>
+#include <unistd.h>
+#include <vector>
+
+// Maximum supported size of a vibration pattern.
+// Must be at least 2.
+#define MAX_VIBRATE_PATTERN_SIZE 100
+
+// Maximum allowable delay value in a vibration pattern before
+// which the delay will be truncated.
+#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
+
+namespace android {
+
+/* Processes raw input events and sends cooked event data to an input listener. */
+class InputReaderInterface : public virtual RefBase {
+protected:
+ InputReaderInterface() { }
+ virtual ~InputReaderInterface() { }
+
+public:
+ /* Dumps the state of the input reader.
+ *
+ * This method may be called on any thread (usually by the input manager). */
+ virtual void dump(std::string& dump) = 0;
+
+ /* Called by the heatbeat to ensures that the reader has not deadlocked. */
+ virtual void monitor() = 0;
+
+ /* Returns true if the input device is enabled. */
+ virtual bool isInputDeviceEnabled(int32_t deviceId) = 0;
+
+ /* Runs a single iteration of the processing loop.
+ * Nominally reads and processes one incoming message from the EventHub.
+ *
+ * This method should be called on the input reader thread.
+ */
+ virtual void loopOnce() = 0;
+
+ /* Gets information about all input devices.
+ *
+ * This method may be called on any thread (usually by the input manager).
+ */
+ virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0;
+
+ /* Query current input state. */
+ virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t scanCode) = 0;
+ virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+ int32_t keyCode) = 0;
+ virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+ int32_t sw) = 0;
+
+ /* Toggle Caps Lock */
+ virtual void toggleCapsLockState(int32_t deviceId) = 0;
+
+ /* Determine whether physical keys exist for the given framework-domain key codes. */
+ virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
+
+ /* Requests that a reconfiguration of all input devices.
+ * The changes flag is a bitfield that indicates what has changed and whether
+ * the input devices must all be reopened. */
+ virtual void requestRefreshConfiguration(uint32_t changes) = 0;
+
+ /* Controls the vibrator of a particular input device. */
+ virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
+ ssize_t repeat, int32_t token) = 0;
+ virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;
+};
+
+/* Reads raw events from the event hub and processes them, endlessly. */
+class InputReaderThread : public Thread {
+public:
+ explicit InputReaderThread(const sp<InputReaderInterface>& reader);
+ virtual ~InputReaderThread();
+
+private:
+ sp<InputReaderInterface> mReader;
+
+ virtual bool threadLoop();
+};
+
+/*
+ * Input reader configuration.
+ *
+ * Specifies various options that modify the behavior of the input reader.
+ */
+struct InputReaderConfiguration {
+ // Describes changes that have occurred.
+ enum {
+ // The pointer speed changed.
+ CHANGE_POINTER_SPEED = 1 << 0,
+
+ // The pointer gesture control changed.
+ CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
+
+ // The display size or orientation changed.
+ CHANGE_DISPLAY_INFO = 1 << 2,
+
+ // The visible touches option changed.
+ CHANGE_SHOW_TOUCHES = 1 << 3,
+
+ // The keyboard layouts must be reloaded.
+ CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
+
+ // The device name alias supplied by the may have changed for some devices.
+ CHANGE_DEVICE_ALIAS = 1 << 5,
+
+ // The location calibration matrix changed.
+ CHANGE_TOUCH_AFFINE_TRANSFORMATION = 1 << 6,
+
+ // The presence of an external stylus has changed.
+ CHANGE_EXTERNAL_STYLUS_PRESENCE = 1 << 7,
+
+ // The pointer capture mode has changed.
+ CHANGE_POINTER_CAPTURE = 1 << 8,
+
+ // The set of disabled input devices (disabledDevices) has changed.
+ CHANGE_ENABLED_STATE = 1 << 9,
+
+ // All devices must be reopened.
+ CHANGE_MUST_REOPEN = 1 << 31,
+ };
+
+ // Gets the amount of time to disable virtual keys after the screen is touched
+ // in order to filter out accidental virtual key presses due to swiping gestures
+ // or taps near the edge of the display. May be 0 to disable the feature.
+ nsecs_t virtualKeyQuietTime;
+
+ // The excluded device names for the platform.
+ // Devices with these names will be ignored.
+ std::vector<std::string> excludedDeviceNames;
+
+ // Velocity control parameters for mouse pointer movements.
+ VelocityControlParameters pointerVelocityControlParameters;
+
+ // Velocity control parameters for mouse wheel movements.
+ VelocityControlParameters wheelVelocityControlParameters;
+
+ // True if pointer gestures are enabled.
+ bool pointerGesturesEnabled;
+
+ // Quiet time between certain pointer gesture transitions.
+ // Time to allow for all fingers or buttons to settle into a stable state before
+ // starting a new gesture.
+ nsecs_t pointerGestureQuietInterval;
+
+ // The minimum speed that a pointer must travel for us to consider switching the active
+ // touch pointer to it during a drag. This threshold is set to avoid switching due
+ // to noise from a finger resting on the touch pad (perhaps just pressing it down).
+ float pointerGestureDragMinSwitchSpeed; // in pixels per second
+
+ // Tap gesture delay time.
+ // The time between down and up must be less than this to be considered a tap.
+ nsecs_t pointerGestureTapInterval;
+
+ // Tap drag gesture delay time.
+ // The time between the previous tap's up and the next down must be less than
+ // this to be considered a drag. Otherwise, the previous tap is finished and a
+ // new tap begins.
+ //
+ // Note that the previous tap will be held down for this entire duration so this
+ // interval must be shorter than the long press timeout.
+ nsecs_t pointerGestureTapDragInterval;
+
+ // The distance in pixels that the pointer is allowed to move from initial down
+ // to up and still be called a tap.
+ float pointerGestureTapSlop; // in pixels
+
+ // Time after the first touch points go down to settle on an initial centroid.
+ // This is intended to be enough time to handle cases where the user puts down two
+ // fingers at almost but not quite exactly the same time.
+ nsecs_t pointerGestureMultitouchSettleInterval;
+
+ // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
+ // at least two pointers have moved at least this far from their starting place.
+ float pointerGestureMultitouchMinDistance; // in pixels
+
+ // The transition from PRESS to SWIPE gesture mode can only occur when the
+ // cosine of the angle between the two vectors is greater than or equal to than this value
+ // which indicates that the vectors are oriented in the same direction.
+ // When the vectors are oriented in the exactly same direction, the cosine is 1.0.
+ // (In exactly opposite directions, the cosine is -1.0.)
+ float pointerGestureSwipeTransitionAngleCosine;
+
+ // The transition from PRESS to SWIPE gesture mode can only occur when the
+ // fingers are no more than this far apart relative to the diagonal size of
+ // the touch pad. For example, a ratio of 0.5 means that the fingers must be
+ // no more than half the diagonal size of the touch pad apart.
+ float pointerGestureSwipeMaxWidthRatio;
+
+ // The gesture movement speed factor relative to the size of the display.
+ // Movement speed applies when the fingers are moving in the same direction.
+ // Without acceleration, a full swipe of the touch pad diagonal in movement mode
+ // will cover this portion of the display diagonal.
+ float pointerGestureMovementSpeedRatio;
+
+ // The gesture zoom speed factor relative to the size of the display.
+ // Zoom speed applies when the fingers are mostly moving relative to each other
+ // to execute a scale gesture or similar.
+ // Without acceleration, a full swipe of the touch pad diagonal in zoom mode
+ // will cover this portion of the display diagonal.
+ float pointerGestureZoomSpeedRatio;
+
+ // True to show the location of touches on the touch screen as spots.
+ bool showTouches;
+
+ // True if pointer capture is enabled.
+ bool pointerCapture;
+
+ // The set of currently disabled input devices.
+ SortedVector<int32_t> disabledDevices;
+
+ InputReaderConfiguration() :
+ virtualKeyQuietTime(0),
+ pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
+ wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
+ pointerGesturesEnabled(true),
+ pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
+ pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
+ pointerGestureTapInterval(150 * 1000000LL), // 150 ms
+ pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
+ pointerGestureTapSlop(10.0f), // 10 pixels
+ pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
+ pointerGestureMultitouchMinDistance(15), // 15 pixels
+ pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
+ pointerGestureSwipeMaxWidthRatio(0.25f),
+ pointerGestureMovementSpeedRatio(0.8f),
+ pointerGestureZoomSpeedRatio(0.3f),
+ showTouches(false) { }
+
+ std::optional<DisplayViewport> getDisplayViewport(ViewportType viewportType,
+ const std::string& uniqueDisplayId) const;
+ void setDisplayViewports(const std::vector<DisplayViewport>& viewports);
+
+
+ void dump(std::string& dump) const;
+ void dumpViewport(std::string& dump, const DisplayViewport& viewport) const;
+
+private:
+ std::vector<DisplayViewport> mDisplays;
+};
+
+struct TouchAffineTransformation {
+ float x_scale;
+ float x_ymix;
+ float x_offset;
+ float y_xmix;
+ float y_scale;
+ float y_offset;
+
+ TouchAffineTransformation() :
+ x_scale(1.0f), x_ymix(0.0f), x_offset(0.0f),
+ y_xmix(0.0f), y_scale(1.0f), y_offset(0.0f) {
+ }
+
+ TouchAffineTransformation(float xscale, float xymix, float xoffset,
+ float yxmix, float yscale, float yoffset) :
+ x_scale(xscale), x_ymix(xymix), x_offset(xoffset),
+ y_xmix(yxmix), y_scale(yscale), y_offset(yoffset) {
+ }
+
+ void applyTo(float& x, float& y) const;
+};
+
+/*
+ * Input reader policy interface.
+ *
+ * The input reader policy is used by the input reader to interact with the Window Manager
+ * and other system components.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI. This interface is also mocked in the unit tests.
+ *
+ * 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:
+ InputReaderPolicyInterface() { }
+ virtual ~InputReaderPolicyInterface() { }
+
+public:
+ /* Gets the input reader configuration. */
+ virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
+
+ /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
+ virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
+
+ /* Notifies the input reader policy that some input devices have changed
+ * and provides information about all current input devices.
+ */
+ virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
+
+ /* Gets the keyboard layout for a particular input device. */
+ virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(
+ const InputDeviceIdentifier& identifier) = 0;
+
+ /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
+ virtual std::string getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
+
+ /* Gets the affine calibration associated with the specified device. */
+ virtual TouchAffineTransformation getTouchAffineTransformation(
+ const std::string& inputDeviceDescriptor, int32_t surfaceRotation) = 0;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_READER_COMMON_H
\ No newline at end of file
diff --git a/services/inputflinger/include/InputReaderFactory.h b/services/inputflinger/include/InputReaderFactory.h
new file mode 100644
index 0000000..9db6233
--- /dev/null
+++ b/services/inputflinger/include/InputReaderFactory.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class InputReaderInterface;
+class InputReaderPolicyInterface;
+class InputListenerInterface;
+
+sp<InputReaderInterface> createInputReader(
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputListenerInterface>& listener);
+
+} // namespace android
diff --git a/services/inputflinger/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
similarity index 100%
rename from services/inputflinger/PointerControllerInterface.h
rename to services/inputflinger/include/PointerControllerInterface.h
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index ea42855..389a57c 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -24,6 +24,8 @@
"libui",
"libinput",
"libinputflinger",
+ "libinputreader",
+ "libinputflinger_base",
"libinputservice",
],
}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 6114f51..929424b 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1753,11 +1753,11 @@
mFakePolicy->clearViewports();
}
- static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
+ static void process(InputMapper* mapper, nsecs_t when, int32_t type,
int32_t code, int32_t value) {
RawEvent event;
event.when = when;
- event.deviceId = deviceId;
+ event.deviceId = mapper->getDeviceId();
event.type = type;
event.code = code;
event.value = value;
@@ -1835,10 +1835,10 @@
SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
addMapperAndConfigure(mapper);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_HEADPHONE_INSERT, 0);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SW, SW_LID, 1);
+ process(mapper, ARBITRARY_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
+ process(mapper, ARBITRARY_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
NotifySwitchArgs args;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
@@ -1874,13 +1874,13 @@
int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
NotifyKeyArgs args;
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, originalScanCode, 1);
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, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, originalScanCode, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(originalScanCode, args.scanCode);
@@ -1907,8 +1907,7 @@
addMapperAndConfigure(mapper);
// Key down by scan code.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_HOME, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_HOME, 1);
NotifyKeyArgs args;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
@@ -1923,8 +1922,7 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Key up by scan code.
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
- EV_KEY, KEY_HOME, 0);
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_HOME, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -1938,10 +1936,8 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Key down by usage code.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_MSC, MSC_SCAN, USAGE_A);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, 0, 1);
+ process(mapper, ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A);
+ process(mapper, ARBITRARY_TIME, EV_KEY, 0, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -1955,10 +1951,8 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Key up by usage code.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_MSC, MSC_SCAN, USAGE_A);
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
- EV_KEY, 0, 0);
+ process(mapper, ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_A);
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, 0, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -1972,10 +1966,8 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Key down with unknown scan code or usage code.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_UNKNOWN, 1);
+ process(mapper, ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UNKNOWN, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -1989,10 +1981,8 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Key up with unknown scan code or usage code.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
- EV_KEY, KEY_UNKNOWN, 0);
+ process(mapper, ARBITRARY_TIME, EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_UNKNOWN, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DEVICE_ID, args.deviceId);
ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
@@ -2018,8 +2008,7 @@
ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
// Metakey down.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_LEFTSHIFT, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_LEFTSHIFT, 1);
NotifyKeyArgs args;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
@@ -2027,22 +2016,19 @@
ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
// Key down.
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
- EV_KEY, KEY_A, 1);
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, KEY_A, 1);
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, 0);
+ process(mapper, ARBITRARY_TIME + 2, EV_KEY, KEY_A, 0);
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, 0);
+ process(mapper, ARBITRARY_TIME + 3, EV_KEY, KEY_LEFTSHIFT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AMETA_NONE, args.metaState);
ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
@@ -2129,7 +2115,7 @@
NotifyKeyArgs args;
clearViewports();
prepareDisplay(DISPLAY_ORIENTATION_270);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
@@ -2137,7 +2123,7 @@
clearViewports();
prepareDisplay(DISPLAY_ORIENTATION_180);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
ASSERT_EQ(KEY_UP, args.scanCode);
@@ -2155,16 +2141,16 @@
NotifyKeyArgs args;
// Display id should be ADISPLAY_ID_NONE without any display configuration.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
prepareDisplay(DISPLAY_ORIENTATION_0);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
}
@@ -2185,9 +2171,9 @@
setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
UNIQUE_ID, ViewportType::VIEWPORT_INTERNAL);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(DISPLAY_ID, args.displayId);
@@ -2195,9 +2181,9 @@
clearViewports();
setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0,
UNIQUE_ID, ViewportType::VIEWPORT_INTERNAL);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 1);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_UP, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
ASSERT_EQ(newDisplayId, args.displayId);
}
@@ -2258,60 +2244,48 @@
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
// Toggle caps lock on.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_CAPSLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_CAPSLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState());
// Toggle num lock on.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_NUMLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_NUMLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState());
// Toggle caps lock off.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_CAPSLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_CAPSLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_CAPSLOCK, 0);
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState());
// Toggle scroll lock on.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_SCROLLLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_SCROLLLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
// Toggle num lock off.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_NUMLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_NUMLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_NUMLOCK, 0);
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
// Toggle scroll lock off.
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_SCROLLLOCK, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID,
- EV_KEY, KEY_SCROLLLOCK, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, KEY_SCROLLLOCK, 0);
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
@@ -2344,9 +2318,9 @@
int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
NotifyMotionArgs args;
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, originalX);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, originalY);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, originalX);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, originalY);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2432,8 +2406,8 @@
// 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, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
@@ -2473,8 +2447,8 @@
ASSERT_EQ(ARBITRARY_TIME, args.downTime);
// Button release. Should have same down time.
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
- process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME + 1, EV_KEY, BTN_MOUSE, 0);
+ process(mapper, ARBITRARY_TIME + 1, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
ASSERT_EQ(DEVICE_ID, args.deviceId);
@@ -2522,16 +2496,16 @@
NotifyMotionArgs args;
// Motion in X but not Y.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
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, 0.0f));
// Motion in Y but not X.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, -2);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2546,8 +2520,8 @@
NotifyMotionArgs args;
// Button press.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2559,8 +2533,8 @@
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Button release.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2580,10 +2554,10 @@
NotifyMotionArgs args;
// Combined X, Y and Button.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 1);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, -2);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2597,9 +2571,9 @@
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, 2);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 2);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2607,8 +2581,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
@@ -2708,8 +2682,8 @@
NotifyKeyArgs keyArgs;
// press BTN_LEFT, release BTN_LEFT
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_LEFT, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
@@ -2724,8 +2698,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_LEFT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2748,9 +2722,9 @@
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, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_RIGHT, 1);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MIDDLE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 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,
@@ -2777,8 +2751,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_RIGHT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
@@ -2793,16 +2767,16 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MIDDLE, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
ASSERT_EQ(0, mFakePointerController->getButtonState());
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_MIDDLE, 0);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MIDDLE, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2819,8 +2793,8 @@
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, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_BACK, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
@@ -2839,8 +2813,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_BACK, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2860,8 +2834,8 @@
ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
// press BTN_SIDE, release BTN_SIDE
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_SIDE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
@@ -2880,8 +2854,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_SIDE, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2901,8 +2875,8 @@
ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
// press BTN_FORWARD, release BTN_FORWARD
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_FORWARD, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
@@ -2921,8 +2895,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_FORWARD, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2942,8 +2916,8 @@
ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
// press BTN_EXTRA, release BTN_EXTRA
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_EXTRA, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
@@ -2962,8 +2936,8 @@
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);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_EXTRA, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, motionArgs.action);
ASSERT_EQ(0, motionArgs.buttonState);
@@ -2994,9 +2968,9 @@
NotifyMotionArgs args;
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
@@ -3023,9 +2997,9 @@
NotifyMotionArgs args;
// Move.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
@@ -3034,8 +3008,8 @@
ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 100.0f, 200.0f));
// Button press.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_MOUSE, 1);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
@@ -3048,8 +3022,8 @@
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Button release.
- process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
- process(mapper, ARBITRARY_TIME + 2, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME + 2, EV_KEY, BTN_MOUSE, 0);
+ process(mapper, ARBITRARY_TIME + 2, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_BUTTON_RELEASE, args.action);
@@ -3062,9 +3036,9 @@
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
// Another move.
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 30);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 40);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 30);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 40);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
@@ -3083,9 +3057,9 @@
ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
@@ -3305,48 +3279,48 @@
}
void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 1);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 1);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_X, x);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Y, y);
}
void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_X, x);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_Y, y);
}
void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0);
+ process(mapper, ARBITRARY_TIME, EV_KEY, BTN_TOUCH, 0);
}
void SingleTouchInputMapperTest::processPressure(
SingleTouchInputMapper* mapper, int32_t pressure) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, pressure);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_PRESSURE, pressure);
}
void SingleTouchInputMapperTest::processToolMajor(
SingleTouchInputMapper* mapper, int32_t toolMajor) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
}
void SingleTouchInputMapperTest::processDistance(
SingleTouchInputMapper* mapper, int32_t distance) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, distance);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_DISTANCE, distance);
}
void SingleTouchInputMapperTest::processTilt(
SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_X, tiltX);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_Y, tiltY);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TILT_X, tiltX);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_TILT_Y, tiltY);
}
void SingleTouchInputMapperTest::processKey(
SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
+ process(mapper, ARBITRARY_TIME, EV_KEY, code, value);
}
void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
}
@@ -4661,75 +4635,75 @@
void MultiTouchInputMapperTest::processPosition(
MultiTouchInputMapper* mapper, int32_t x, int32_t y) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, x);
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, y);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_X, x);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_POSITION_Y, y);
}
void MultiTouchInputMapperTest::processTouchMajor(
MultiTouchInputMapper* mapper, int32_t touchMajor) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
}
void MultiTouchInputMapperTest::processTouchMinor(
MultiTouchInputMapper* mapper, int32_t touchMinor) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
}
void MultiTouchInputMapperTest::processToolMajor(
MultiTouchInputMapper* mapper, int32_t toolMajor) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
}
void MultiTouchInputMapperTest::processToolMinor(
MultiTouchInputMapper* mapper, int32_t toolMinor) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
}
void MultiTouchInputMapperTest::processOrientation(
MultiTouchInputMapper* mapper, int32_t orientation) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, orientation);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_ORIENTATION, orientation);
}
void MultiTouchInputMapperTest::processPressure(
MultiTouchInputMapper* mapper, int32_t pressure) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, pressure);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_PRESSURE, pressure);
}
void MultiTouchInputMapperTest::processDistance(
MultiTouchInputMapper* mapper, int32_t distance) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, distance);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_DISTANCE, distance);
}
void MultiTouchInputMapperTest::processId(
MultiTouchInputMapper* mapper, int32_t id) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, id);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TRACKING_ID, id);
}
void MultiTouchInputMapperTest::processSlot(
MultiTouchInputMapper* mapper, int32_t slot) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, slot);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_SLOT, slot);
}
void MultiTouchInputMapperTest::processToolType(
MultiTouchInputMapper* mapper, int32_t toolType) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
+ process(mapper, ARBITRARY_TIME, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
}
void MultiTouchInputMapperTest::processKey(
MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
+ process(mapper, ARBITRARY_TIME, EV_KEY, code, value);
}
void MultiTouchInputMapperTest::processTimestamp(MultiTouchInputMapper* mapper, uint32_t value) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_MSC, MSC_TIMESTAMP, value);
+ process(mapper, ARBITRARY_TIME, EV_MSC, MSC_TIMESTAMP, value);
}
void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_MT_REPORT, 0);
}
void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
- process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
+ process(mapper, ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
}
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index f168db9..088c256 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -139,6 +139,7 @@
"Scheduler/DispSyncSource.cpp",
"Scheduler/EventControlThread.cpp",
"Scheduler/EventThread.cpp",
+ "Scheduler/LayerHistory.cpp",
"Scheduler/MessageQueue.cpp",
"Scheduler/Scheduler.cpp",
"StartPropertySetThread.cpp",
@@ -184,6 +185,7 @@
"libhidltransport",
"liblayers_proto",
"liblog",
+ "libsync",
"libtimestats_proto",
"libutils",
],
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 5342bcf..1215bd9 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -35,6 +35,8 @@
#include <gui/Surface.h>
#include <hardware/gralloc.h>
#include <renderengine/RenderEngine.h>
+#include <sync/sync.h>
+#include <system/window.h>
#include <ui/DebugUtils.h>
#include <ui/DisplayInfo.h>
#include <ui/PixelFormat.h>
@@ -221,8 +223,8 @@
mDisplayToken(args.displayToken),
mId(args.displayId),
mNativeWindow(args.nativeWindow),
+ mGraphicBuffer(nullptr),
mDisplaySurface(args.displaySurface),
- mSurface{std::move(args.renderSurface)},
mDisplayInstallOrientation(args.displayInstallOrientation),
mPageFlipCount(0),
mIsVirtual(args.isVirtual),
@@ -244,7 +246,6 @@
ALOGE_IF(!mNativeWindow, "No native window was set for display");
ALOGE_IF(!mDisplaySurface, "No display surface was set for display");
- ALOGE_IF(!mSurface, "No render surface was set for display");
std::vector<Hdr> types = args.hdrCapabilities.getSupportedHdrTypes();
for (Hdr hdrType : types) {
@@ -284,6 +285,14 @@
mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance);
ANativeWindow* const window = mNativeWindow.get();
+
+ int status = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
+ ALOGE_IF(status != NO_ERROR, "Unable to connect BQ producer: %d", status);
+ status = native_window_set_buffers_format(window, HAL_PIXEL_FORMAT_RGBA_8888);
+ ALOGE_IF(status != NO_ERROR, "Unable to set BQ format to RGBA888: %d", status);
+ status = native_window_set_usage(window, GRALLOC_USAGE_HW_RENDER);
+ ALOGE_IF(status != NO_ERROR, "Unable to set BQ usage bits for GPU rendering: %d", status);
+
mDisplayWidth = ANativeWindow_getWidth(window);
mDisplayHeight = ANativeWindow_getHeight(window);
@@ -321,7 +330,6 @@
void DisplayDevice::flip() const
{
- mFlinger->getRenderEngine().checkErrors();
mPageFlipCount++;
}
@@ -356,9 +364,71 @@
return mDisplaySurface->prepareFrame(compositionType);
}
-void DisplayDevice::swapBuffers(HWComposer& hwc) const {
+sp<GraphicBuffer> DisplayDevice::dequeueBuffer() {
+ int fd;
+ ANativeWindowBuffer* buffer;
+
+ status_t res = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fd);
+
+ if (res != NO_ERROR) {
+ ALOGE("ANativeWindow::dequeueBuffer failed for display [%s] with error: %d",
+ getDisplayName().c_str(), res);
+ // Return fast here as we can't do much more - any rendering we do
+ // now will just be wrong.
+ return mGraphicBuffer;
+ }
+
+ ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].",
+ mGraphicBuffer->getNativeBuffer()->handle);
+ mGraphicBuffer = GraphicBuffer::from(buffer);
+
+ // Block until the buffer is ready
+ // TODO(alecmouri): it's perhaps more appropriate to block renderengine so
+ // that the gl driver can block instead.
+ if (fd >= 0) {
+ sync_wait(fd, -1);
+ close(fd);
+ }
+
+ return mGraphicBuffer;
+}
+
+void DisplayDevice::queueBuffer(HWComposer& hwc) {
if (hwc.hasClientComposition(mId) || hwc.hasFlipClientTargetRequest(mId)) {
- mSurface->swapBuffers();
+ // hasFlipClientTargetRequest could return true even if we haven't
+ // dequeued a buffer before. Try dequeueing one if we don't have a
+ // buffer ready.
+ if (mGraphicBuffer == nullptr) {
+ ALOGI("Attempting to queue a client composited buffer without one "
+ "previously dequeued for display [%s]. Attempting to dequeue "
+ "a scratch buffer now",
+ mDisplayName.c_str());
+ // We shouldn't deadlock here, since mGraphicBuffer == nullptr only
+ // after a successful call to queueBuffer, or if dequeueBuffer has
+ // never been called.
+ dequeueBuffer();
+ }
+
+ if (mGraphicBuffer == nullptr) {
+ ALOGE("No buffer is ready for display [%s]", mDisplayName.c_str());
+ } else {
+ int fd = mBufferReady.release();
+
+ status_t res = mNativeWindow->queueBuffer(mNativeWindow.get(),
+ mGraphicBuffer->getNativeBuffer(), fd);
+ if (res != NO_ERROR) {
+ ALOGE("Error when queueing buffer for display [%s]: %d", mDisplayName.c_str(), res);
+ // We risk blocking on dequeueBuffer if the primary display failed
+ // to queue up its buffer, so crash here.
+ if (isPrimary()) {
+ LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", res);
+ } else {
+ mNativeWindow->cancelBuffer(mNativeWindow.get(),
+ mGraphicBuffer->getNativeBuffer(), fd);
+ }
+ }
+ mGraphicBuffer = nullptr;
+ }
}
status_t result = mDisplaySurface->advanceFrame();
@@ -367,16 +437,10 @@
}
}
-void DisplayDevice::onSwapBuffersCompleted() const {
+void DisplayDevice::onPresentDisplayCompleted() {
mDisplaySurface->onFrameCommitted();
}
-bool DisplayDevice::makeCurrent() const {
- bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
- setViewportAndProjection();
- return success;
-}
-
void DisplayDevice::setViewportAndProjection() const {
size_t w = mDisplayWidth;
size_t h = mDisplayHeight;
@@ -384,6 +448,13 @@
mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, ui::Transform::ROT_0);
}
+void DisplayDevice::finishBuffer() {
+ mBufferReady = mFlinger->getRenderEngine().flush();
+ if (mBufferReady.get() < 0) {
+ mFlinger->getRenderEngine().finish();
+ }
+}
+
const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
return mDisplaySurface->getClientTargetAcquireFence();
}
@@ -532,12 +603,8 @@
void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
dirtyRegion.set(getBounds());
- mSurface->setNativeWindow(nullptr);
-
mDisplaySurface->resizeBuffers(newWidth, newHeight);
- ANativeWindow* const window = mNativeWindow.get();
- mSurface->setNativeWindow(window);
mDisplayWidth = newWidth;
mDisplayHeight = newHeight;
}
@@ -653,12 +720,11 @@
ANativeWindow* const window = mNativeWindow.get();
result.appendFormat("+ %s\n", getDebugName().c_str());
result.appendFormat(" layerStack=%u, (%4dx%4d), ANativeWindow=%p "
- "(%d:%d:%d:%d), orient=%2d (type=%08x), "
- "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
+ "format=%d, orient=%2d (type=%08x), flips=%u, isSecure=%d, "
+ "powerMode=%d, activeConfig=%d, numLayers=%zu\n",
mLayerStack, mDisplayWidth, mDisplayHeight, window,
- mSurface->queryRedSize(), mSurface->queryGreenSize(),
- mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation,
- tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
+ ANativeWindow_getFormat(window), mOrientation, tr.getType(),
+ getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
mVisibleLayersSortedByZ.size());
result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
@@ -669,9 +735,9 @@
auto const surface = static_cast<Surface*>(window);
ui::Dataspace dataspace = surface->getBuffersDataSpace();
result.appendFormat(" wideColorGamut=%d, hdr10=%d, colorMode=%s, dataspace: %s (%d)\n",
- mHasWideColorGamut, mHasHdr10,
- decodeColorMode(mActiveColorMode).c_str(),
- dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace);
+ mHasWideColorGamut, mHasHdr10, decodeColorMode(mActiveColorMode).c_str(),
+ dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(),
+ dataspace);
String8 surfaceDump;
mDisplaySurface->dumpAsString(surfaceDump);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index bcd3330..eb2c5c3 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -24,25 +24,25 @@
#include <string>
#include <unordered_map>
+#include <android/native_window.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
#include <hardware/hwcomposer_defs.h>
#include <math/mat4.h>
-#include <renderengine/Surface.h>
+#include <renderengine/RenderEngine.h>
+#include <system/window.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
#include <ui/Transform.h>
-#include <utils/RefBase.h>
#include <utils/Mutex.h>
+#include <utils/RefBase.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include "DisplayHardware/DisplayIdentification.h"
#include "RenderArea.h"
-struct ANativeWindow;
-
namespace android {
class DisplaySurface;
@@ -146,10 +146,13 @@
ui::Dataspace* outDataspace, ui::ColorMode* outMode,
ui::RenderIntent* outIntent) const;
- void swapBuffers(HWComposer& hwc) const;
+ // Queues the drawn buffer for consumption by HWC.
+ void queueBuffer(HWComposer& hwc);
+ // Allocates a buffer as scratch space for GPU composition
+ sp<GraphicBuffer> dequeueBuffer();
// called after h/w composer has completed its set() call
- void onSwapBuffersCompleted() const;
+ void onPresentDisplayCompleted();
Rect getBounds() const {
return Rect(mDisplayWidth, mDisplayHeight);
@@ -159,7 +162,11 @@
void setDisplayName(const std::string& displayName);
const std::string& getDisplayName() const { return mDisplayName; }
- bool makeCurrent() const;
+ // Acquires a new buffer for GPU composition.
+ void readyNewBuffer();
+ // Marks the current buffer has finished, so that it can be presented and
+ // swapped out.
+ void finishBuffer();
void setViewportAndProjection() const;
const sp<Fence>& getClientTargetAcquireFence() const;
@@ -204,9 +211,13 @@
// ANativeWindow this display is rendering into
sp<ANativeWindow> mNativeWindow;
+ // Current buffer that this display can render to.
+ sp<GraphicBuffer> mGraphicBuffer;
sp<DisplaySurface> mDisplaySurface;
+ // File descriptor indicating that mGraphicBuffer is ready for display, i.e.
+ // that drawing to the buffer is now complete.
+ base::unique_fd mBufferReady;
- std::unique_ptr<renderengine::Surface> mSurface;
int mDisplayWidth;
int mDisplayHeight;
const int mDisplayInstallOrientation;
@@ -326,7 +337,6 @@
bool isSecure{false};
sp<ANativeWindow> nativeWindow;
sp<DisplaySurface> displaySurface;
- std::unique_ptr<renderengine::Surface> renderSurface;
int displayInstallOrientation{DisplayState::eOrientationDefault};
bool hasWideColorGamut{false};
HdrCapabilities hdrCapabilities;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0f25b52..9bbc37f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -20,31 +20,12 @@
#define LOG_TAG "HWComposer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
#include <utils/Errors.h>
-#include <utils/misc.h>
-#include <utils/NativeHandle.h>
-#include <utils/String8.h>
-#include <utils/Thread.h>
#include <utils/Trace.h>
-#include <utils/Vector.h>
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <android/configuration.h>
-
-#include <cutils/properties.h>
#include <log/log.h>
#include "HWComposer.h"
@@ -85,11 +66,7 @@
namespace android {
-#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
-
-// ---------------------------------------------------------------------------
-
-HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
+HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
: mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
HWComposer::~HWComposer() {
@@ -184,30 +161,31 @@
RETURN_IF_INVALID_DISPLAY(*displayId, false);
- const auto& displayData = mDisplayData[*displayId];
+ auto& displayData = mDisplayData[*displayId];
if (displayData.isVirtual) {
LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
return false;
}
{
- Mutex::Autolock _l(mLock);
+ std::lock_guard lock(displayData.lastHwVsyncLock);
// There have been reports of HWCs that signal several vsync events
// with the same timestamp when turning the display off and on. This
// is a bug in the HWC implementation, but filter the extra events
// out here so they don't cause havoc downstream.
- if (timestamp == mLastHwVSync[*displayId]) {
+ if (timestamp == displayData.lastHwVsync) {
ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
to_string(*displayId).c_str(), timestamp);
return false;
}
- mLastHwVSync[*displayId] = timestamp;
+ displayData.lastHwVsync = timestamp;
}
const auto tag = "HW_VSYNC_" + to_string(*displayId);
- ATRACE_INT(tag.c_str(), ++mVSyncCounts[*displayId] & 1);
+ ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
+ displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
return true;
}
@@ -270,13 +248,14 @@
nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
RETURN_IF_INVALID_DISPLAY(displayId, 0);
+ const auto& displayData = mDisplayData.at(displayId);
// this returns the last refresh timestamp.
// if the last one is not available, we estimate it based on
// the refresh period and whatever closest timestamp we have.
- Mutex::Autolock _l(mLock);
+ std::lock_guard lock(displayData.lastHwVsyncLock);
nsecs_t now = systemTime(CLOCK_MONOTONIC);
auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
- return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
+ return now - ((now - displayData.lastHwVsync) % vsyncPeriod);
}
bool HWComposer::isConnected(DisplayId displayId) const {
@@ -375,17 +354,19 @@
// into the HWC with the lock held, and we want to make sure
// that even if HWC blocks (which it shouldn't), it won't
// affect other threads.
- Mutex::Autolock _l(mVsyncLock);
- if (enabled != displayData.vsyncEnabled) {
- ATRACE_CALL();
- auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
- RETURN_IF_HWC_ERROR(error, displayId);
-
- displayData.vsyncEnabled = enabled;
-
- const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
- ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
+ std::lock_guard lock(displayData.vsyncEnabledLock);
+ if (enabled == displayData.vsyncEnabled) {
+ return;
}
+
+ ATRACE_CALL();
+ auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
+ RETURN_IF_HWC_ERROR(error, displayId);
+
+ displayData.vsyncEnabled = enabled;
+
+ const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
+ ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
}
status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
@@ -405,8 +386,6 @@
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
- Mutex::Autolock _l(mDisplayLock);
-
auto& displayData = mDisplayData[displayId];
auto& hwcDisplay = displayData.hwcDisplay;
if (!hwcDisplay->isConnected()) {
@@ -428,7 +407,7 @@
// back to validate when there is any client layer.
displayData.validateWasSkipped = false;
if (!displayData.hasClientComposition) {
- sp<android::Fence> outPresentFence;
+ sp<Fence> outPresentFence;
uint32_t state = UINT32_MAX;
error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
if (error != HWC2::Error::HasChanges) {
@@ -689,7 +668,6 @@
const auto hwcDisplayId = displayData.hwcDisplay->getId();
mPhysicalDisplayIdMap.erase(hwcDisplayId);
mDisplayData.erase(displayId);
- mVSyncCounts.erase(displayId);
// TODO(b/74619554): Select internal/external display from remaining displays.
if (hwcDisplayId == mInternalHwcDisplayId) {
@@ -755,26 +733,6 @@
return matrix;
}
-// Converts a PixelFormat to a human-readable string. Max 11 chars.
-// (Could use a table of prefab String8 objects.)
-/*
-static String8 getFormatStr(PixelFormat format) {
- switch (format) {
- case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888");
- case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888");
- case PIXEL_FORMAT_RGB_888: return String8("RGB_888");
- case PIXEL_FORMAT_RGB_565: return String8("RGB_565");
- case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888");
- case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
- return String8("ImplDef");
- default:
- String8 result;
- result.appendFormat("? %08x", format);
- return result;
- }
-}
-*/
-
bool HWComposer::isUsingVrComposer() const {
return getComposer()->isUsingVrComposer();
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index b78433d..2f57907 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -17,49 +17,26 @@
#ifndef ANDROID_SF_HWCOMPOSER_H
#define ANDROID_SF_HWCOMPOSER_H
-#include "HWC2.h"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Fence.h>
-#include <ui/GraphicTypes.h>
-#include <utils/BitSet.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <utils/StrongPointer.h>
-#include <utils/Thread.h>
-#include <utils/Timers.h>
-#include <utils/Vector.h>
-
+#include <cstdint>
#include <memory>
+#include <mutex>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
+#include <android-base/thread_annotations.h>
+#include <ui/Fence.h>
+#include <ui/GraphicTypes.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
#include "DisplayIdentification.h"
-
-extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
- const struct timespec *request,
- struct timespec *remain);
-
-struct framebuffer_device_t;
-
-namespace HWC2 {
- class Device;
- class Display;
-}
+#include "HWC2.h"
namespace android {
-// ---------------------------------------------------------------------------
-class DisplayDevice;
-class Fence;
-class FloatRect;
class GraphicBuffer;
-class NativeHandle;
-class Region;
class String8;
class TestableSurfaceFlinger;
struct CompositionInfo;
@@ -71,7 +48,7 @@
class HWComposer
{
public:
- explicit HWComposer(std::unique_ptr<android::Hwc2::Composer> composer);
+ explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
~HWComposer();
@@ -177,7 +154,7 @@
// for debugging ----------------------------------------------------------
void dump(String8& out) const;
- android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
+ Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
// TODO(b/74619554): Remove special cases for internal/external display.
std::optional<hwc2_display_t> getInternalHwcDisplayId() const { return mInternalHwcDisplayId; }
@@ -194,8 +171,6 @@
static void validateChange(HWC2::Composition from, HWC2::Composition to);
- struct cb_context;
-
struct DisplayData {
bool isVirtual = false;
bool hasClientComposition = false;
@@ -209,11 +184,16 @@
mutable std::unordered_map<int32_t,
std::shared_ptr<const HWC2::Display::Config>> configMap;
- // protected by mVsyncLock
- HWC2::Vsync vsyncEnabled = HWC2::Vsync::Disable;
-
bool validateWasSkipped;
HWC2::Error presentError;
+
+ bool vsyncTraceToggle = false;
+
+ std::mutex vsyncEnabledLock;
+ HWC2::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = HWC2::Vsync::Disable;
+
+ mutable std::mutex lastHwVsyncLock;
+ nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
};
std::unordered_map<DisplayId, DisplayData> mDisplayData;
@@ -227,25 +207,11 @@
std::optional<hwc2_display_t> mExternalHwcDisplayId;
bool mHasMultiDisplaySupport = false;
- // protect mDisplayData from races between prepare and dump
- mutable Mutex mDisplayLock;
-
- cb_context* mCBContext = nullptr;
- std::unordered_map<DisplayId, size_t> mVSyncCounts;
-
std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
uint32_t mNextVirtualDisplayId = 0;
uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
-
- // protected by mLock
- mutable Mutex mLock;
- mutable std::unordered_map<DisplayId, nsecs_t> mLastHwVSync;
-
- // thread-safe
- mutable Mutex mVsyncLock;
};
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
#endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1e910ce..f3182be 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1021,6 +1021,10 @@
uint32_t Layer::doTransaction(uint32_t flags) {
ATRACE_CALL();
+ if (mLayerDetached) {
+ return 0;
+ }
+
pushPendingState();
State c = getCurrentState();
if (!applyPendingStates(&c)) {
@@ -1553,6 +1557,9 @@
return false;
}
+ if (attachChildren()) {
+ setTransactionFlags(eTransactionNeeded);
+ }
for (const sp<Layer>& child : mCurrentChildren) {
newParent->addChild(child);
@@ -1597,6 +1604,13 @@
client->updateParent(newParent);
}
+ if (mLayerDetached) {
+ mLayerDetached = false;
+ setTransactionFlags(eTransactionNeeded);
+ }
+ if (attachChildren()) {
+ setTransactionFlags(eTransactionNeeded);
+ }
return true;
}
@@ -1605,7 +1619,7 @@
sp<Client> parentClient = mClientRef.promote();
sp<Client> client(child->mClientRef.promote());
if (client != nullptr && parentClient != client) {
- client->detachLayer(child.get());
+ child->mLayerDetached = true;
child->detachChildren();
}
}
@@ -1613,6 +1627,23 @@
return true;
}
+bool Layer::attachChildren() {
+ bool changed = false;
+ for (const sp<Layer>& child : mCurrentChildren) {
+ sp<Client> parentClient = mClientRef.promote();
+ sp<Client> client(child->mClientRef.promote());
+ if (client != nullptr && parentClient != client) {
+ if (child->mLayerDetached) {
+ child->mLayerDetached = false;
+ changed = true;
+ }
+ changed |= child->attachChildren();
+ }
+ }
+
+ return changed;
+}
+
bool Layer::setColorTransform(const mat4& matrix) {
static const mat4 identityMatrix = mat4();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 40ebe1e..ed51c61 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -263,6 +263,8 @@
virtual void setChildrenDrawingParent(const sp<Layer>& layer);
virtual bool reparent(const sp<IBinder>& newParentHandle);
virtual bool detachChildren();
+ bool attachChildren();
+ bool isLayerDetached() const { return mLayerDetached; }
virtual bool setColorTransform(const mat4& matrix);
virtual const mat4& getColorTransform() const;
virtual bool hasColorTransform() const;
@@ -355,7 +357,6 @@
// to avoid grabbing the lock again to avoid deadlock
virtual bool isCreatedFromMainThread() const { return false; }
-
bool isRemovedFromCurrentState() const;
void writeToProto(LayerProto* layerInfo,
@@ -776,6 +777,9 @@
mutable LayerBE mBE;
+ // Can only be accessed with the SF state lock held.
+ bool mLayerDetached{false};
+
private:
/**
* Returns an unsorted vector of all layers that are part of this tree.
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
new file mode 100644
index 0000000..e944eb9
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#include "LayerHistory.h"
+
+#include <cinttypes>
+#include <cstdint>
+#include <numeric>
+#include <string>
+#include <unordered_map>
+
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <utils/Trace.h>
+
+namespace android {
+
+LayerHistory::LayerHistory() {}
+
+LayerHistory::~LayerHistory() = default;
+
+void LayerHistory::insert(const std::string layerName, nsecs_t presentTime) {
+ mElements[mCounter].insert(std::make_pair(layerName, presentTime));
+}
+
+void LayerHistory::incrementCounter() {
+ mCounter++;
+ mCounter = mCounter % ARRAY_SIZE;
+ mElements[mCounter].clear();
+}
+
+const std::unordered_map<std::string, nsecs_t>& LayerHistory::get(size_t index) const {
+ return mElements.at(index);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
new file mode 100644
index 0000000..1a7f9cd
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <array>
+#include <cinttypes>
+#include <cstdint>
+#include <numeric>
+#include <string>
+#include <unordered_map>
+
+#include <utils/Timers.h>
+
+namespace android {
+
+/*
+ * This class represents a circular buffer in which we keep layer history for
+ * the past ARRAY_SIZE frames. Each time, a signal for new frame comes, the counter
+ * gets incremented and includes all the layers that are requested to draw in that
+ * frame.
+ *
+ * Once the buffer reaches the end of the array, it starts overriding the elements
+ * at the beginning of the array.
+ */
+class LayerHistory {
+public:
+ LayerHistory();
+ ~LayerHistory();
+
+ // Method for inserting layers and their requested present time into the ring buffer.
+ // The elements are going to be inserted into an unordered_map at the position of
+ // mCounter.
+ void insert(const std::string layerName, nsecs_t presentTime);
+ // Method for incrementing the current slot in the ring buffer. It also clears the
+ // unordered_map, if it was created previously.
+ void incrementCounter();
+ // Returns unordered_map at the given at index.
+ const std::unordered_map<std::string, nsecs_t>& get(size_t index) const;
+
+private:
+ size_t mCounter = 0;
+ static constexpr size_t ARRAY_SIZE = 30;
+ std::array<std::unordered_map<std::string, nsecs_t>, ARRAY_SIZE> mElements;
+};
+
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 41c7a93..af73346 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -45,6 +45,7 @@
#include <gui/BufferQueue.h>
#include <gui/GuiConfig.h>
#include <gui/IDisplayEventConnection.h>
+#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
#include <renderengine/RenderEngine.h>
@@ -676,10 +677,6 @@
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
"Internal display is disconnected.");
- // make the default display GLContext current so that we can create textures
- // when creating Layers (which may happens before we render something)
- display->makeCurrent();
-
if (useVrFlinger) {
auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
// This callback is called from the vr flinger dispatch thread. We
@@ -1409,7 +1406,6 @@
// mCurrentState and mDrawingState and re-apply all changes when we make the
// transition.
mDrawingState.displays.clear();
- getRenderEngine().resetCurrentSurface();
mDisplays.clear();
}
@@ -1717,7 +1713,7 @@
auto& engine(getRenderEngine());
engine.fillRegionWithColor(dirtyRegion, 1, 0, 1, 1);
- display->swapBuffers(getHwComposer());
+ display->queueBuffer(getHwComposer());
}
}
@@ -2203,8 +2199,7 @@
if (displayId) {
getHwComposer().presentAndGetReleaseFences(*displayId);
}
- display->onSwapBuffersCompleted();
- display->makeCurrent();
+ display->onPresentDisplayCompleted();
for (auto& layer : display->getVisibleLayersSortedByZ()) {
sp<Fence> releaseFence = Fence::NO_FENCE;
@@ -2351,22 +2346,9 @@
auto nativeWindow = nativeWindowSurface->getNativeWindow();
creationArgs.nativeWindow = nativeWindow;
- /*
- * Create our display's surface
- */
- std::unique_ptr<renderengine::Surface> renderSurface = getRenderEngine().createSurface();
- renderSurface->setCritical(isInternalDisplay);
- renderSurface->setAsync(state.isVirtual());
- renderSurface->setNativeWindow(nativeWindow.get());
- creationArgs.renderSurface = std::move(renderSurface);
-
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
- // in two places:
- // * Here, in case the display is composed entirely by HWC.
- // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
- // window's swap interval in eglMakeCurrent, so they'll override the
- // interval we set here.
+ // here, in case the display is composed entirely by HWC.
if (state.isVirtual()) {
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
@@ -2426,12 +2408,6 @@
const auto externalDisplayId = getExternalDisplayId();
// in drawing state but not in current state
- // Call makeCurrent() on the primary display so we can
- // be sure that nothing associated with this display
- // is current.
- if (const auto defaultDisplay = getDefaultDisplayDeviceLocked()) {
- defaultDisplay->makeCurrent();
- }
if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) {
display->disconnect(getHwComposer());
}
@@ -2982,7 +2958,7 @@
mGeometryInvalid = true;
}
-void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& display,
+void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& display,
const Region& inDirtyRegion) {
// We only need to actually compose the display if:
// 1) It is being handled by hardware composer, which may need this to
@@ -2997,10 +2973,10 @@
if (!doComposeSurfaces(display)) return;
// swap buffers (presentation)
- display->swapBuffers(getHwComposer());
+ display->queueBuffer(getHwComposer());
}
-bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& display) {
+bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& display) {
ALOGV("doComposeSurfaces");
const Region bounds(display->bounds());
@@ -3013,9 +2989,31 @@
bool applyColorMatrix = false;
bool needsEnhancedColorMatrix = false;
+ // Framebuffer will live in this scope for GPU composition.
+ std::unique_ptr<renderengine::BindNativeBufferAsFramebuffer> fbo;
+
if (hasClientComposition) {
ALOGV("hasClientComposition");
+ sp<GraphicBuffer> buf = display->dequeueBuffer();
+
+ if (buf == nullptr) {
+ ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
+ "client composition for this frame",
+ display->getDisplayName().c_str());
+ return false;
+ }
+
+ // Bind the framebuffer in this scope.
+ fbo = std::make_unique<renderengine::BindNativeBufferAsFramebuffer>(getRenderEngine(),
+ buf->getNativeBuffer());
+
+ if (fbo->getStatus() != NO_ERROR) {
+ ALOGW("Binding buffer for display [%s] failed with status: %d",
+ display->getDisplayName().c_str(), fbo->getStatus());
+ return false;
+ }
+
Dataspace outputDataspace = Dataspace::UNKNOWN;
if (display->hasWideColorGamut()) {
outputDataspace = display->getCompositionDataSpace();
@@ -3044,18 +3042,7 @@
colorMatrix *= mEnhancedSaturationMatrix;
}
- if (!display->makeCurrent()) {
- ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
- display->getDisplayName().c_str());
- getRenderEngine().resetCurrentSurface();
-
- // |mStateLock| not needed as we are on the main thread
- const auto defaultDisplay = getDefaultDisplayDeviceLocked();
- if (!defaultDisplay || !defaultDisplay->makeCurrent()) {
- ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
- }
- return false;
- }
+ display->setViewportAndProjection();
// Never touch the framebuffer if we don't have any framebuffer layers
if (hasDeviceComposition) {
@@ -3148,11 +3135,15 @@
firstLayer = false;
}
- // Clear color transform matrix at the end of the frame.
- getRenderEngine().setColorTransform(mat4());
-
- // disable scissor at the end of the frame
- getBE().mRenderEngine->disableScissor();
+ // Perform some cleanup steps if we used client composition.
+ if (hasClientComposition) {
+ getRenderEngine().setColorTransform(mat4());
+ getBE().mRenderEngine->disableScissor();
+ display->finishBuffer();
+ // Clear out error flags here so that we don't wait until next
+ // composition to log.
+ getRenderEngine().checkErrors();
+ }
return true;
}
@@ -3208,6 +3199,10 @@
}
status_t SurfaceFlinger::removeLayerLocked(const Mutex& lock, const sp<Layer>& layer) {
+ if (layer->isLayerDetached()) {
+ return NO_ERROR;
+ }
+
const auto& p = layer->getParent();
ssize_t index;
if (p != nullptr) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8b389bc..f98dddf 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -721,10 +721,10 @@
void doDebugFlashRegions(const sp<DisplayDevice>& display, bool repaintEverything);
void doTracing(const char* where);
void logLayerStats();
- void doDisplayComposition(const sp<const DisplayDevice>& display, const Region& dirtyRegion);
+ void doDisplayComposition(const sp<DisplayDevice>& display, const Region& dirtyRegion);
// This fails if using GL and the surface has been destroyed.
- bool doComposeSurfaces(const sp<const DisplayDevice>& display);
+ bool doComposeSurfaces(const sp<DisplayDevice>& display);
void postFramebuffer(const sp<DisplayDevice>& display);
void postFrame();
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 67dcd06..1835929 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -26,22 +26,48 @@
namespace android {
-void SurfaceTracing::enable() {
- ATRACE_CALL();
+void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
+ // use the swap trick to make sure memory is released
+ std::queue<LayersTraceProto>().swap(mStorage);
+ mSizeInBytes = newSize;
+ mUsedInBytes = 0U;
+}
+
+void SurfaceTracing::LayersTraceBuffer::emplace(LayersTraceProto&& proto) {
+ auto protoSize = proto.ByteSize();
+ while (mUsedInBytes + protoSize > mSizeInBytes) {
+ if (mStorage.empty()) {
+ return;
+ }
+ mUsedInBytes -= mStorage.front().ByteSize();
+ mStorage.pop();
+ }
+ mUsedInBytes += protoSize;
+ mStorage.emplace();
+ mStorage.back().Swap(&proto);
+}
+
+void SurfaceTracing::LayersTraceBuffer::flush(LayersTraceFileProto* fileProto) {
+ fileProto->mutable_entry()->Reserve(mStorage.size());
+
+ while (!mStorage.empty()) {
+ auto entry = fileProto->add_entry();
+ entry->Swap(&mStorage.front());
+ mStorage.pop();
+ }
+}
+
+void SurfaceTracing::enable(size_t bufferSizeInByte) {
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
if (mEnabled) {
return;
}
mEnabled = true;
-
- mTrace = std::make_unique<LayersTraceFileProto>();
- mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
- LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+ mBuffer.reset(bufferSizeInByte);
}
status_t SurfaceTracing::disable() {
- ATRACE_CALL();
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
if (!mEnabled) {
@@ -51,7 +77,7 @@
status_t err(writeProtoFileLocked());
ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
- mTrace.reset();
+ mBuffer.reset(0);
return err;
}
@@ -65,32 +91,29 @@
if (!mEnabled) {
return;
}
- LayersTraceProto* entry = mTrace->add_entry();
- entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
- entry->set_where(where);
- entry->mutable_layers()->Swap(&layers);
- constexpr int maxBufferedEntryCount = 3600;
- if (mTrace->entry_size() >= maxBufferedEntryCount) {
- // TODO: flush buffered entries without disabling tracing
- ALOGE("too many buffered frames; force disable tracing");
- mEnabled = false;
- writeProtoFileLocked();
- mTrace.reset();
- }
+ LayersTraceProto entry;
+ entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
+ entry.set_where(where);
+ entry.mutable_layers()->Swap(&layers);
+
+ mBuffer.emplace(std::move(entry));
}
status_t SurfaceTracing::writeProtoFileLocked() {
ATRACE_CALL();
- if (!mTrace->IsInitialized()) {
- return NOT_ENOUGH_DATA;
- }
+ LayersTraceFileProto fileProto;
std::string output;
- if (!mTrace->SerializeToString(&output)) {
+
+ fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+ LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+ mBuffer.flush(&fileProto);
+
+ if (!fileProto.SerializeToString(&output)) {
return PERMISSION_DENIED;
}
- if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
+ if (!android::base::WriteStringToFile(output, kDefaultFileName, true)) {
return PERMISSION_DENIED;
}
@@ -101,7 +124,8 @@
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
- result.appendFormat(" number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
+ result.appendFormat(" number of entries: %zu (%.2fMB / %.2fMB)\n", mBuffer.frameCount(),
+ float(mBuffer.used()) / float(1_MB), float(mBuffer.size()) / float(1_MB));
}
} // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index fd8cb82..ec01be7 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -22,32 +22,54 @@
#include <memory>
#include <mutex>
+#include <queue>
using namespace android::surfaceflinger;
namespace android {
+constexpr auto operator""_MB(unsigned long long const num) {
+ return num * 1024 * 1024;
+}
+
/*
* SurfaceTracing records layer states during surface flinging.
*/
class SurfaceTracing {
public:
- void enable();
+ void enable() { enable(kDefaultBufferCapInByte); }
+ void enable(size_t bufferSizeInByte);
status_t disable();
- bool isEnabled() const;
-
void traceLayers(const char* where, LayersProto);
+
+ bool isEnabled() const;
void dump(String8& result) const;
private:
- static constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/layers_trace.pb";
+ static constexpr auto kDefaultBufferCapInByte = 100_MB;
+ static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
+
+ class LayersTraceBuffer { // ring buffer
+ public:
+ size_t size() const { return mSizeInBytes; }
+ size_t used() const { return mUsedInBytes; }
+ size_t frameCount() const { return mStorage.size(); }
+
+ void reset(size_t newSize);
+ void emplace(LayersTraceProto&& proto);
+ void flush(LayersTraceFileProto* fileProto);
+
+ private:
+ size_t mUsedInBytes = 0U;
+ size_t mSizeInBytes = 0U;
+ std::queue<LayersTraceProto> mStorage;
+ };
status_t writeProtoFileLocked();
bool mEnabled = false;
- std::string mOutputFileName = DEFAULT_FILENAME;
mutable std::mutex mTraceMutex;
- std::unique_ptr<LayersTraceFileProto> mTrace;
+ LayersTraceBuffer mBuffer;
};
} // namespace android
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index 599ff5c..75ce4be 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -13,8 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include "timestatsproto/TimeStatsHelper.h"
+
#include <android-base/stringprintf.h>
-#include <timestatsproto/TimeStatsHelper.h>
+#include <inttypes.h>
#include <array>
@@ -46,6 +48,14 @@
hist[*iter]++;
}
+int64_t TimeStatsHelper::Histogram::totalTime() const {
+ int64_t ret = 0;
+ for (const auto& ele : hist) {
+ ret += ele.first * ele.second;
+ }
+ return ret;
+}
+
float TimeStatsHelper::Histogram::averageTime() const {
int64_t ret = 0;
int64_t count = 0;
@@ -87,12 +97,13 @@
std::string TimeStatsHelper::TimeStatsGlobal::toString(std::optional<uint32_t> maxLayers) const {
std::string result = "SurfaceFlinger TimeStats:\n";
- StringAppendF(&result, "statsStart = %lld\n", static_cast<long long int>(statsStart));
- StringAppendF(&result, "statsEnd = %lld\n", static_cast<long long int>(statsEnd));
+ StringAppendF(&result, "statsStart = %" PRId64 "\n", statsStart);
+ StringAppendF(&result, "statsEnd = %" PRId64 "\n", statsEnd);
StringAppendF(&result, "totalFrames = %d\n", totalFrames);
StringAppendF(&result, "missedFrames = %d\n", missedFrames);
StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames);
- StringAppendF(&result, "displayOnTime = %lld ms\n", static_cast<long long int>(displayOnTime));
+ StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTime);
+ StringAppendF(&result, "totalP2PTime = %" PRId64 " ms\n", presentToPresent.totalTime());
StringAppendF(&result, "presentToPresent histogram is as below:\n");
result.append(presentToPresent.toString());
const auto dumpStats = generateDumpStats(maxLayers);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 7d0fe79..5f40a1a 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -34,6 +34,7 @@
std::unordered_map<int32_t, int32_t> hist;
void insert(int32_t delta);
+ int64_t totalTime() const;
float averageTime() const;
std::string toString() const;
};
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 988454a..a600a0a 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -3356,6 +3356,61 @@
}
}
+TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
+ sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
+ sp<SurfaceControl> childNewClient =
+ newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
+ PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
+
+ ASSERT_TRUE(childNewClient != nullptr);
+ ASSERT_TRUE(childNewClient->isValid());
+
+ fillSurfaceRGBA8(childNewClient, 200, 200, 200);
+
+ Transaction()
+ .hide(mChild)
+ .show(childNewClient)
+ .setPosition(childNewClient, 10, 10)
+ .setPosition(mFGSurfaceControl, 64, 64)
+ .apply();
+
+ {
+ mCapture = screenshot();
+ // Top left of foreground must now be visible
+ mCapture->expectFGColor(64, 64);
+ // But 10 pixels in we should see the child surface
+ mCapture->expectChildColor(74, 74);
+ // And 10 more pixels we should be back to the foreground surface
+ mCapture->expectFGColor(84, 84);
+ }
+
+ Transaction().detachChildren(mFGSurfaceControl).apply();
+ Transaction().hide(childNewClient).apply();
+
+ // Nothing should have changed.
+ {
+ mCapture = screenshot();
+ mCapture->expectFGColor(64, 64);
+ mCapture->expectChildColor(74, 74);
+ mCapture->expectFGColor(84, 84);
+ }
+
+ sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0);
+ fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32,
+ 32);
+ Transaction()
+ .setLayer(newParentSurface, INT32_MAX - 1)
+ .show(newParentSurface)
+ .setPosition(newParentSurface, 20, 20)
+ .reparent(childNewClient, newParentSurface->getHandle())
+ .apply();
+ {
+ mCapture = screenshot();
+ // Child is now hidden.
+ mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
+ }
+}
+
TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
asTransaction([&](Transaction& t) {
t.show(mChild);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 6fe52d3..58f1e9c 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -29,6 +29,7 @@
"DisplayTransactionTest.cpp",
"EventControlThreadTest.cpp",
"EventThreadTest.cpp",
+ "LayerHistoryTest.cpp",
"SchedulerTest.cpp",
"mock/DisplayHardware/MockComposer.cpp",
"mock/DisplayHardware/MockDisplaySurface.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index ab1b252..cfaf495 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -46,6 +46,7 @@
using testing::AtLeast;
using testing::ByMove;
using testing::DoAll;
+using testing::Invoke;
using testing::IsNull;
using testing::Mock;
using testing::NotNull;
@@ -93,6 +94,10 @@
EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
EXPECT_CALL(*mPrimaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+ EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
+ EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
+ .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
setupComposer(0);
@@ -139,9 +144,11 @@
sp<DisplayDevice> mDisplay;
sp<DisplayDevice> mExternalDisplay;
sp<mock::DisplaySurface> mDisplaySurface = new mock::DisplaySurface();
- renderengine::mock::Surface* mRenderSurface = new renderengine::mock::Surface();
mock::NativeWindow* mNativeWindow = new mock::NativeWindow();
+ sp<GraphicBuffer> mBuffer = new GraphicBuffer();
+ ANativeWindowBuffer* mNativeWindowBuffer = mBuffer->getNativeBuffer();
+
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
@@ -242,8 +249,6 @@
test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, DEFAULT_DISPLAY_ID,
false /* isVirtual */, true /* isPrimary */)
.setDisplaySurface(test->mDisplaySurface)
- .setRenderSurface(std::unique_ptr<renderengine::Surface>(
- test->mRenderSurface))
.setNativeWindow(test->mNativeWindow)
.setSecure(Derived::IS_SECURE)
.setPowerMode(Derived::INIT_POWER_MODE)
@@ -266,13 +271,9 @@
EXPECT_CALL(*test->mRenderEngine, checkErrors()).WillRepeatedly(Return());
EXPECT_CALL(*test->mRenderEngine, isCurrent()).WillRepeatedly(Return(true));
- EXPECT_CALL(*test->mRenderEngine, setCurrentSurface(Ref(*test->mRenderSurface)))
- .WillOnce(Return(true));
- EXPECT_CALL(*test->mRenderEngine,
- setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
- Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
- ui::Transform::ROT_0))
- .Times(1);
+ EXPECT_CALL(*test->mRenderEngine, flush()).WillRepeatedly(Invoke([]() {
+ return base::unique_fd(0);
+ }));
EXPECT_CALL(*test->mDisplaySurface, onFrameCommitted()).Times(1);
EXPECT_CALL(*test->mDisplaySurface, advanceFrame()).Times(1);
@@ -323,8 +324,6 @@
static void setupHwcCompositionCallExpectations(CompositionTest* test) {
EXPECT_CALL(*test->mDisplaySurface, prepareFrame(DisplaySurface::COMPOSITION_HWC)).Times(1);
-
- EXPECT_CALL(*test->mRenderEngine, disableScissor()).Times(1);
}
static void setupRECompositionCallExpectations(CompositionTest* test) {
@@ -344,12 +343,18 @@
setViewportAndProjection(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
ui::Transform::ROT_0))
- .Times(1)
- .RetiresOnSaturation();
- EXPECT_CALL(*test->mRenderEngine, setCurrentSurface(Ref(*test->mRenderSurface)))
- .WillOnce(Return(true))
- .RetiresOnSaturation();
- EXPECT_CALL(*test->mRenderSurface, swapBuffers()).Times(1);
+ .Times(1);
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(NotNull())).WillOnce(Return(true));
+ EXPECT_CALL(*test->mReFrameBuffer, setNativeWindowBuffer(IsNull())).WillOnce(Return(true));
+ EXPECT_CALL(*test->mRenderEngine, createFramebuffer())
+ .WillOnce(Return(
+ ByMove(std::unique_ptr<renderengine::Framebuffer>(test->mReFrameBuffer))));
+ EXPECT_CALL(*test->mRenderEngine, bindFrameBuffer(test->mReFrameBuffer)).Times(1);
+ EXPECT_CALL(*test->mRenderEngine, unbindFrameBuffer(test->mReFrameBuffer)).Times(1);
+ EXPECT_CALL(*test->mNativeWindow, queueBuffer(_, _)).WillOnce(Return(0));
+ EXPECT_CALL(*test->mNativeWindow, dequeueBuffer(_, _))
+ .WillOnce(DoAll(SetArgPointee<0>(test->mNativeWindowBuffer), SetArgPointee<1>(-1),
+ Return(0)));
}
template <typename Case>
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 32fce67..5aaf848 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -120,6 +120,7 @@
mock::EventThread* mEventThread = new mock::EventThread();
mock::EventControlThread* mEventControlThread = new mock::EventControlThread();
sp<mock::NativeWindow> mNativeWindow = new mock::NativeWindow();
+ sp<GraphicBuffer> mBuffer = new GraphicBuffer();
// These mocks are created by the test, but are destroyed by SurfaceFlinger
// by virtue of being stored into a std::unique_ptr. However we still need
@@ -134,7 +135,6 @@
sp<mock::GraphicBufferConsumer> mConsumer;
sp<mock::GraphicBufferProducer> mProducer;
surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
- renderengine::mock::Surface* mRenderSurface = nullptr;
};
DisplayTransactionTest::DisplayTransactionTest() {
@@ -340,26 +340,11 @@
static void setupNativeWindowSurfaceCreationCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
.WillOnce(Return(test->mNativeWindow));
- EXPECT_CALL(*test->mNativeWindow, perform(19)).WillRepeatedly(Return(NO_ERROR));
- // For simplicity, we only expect to create a single render surface for
- // each test.
- ASSERT_TRUE(test->mRenderSurface == nullptr);
- test->mRenderSurface = new renderengine::mock::Surface();
- EXPECT_CALL(*test->mRenderEngine, createSurface())
- .WillOnce(Return(ByMove(
- std::unique_ptr<renderengine::Surface>(test->mRenderSurface))));
-
- // Creating a DisplayDevice requires getting default dimensions from the
- // native window.
EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
-
- EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
- EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
- EXPECT_CALL(*test->mRenderSurface, setNativeWindow(test->mNativeWindow.get())).Times(1);
}
static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
@@ -1070,9 +1055,6 @@
// The call disable vsyncs
EXPECT_CALL(*mEventControlThread, setVsyncEnabled(false)).Times(1);
- // The call clears the current render engine surface
- EXPECT_CALL(*mRenderEngine, resetCurrentSurface());
-
// The call ends any display resyncs
EXPECT_CALL(*mPrimaryDispSync, endResync()).Times(1);
@@ -1132,6 +1114,9 @@
.WillRepeatedly(DoAll(SetArgPointee<1>(1080 /* arbitrary */), Return(0)));
EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(1920 /* arbitrary */), Return(0)));
+ EXPECT_CALL(*mNativeWindow, perform(9)).Times(1);
+ EXPECT_CALL(*mNativeWindow, perform(13)).Times(1);
+ EXPECT_CALL(*mNativeWindow, perform(30)).Times(1);
auto displayDevice = mInjector.inject();
displayDevice->getBestColorMode(mInputDataspace, mInputRenderIntent, &mOutDataspace,
@@ -1287,7 +1272,7 @@
// Insert display data so that the HWC thinks it created the virtual display.
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData()[*displayId] = {};
+ mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
setupNewDisplayDeviceInternalTest<Case>();
}
@@ -1725,7 +1710,6 @@
EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
- EXPECT_CALL(*mProducer, connect(_, _, _, _)).Times(1);
EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
@@ -1801,7 +1785,7 @@
// A virtual display is set up but is removed from the current state.
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData()[*displayId] = {};
+ mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Case::Display::injectHwcDisplay(this);
auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
existing.inject();
@@ -1949,11 +1933,18 @@
// A display is set up
auto nativeWindow = new mock::NativeWindow();
auto displaySurface = new mock::DisplaySurface();
- auto renderSurface = new renderengine::mock::Surface();
+ sp<GraphicBuffer> buf = new GraphicBuffer();
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.setNativeWindow(nativeWindow);
display.setDisplaySurface(displaySurface);
- display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
+ // Setup injection expections
+ EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
+ .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
+ EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
+ .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
+ EXPECT_CALL(*nativeWindow, perform(9)).Times(1);
+ EXPECT_CALL(*nativeWindow, perform(13)).Times(1);
+ EXPECT_CALL(*nativeWindow, perform(30)).Times(1);
display.inject();
// There is a change to the viewport state
@@ -1965,9 +1956,7 @@
// --------------------------------------------------------------------
// Call Expectations
- EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(newWidth, oldHeight)).Times(1);
- EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
// --------------------------------------------------------------------
// Invocation
@@ -1988,11 +1977,18 @@
// A display is set up
auto nativeWindow = new mock::NativeWindow();
auto displaySurface = new mock::DisplaySurface();
- auto renderSurface = new renderengine::mock::Surface();
+ sp<GraphicBuffer> buf = new GraphicBuffer();
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.setNativeWindow(nativeWindow);
display.setDisplaySurface(displaySurface);
- display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
+ // Setup injection expections
+ EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
+ .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
+ EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
+ .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
+ EXPECT_CALL(*nativeWindow, perform(9)).Times(1);
+ EXPECT_CALL(*nativeWindow, perform(13)).Times(1);
+ EXPECT_CALL(*nativeWindow, perform(30)).Times(1);
display.inject();
// There is a change to the viewport state
@@ -2004,9 +2000,7 @@
// --------------------------------------------------------------------
// Call Expectations
- EXPECT_CALL(*renderSurface, setNativeWindow(nullptr)).Times(1);
EXPECT_CALL(*displaySurface, resizeBuffers(oldWidth, newHeight)).Times(1);
- EXPECT_CALL(*renderSurface, setNativeWindow(nativeWindow)).Times(1);
// --------------------------------------------------------------------
// Invocation
@@ -2920,7 +2914,7 @@
// Insert display data so that the HWC thinks it created the virtual display.
const auto displayId = Case::Display::DISPLAY_ID::get();
ASSERT_TRUE(displayId);
- mFlinger.mutableHwcDisplayData()[*displayId] = {};
+ mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
// A virtual display device is set up
Case::Display::injectHwcDisplay(this);
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
new file mode 100644
index 0000000..b518f10
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -0,0 +1,144 @@
+#undef LOG_TAG
+#define LOG_TAG "LayerHistoryUnittests"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <log/log.h>
+
+#include <mutex>
+
+#include "Scheduler/LayerHistory.h"
+
+using testing::_;
+using testing::Return;
+
+namespace android {
+
+class LayerHistoryTest : public testing::Test {
+public:
+ LayerHistoryTest();
+ ~LayerHistoryTest() override;
+
+protected:
+ std::unique_ptr<LayerHistory> mLayerHistory;
+};
+
+LayerHistoryTest::LayerHistoryTest() {
+ mLayerHistory = std::make_unique<LayerHistory>();
+}
+LayerHistoryTest::~LayerHistoryTest() {}
+
+namespace {
+TEST_F(LayerHistoryTest, simpleInsertAndGet) {
+ mLayerHistory->insert("TestLayer", 0);
+
+ const std::unordered_map<std::string, nsecs_t>& testMap = mLayerHistory->get(0);
+ EXPECT_EQ(1, testMap.size());
+ auto element = testMap.find("TestLayer");
+ EXPECT_EQ("TestLayer", element->first);
+ EXPECT_EQ(0, element->second);
+
+ // Testing accessing object at an empty container will return an empty map.
+ const std::unordered_map<std::string, nsecs_t>& emptyMap = mLayerHistory->get(1);
+ EXPECT_EQ(0, emptyMap.size());
+}
+
+TEST_F(LayerHistoryTest, multipleInserts) {
+ mLayerHistory->insert("TestLayer0", 0);
+ mLayerHistory->insert("TestLayer1", 1);
+ mLayerHistory->insert("TestLayer2", 2);
+ mLayerHistory->insert("TestLayer3", 3);
+
+ const std::unordered_map<std::string, nsecs_t>& testMap = mLayerHistory->get(0);
+ // Because the counter was not incremented, all elements were inserted into the first
+ // container.
+ EXPECT_EQ(4, testMap.size());
+ auto element = testMap.find("TestLayer0");
+ EXPECT_EQ("TestLayer0", element->first);
+ EXPECT_EQ(0, element->second);
+
+ element = testMap.find("TestLayer1");
+ EXPECT_EQ("TestLayer1", element->first);
+ EXPECT_EQ(1, element->second);
+
+ element = testMap.find("TestLayer2");
+ EXPECT_EQ("TestLayer2", element->first);
+ EXPECT_EQ(2, element->second);
+
+ element = testMap.find("TestLayer3");
+ EXPECT_EQ("TestLayer3", element->first);
+ EXPECT_EQ(3, element->second);
+
+ // Testing accessing object at an empty container will return an empty map.
+ const std::unordered_map<std::string, nsecs_t>& emptyMap = mLayerHistory->get(1);
+ EXPECT_EQ(0, emptyMap.size());
+}
+
+TEST_F(LayerHistoryTest, incrementingCounter) {
+ mLayerHistory->insert("TestLayer0", 0);
+ mLayerHistory->incrementCounter();
+ mLayerHistory->insert("TestLayer1", 1);
+ mLayerHistory->insert("TestLayer2", 2);
+ mLayerHistory->incrementCounter();
+ mLayerHistory->insert("TestLayer3", 3);
+
+ // Because the counter was incremented, the elements were inserted into different
+ // containers.
+ const std::unordered_map<std::string, nsecs_t>& testMap1 = mLayerHistory->get(0);
+ EXPECT_EQ(1, testMap1.size());
+ auto element = testMap1.find("TestLayer0");
+ EXPECT_EQ("TestLayer0", element->first);
+ EXPECT_EQ(0, element->second);
+
+ const std::unordered_map<std::string, nsecs_t>& testMap2 = mLayerHistory->get(1);
+ EXPECT_EQ(2, testMap2.size());
+ element = testMap2.find("TestLayer1");
+ EXPECT_EQ("TestLayer1", element->first);
+ EXPECT_EQ(1, element->second);
+ element = testMap2.find("TestLayer2");
+ EXPECT_EQ("TestLayer2", element->first);
+ EXPECT_EQ(2, element->second);
+
+ const std::unordered_map<std::string, nsecs_t>& testMap3 = mLayerHistory->get(2);
+ EXPECT_EQ(1, testMap3.size());
+ element = testMap3.find("TestLayer3");
+ EXPECT_EQ("TestLayer3", element->first);
+ EXPECT_EQ(3, element->second);
+
+ // Testing accessing object at an empty container will return an empty map.
+ const std::unordered_map<std::string, nsecs_t>& emptyMap = mLayerHistory->get(3);
+ EXPECT_EQ(0, emptyMap.size());
+}
+
+TEST_F(LayerHistoryTest, clearTheMap) {
+ mLayerHistory->insert("TestLayer0", 0);
+ mLayerHistory->incrementCounter();
+
+ const std::unordered_map<std::string, nsecs_t>& testMap1 = mLayerHistory->get(0);
+ EXPECT_EQ(1, testMap1.size());
+ auto element = testMap1.find("TestLayer0");
+ EXPECT_EQ("TestLayer0", element->first);
+ EXPECT_EQ(0, element->second);
+
+ // The array currently contains 30 elements.
+ for (int i = 1; i < 30; ++i) {
+ mLayerHistory->insert("TestLayer0", i);
+ mLayerHistory->incrementCounter();
+ }
+ // Expect the map to be cleared.
+ const std::unordered_map<std::string, nsecs_t>& testMap2 = mLayerHistory->get(0);
+ EXPECT_EQ(0, testMap2.size());
+
+ mLayerHistory->insert("TestLayer30", 30);
+ const std::unordered_map<std::string, nsecs_t>& testMap3 = mLayerHistory->get(0);
+ element = testMap3.find("TestLayer30");
+ EXPECT_EQ("TestLayer30", element->first);
+ EXPECT_EQ(30, element->second);
+ // The original element in this location does not exist anymore.
+ element = testMap3.find("TestLayer0");
+ EXPECT_EQ(testMap3.end(), element);
+}
+
+} // namespace
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index a519f1f..85c835e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -474,11 +474,6 @@
return *this;
}
- auto& setRenderSurface(std::unique_ptr<renderengine::Surface> renderSurface) {
- mCreationArgs.renderSurface = std::move(renderSurface);
- return *this;
- }
-
auto& setSecure(bool secure) {
mCreationArgs.isSecure = secure;
return *this;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
index af54df6..fbfbc3f 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
@@ -26,9 +26,6 @@
RenderEngine::RenderEngine() = default;
RenderEngine::~RenderEngine() = default;
-Surface::Surface() = default;
-Surface::~Surface() = default;
-
Image::Image() = default;
Image::~Image() = default;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index afca63a..90c3c20 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -23,7 +23,6 @@
#include <renderengine/LayerSettings.h>
#include <renderengine/Mesh.h>
#include <renderengine/RenderEngine.h>
-#include <renderengine/Surface.h>
#include <renderengine/Texture.h>
#include <ui/GraphicBuffer.h>
@@ -37,15 +36,12 @@
~RenderEngine() override;
MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
- MOCK_METHOD0(createSurface, std::unique_ptr<renderengine::Surface>());
MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
MOCK_CONST_METHOD0(primeCache, void());
MOCK_METHOD1(dump, void(String8&));
MOCK_CONST_METHOD0(useNativeFenceSync, bool());
MOCK_CONST_METHOD0(useWaitSync, bool());
MOCK_CONST_METHOD0(isCurrent, bool());
- MOCK_METHOD1(setCurrentSurface, bool(const renderengine::Surface&));
- MOCK_METHOD0(resetCurrentSurface, void());
MOCK_METHOD0(flush, base::unique_fd());
MOCK_METHOD0(finish, bool());
MOCK_METHOD1(waitFence, bool(base::unique_fd*));
@@ -82,23 +78,6 @@
ANativeWindowBuffer* const, base::unique_fd*));
};
-class Surface : public renderengine::Surface {
-public:
- Surface();
- ~Surface() override;
-
- MOCK_METHOD1(setCritical, void(bool));
- MOCK_METHOD1(setAsync, void(bool));
- MOCK_METHOD1(setNativeWindow, void(ANativeWindow*));
- MOCK_CONST_METHOD0(swapBuffers, void());
- MOCK_CONST_METHOD0(queryRedSize, int32_t());
- MOCK_CONST_METHOD0(queryGreenSize, int32_t());
- MOCK_CONST_METHOD0(queryBlueSize, int32_t());
- MOCK_CONST_METHOD0(queryAlphaSize, int32_t());
- MOCK_CONST_METHOD0(getWidth, int32_t());
- MOCK_CONST_METHOD0(getHeight, int32_t());
-};
-
class Image : public renderengine::Image {
public:
Image();
diff --git a/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
index 561fd58..4950a4b 100644
--- a/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
+++ b/services/surfaceflinger/tests/unittests/mock/system/window/MockNativeWindow.h
@@ -36,6 +36,7 @@
MOCK_METHOD1(queueBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
MOCK_CONST_METHOD2(query, int(int, int*));
MOCK_METHOD1(perform, int(int));
+ MOCK_METHOD2(perform, int(int, int));
MOCK_METHOD1(cancelBuffer_DEPRECATED, int(struct ANativeWindowBuffer*));
MOCK_METHOD2(dequeueBuffer, int(struct ANativeWindowBuffer**, int*));
MOCK_METHOD2(queueBuffer, int(struct ANativeWindowBuffer*, int));