Add DaydreamVR native libraries and services
Upstreaming the main VR system components from master-dreamos-dev
into goog/master.
Bug: None
Test: `m -j32` succeeds. Sailfish boots and basic_vr sample app works
Change-Id: I853015872afc443aecee10411ef2d6b79184d051
diff --git a/libs/vr/libbufferhub/bufferhub_tests.cpp b/libs/vr/libbufferhub/bufferhub_tests.cpp
new file mode 100644
index 0000000..cb45dbe
--- /dev/null
+++ b/libs/vr/libbufferhub/bufferhub_tests.cpp
@@ -0,0 +1,219 @@
+#include <android/native_window.h>
+#include <base/posix/eintr_wrapper.h>
+#include <gtest/gtest.h>
+#include <private/dvr/buffer_hub_client.h>
+
+#include <mutex>
+#include <thread>
+
+using android::dvr::BufferProducer;
+using android::dvr::BufferConsumer;
+using android::pdx::LocalHandle;
+
+const int kWidth = 640;
+const int kHeight = 480;
+const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+const int kUsage = 0;
+const uint64_t kContext = 42;
+
+using LibBufferHubTest = ::testing::Test;
+
+TEST_F(LibBufferHubTest, TestBasicUsage) {
+ std::unique_ptr<BufferProducer> p = BufferProducer::Create(
+ kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+ // Check that consumers can spawn other consumers.
+ std::unique_ptr<BufferConsumer> c2 =
+ BufferConsumer::Import(c->CreateConsumer());
+ ASSERT_TRUE(c2.get() != nullptr);
+
+ EXPECT_EQ(0, p->Post(LocalHandle(), kContext));
+ // Both consumers should be triggered.
+ EXPECT_GE(0, HANDLE_EINTR(p->Poll(0)));
+ EXPECT_LT(0, HANDLE_EINTR(c->Poll(10)));
+ EXPECT_LT(0, HANDLE_EINTR(c2->Poll(10)));
+
+ uint64_t context;
+ LocalHandle fence;
+ EXPECT_LE(0, c->Acquire(&fence, &context));
+ EXPECT_EQ(kContext, context);
+ EXPECT_GE(0, HANDLE_EINTR(c->Poll(0)));
+
+ EXPECT_LE(0, c2->Acquire(&fence, &context));
+ EXPECT_EQ(kContext, context);
+ EXPECT_GE(0, HANDLE_EINTR(c2->Poll(0)));
+
+ EXPECT_EQ(0, c->Release(LocalHandle()));
+ EXPECT_GE(0, HANDLE_EINTR(p->Poll(0)));
+ EXPECT_EQ(0, c2->Discard());
+
+ EXPECT_LE(0, HANDLE_EINTR(p->Poll(0)));
+ EXPECT_EQ(0, p->Gain(&fence));
+ EXPECT_GE(0, HANDLE_EINTR(p->Poll(0)));
+}
+
+TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
+ struct Metadata {
+ int64_t field1;
+ int64_t field2;
+ };
+ std::unique_ptr<BufferProducer> p = BufferProducer::Create(
+ kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ Metadata m = {1, 3};
+ EXPECT_EQ(0, p->Post(LocalHandle(), m));
+ EXPECT_LE(0, HANDLE_EINTR(c->Poll(10)));
+
+ LocalHandle fence;
+ Metadata m2 = {};
+ EXPECT_EQ(0, c->Acquire(&fence, &m2));
+ EXPECT_EQ(m.field1, m2.field1);
+ EXPECT_EQ(m.field2, m2.field2);
+
+ EXPECT_EQ(0, c->Release(LocalHandle()));
+ EXPECT_LT(0, HANDLE_EINTR(p->Poll(0)));
+}
+
+TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
+ struct Metadata {
+ int64_t field1;
+ int64_t field2;
+ };
+ std::unique_ptr<BufferProducer> p = BufferProducer::Create(
+ kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ int64_t sequence = 3;
+ EXPECT_NE(0, p->Post(LocalHandle(), sequence));
+ EXPECT_GE(0, HANDLE_EINTR(c->Poll(10)));
+}
+
+TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
+ struct Metadata {
+ int64_t field1;
+ int64_t field2;
+ };
+ std::unique_ptr<BufferProducer> p = BufferProducer::Create(
+ kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ Metadata m = {1, 3};
+ EXPECT_EQ(0, p->Post(LocalHandle(), m));
+
+ LocalHandle fence;
+ int64_t sequence;
+ EXPECT_NE(0, c->Acquire(&fence, &sequence));
+}
+
+TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
+ std::unique_ptr<BufferProducer> p = BufferProducer::Create(
+ kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ int64_t sequence = 3;
+ EXPECT_EQ(0, p->Post(LocalHandle(), sequence));
+
+ LocalHandle fence;
+ EXPECT_EQ(0, c->Acquire(&fence));
+}
+
+TEST_F(LibBufferHubTest, TestWithNoMeta) {
+ std::unique_ptr<BufferProducer> p =
+ BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ LocalHandle fence;
+
+ EXPECT_EQ(0, p->Post<void>(LocalHandle()));
+ EXPECT_EQ(0, c->Acquire(&fence));
+}
+
+TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
+ std::unique_ptr<BufferProducer> p =
+ BufferProducer::Create(kWidth, kHeight, kFormat, kUsage);
+ ASSERT_TRUE(p.get() != nullptr);
+ std::unique_ptr<BufferConsumer> c =
+ BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_TRUE(c.get() != nullptr);
+
+ int64_t sequence = 3;
+ EXPECT_NE(0, p->Post(LocalHandle(), sequence));
+}
+
+TEST_F(LibBufferHubTest, TestPersistentBufferPersistence) {
+ auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
+ kHeight, kFormat, kUsage);
+ ASSERT_NE(nullptr, p);
+
+ // Record the original buffer id for later comparison.
+ const int buffer_id = p->id();
+
+ auto c = BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_NE(nullptr, c);
+
+ EXPECT_EQ(0, p->Post<void>(LocalHandle()));
+
+ // Close the connection to the producer. This should not affect the consumer.
+ p = nullptr;
+
+ LocalHandle fence;
+ EXPECT_EQ(0, c->Acquire(&fence));
+ EXPECT_EQ(0, c->Release(LocalHandle()));
+
+ // Attempt to reconnect to the persistent buffer.
+ p = BufferProducer::Create("TestPersistentBuffer");
+ ASSERT_NE(nullptr, p);
+ EXPECT_EQ(buffer_id, p->id());
+ EXPECT_EQ(0, p->Gain(&fence));
+}
+
+TEST_F(LibBufferHubTest, TestPersistentBufferMismatchParams) {
+ auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
+ kHeight, kFormat, kUsage);
+ ASSERT_NE(nullptr, p);
+
+ // Close the connection to the producer.
+ p = nullptr;
+
+ // Mismatch the params.
+ p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth * 2,
+ kHeight, kFormat, kUsage);
+ ASSERT_EQ(nullptr, p);
+}
+
+TEST_F(LibBufferHubTest, TestRemovePersistentBuffer) {
+ auto p = BufferProducer::Create("TestPersistentBuffer", -1, -1, kWidth,
+ kHeight, kFormat, kUsage);
+ ASSERT_NE(nullptr, p);
+
+ LocalHandle fence;
+ auto c = BufferConsumer::Import(p->CreateConsumer());
+ ASSERT_NE(nullptr, c);
+ EXPECT_NE(-EPIPE, c->Acquire(&fence));
+
+ // Test that removing persistence and closing the producer orphans the
+ // consumer.
+ EXPECT_EQ(0, p->RemovePersistence());
+ p = nullptr;
+
+ EXPECT_EQ(-EPIPE, c->Release(LocalHandle()));
+}