Merge "Fix names of headtracking feature files."
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 4655d33..3153aa5 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -58,6 +58,8 @@
using android::os::dumpstate::DumpFileToFd;
using android::os::dumpstate::PropertiesHelper;
+// Keep in sync with
+// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
static const int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
/* Most simple commands have 10 as timeout, so 5 is a good estimate */
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index f567a10..be1a434 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -23,10 +23,9 @@
LOCAL_CFLAGS += -DART_BASE_ADDRESS_MIN_DELTA=$(LOCAL_LIBART_IMG_HOST_MIN_BASE_ADDRESS_DELTA)
LOCAL_CFLAGS += -DART_BASE_ADDRESS_MAX_DELTA=$(LOCAL_LIBART_IMG_HOST_MAX_BASE_ADDRESS_DELTA)
-LOCAL_SRC_FILES := otapreopt.cpp InstalldNativeService.cpp globals.cpp utils.cpp dexopt.cpp binder/android/os/IInstalld.aidl
+LOCAL_SRC_FILES := otapreopt.cpp globals.cpp utils.cpp dexopt.cpp
LOCAL_SHARED_LIBRARIES := \
libbase \
- libbinder \
libcutils \
liblog \
liblogwrap \
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5bb2ce7..f7e8d13 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1564,7 +1564,7 @@
ALOGV("DexInv: --- END '%s' (success) ---\n", dex_path);
} else {
ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", dex_path, res);
- return -1;
+ return res;
}
}
diff --git a/cmds/installd/globals.h b/cmds/installd/globals.h
index 8242eec..c90beec 100644
--- a/cmds/installd/globals.h
+++ b/cmds/installd/globals.h
@@ -20,8 +20,6 @@
#include <inttypes.h>
-#include "InstalldNativeService.h"
-
namespace android {
namespace installd {
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index c74c65b..82b8cc2 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -36,7 +36,6 @@
#include <log/log.h>
#include <private/android_filesystem_config.h>
-#include "InstalldNativeService.h"
#include "dexopt.h"
#include "file_parsing.h"
#include "globals.h"
diff --git a/data/etc/car_core_hardware.xml b/data/etc/car_core_hardware.xml
index ab89ef5..835504f 100644
--- a/data/etc/car_core_hardware.xml
+++ b/data/etc/car_core_hardware.xml
@@ -23,6 +23,9 @@
devices.
-->
<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+
<feature name="android.hardware.audio.output" />
<feature name="android.hardware.location" />
<feature name="android.hardware.location.network" />
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index ed3db5c..2607d58 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -23,6 +23,9 @@
devices.
-->
<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+
<feature name="android.hardware.audio.output" />
<feature name="android.hardware.camera" />
<feature name="android.hardware.location" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 7f545e6..f0ca067 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -23,6 +23,9 @@
devices.
-->
<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+
<feature name="android.hardware.audio.output" />
<feature name="android.hardware.location" />
<feature name="android.hardware.location.network" />
diff --git a/data/etc/wearable_core_hardware.xml b/data/etc/wearable_core_hardware.xml
index 84230da..a7955e9 100644
--- a/data/etc/wearable_core_hardware.xml
+++ b/data/etc/wearable_core_hardware.xml
@@ -21,6 +21,9 @@
Wearable devices include watches, glasses, backpacks, and sweaters.
-->
<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+
<feature name="android.hardware.location" />
<!-- devices supporting compass/magnitometer sensor must include
android.hardware.sensor.compass.xml -->
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 4492a08..3a99147 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -8,6 +8,7 @@
clang: true,
srcs: [
+ "BufferItemConsumer_test.cpp",
"BufferQueue_test.cpp",
"CpuConsumer_test.cpp",
"FillBuffer.cpp",
diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp
new file mode 100644
index 0000000..d64e530
--- /dev/null
+++ b/libs/gui/tests/BufferItemConsumer_test.cpp
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#define LOG_TAG "BufferItemConsumer_test"
+//#define LOG_NDEBUG 0
+
+#include <gtest/gtest.h>
+#include <gui/BufferItemConsumer.h>
+#include <gui/IProducerListener.h>
+#include <gui/Surface.h>
+
+namespace android {
+
+static constexpr int kWidth = 100;
+static constexpr int kHeight = 100;
+static constexpr int kMaxLockedBuffers = 3;
+static constexpr int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+static constexpr int kFrameSleepUs = 30 * 1000;
+
+class BufferItemConsumerTest : public ::testing::Test {
+ protected:
+ struct BufferFreedListener
+ : public BufferItemConsumer::BufferFreedListener {
+ explicit BufferFreedListener(BufferItemConsumerTest* test)
+ : mTest(test) {}
+ void onBufferFreed(const wp<GraphicBuffer>& /* gBuffer */) override {
+ mTest->HandleBufferFreed();
+ }
+ BufferItemConsumerTest* mTest;
+ };
+
+ void SetUp() override {
+ BufferQueue::createBufferQueue(&mProducer, &mConsumer);
+ mBIC =
+ new BufferItemConsumer(mConsumer, kFormat, kMaxLockedBuffers, true);
+ String8 name("BufferItemConsumer_Under_Test");
+ mBIC->setName(name);
+ mBFL = new BufferFreedListener(this);
+ mBIC->setBufferFreedListener(mBFL);
+
+ sp<IProducerListener> producerListener = new DummyProducerListener();
+ IGraphicBufferProducer::QueueBufferOutput bufferOutput;
+ ASSERT_EQ(NO_ERROR,
+ mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
+ true, &bufferOutput));
+ ASSERT_EQ(NO_ERROR,
+ mProducer->setMaxDequeuedBufferCount(kMaxLockedBuffers));
+ }
+
+ int GetFreedBufferCount() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mFreedBufferCount;
+ }
+
+ void HandleBufferFreed() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mFreedBufferCount++;
+ ALOGV("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
+ }
+
+ void DequeueBuffer(int* outSlot) {
+ ASSERT_NE(outSlot, nullptr);
+
+ int slot;
+ sp<Fence> outFence;
+ status_t ret = mProducer->dequeueBuffer(&slot, &outFence, kWidth,
+ kHeight, 0, 0, nullptr);
+ ASSERT_GE(ret, 0);
+
+ ALOGV("dequeueBuffer: slot=%d", slot);
+ if (ret & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
+ ret = mProducer->requestBuffer(slot, &mBuffers[slot]);
+ ASSERT_EQ(NO_ERROR, ret);
+ }
+ *outSlot = slot;
+ }
+
+ void QueueBuffer(int slot) {
+ ALOGV("enqueueBuffer: slot=%d", slot);
+ IGraphicBufferProducer::QueueBufferInput bufferInput(
+ 0ULL, true, HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
+ NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
+ IGraphicBufferProducer::QueueBufferOutput bufferOutput;
+ status_t ret = mProducer->queueBuffer(slot, bufferInput, &bufferOutput);
+ ASSERT_EQ(NO_ERROR, ret);
+ }
+
+ void AcquireBuffer(int* outSlot) {
+ ASSERT_NE(outSlot, nullptr);
+ BufferItem buffer;
+ status_t ret = mBIC->acquireBuffer(&buffer, 0, false);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ ALOGV("acquireBuffer: slot=%d", buffer.mSlot);
+ *outSlot = buffer.mSlot;
+ }
+
+ void ReleaseBuffer(int slot) {
+ ALOGV("releaseBuffer: slot=%d", slot);
+ BufferItem buffer;
+ buffer.mSlot = slot;
+ buffer.mGraphicBuffer = mBuffers[slot];
+ status_t ret = mBIC->releaseBuffer(buffer, Fence::NO_FENCE);
+ ASSERT_EQ(NO_ERROR, ret);
+ }
+
+
+ std::mutex mMutex;
+ int mFreedBufferCount{0};
+
+ sp<BufferItemConsumer> mBIC;
+ sp<BufferFreedListener> mBFL;
+ sp<IGraphicBufferProducer> mProducer;
+ sp<IGraphicBufferConsumer> mConsumer;
+ sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS];
+};
+
+// Test that detaching buffer from consumer side triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DetachBufferFromConsumer) {
+ int slot;
+ // Producer: generate a dummy buffer.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+
+ ASSERT_EQ(0, GetFreedBufferCount());
+ // Consumer: acquire the buffer and then detach it.
+ AcquireBuffer(&slot);
+ status_t ret = mBIC->detachBuffer(slot);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ // Sleep to give some time for callbacks to happen.
+ usleep(kFrameSleepUs);
+ ASSERT_EQ(1, GetFreedBufferCount());
+}
+
+// Test that detaching buffer from producer side triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DetachBufferFromProducer) {
+ int slot;
+ // Let buffer go through the cycle at least once.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+ AcquireBuffer(&slot);
+ ReleaseBuffer(slot);
+
+ ASSERT_EQ(0, GetFreedBufferCount());
+
+ // Producer: generate the buffer again.
+ DequeueBuffer(&slot);
+
+ // Producer: detach the buffer.
+ status_t ret = mProducer->detachBuffer(slot);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ // Sleep to give some time for callbacks to happen.
+ usleep(kFrameSleepUs);
+ ASSERT_EQ(1, GetFreedBufferCount());
+}
+
+// Test that abandoning BufferItemConsumer triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, TriggerBufferFreed_AbandonBufferItemConsumer) {
+ int slot;
+ // Let buffer go through the cycle at least once.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+ AcquireBuffer(&slot);
+ ReleaseBuffer(slot);
+
+ // Abandon the BufferItemConsumer.
+ mBIC->abandon();
+
+ // Sleep to give some time for callbacks to happen.
+ usleep(kFrameSleepUs);
+ ASSERT_EQ(1, GetFreedBufferCount());
+}
+
+// Test that delete BufferItemConsumer triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DeleteBufferItemConsumer) {
+ int slot;
+ // Let buffer go through the cycle at least once.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+ AcquireBuffer(&slot);
+ ReleaseBuffer(slot);
+
+ // Delete the BufferItemConsumer.
+ mBIC.clear();
+
+ // Sleep to give some time for callbacks to happen.
+ usleep(kFrameSleepUs);
+ ASSERT_EQ(1, GetFreedBufferCount());
+}
+
+} // namespace android
diff --git a/libs/hwc2on1adapter/Android.bp b/libs/hwc2on1adapter/Android.bp
index 2be3e67..438d3f5 100644
--- a/libs/hwc2on1adapter/Android.bp
+++ b/libs/hwc2on1adapter/Android.bp
@@ -48,6 +48,9 @@
"-Wno-sign-conversion",
"-Wno-switch-enum",
"-Wno-float-equal",
+ "-Wno-shorten-64-to-32",
+ "-Wno-sign-compare",
+ "-Wno-missing-prototypes",
],
srcs: [
diff --git a/libs/sensor/SensorManager.cpp b/libs/sensor/SensorManager.cpp
index 9309275..d6d3304 100644
--- a/libs/sensor/SensorManager.cpp
+++ b/libs/sensor/SensorManager.cpp
@@ -38,14 +38,15 @@
namespace android {
// ----------------------------------------------------------------------------
-android::Mutex android::SensorManager::sLock;
-std::map<String16, SensorManager*> android::SensorManager::sPackageInstances;
+Mutex SensorManager::sLock;
+std::map<String16, SensorManager*> SensorManager::sPackageInstances;
SensorManager& SensorManager::getInstanceForPackage(const String16& packageName) {
+ waitForSensorService(nullptr);
+
Mutex::Autolock _l(sLock);
SensorManager* sensorManager;
- std::map<String16, SensorManager*>::iterator iterator =
- sPackageInstances.find(packageName);
+ auto iterator = sPackageInstances.find(packageName);
if (iterator != sPackageInstances.end()) {
sensorManager = iterator->second;
@@ -100,6 +101,28 @@
free(mSensorList);
}
+status_t SensorManager::waitForSensorService(sp<ISensorServer> *server) {
+ // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ...
+ sp<ISensorServer> s;
+ const String16 name("sensorservice");
+ for (int i = 0; i < 60; i++) {
+ status_t err = getService(name, &s);
+ switch (err) {
+ case NAME_NOT_FOUND:
+ sleep(1);
+ continue;
+ case NO_ERROR:
+ if (server != nullptr) {
+ *server = s;
+ }
+ return NO_ERROR;
+ default:
+ return err;
+ }
+ }
+ return TIMED_OUT;
+}
+
void SensorManager::sensorManagerDied() {
Mutex::Autolock _l(mLock);
mSensorServer.clear();
@@ -120,19 +143,8 @@
}
}
if (initSensorManager) {
- // try for 300 seconds (60*5(getService() tries for 5 seconds)) before giving up ...
- const String16 name("sensorservice");
- for (int i = 0; i < 60; i++) {
- status_t err = getService(name, &mSensorServer);
- if (err == NAME_NOT_FOUND) {
- sleep(1);
- continue;
- }
- if (err != NO_ERROR) {
- return err;
- }
- break;
- }
+ waitForSensorService(&mSensorServer);
+ LOG_ALWAYS_FATAL_IF(mSensorServer == nullptr, "getService(SensorService) NULL");
class DeathObserver : public IBinder::DeathRecipient {
SensorManager& mSensorManager;
@@ -144,8 +156,6 @@
explicit DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
};
- LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
-
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
diff --git a/libs/sensor/include/sensor/SensorManager.h b/libs/sensor/include/sensor/SensorManager.h
index a3d9741..92c9823 100644
--- a/libs/sensor/include/sensor/SensorManager.h
+++ b/libs/sensor/include/sensor/SensorManager.h
@@ -68,6 +68,7 @@
private:
// DeathRecipient interface
void sensorManagerDied();
+ static status_t waitForSensorService(sp<ISensorServer> *server);
SensorManager(const String16& opPackageName);
status_t assertStateLocked();
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index 452bad0..e068469 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -15,6 +15,7 @@
sourceFiles = [
"buffer_hub_client.cpp",
"buffer_hub_rpc.cpp",
+ "dvr_buffer.cpp",
"ion_buffer.cpp",
]
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 7268b76..2749fd1 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -130,6 +130,13 @@
return ret;
}
+void BufferHubBuffer::GetBlobFds(int* fds, size_t* fds_count,
+ size_t max_fds_count) const {
+ size_t numFds = static_cast<size_t>(native_handle()->numFds);
+ *fds_count = std::min(max_fds_count, numFds);
+ std::copy(native_handle()->data, native_handle()->data + *fds_count, fds);
+}
+
BufferConsumer::BufferConsumer(LocalChannelHandle channel)
: BASE(std::move(channel)) {
const int ret = ImportBuffer();
diff --git a/libs/vr/libbufferhub/dvr_buffer.cpp b/libs/vr/libbufferhub/dvr_buffer.cpp
new file mode 100644
index 0000000..3eb611f
--- /dev/null
+++ b/libs/vr/libbufferhub/dvr_buffer.cpp
@@ -0,0 +1,124 @@
+#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/dvr_buffer.h>
+#include <ui/GraphicBuffer.h>
+
+using namespace android;
+
+struct DvrWriteBuffer {
+ std::unique_ptr<dvr::BufferProducer> write_buffer_;
+ sp<GraphicBuffer> graphic_buffer_;
+};
+
+struct DvrReadBuffer {
+ std::unique_ptr<dvr::BufferConsumer> read_buffer_;
+ sp<GraphicBuffer> graphic_buffer_;
+};
+
+namespace android {
+namespace dvr {
+
+DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
+ std::unique_ptr<dvr::BufferProducer> buffer_producer) {
+ DvrWriteBuffer* write_buffer = new DvrWriteBuffer;
+ write_buffer->write_buffer_ = std::move(buffer_producer);
+ return write_buffer;
+}
+
+DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
+ std::unique_ptr<dvr::BufferConsumer> buffer_consumer) {
+ DvrReadBuffer* read_buffer = new DvrReadBuffer;
+ read_buffer->read_buffer_ = std::move(buffer_consumer);
+ return read_buffer;
+}
+
+} // namespace dvr
+} // namespace android
+
+namespace {
+
+void InitializeGraphicBuffer(const dvr::BufferHubBuffer* buffer,
+ sp<GraphicBuffer>* graphic_buffer) {
+ *graphic_buffer = sp<GraphicBuffer>(new GraphicBuffer(
+ buffer->width(), buffer->height(), buffer->format(), 1, /* layer count */
+ buffer->usage(), buffer->stride(), buffer->native_handle(),
+ false /* keep ownership */));
+}
+
+} // anonymous namespace
+
+extern "C" {
+
+void dvrWriteBufferDestroy(DvrWriteBuffer* client) { delete client; }
+
+void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
+ size_t* fds_count, size_t max_fds_count) {
+ client->write_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+}
+
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+ AHardwareBuffer** hardware_buffer) {
+ if (!client->graphic_buffer_.get()) {
+ InitializeGraphicBuffer(client->write_buffer_.get(),
+ &client->graphic_buffer_);
+ }
+ *hardware_buffer =
+ reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+ return 0;
+}
+
+int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+ const void* meta, size_t meta_size_bytes) {
+ pdx::LocalHandle fence(ready_fence_fd);
+ int result = client->write_buffer_->Post(fence, meta, meta_size_bytes);
+ fence.Release();
+ return result;
+}
+
+int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd) {
+ pdx::LocalHandle release_fence;
+ int result = client->write_buffer_->Gain(&release_fence);
+ *release_fence_fd = release_fence.Release();
+ return result;
+}
+
+int dvrWriteBufferGainAsync(DvrWriteBuffer* client) {
+ return client->write_buffer_->GainAsync();
+}
+
+void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
+ size_t max_fds_count) {
+ client->read_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+}
+
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+ AHardwareBuffer** hardware_buffer) {
+ if (!client->graphic_buffer_.get()) {
+ InitializeGraphicBuffer(client->read_buffer_.get(),
+ &client->graphic_buffer_);
+ }
+ *hardware_buffer =
+ reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+ return 0;
+}
+
+int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
+ size_t meta_size_bytes) {
+ pdx::LocalHandle ready_fence;
+ int result =
+ client->read_buffer_->Acquire(&ready_fence, meta, meta_size_bytes);
+ *ready_fence_fd = ready_fence.Release();
+ return result;
+}
+
+int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd) {
+ pdx::LocalHandle fence(release_fence_fd);
+ int result = client->read_buffer_->Release(fence);
+ fence.Release();
+ return result;
+}
+
+int dvrReadBufferReleaseAsync(DvrReadBuffer* client) {
+ return client->read_buffer_->ReleaseAsync();
+}
+
+} // extern "C"
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
index cefde7b..aacc385 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
@@ -70,6 +70,10 @@
return LocalHandle(dup(native_handle()->data[0]));
}
+ // Get up to |max_fds_count| file descriptors for accessing the blob shared
+ // memory. |fds_count| will contain the actual number of file descriptors.
+ void GetBlobFds(int* fds, size_t* fds_count, size_t max_fds_count) const;
+
using Client::event_fd;
Status<int> GetEventMask(int events) {
diff --git a/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h b/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
new file mode 100644
index 0000000..c14b1a3
--- /dev/null
+++ b/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
@@ -0,0 +1,55 @@
+#ifndef ANDROID_DVR_BUFFER_H_
+#define ANDROID_DVR_BUFFER_H_
+
+#include <memory>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct AHardwareBuffer AHardwareBuffer;
+
+// Write buffer
+void dvrWriteBufferDestroy(DvrWriteBuffer* client);
+void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
+ size_t* fds_count, size_t max_fds_count);
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+ AHardwareBuffer** hardware_buffer);
+int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+ const void* meta, size_t meta_size_bytes);
+int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd);
+int dvrWriteBufferGainAsync(DvrWriteBuffer* client);
+
+// Read buffer
+void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
+ size_t max_fds_count);
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+ AHardwareBuffer** hardware_buffer);
+int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
+ size_t meta_size_bytes);
+int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd);
+int dvrReadBufferReleaseAsync(DvrReadBuffer* client);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+namespace android {
+namespace dvr {
+
+class BufferProducer;
+class BufferConsumer;
+
+DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
+ std::unique_ptr<BufferProducer> buffer_producer);
+DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
+ std::unique_ptr<BufferConsumer> buffer_consumer);
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_BUFFER_H_
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
index b976097..1c8f2c0 100644
--- a/libs/vr/libbufferhubqueue/Android.bp
+++ b/libs/vr/libbufferhubqueue/Android.bp
@@ -42,7 +42,10 @@
cc_library {
name: "libbufferhubqueue",
- cflags = [ "-DLOGTAG=\"libbufferhubqueue\"" ],
+ cflags = [
+ "-DLOGTAG=\"libbufferhubqueue\"",
+ "-DTRACE=0",
+ ],
srcs: sourceFiles,
export_include_dirs: includeFiles,
export_static_lib_headers: staticLibraries,
@@ -50,3 +53,4 @@
shared_libs: sharedLibraries,
}
+subdirs = ["tests"]
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index a8077b9..bd6511d 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -1,7 +1,5 @@
#include "include/private/dvr/buffer_hub_queue_client.h"
-//#define LOG_NDEBUG 0
-
#include <inttypes.h>
#include <log/log.h>
#include <sys/epoll.h>
@@ -73,7 +71,8 @@
auto return_value = status.take();
- ALOGD("CreateConsumerQueue: meta_size_bytes=%zu", return_value.second);
+ ALOGD_IF(TRACE, "BufferHubQueue::CreateConsumerQueue: meta_size_bytes=%zu",
+ return_value.second);
return ConsumerQueue::Create(std::move(return_value.first),
return_value.second);
}
@@ -85,7 +84,7 @@
int ret = epoll_fd_.Wait(events.data(), events.size(), timeout);
if (ret == 0) {
- ALOGD("Wait on epoll returns nothing before timeout.");
+ ALOGD_IF(TRACE, "Wait on epoll returns nothing before timeout.");
return false;
}
@@ -102,7 +101,7 @@
for (int i = 0; i < num_events; i++) {
int64_t index = static_cast<int64_t>(events[i].data.u64);
- ALOGD("New BufferHubQueue event %d: index=%" PRId64, i, index);
+ ALOGD_IF(TRACE, "New BufferHubQueue event %d: index=%" PRId64, i, index);
if (is_buffer_event_index(index)) {
HandleBufferEvent(static_cast<size_t>(index), events[i]);
@@ -255,7 +254,7 @@
size_t* slot,
void* meta,
LocalHandle* fence) {
- ALOGD("Dequeue: count=%zu, timeout=%d", count(), timeout);
+ ALOGD_IF(TRACE, "Dequeue: count=%zu, timeout=%d", count(), timeout);
if (count() == 0 && !WaitForBuffers(timeout))
return nullptr;
@@ -341,8 +340,9 @@
// We only allocate one buffer at a time.
auto& buffer_handle = buffer_handle_slots[0].first;
size_t buffer_slot = buffer_handle_slots[0].second;
- ALOGD("ProducerQueue::AllocateBuffer, new buffer, channel_handle: %d",
- buffer_handle.value());
+ ALOGD_IF(TRACE,
+ "ProducerQueue::AllocateBuffer, new buffer, channel_handle: %d",
+ buffer_handle.value());
*out_slot = buffer_slot;
return AddBuffer(BufferProducer::Import(std::move(buffer_handle)),
@@ -414,8 +414,9 @@
auto buffer_handle_slots = status.take();
for (auto& buffer_handle_slot : buffer_handle_slots) {
- ALOGD("ConsumerQueue::ImportBuffers, new buffer, buffer_handle: %d",
- buffer_handle_slot.first.value());
+ ALOGD_IF(TRACE,
+ "ConsumerQueue::ImportBuffers, new buffer, buffer_handle: %d",
+ buffer_handle_slot.first.value());
std::unique_ptr<BufferConsumer> buffer_consumer =
BufferConsumer::Import(std::move(buffer_handle_slot.first));
@@ -473,7 +474,7 @@
} else if (ret < 0) {
ALOGE("Failed to import buffers on buffer allocated event.");
}
- ALOGD("Imported %d consumer buffers.", ret);
+ ALOGD_IF(TRACE, "Imported %d consumer buffers.", ret);
return ret;
}
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp
index 02bca09..1ea3994 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_consumer.cpp
@@ -1,7 +1,5 @@
#include "include/private/dvr/buffer_hub_queue_consumer.h"
-//#define LOG_NDEBUG 0
-
namespace android {
namespace dvr {
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
index b013c85..a108042 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
@@ -1,8 +1,5 @@
#include "include/private/dvr/buffer_hub_queue_core.h"
-//#define LOG_NDEBUG 0
-#define LOG_TAG "BufferHubQueueCore"
-
#include <log/log.h>
namespace android {
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 0deb764..ddf7fd2 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -1,7 +1,5 @@
#include "include/private/dvr/buffer_hub_queue_producer.h"
-//#define LOG_NDEBUG 0
-
#include <inttypes.h>
#include <log/log.h>
@@ -14,7 +12,7 @@
status_t BufferHubQueueProducer::requestBuffer(int slot,
sp<GraphicBuffer>* buf) {
- ALOGD("requestBuffer: slot=%d", slot);
+ ALOGD_IF(TRACE, "requestBuffer: slot=%d", slot);
std::unique_lock<std::mutex> lock(core_->mutex_);
@@ -35,8 +33,8 @@
status_t BufferHubQueueProducer::setMaxDequeuedBufferCount(
int max_dequeued_buffers) {
- ALOGD("setMaxDequeuedBufferCount: max_dequeued_buffers=%d",
- max_dequeued_buffers);
+ ALOGD_IF(TRACE, "setMaxDequeuedBufferCount: max_dequeued_buffers=%d",
+ max_dequeued_buffers);
std::unique_lock<std::mutex> lock(core_->mutex_);
@@ -63,8 +61,8 @@
PixelFormat format,
uint32_t usage,
FrameEventHistoryDelta* /* outTimestamps */) {
- ALOGD("dequeueBuffer: w=%u, h=%u, format=%d, usage=%u", width, height, format,
- usage);
+ ALOGD_IF(TRACE, "dequeueBuffer: w=%u, h=%u, format=%d, usage=%u", width,
+ height, format, usage);
status_t ret;
std::unique_lock<std::mutex> lock(core_->mutex_);
@@ -134,7 +132,7 @@
core_->buffers_[slot].mBufferState.freeQueued();
core_->buffers_[slot].mBufferState.dequeue();
- ALOGD("dequeueBuffer: slot=%zu", slot);
+ ALOGD_IF(TRACE, "dequeueBuffer: slot=%zu", slot);
// TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we
// just need to exopose that through |BufferHubQueue| once we need fence.
@@ -173,7 +171,7 @@
status_t BufferHubQueueProducer::queueBuffer(int slot,
const QueueBufferInput& input,
QueueBufferOutput* /* output */) {
- ALOGD("queueBuffer: slot %d", slot);
+ ALOGD_IF(TRACE, "queueBuffer: slot %d", slot);
int64_t timestamp;
sp<Fence> fence;
@@ -220,7 +218,7 @@
status_t BufferHubQueueProducer::cancelBuffer(int slot,
const sp<Fence>& fence) {
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
std::unique_lock<std::mutex> lock(core_->mutex_);
@@ -241,13 +239,13 @@
core_->producer_->Enqueue(buffer_producer, slot);
core_->buffers_[slot].mBufferState.cancel();
core_->buffers_[slot].mFence = fence;
- ALOGD("cancelBuffer: slot %d", slot);
+ ALOGD_IF(TRACE, "cancelBuffer: slot %d", slot);
return NO_ERROR;
}
status_t BufferHubQueueProducer::query(int what, int* out_value) {
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
std::unique_lock<std::mutex> lock(core_->mutex_);
@@ -278,7 +276,7 @@
return BAD_VALUE;
}
- ALOGD("query: key=%d, v=%d", what, value);
+ ALOGD_IF(TRACE, "query: key=%d, v=%d", what, value);
*out_value = value;
return NO_ERROR;
}
@@ -288,14 +286,14 @@
bool /* producer_controlled_by_app */, QueueBufferOutput* /* output */) {
// Consumer interaction are actually handled by buffer hub, and we need
// to maintain consumer operations here. Hence |connect| is a NO-OP.
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
return NO_ERROR;
}
status_t BufferHubQueueProducer::disconnect(int /* api */, DisconnectMode /* mode */) {
// Consumer interaction are actually handled by buffer hub, and we need
// to maintain consumer operations here. Hence |disconnect| is a NO-OP.
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
return NO_ERROR;
}
@@ -327,7 +325,7 @@
status_t BufferHubQueueProducer::setGenerationNumber(
uint32_t generation_number) {
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
std::unique_lock<std::mutex> lock(core_->mutex_);
core_->generation_number_ = generation_number;
@@ -354,7 +352,7 @@
}
status_t BufferHubQueueProducer::setDequeueTimeout(nsecs_t timeout) {
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
std::unique_lock<std::mutex> lock(core_->mutex_);
core_->dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
@@ -374,7 +372,7 @@
}
status_t BufferHubQueueProducer::getUniqueId(uint64_t* out_id) const {
- ALOGD(__FUNCTION__);
+ ALOGD_IF(TRACE, __FUNCTION__);
*out_id = core_->unique_id_;
return NO_ERROR;
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index dcdd994..3a1cc72 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -276,5 +276,18 @@
return DisplaySurfaceClient::Create(width, height, format, usage, flags);
}
+std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
+ if (!status) {
+ ALOGE(
+ "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
+ status.GetErrorMessage().c_str());
+ return nullptr;
+ }
+
+ return BufferConsumer::Import(std::move(status));
+}
+
+
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdisplay/display_manager_client.cpp
index fe18619..d60d35b 100644
--- a/libs/vr/libdisplay/display_manager_client.cpp
+++ b/libs/vr/libdisplay/display_manager_client.cpp
@@ -2,6 +2,7 @@
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/display_manager_client_impl.h>
+#include <private/dvr/dvr_buffer.h>
using android::dvr::DisplaySurfaceAttributeEnum;
@@ -41,6 +42,18 @@
delete client;
}
+DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
+ DvrDisplayManagerClient* client, size_t extended_region_size,
+ uint64_t usage0, uint64_t usage1) {
+ // TODO(hendrikw): When we move to gralloc1, pass both usage0 and usage1 down.
+ auto buffer_producer = client->client->SetupPoseBuffer(
+ extended_region_size, static_cast<int>(usage0));
+ if (buffer_producer) {
+ return CreateDvrWriteBufferFromBufferProducer(std::move(buffer_producer));
+ }
+ return nullptr;
+}
+
int dvrDisplayManagerClientGetEventFd(DvrDisplayManagerClient* client) {
return client->client->event_fd();
}
diff --git a/libs/vr/libdisplay/display_manager_client_impl.cpp b/libs/vr/libdisplay/display_manager_client_impl.cpp
index 3fbd1e0..7993fce 100644
--- a/libs/vr/libdisplay/display_manager_client_impl.cpp
+++ b/libs/vr/libdisplay/display_manager_client_impl.cpp
@@ -31,5 +31,20 @@
return 0;
}
+std::unique_ptr<BufferProducer> DisplayManagerClient::SetupPoseBuffer(
+ size_t extended_region_size, int usage) {
+ auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
+ extended_region_size, usage);
+ if (!status) {
+ ALOGE(
+ "DisplayManagerClient::SetupPoseBuffer: Failed to create the pose "
+ "buffer %s",
+ status.GetErrorMessage().c_str());
+ return {};
+ }
+
+ return BufferProducer::Import(std::move(status));
+}
+
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/graphics.cpp b/libs/vr/libdisplay/graphics.cpp
index 61f6fea..c2fbb8b 100644
--- a/libs/vr/libdisplay/graphics.cpp
+++ b/libs/vr/libdisplay/graphics.cpp
@@ -17,6 +17,7 @@
#include <private/dvr/clock_ns.h>
#include <private/dvr/debug.h>
#include <private/dvr/display_types.h>
+#include <private/dvr/dvr_buffer.h>
#include <private/dvr/frame_history.h>
#include <private/dvr/gl_fenced_flush.h>
#include <private/dvr/graphics/vr_gl_extensions.h>
@@ -1571,3 +1572,14 @@
};
}
}
+
+extern "C" int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
+ auto client = android::dvr::DisplayClient::Create();
+ if (!client) {
+ ALOGE("Failed to create display client!");
+ return -ECOMM;
+ }
+
+ *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
+ return 0;
+}
diff --git a/libs/vr/libdisplay/include/dvr/graphics.h b/libs/vr/libdisplay/include/dvr/graphics.h
index 19deec3..fc51d52 100644
--- a/libs/vr/libdisplay/include/dvr/graphics.h
+++ b/libs/vr/libdisplay/include/dvr/graphics.h
@@ -160,6 +160,8 @@
int dvrGetNativeDisplayDimensions(int* native_width, int* native_height);
+typedef struct DvrReadBuffer DvrReadBuffer;
+
// Opaque struct that represents a graphics context, the texture swap chain,
// and surfaces.
typedef struct DvrGraphicsContext DvrGraphicsContext;
@@ -440,6 +442,9 @@
const int eye,
const float* transform);
+// Get a pointer to the global pose buffer.
+int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
+
__END_DECLS
#endif // DVR_GRAPHICS_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index e1471c3..bfc167e 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -111,6 +111,8 @@
std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
int width, int height, int format, int usage, int flags);
+ std::unique_ptr<BufferConsumer> GetPoseBuffer();
+
private:
friend BASE;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
index f515b8f..0928d43 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
@@ -14,11 +14,16 @@
DvrDisplayManagerClientSurfaceList;
typedef struct DvrDisplayManagerClientSurfaceBuffers
DvrDisplayManagerClientSurfaceBuffers;
+typedef struct DvrWriteBuffer DvrWriteBuffer;
DvrDisplayManagerClient* dvrDisplayManagerClientCreate();
void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client);
+DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
+ DvrDisplayManagerClient* client, size_t extended_region_size,
+ uint64_t usage0, uint64_t usage1);
+
// Return an event fd for checking if there was an event on the server
// Note that the only event which will be flagged is POLLIN. You must use
// dvrDisplayManagerClientTranslateEpollEventMask in order to get the real
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
index 0897126..144cd3b 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
@@ -9,7 +9,7 @@
namespace android {
namespace dvr {
-class BufferConsumer;
+class BufferProducer;
class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
public:
@@ -17,6 +17,9 @@
int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
+ std::unique_ptr<BufferProducer> SetupPoseBuffer(size_t extended_region_size,
+ int usage);
+
using Client::event_fd;
using Client::GetChannel;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_rpc.h b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
index 465fbae..e373123 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -219,7 +219,8 @@
kOpVideoMeshSurfaceCreateProducerQueue,
kOpEnterVrMode,
kOpExitVrMode,
- kOpSetViewerParams
+ kOpSetViewerParams,
+ kOpGetPoseBuffer,
};
// Aliases.
@@ -249,6 +250,8 @@
PDX_REMOTE_METHOD(ExitVrMode, kOpExitVrMode, int(Void));
PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
void(const ViewerParams& viewer_params));
+ PDX_REMOTE_METHOD(GetPoseBuffer, kOpGetPoseBuffer,
+ LocalChannelHandle(Void));
};
struct DisplayManagerRPC {
@@ -259,6 +262,7 @@
enum {
kOpGetSurfaceList = 0,
kOpUpdateSurfaces,
+ kOpSetupPoseBuffer,
};
// Aliases.
@@ -271,6 +275,8 @@
PDX_REMOTE_METHOD(
UpdateSurfaces, kOpUpdateSurfaces,
int(const std::map<int, DisplaySurfaceAttributes>& updates));
+ PDX_REMOTE_METHOD(SetupPoseBuffer, kOpSetupPoseBuffer,
+ LocalChannelHandle(size_t extended_region_size, int usage));
};
struct ScreenshotData {
diff --git a/libs/vr/libpdx/private/pdx/rpc/function_traits.h b/libs/vr/libpdx/private/pdx/rpc/function_traits.h
index 5fdad72..7641b0a 100644
--- a/libs/vr/libpdx/private/pdx/rpc/function_traits.h
+++ b/libs/vr/libpdx/private/pdx/rpc/function_traits.h
@@ -43,6 +43,12 @@
SignatureType<ConditionalRewrite<Return_, ReturnType>(
ConditionalRewrite<Args_, Params>...)>;
+ template <template <typename> class Wrapper, typename ReturnType,
+ typename... Params>
+ using RewriteSignatureWrapReturn =
+ SignatureType<Wrapper<ConditionalRewrite<Return_, ReturnType>>(
+ ConditionalRewrite<Args_, Params>...)>;
+
template <typename ReturnType>
using RewriteReturn =
SignatureType<ConditionalRewrite<Return_, ReturnType>(Args_...)>;
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method.h b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
index 679503c..e5c6616 100644
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method.h
+++ b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
@@ -10,6 +10,7 @@
#include <pdx/rpc/payload.h>
#include <pdx/rpc/remote_method_type.h>
#include <pdx/service.h>
+#include <pdx/status.h>
namespace android {
namespace pdx {
@@ -157,6 +158,25 @@
strerror(-ret));
}
+// Overload for Status<void> return types.
+template <typename RemoteMethodType>
+void RemoteMethodReturn(Message& message, const Status<void>& return_value) {
+ if (return_value)
+ RemoteMethodReturn<RemoteMethodType>(message, 0);
+ else
+ RemoteMethodError(message, return_value.error());
+}
+
+// Overload for Status<T> return types. This overload forwards the underlying
+// value or error within the Status<T>.
+template <typename RemoteMethodType, typename Return>
+void RemoteMethodReturn(Message& message, const Status<Return>& return_value) {
+ if (return_value)
+ RemoteMethodReturn<RemoteMethodType, Return>(message, return_value.get());
+ else
+ RemoteMethodError(message, return_value.error());
+}
+
// Dispatches a method by deserializing arguments from the given Message, with
// compile-time interface check. Overload for void return types.
template <typename RemoteMethodType, typename Class, typename... Args,
@@ -340,6 +360,46 @@
RemoteMethodReturn<RemoteMethodType>(message, return_value);
}
+// Dispatches a method by deserializing arguments from the given Message, with
+// compile-time interface signature check. Overload for Status<T> return types.
+template <typename RemoteMethodType, typename Class, typename Return,
+ typename... Args, typename = EnableIfNotVoidMethod<RemoteMethodType>>
+void DispatchRemoteMethod(Class& instance,
+ Status<Return> (Class::*method)(Message&, Args...),
+ Message& message,
+ std::size_t max_capacity = InitialBufferCapacity) {
+ using Signature =
+ typename RemoteMethodType::template RewriteSignature<Return, Args...>;
+ using InvokeSignature =
+ typename RemoteMethodType::template RewriteSignatureWrapReturn<
+ Status, Return, Args...>;
+ rpc::ServicePayload<ReceiveBuffer> payload(message);
+ payload.Resize(max_capacity);
+
+ auto size = message.Read(payload.Data(), payload.Size());
+ if (size < 0) {
+ RemoteMethodError(message, -size);
+ return;
+ }
+
+ payload.Resize(size);
+
+ ErrorType error;
+ auto decoder = MakeArgumentDecoder<Signature>(&payload);
+ auto arguments = decoder.DecodeArguments(&error);
+ if (error) {
+ RemoteMethodError(message, EIO);
+ return;
+ }
+
+ auto return_value = UnpackArguments<Class, InvokeSignature>(
+ instance, method, message, arguments)
+ .Invoke();
+ // Return the value to the caller unless the message was moved.
+ if (message)
+ RemoteMethodReturn<RemoteMethodType>(message, return_value);
+}
+
#ifdef __clang__
// Overloads to handle Void argument type without exploding clang.
@@ -399,6 +459,18 @@
if (message)
RemoteMethodReturn<RemoteMethodType>(message, return_value);
}
+
+// Overload for Status<T> return type.
+template <typename RemoteMethodType, typename Class, typename Return,
+ typename = EnableIfVoidMethod<RemoteMethodType>>
+void DispatchRemoteMethod(Class& instance,
+ Status<Return> (Class::*method)(Message&),
+ Message& message) {
+ auto return_value = (instance.*method)(message);
+ // Return the value to the caller unless the message was moved.
+ if (message)
+ RemoteMethodReturn<RemoteMethodType>(message, return_value);
+}
#endif
} // namespace rpc
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h b/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
index de9a3cc..cf9a189 100644
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
+++ b/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
@@ -31,6 +31,12 @@
using RewriteSignature =
typename Traits::template RewriteSignature<ReturnType, Params...>;
+ template <template <typename> class Wrapper, typename ReturnType,
+ typename... Params>
+ using RewriteSignatureWrapReturn =
+ typename Traits::template RewriteSignatureWrapReturn<Wrapper, ReturnType,
+ Params...>;
+
template <typename ReturnType>
using RewriteReturn = typename Traits::template RewriteReturn<ReturnType>;
};
diff --git a/libs/vr/libpdx/thread_local_buffer_tests.cpp b/libs/vr/libpdx/thread_local_buffer_tests.cpp
index c6a7b0b..1747d79 100644
--- a/libs/vr/libpdx/thread_local_buffer_tests.cpp
+++ b/libs/vr/libpdx/thread_local_buffer_tests.cpp
@@ -89,8 +89,9 @@
EXPECT_NE(id1, id2);
}
+// TODO(b/36456321): Fix this and enable it again.
// Tests that thread-local buffers are allocated at the first buffer request.
-TEST(ThreadLocalBufferTest, InitialValue) {
+TEST(ThreadLocalBufferTest, DISABLED_InitialValue) {
struct TypeTagX;
using SendSlotX = ThreadLocalSlot<TypeTagX, kSendBufferIndex>;
diff --git a/libs/vr/libpdx_uds/remote_method_tests.cpp b/libs/vr/libpdx_uds/remote_method_tests.cpp
index 299910c..9050500 100644
--- a/libs/vr/libpdx_uds/remote_method_tests.cpp
+++ b/libs/vr/libpdx_uds/remote_method_tests.cpp
@@ -23,6 +23,7 @@
using android::pdx::BorrowedHandle;
using android::pdx::Channel;
using android::pdx::ClientBase;
+using android::pdx::ErrorStatus;
using android::pdx::LocalChannelHandle;
using android::pdx::LocalHandle;
using android::pdx::Message;
@@ -36,6 +37,20 @@
namespace {
+std::string Rot13(const std::string& s) {
+ std::string text = s;
+ std::transform(std::begin(text), std::end(text), std::begin(text),
+ [](char c) -> char {
+ if (!std::isalpha(c)) {
+ return c;
+ } else {
+ const char pivot = std::isupper(c) ? 'A' : 'a';
+ return (c - pivot + 13) % 26 + pivot;
+ }
+ });
+ return text;
+}
+
// Defines a serializable user type that may be transferred between client and
// service.
struct TestType {
@@ -134,6 +149,7 @@
kOpOpenFiles,
kOpReadFile,
kOpPushChannel,
+ kOpPositive,
};
// Methods.
@@ -161,10 +177,11 @@
std::pair<int, BufferWrapper<std::uint8_t*>>(
const std::string&, int, std::size_t));
PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
+ PDX_REMOTE_METHOD(Positive, kOpPositive, void(int));
PDX_REMOTE_API(API, Add, Foo, Concatenate, SumVector, StringLength,
SendTestType, SendVector, Rot13, NoArgs, SendFile, GetFile,
- GetTestFdType, OpenFiles, PushChannel);
+ GetTestFdType, OpenFiles, PushChannel, Positive);
};
constexpr char TestInterface::kClientPath[];
@@ -301,6 +318,11 @@
return status ? 0 : -status.error();
}
+ bool Positive(int test_value) {
+ auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value);
+ return status.ok();
+ }
+
int GetFd() const { return event_fd(); }
private:
@@ -397,6 +419,11 @@
*this, &TestService::OnPushChannel, message);
return 0;
+ case TestInterface::Positive::Opcode:
+ DispatchRemoteMethod<TestInterface::Positive>(
+ *this, &TestService::OnPositive, message);
+ return 0;
+
default:
return Service::DefaultHandleMessage(message);
}
@@ -438,18 +465,8 @@
return return_value;
}
- std::string OnRot13(Message&, const std::string& s) {
- std::string text = s;
- std::transform(std::begin(text), std::end(text), std::begin(text),
- [](char c) -> char {
- if (!std::isalpha(c)) {
- return c;
- } else {
- const char pivot = std::isupper(c) ? 'A' : 'a';
- return (c - pivot + 13) % 26 + pivot;
- }
- });
- return text;
+ Status<std::string> OnRot13(Message&, const std::string& s) {
+ return {Rot13(s)};
}
int OnNoArgs(Message&) { return 1; }
@@ -514,6 +531,13 @@
return status.take();
}
+ Status<void> OnPositive(Message& /*message*/, int test_value) {
+ if (test_value >= 0)
+ return {};
+ else
+ return ErrorStatus(EINVAL);
+ }
+
TestService(const TestService&) = delete;
void operator=(const TestService&) = delete;
};
@@ -575,6 +599,10 @@
const auto cat = client->Concatenate("This is a string", ", that it is.");
EXPECT_EQ("This is a string, that it is.", cat);
+ std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
+ const auto rot13_alphabet = client->Rot13(alphabet);
+ EXPECT_EQ(Rot13(alphabet), rot13_alphabet);
+
const auto length = client->Foo(10, "123");
EXPECT_EQ(13, length);
@@ -677,6 +705,21 @@
EXPECT_GE(35, sum);
}
+TEST_F(RemoteMethodTest, Positive) {
+ // Create a test service and add it to the dispatcher.
+ auto service = TestService::Create();
+ ASSERT_NE(nullptr, service);
+ ASSERT_EQ(0, dispatcher_->AddService(service));
+
+ // Create a client to service.
+ auto client = TestClient::Create();
+ ASSERT_NE(nullptr, client);
+
+ ASSERT_TRUE(client->Positive(0));
+ ASSERT_TRUE(client->Positive(1));
+ ASSERT_FALSE(client->Positive(-1));
+}
+
TEST_F(RemoteMethodTest, AggregateLocalHandle) {
// Create a test service and add it to the dispatcher.
auto service = TestService::Create();
diff --git a/libs/vr/libpdx_uds/service_framework_tests.cpp b/libs/vr/libpdx_uds/service_framework_tests.cpp
index 8891600..9e31e82 100644
--- a/libs/vr/libpdx_uds/service_framework_tests.cpp
+++ b/libs/vr/libpdx_uds/service_framework_tests.cpp
@@ -26,6 +26,7 @@
using android::pdx::Channel;
using android::pdx::ChannelReference;
using android::pdx::ClientBase;
+using android::pdx::ErrorStatus;
using android::pdx::LocalChannelHandle;
using android::pdx::LocalHandle;
using android::pdx::Message;
@@ -379,6 +380,14 @@
data_array.size() * sizeof(int), nullptr, 0));
}
+ Status<int> GetEventMask(int events) {
+ if (auto* client_channel = GetChannel()) {
+ return client_channel->GetEventMask(events);
+ } else {
+ return ErrorStatus(EINVAL);
+ }
+ }
+
using ClientBase<TestClient>::event_fd;
enum : size_t { kMaxPayload = MAX_IMPULSE_LENGTH };
@@ -634,7 +643,9 @@
count = epoll_wait(client->event_fd(), &event, 1, -1);
ASSERT_EQ(1, count);
- ASSERT_TRUE((EPOLLHUP & event.events) != 0);
+ auto event_status = client->GetEventMask(event.events);
+ ASSERT_TRUE(event_status.ok());
+ ASSERT_TRUE((EPOLLHUP & event_status.get()) != 0);
}
TEST_F(ServiceFrameworkTest, LargeDataSum) {
diff --git a/libs/vr/libvrflinger/display_manager_service.cpp b/libs/vr/libvrflinger/display_manager_service.cpp
index 6df1642..e07901d 100644
--- a/libs/vr/libvrflinger/display_manager_service.cpp
+++ b/libs/vr/libvrflinger/display_manager_service.cpp
@@ -82,6 +82,11 @@
*this, &DisplayManagerService::OnUpdateSurfaces, message);
return 0;
+ case DisplayManagerRPC::SetupPoseBuffer::Opcode:
+ DispatchRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
+ *this, &DisplayManagerService::OnSetupPoseBuffer, message);
+ return 0;
+
default:
return Service::DefaultHandleMessage(message);
}
@@ -91,30 +96,31 @@
pdx::Message& /*message*/) {
std::vector<DisplaySurfaceInfo> items;
- display_service_->ForEachDisplaySurface([&items](
- const std::shared_ptr<DisplaySurface>& surface) mutable {
- DisplaySurfaceInfo item;
+ display_service_->ForEachDisplaySurface(
+ [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
+ DisplaySurfaceInfo item;
- item.surface_id = surface->surface_id();
- item.process_id = surface->process_id();
- item.type = surface->type();
- item.flags = 0; // TODO(eieio)
- item.client_attributes = DisplaySurfaceAttributes{
- {DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{surface->client_visible()}},
- {DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{surface->client_z_order()}},
- {DisplaySurfaceAttributeEnum::Blur, DisplaySurfaceAttributeValue{0.f}}};
- item.manager_attributes = DisplaySurfaceAttributes{
- {DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{surface->manager_visible()}},
- {DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{surface->manager_z_order()}},
- {DisplaySurfaceAttributeEnum::Blur,
- DisplaySurfaceAttributeValue{surface->manager_blur()}}};
+ item.surface_id = surface->surface_id();
+ item.process_id = surface->process_id();
+ item.type = surface->type();
+ item.flags = 0; // TODO(eieio)
+ item.client_attributes = DisplaySurfaceAttributes{
+ {DisplaySurfaceAttributeEnum::Visible,
+ DisplaySurfaceAttributeValue{surface->client_visible()}},
+ {DisplaySurfaceAttributeEnum::ZOrder,
+ DisplaySurfaceAttributeValue{surface->client_z_order()}},
+ {DisplaySurfaceAttributeEnum::Blur,
+ DisplaySurfaceAttributeValue{0.f}}};
+ item.manager_attributes = DisplaySurfaceAttributes{
+ {DisplaySurfaceAttributeEnum::Visible,
+ DisplaySurfaceAttributeValue{surface->manager_visible()}},
+ {DisplaySurfaceAttributeEnum::ZOrder,
+ DisplaySurfaceAttributeValue{surface->manager_z_order()}},
+ {DisplaySurfaceAttributeEnum::Blur,
+ DisplaySurfaceAttributeValue{surface->manager_blur()}}};
- items.push_back(item);
- });
+ items.push_back(item);
+ });
// The fact that we're in the message handler implies that display_manager_ is
// not nullptr. No check required, unless this service becomes multi-threaded.
@@ -182,6 +188,11 @@
return 0;
}
+pdx::BorrowedChannelHandle DisplayManagerService::OnSetupPoseBuffer(
+ pdx::Message& message, size_t extended_region_size, int usage) {
+ return display_service_->SetupPoseBuffer(extended_region_size, usage);
+}
+
void DisplayManagerService::OnDisplaySurfaceChange() {
if (display_manager_) {
display_manager_->SetNotificationsPending(true);
diff --git a/libs/vr/libvrflinger/display_manager_service.h b/libs/vr/libvrflinger/display_manager_service.h
index 3f83c7d..19098c2 100644
--- a/libs/vr/libvrflinger/display_manager_service.h
+++ b/libs/vr/libvrflinger/display_manager_service.h
@@ -54,6 +54,10 @@
int OnUpdateSurfaces(pdx::Message& message,
const std::map<int, DisplaySurfaceAttributes>& updates);
+ pdx::BorrowedChannelHandle OnSetupPoseBuffer(pdx::Message& message,
+ size_t extended_region_size,
+ int usage);
+
// Called by the display service to indicate changes to display surfaces that
// the display manager should evaluate.
void OnDisplaySurfaceChange();
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index fdb84c5..e3d7564 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -18,6 +18,15 @@
using android::pdx::rpc::DispatchRemoteMethod;
using android::pdx::rpc::WrapBuffer;
+namespace {
+
+constexpr char kPersistentPoseBufferName[] = "DvrPersistentPoseBuffer";
+const int kPersistentPoseBufferUserId = 0;
+const int kPersistentPoseBufferGroupId = 0;
+const size_t kTimingDataSizeOffset = 128;
+
+} // anonymous namespace
+
namespace android {
namespace dvr {
@@ -89,6 +98,11 @@
*this, &DisplayService::OnSetViewerParams, message);
return 0;
+ case DisplayRPC::GetPoseBuffer::Opcode:
+ DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>(
+ *this, &DisplayService::OnGetPoseBuffer, message);
+ return 0;
+
// Direct the surface specific messages to the surface instance.
case DisplayRPC::CreateBufferQueue::Opcode:
case DisplayRPC::SetAttributes::Opcode:
@@ -254,6 +268,15 @@
compositor->UpdateHeadMountMetrics(head_mount_metrics);
}
+pdx::LocalChannelHandle DisplayService::OnGetPoseBuffer(pdx::Message& message) {
+ if (pose_buffer_) {
+ return pose_buffer_->CreateConsumer().take();
+ }
+
+ pdx::rpc::RemoteMethodError(message, EAGAIN);
+ return {};
+}
+
// Calls the message handler for the DisplaySurface associated with this
// channel.
int DisplayService::HandleSurfaceMessage(pdx::Message& message) {
@@ -324,6 +347,18 @@
return hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
}
+pdx::BorrowedChannelHandle DisplayService::SetupPoseBuffer(
+ size_t extended_region_size, int usage) {
+ if (!pose_buffer_) {
+ pose_buffer_ = BufferProducer::Create(
+ kPersistentPoseBufferName, kPersistentPoseBufferUserId,
+ kPersistentPoseBufferGroupId, usage,
+ extended_region_size + kTimingDataSizeOffset);
+ }
+
+ return pose_buffer_->GetChannelHandle().Borrow();
+}
+
void DisplayService::OnHardwareComposerRefresh() {
hardware_composer_.OnHardwareComposerRefresh();
}
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index 9d116c1..a2b3ed5 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -38,6 +38,9 @@
// any change to client/manager attributes that affect visibility or z order.
int UpdateActiveDisplaySurfaces();
+ pdx::BorrowedChannelHandle SetupPoseBuffer(size_t extended_region_size,
+ int usage);
+
template <class A>
void ForEachDisplaySurface(A action) const {
ForEachChannel([action](const ChannelIterator::value_type& pair) mutable {
@@ -80,14 +83,16 @@
DisplayService(android::Hwc2::Composer* hidl);
SystemDisplayMetrics OnGetMetrics(pdx::Message& message);
- int OnCreateSurface(pdx::Message& message, int width, int height,
- int format, int usage, DisplaySurfaceFlags flags);
+ int OnCreateSurface(pdx::Message& message, int width, int height, int format,
+ int usage, DisplaySurfaceFlags flags);
DisplayRPC::ByteBuffer OnGetEdsCapture(pdx::Message& message);
int OnEnterVrMode(pdx::Message& message);
int OnExitVrMode(pdx::Message& message);
- void OnSetViewerParams(pdx::Message& message, const ViewerParams& view_params);
+ void OnSetViewerParams(pdx::Message& message,
+ const ViewerParams& view_params);
+ pdx::LocalChannelHandle OnGetPoseBuffer(pdx::Message& message);
// Called by DisplaySurface to signal that a surface property has changed and
// the display manager should be notified.
@@ -100,6 +105,8 @@
HardwareComposer hardware_composer_;
DisplayConfigurationUpdateNotifier update_notifier_;
+
+ std::unique_ptr<BufferProducer> pose_buffer_;
};
} // namespace dvr
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
index ad999b7..c8bc884 100644
--- a/services/vr/virtual_touchpad/Android.bp
+++ b/services/vr/virtual_touchpad/Android.bp
@@ -94,6 +94,7 @@
client_src = [
"VirtualTouchpadClient.cpp",
+ "DvrVirtualTouchpadClient.cpp",
"aidl/android/dvr/VirtualTouchpadService.aidl",
]
diff --git a/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
new file mode 100644
index 0000000..eb152ed
--- /dev/null
+++ b/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
@@ -0,0 +1,45 @@
+#include "VirtualTouchpadClient.h"
+#include "dvr/virtual_touchpad_client.h"
+
+struct DvrVirtualTouchpad {};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+namespace {
+android::dvr::VirtualTouchpad* FromC(DvrVirtualTouchpad* client) {
+ return reinterpret_cast<android::dvr::VirtualTouchpad*>(client);
+}
+} // namespace
+
+DvrVirtualTouchpad* dvrVirtualTouchpadCreate() {
+ return reinterpret_cast<DvrVirtualTouchpad*>(
+ android::dvr::VirtualTouchpadClient::Create().release());
+}
+
+void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client) {
+ delete FromC(client);
+}
+
+int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client) {
+ return FromC(client)->Attach();
+}
+
+int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client) {
+ return FromC(client)->Detach();
+}
+
+int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
+ float y, float pressure) {
+ return FromC(client)->Touch(touchpad, x, y, pressure);
+}
+
+int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
+ int buttons) {
+ return FromC(client)->ButtonState(touchpad, buttons);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
index 782b19c..c7c8184 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
@@ -72,8 +72,8 @@
} // anonymous namespace
-sp<VirtualTouchpad> VirtualTouchpadClient::Create() {
- return new VirtualTouchpadClientImpl();
+std::unique_ptr<VirtualTouchpad> VirtualTouchpadClient::Create() {
+ return std::unique_ptr<VirtualTouchpad>(new VirtualTouchpadClientImpl());
}
} // namespace dvr
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
index 92193d3..ee09d48 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
@@ -30,10 +30,10 @@
} // anonymous namespace
-sp<VirtualTouchpad> VirtualTouchpadEvdev::Create() {
- VirtualTouchpadEvdev* const touchpad = new VirtualTouchpadEvdev();
+std::unique_ptr<VirtualTouchpad> VirtualTouchpadEvdev::Create() {
+ std::unique_ptr<VirtualTouchpadEvdev> touchpad(new VirtualTouchpadEvdev());
touchpad->Reset();
- return sp<VirtualTouchpad>(touchpad);
+ return touchpad;
}
void VirtualTouchpadEvdev::Reset() {
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
index dbaca9a..2fb8ff3 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
@@ -1,8 +1,6 @@
#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
#define ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
-#include <memory>
-
#include "EvdevInjector.h"
#include "VirtualTouchpad.h"
@@ -15,7 +13,8 @@
//
class VirtualTouchpadEvdev : public VirtualTouchpad {
public:
- static sp<VirtualTouchpad> Create();
+ static std::unique_ptr<VirtualTouchpad> Create();
+ ~VirtualTouchpadEvdev() override {}
// VirtualTouchpad implementation:
status_t Attach() override;
@@ -28,7 +27,6 @@
static constexpr int kTouchpads = 2;
VirtualTouchpadEvdev() {}
- ~VirtualTouchpadEvdev() override {}
void Reset();
// Must be called only between construction (or Detach()) and Attach().
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
index 194d787..cf236f9 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.h
@@ -13,8 +13,8 @@
//
class VirtualTouchpadService : public BnVirtualTouchpadService {
public:
- VirtualTouchpadService(sp<VirtualTouchpad> touchpad)
- : touchpad_(touchpad), client_pid_(0) {}
+ VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
+ : touchpad_(std::move(touchpad)), client_pid_(0) {}
~VirtualTouchpadService() override;
protected:
@@ -31,7 +31,7 @@
bool CheckPermissions();
bool CheckTouchPermission(pid_t* out_pid);
- sp<VirtualTouchpad> touchpad_;
+ std::unique_ptr<VirtualTouchpad> touchpad_;
// Only one client at a time can use the virtual touchpad.
pid_t client_pid_;
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpad.h b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
index b1ee700..da3a0b7 100644
--- a/services/vr/virtual_touchpad/include/VirtualTouchpad.h
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
@@ -1,31 +1,34 @@
#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
#define ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
+#include "dvr/virtual_touchpad_client.h"
+
+#include <memory>
#include <utils/Errors.h>
-#include <utils/RefBase.h>
#include <utils/String8.h>
-#include <utils/StrongPointer.h>
namespace android {
namespace dvr {
// Provides a virtual touchpad for injecting events into the input system.
//
-class VirtualTouchpad : public RefBase {
+class VirtualTouchpad {
public:
enum : int {
- PRIMARY = 0,
- VIRTUAL = 1,
+ PRIMARY = DVR_VIRTUAL_TOUCHPAD_PRIMARY,
+ VIRTUAL = DVR_VIRTUAL_TOUCHPAD_VIRTUAL,
};
+ virtual ~VirtualTouchpad() {}
+
// Create a virtual touchpad.
// Implementations should provide this, and hide their constructors.
// For the user, switching implementations should be as simple as changing
// the class whose |Create()| is called.
// Implementations should be minimial; major resource allocation should
// be performed in Attach().
- static sp<VirtualTouchpad> Create() {
- return sp<VirtualTouchpad>();
+ static std::unique_ptr<VirtualTouchpad> Create() {
+ return nullptr;
}
// Initialize a virtual touchpad.
@@ -63,7 +66,6 @@
protected:
VirtualTouchpad() {}
- ~VirtualTouchpad() override {}
private:
VirtualTouchpad(const VirtualTouchpad&) = delete;
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
index 471d9e0..23fb9f8 100644
--- a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
@@ -12,7 +12,7 @@
class VirtualTouchpadClient : public VirtualTouchpad {
public:
// VirtualTouchpad implementation:
- static sp<VirtualTouchpad> Create();
+ static std::unique_ptr<VirtualTouchpad> Create();
status_t Attach() override;
status_t Detach() override;
status_t Touch(int touchpad, float x, float y, float pressure) override;
diff --git a/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h b/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
new file mode 100644
index 0000000..08cca1b
--- /dev/null
+++ b/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
@@ -0,0 +1,71 @@
+#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
+#define ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
+
+enum {
+ DVR_VIRTUAL_TOUCHPAD_PRIMARY = 0,
+ DVR_VIRTUAL_TOUCHPAD_VIRTUAL = 1,
+};
+
+// Creates a new virtual touchpad client.
+//
+// @return Pointer to the created virtual touchpad client; nullptr on failure.
+//
+DvrVirtualTouchpad* dvrVirtualTouchpadCreate();
+
+// Destroys a virtual touchpad client.
+//
+// @param client Pointer to the virtual touchpad client to be destroyed.
+//
+void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client);
+
+// Initialize the virtual touchpad.
+//
+// In the current server implementation, attachment creates and configures
+// the kernel virtual touchpad device(s). A single client may be attached
+// and detached repeatedly, e.g. on entering and leaving VR mode.
+//
+// @param client Pointer to the virtual touchpad client to be attached.
+// @return Zero on success, status_t-style error code on failure.
+//
+int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client);
+
+// Shut down the virtual touchpad.
+//
+// @param client Pointer to the virtual touchpad client to be detached.
+// @return Zero on success, status_t-style error code on failure.
+//
+int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client);
+
+// Generate a simulated touch event.
+//
+// @param client Pointer to the virtual touchpad client.
+// @param touchpad Selects touchpad.
+// @param x Horizontal touch position.
+// @param y Vertical touch position.
+// @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
+// @return Zero on success, status_t-style error code on failure.
+//
+int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
+ float y, float pressure);
+
+// Generate a simulated touchpad button state event.
+//
+// @param client Pointer to the virtual touchpad client.
+// @param touchpad Selects touchpad.
+// @param buttons A union of MotionEvent BUTTON_* values.
+// @return Zero on success, status_t-style error code on failure.
+//
+int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
+ int buttons);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/main.cpp b/services/vr/virtual_touchpad/main.cpp
index e73f8b9..68f1d70 100644
--- a/services/vr/virtual_touchpad/main.cpp
+++ b/services/vr/virtual_touchpad/main.cpp
@@ -9,7 +9,7 @@
int main() {
ALOGI("Starting");
android::dvr::VirtualTouchpadService touchpad_service(
- android::dvr::VirtualTouchpadEvdev::Create());
+ std::move(android::dvr::VirtualTouchpadEvdev::Create()));
signal(SIGPIPE, SIG_IGN);
android::sp<android::ProcessState> ps(android::ProcessState::self());
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
index bc34850..24cfdf8 100644
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
@@ -95,7 +95,9 @@
class VirtualTouchpadForTesting : public VirtualTouchpadEvdev {
public:
- static sp<VirtualTouchpad> Create() { return sp<VirtualTouchpad>(New()); }
+ static std::unique_ptr<VirtualTouchpad> Create() {
+ return std::unique_ptr<VirtualTouchpad>(New());
+ }
static VirtualTouchpadForTesting* New() {
VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting();
touchpad->Reset();
@@ -124,7 +126,8 @@
class VirtualTouchpadTest : public testing::Test {};
TEST_F(VirtualTouchpadTest, Goodness) {
- sp<VirtualTouchpadForTesting> touchpad(VirtualTouchpadForTesting::New());
+ std::unique_ptr<VirtualTouchpadForTesting> touchpad(
+ VirtualTouchpadForTesting::New());
UInputRecorder expect;
status_t touch_status = touchpad->Attach();
@@ -284,7 +287,8 @@
}
TEST_F(VirtualTouchpadTest, Badness) {
- sp<VirtualTouchpadForTesting> touchpad(VirtualTouchpadForTesting::New());
+ std::unique_ptr<VirtualTouchpadForTesting> touchpad(
+ VirtualTouchpadForTesting::New());
UInputRecorder expect;
UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record;
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index 60ca818..684d15b 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -240,12 +240,14 @@
}
}
-uint32_t VrHwc::getMaxVirtualDisplayCount() { return 0; }
+uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; }
Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
PixelFormat* format, Display* outDisplay) {
*format = PixelFormat::RGBA_8888;
- *outDisplay = 0;
+ *outDisplay = display_count_;
+ displays_[display_count_].reset(new HwcDisplay());
+ display_count_++;
return Error::NONE;
}
@@ -356,7 +358,11 @@
return Error::BAD_DISPLAY;
}
- *outType = IComposerClient::DisplayType::PHYSICAL;
+ if (display == kDefaultDisplayId)
+ *outType = IComposerClient::DisplayType::PHYSICAL;
+ else
+ *outType = IComposerClient::DisplayType::VIRTUAL;
+
return Error::NONE;
}
@@ -443,8 +449,8 @@
if (!display_ptr)
return Error::BAD_DISPLAY;
- ALOGE("Virtual display support not implemented");
- return Error::UNSUPPORTED;
+ // TODO(dnicoara): Is it necessary to do anything here?
+ return Error::NONE;
}
Error VrHwc::validateDisplay(
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
index b869d3e..3c76120 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -248,6 +248,7 @@
std::mutex mutex_;
std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_;
+ Display display_count_ = 2;
Observer* observer_ = nullptr;
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 72a2c26..a21e883 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -5,6 +5,7 @@
#include <android/input.h>
#include <binder/IServiceManager.h>
#include <hardware/hwcomposer2.h>
+#include <inttypes.h>
#include <log/log.h>
#include "controller_mesh.h"
@@ -95,7 +96,8 @@
}
int GetTouchIdForDisplay(uint32_t display) {
- return display == 1 ? VirtualTouchpad::PRIMARY : VirtualTouchpad::VIRTUAL;
+ return display == 1 ? DVR_VIRTUAL_TOUCHPAD_PRIMARY
+ : DVR_VIRTUAL_TOUCHPAD_VIRTUAL;
}
} // namespace
@@ -109,8 +111,9 @@
if (ret)
return ret;
- virtual_touchpad_ = VirtualTouchpadClient::Create();
- const status_t touchpad_status = virtual_touchpad_->Attach();
+ virtual_touchpad_.reset(dvrVirtualTouchpadCreate());
+ const status_t touchpad_status =
+ dvrVirtualTouchpadAttach(virtual_touchpad_.get());
if (touchpad_status != OK) {
ALOGE("Failed to connect to virtual touchpad");
return touchpad_status;
@@ -164,13 +167,11 @@
}
void ShellView::EnableDebug(bool debug) {
- ALOGI("EnableDebug(%d)", (int)debug); // XXX TODO delete
QueueTask(debug ? MainThreadTask::EnableDebugMode
: MainThreadTask::DisableDebugMode);
}
void ShellView::VrMode(bool mode) {
- ALOGI("VrMode(%d)", (int)mode); // XXX TODO delete
QueueTask(mode ? MainThreadTask::EnteringVrMode
: MainThreadTask::ExitingVrMode);
}
@@ -180,6 +181,13 @@
result.appendFormat("initialized = %s\n", initialized_ ? "true" : "false");
result.appendFormat("is_visible = %s\n", is_visible_ ? "true" : "false");
result.appendFormat("debug_mode = %s\n\n", debug_mode_ ? "true" : "false");
+
+ result.append("[displays]\n");
+ result.appendFormat("count = %zu\n", displays_.size());
+ for (size_t i = 0; i < displays_.size(); ++i)
+ result.appendFormat(" display_id = %" PRId32 "\n", displays_[i]->id());
+
+ result.append("\n");
}
void ShellView::OnDrawFrame() {
@@ -419,7 +427,7 @@
}
void ShellView::Touch() {
- if (!virtual_touchpad_.get()) {
+ if (!virtual_touchpad_) {
ALOGE("missing virtual touchpad");
return;
}
@@ -431,8 +439,8 @@
// Device is portrait, but in landscape when in VR.
// Rotate touch input appropriately.
- const android::status_t status = virtual_touchpad_->Touch(
- active_display_->touchpad_id(),
+ const android::status_t status = dvrVirtualTouchpadTouch(
+ virtual_touchpad_.get(), active_display_->touchpad_id(),
1.0f - hit_location.y() / size_.y(), hit_location.x() / size_.x(),
is_touching_ ? 1.0f : 0.0f);
if (status != OK) {
@@ -453,7 +461,7 @@
return true;
}
touchpad_buttons_ = buttons;
- if (!virtual_touchpad_.get()) {
+ if (!virtual_touchpad_) {
ALOGE("missing virtual touchpad");
return false;
}
@@ -461,8 +469,9 @@
if (!active_display_)
return true;
- const android::status_t status = virtual_touchpad_->ButtonState(
- active_display_->touchpad_id(), touchpad_buttons_);
+ const android::status_t status = dvrVirtualTouchpadButtonState(
+ virtual_touchpad_.get(), active_display_->touchpad_id(),
+ touchpad_buttons_);
if (status != OK) {
ALOGE("touchpad button failed: %d %d", touchpad_buttons_, status);
}
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index c10bd27..856c8b8 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -1,12 +1,12 @@
#ifndef VR_WINDOW_MANAGER_SHELL_VIEW_H_
#define VR_WINDOW_MANAGER_SHELL_VIEW_H_
+#include <dvr/virtual_touchpad_client.h>
#include <private/dvr/graphics/mesh.h>
#include <private/dvr/graphics/shader_program.h>
#include <deque>
-#include "VirtualTouchpadClient.h"
#include "application.h"
#include "display_view.h"
#include "reticle.h"
@@ -53,7 +53,6 @@
DisplayView* FindActiveDisplay(const vec3& position, const quat& quaternion,
vec3* hit_location);
-
// HwcCallback::Client:
base::unique_fd OnFrame(std::unique_ptr<HwcCallback::Frame> frame) override;
DisplayView* FindOrCreateDisplay(uint32_t id);
@@ -64,7 +63,15 @@
std::unique_ptr<SurfaceFlingerView> surface_flinger_view_;
std::unique_ptr<Reticle> reticle_;
- sp<VirtualTouchpad> virtual_touchpad_;
+
+ struct DvrVirtualTouchpadDeleter {
+ void operator()(DvrVirtualTouchpad* p) {
+ dvrVirtualTouchpadDetach(p);
+ dvrVirtualTouchpadDestroy(p);
+ }
+ };
+ std::unique_ptr<DvrVirtualTouchpad, DvrVirtualTouchpadDeleter>
+ virtual_touchpad_;
std::unique_ptr<Mesh<vec3, vec3, vec2>> controller_mesh_;