Align DisplayEventReceiver events
The structs are aligned differently on x86 vs x64, causing them to
parse messages wrong.
Test: CtsGraphicsTestCases android.graphics.drawable.cts.AnimatedImageDrawableTest#testLifeCycle
Bug: 149314120
Change-Id: I745ba7647ecadffed016f1694a7b4a81c5ef195c
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 0e10d1a..7974a06 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -57,16 +57,21 @@
};
struct Event {
+ // We add __attribute__((aligned(8))) for nsecs_t fields because
+ // we need to make sure all fields are aligned the same with x86
+ // and x64 (long long has different default alignment):
+ //
+ // https://en.wikipedia.org/wiki/Data_structure_alignment
struct Header {
uint32_t type;
- PhysicalDisplayId displayId;
+ PhysicalDisplayId displayId __attribute__((aligned(8)));
nsecs_t timestamp __attribute__((aligned(8)));
};
struct VSync {
uint32_t count;
- nsecs_t expectedVSyncTimestamp;
+ nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
};
struct Hotplug {
@@ -75,7 +80,7 @@
struct Config {
int32_t configId;
- nsecs_t vsyncPeriod;
+ nsecs_t vsyncPeriod __attribute__((aligned(8)));
};
Header header;
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index a6bcd10..53c13c8 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -14,7 +14,7 @@
srcs: [
"BLASTBufferQueue_test.cpp",
- "BufferItemConsumer_test.cpp",
+ "BufferItemConsumer_test.cpp",
"BufferQueue_test.cpp",
"CpuConsumer_test.cpp",
"EndToEndNativeInputTest.cpp",
@@ -58,6 +58,30 @@
header_libs: ["libsurfaceflinger_headers"],
}
+// Build the tests that need to run with both 32bit and 64bit.
+cc_test {
+ name: "libgui_multilib_test",
+ test_suites: ["device-tests"],
+
+ clang: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ srcs: [
+ "DisplayEventStructLayout_test.cpp",
+ ],
+
+ shared_libs: [
+ "libgui",
+ ],
+
+ compile_multilib: "both",
+
+ header_libs: ["libsurfaceflinger_headers"],
+}
+
// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
// This test has a main method, and requires a separate binary to be built.
// To add move tests like this, just add additional cc_test statements,
diff --git a/libs/gui/tests/DisplayEventStructLayout_test.cpp b/libs/gui/tests/DisplayEventStructLayout_test.cpp
new file mode 100644
index 0000000..4bcb795
--- /dev/null
+++ b/libs/gui/tests/DisplayEventStructLayout_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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 <gtest/gtest.h>
+#include <gui/DisplayEventReceiver.h>
+
+namespace android::test {
+
+#define CHECK_OFFSET(type, member, expected_offset) \
+ static_assert((offsetof(type, member) == (expected_offset)), "")
+
+TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
+ CHECK_OFFSET(DisplayEventReceiver::Event, vsync, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event, hotplug, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event, config, 24);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, type, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, displayId, 8);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, timestamp, 16);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, count, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, expectedVSyncTimestamp, 8);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Hotplug, connected, 0);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Config, configId, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Config, vsyncPeriod, 8);
+}
+
+} // namespace android::test