Merge "libbinder_ndk: validate the interface before using"
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f54f132..e66bca0 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -28,9 +28,6 @@
"include-filter": "*CropLatchingTest.*"
},
{
- "include-filter": "*ChildLayerTest.*"
- },
- {
"include-filter": "*ScreenCaptureTest.*"
},
{
@@ -56,9 +53,6 @@
},
{
"include-filter": "*RefreshRateOverlayTest.*"
- },
- {
- "exclude-filter": "*ChildLayerTest#ChildrenSurviveParentDestruction"
}
]
},
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c1ae5b4..ee1c63a 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -170,6 +170,7 @@
#define RECOVERY_DIR "/cache/recovery"
#define RECOVERY_DATA_DIR "/data/misc/recovery"
#define UPDATE_ENGINE_LOG_DIR "/data/misc/update_engine_log"
+#define UPDATE_ENGINE_PREF_DIR "/data/misc/update_engine/prefs"
#define LOGPERSIST_DATA_DIR "/data/misc/logd"
#define PREREBOOT_DATA_DIR "/data/misc/prereboot"
#define PROFILE_DATA_DIR_CUR "/data/misc/profiles/cur"
@@ -234,6 +235,7 @@
// task and the log title of the duration report.
static const std::string DUMP_TRACES_TASK = "DUMP TRACES";
static const std::string DUMP_INCIDENT_REPORT_TASK = "INCIDENT REPORT";
+static const std::string DUMP_NETSTATS_PROTO_TASK = "DUMP NETSTATS PROTO";
static const std::string DUMP_HALS_TASK = "DUMP HALS";
static const std::string DUMP_BOARD_TASK = "dumpstate_board()";
static const std::string DUMP_CHECKINS_TASK = "DUMP CHECKINS";
@@ -1041,6 +1043,26 @@
}
}
+static void DumpNetstatsProto() {
+ const std::string path = ds.bugreport_internal_dir_ + "/tmp_netstats_proto";
+ auto fd = android::base::unique_fd(TEMP_FAILURE_RETRY(open(path.c_str(),
+ O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
+ if (fd < 0) {
+ MYLOGE("Could not open %s to dump netstats proto.\n", path.c_str());
+ return;
+ }
+ RunCommandToFd(fd, "", {"dumpsys", "netstats", "--proto"},
+ CommandOptions::WithTimeout(120).Build());
+ bool empty = 0 == lseek(fd, 0, SEEK_END);
+ if (!empty) {
+ ds.EnqueueAddZipEntryAndCleanupIfNeeded(kProtoPath + "netstats" + kProtoExt,
+ path);
+ } else {
+ unlink(path.c_str());
+ }
+}
+
static void MaybeAddSystemTraceToZip() {
// This function copies into the .zip the system trace that was snapshotted
// by the early call to MaybeSnapshotSystemTrace(), if any background
@@ -1576,7 +1598,8 @@
DurationReporter duration_reporter("DUMPSTATE");
// Enqueue slow functions into the thread pool, if the parallel run is enabled.
- std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins;
+ std::future<std::string> dump_hals, dump_incident_report, dump_board, dump_checkins,
+ dump_netstats_report;
if (ds.dump_pool_) {
// Pool was shutdown in DumpstateDefaultAfterCritical method in order to
// drop root user. Restarts it with two threads for the parallel run.
@@ -1585,6 +1608,8 @@
dump_hals = ds.dump_pool_->enqueueTaskWithFd(DUMP_HALS_TASK, &DumpHals, _1);
dump_incident_report = ds.dump_pool_->enqueueTask(
DUMP_INCIDENT_REPORT_TASK, &DumpIncidentReport);
+ dump_netstats_report = ds.dump_pool_->enqueueTask(
+ DUMP_NETSTATS_PROTO_TASK, &DumpNetstatsProto);
dump_board = ds.dump_pool_->enqueueTaskWithFd(
DUMP_BOARD_TASK, &Dumpstate::DumpstateBoard, &ds, _1);
dump_checkins = ds.dump_pool_->enqueueTaskWithFd(DUMP_CHECKINS_TASK, &DumpCheckins, _1);
@@ -1779,6 +1804,13 @@
dump_frozen_cgroupfs();
if (ds.dump_pool_) {
+ WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_netstats_report));
+ } else {
+ RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_NETSTATS_PROTO_TASK,
+ DumpNetstatsProto);
+ }
+
+ if (ds.dump_pool_) {
WAIT_TASK_WITH_CONSENT_CHECK(std::move(dump_incident_report));
} else {
RUN_SLOW_FUNCTION_WITH_CONSENT_CHECK_AND_LOG(DUMP_INCIDENT_REPORT_TASK,
@@ -1828,6 +1860,7 @@
ds.AddDir(RECOVERY_DIR, true);
ds.AddDir(RECOVERY_DATA_DIR, true);
ds.AddDir(UPDATE_ENGINE_LOG_DIR, true);
+ ds.AddDir(UPDATE_ENGINE_PREF_DIR, true);
ds.AddDir(LOGPERSIST_DATA_DIR, false);
if (!PropertiesHelper::IsUserBuild()) {
ds.AddDir(PROFILE_DATA_DIR_CUR, true);
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index f0c19b9..b8e5ce1 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -60,6 +60,7 @@
MOCK_METHOD1(isDeclared, bool(const String16&));
MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
MOCK_METHOD1(updatableViaApex, std::optional<String16>(const String16&));
+ MOCK_METHOD1(getUpdatableNames, Vector<String16>(const String16&));
MOCK_METHOD1(getConnectionInfo, std::optional<ConnectionInfo>(const String16&));
MOCK_METHOD2(registerForNotifications, status_t(const String16&,
const sp<LocalRegistrationCallback>&));
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 6ef41e3..3b589dc 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -23,6 +23,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
@@ -52,22 +53,7 @@
constexpr int kTimeoutMs = 60000;
-// TODO(calin): try to dedup this code.
-#if defined(__arm__)
-static const std::string kRuntimeIsa = "arm";
-#elif defined(__aarch64__)
-static const std::string kRuntimeIsa = "arm64";
-#elif defined(__mips__) && !defined(__LP64__)
-static const std::string kRuntimeIsa = "mips";
-#elif defined(__mips__) && defined(__LP64__)
-static const std::string kRuntimeIsa = "mips64";
-#elif defined(__i386__)
-static const std::string kRuntimeIsa = "x86";
-#elif defined(__x86_64__)
-static const std::string kRuntimeIsa = "x86_64";
-#else
-static const std::string kRuntimeIsa = "none";
-#endif
+static const std::string kRuntimeIsa = ABI_STRING;
int get_property(const char *key, char *value, const char *default_value) {
return property_get(key, value, default_value);
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 3681d5b..2684f04 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -142,6 +142,26 @@
return updatableViaApex;
}
+static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) {
+ std::vector<std::string> instances;
+
+ forEachManifest([&](const ManifestWithDescription& mwd) {
+ mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+ if (manifestInstance.format() == vintf::HalFormat::AIDL &&
+ manifestInstance.updatableViaApex().has_value() &&
+ manifestInstance.updatableViaApex().value() == apexName) {
+ std::string aname = manifestInstance.package() + "." +
+ manifestInstance.interface() + "/" + manifestInstance.instance();
+ instances.push_back(aname);
+ }
+ return false; // continue
+ });
+ return false; // continue
+ });
+
+ return instances;
+}
+
static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
AidlName aname;
if (!AidlName::fill(name, &aname)) return std::nullopt;
@@ -512,6 +532,30 @@
return Status::ok();
}
+Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
+ std::vector<std::string>* outReturn) {
+ auto ctx = mAccess->getCallingContext();
+
+ std::vector<std::string> apexUpdatableInstances;
+#ifndef VENDORSERVICEMANAGER
+ apexUpdatableInstances = getVintfUpdatableInstances(apexName);
+#endif
+
+ outReturn->clear();
+
+ for (const std::string& instance : apexUpdatableInstances) {
+ if (mAccess->canFind(ctx, instance)) {
+ outReturn->push_back(instance);
+ }
+ }
+
+ if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
+ }
+
+ return Status::ok();
+}
+
Status ServiceManager::getConnectionInfo(const std::string& name,
std::optional<ConnectionInfo>* outReturn) {
auto ctx = mAccess->getCallingContext();
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 07b79f8..b24c11c 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -49,6 +49,8 @@
binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override;
binder::Status updatableViaApex(const std::string& name,
std::optional<std::string>* outReturn) override;
+ binder::Status getUpdatableNames(const std::string& apexName,
+ std::vector<std::string>* outReturn) override;
binder::Status getConnectionInfo(const std::string& name,
std::optional<ConnectionInfo>* outReturn) override;
binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
diff --git a/cmds/servicemanager/main.cpp b/cmds/servicemanager/main.cpp
index a831d1b..c1a04dd 100644
--- a/cmds/servicemanager/main.cpp
+++ b/cmds/servicemanager/main.cpp
@@ -111,9 +111,7 @@
};
int main(int argc, char** argv) {
-#ifdef __ANDROID_RECOVERY__
android::base::InitLogging(argv, android::base::KernelLogger);
-#endif
if (argc > 2) {
LOG(FATAL) << "usage: " << argv[0] << " [binder driver]";
diff --git a/cmds/servicemanager/servicemanager.microdroid.rc b/cmds/servicemanager/servicemanager.microdroid.rc
index c516043..8819e1e 100644
--- a/cmds/servicemanager/servicemanager.microdroid.rc
+++ b/cmds/servicemanager/servicemanager.microdroid.rc
@@ -5,5 +5,4 @@
critical
onrestart setprop servicemanager.ready false
onrestart restart apexd
- task_profiles ServiceCapacityLow
shutdown critical
diff --git a/cmds/servicemanager/servicemanager.rc b/cmds/servicemanager/servicemanager.rc
index 6b35265..3bd6db5 100644
--- a/cmds/servicemanager/servicemanager.rc
+++ b/cmds/servicemanager/servicemanager.rc
@@ -3,6 +3,7 @@
user system
group system readproc
critical
+ file /dev/kmsg w
onrestart setprop servicemanager.ready false
onrestart restart apexd
onrestart restart audioserver
diff --git a/cmds/servicemanager/vndservicemanager.rc b/cmds/servicemanager/vndservicemanager.rc
index c9305a1..80af1d1 100644
--- a/cmds/servicemanager/vndservicemanager.rc
+++ b/cmds/servicemanager/vndservicemanager.rc
@@ -2,6 +2,7 @@
class core
user system
group system readproc
+ file /dev/kmsg w
task_profiles ServiceCapacityLow
onrestart class_restart main
onrestart class_restart hal
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp
index 76e3e66..5e539f2 100644
--- a/libs/arect/Android.bp
+++ b/libs/arect/Android.bp
@@ -49,6 +49,9 @@
"com.android.media",
"com.android.media.swcodec",
],
+ llndk: {
+ llndk_headers: true,
+ },
}
cc_library_static {
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index df965ab..2362580 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -161,7 +161,7 @@
],
header_libs: [
- "libandroid_runtime_vm_headers",
+ "jni_headers",
],
export_header_lib_headers: [
@@ -315,7 +315,7 @@
},
recovery: {
exclude_header_libs: [
- "libandroid_runtime_vm_headers",
+ "jni_headers",
],
},
},
@@ -490,9 +490,6 @@
java: {
enabled: false,
},
- cpp: {
- gen_trace: false,
- },
},
}
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 05db774..a0c4334 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -81,6 +81,7 @@
bool isDeclared(const String16& name) override;
Vector<String16> getDeclaredInstances(const String16& interface) override;
std::optional<String16> updatableViaApex(const String16& name) override;
+ Vector<String16> getUpdatableNames(const String16& apexName) override;
std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
class RegistrationWaiter : public android::os::BnServiceCallback {
public:
@@ -479,6 +480,23 @@
return declared ? std::optional<String16>(String16(declared.value().c_str())) : std::nullopt;
}
+Vector<String16> ServiceManagerShim::getUpdatableNames(const String16& apexName) {
+ std::vector<std::string> out;
+ if (Status status = mTheRealServiceManager->getUpdatableNames(String8(apexName).c_str(), &out);
+ !status.isOk()) {
+ ALOGW("Failed to getUpdatableNames for %s: %s", String8(apexName).c_str(),
+ status.toString8().c_str());
+ return {};
+ }
+
+ Vector<String16> res;
+ res.setCapacity(out.size());
+ for (const std::string& instance : out) {
+ res.push(String16(instance.c_str()));
+ }
+ return res;
+}
+
std::optional<IServiceManager::ConnectionInfo> ServiceManagerShim::getConnectionInfo(
const String16& name) {
std::optional<os::ConnectionInfo> connectionInfo;
diff --git a/libs/binder/OS.cpp b/libs/binder/OS.cpp
index 77e401f..ce60e33 100644
--- a/libs/binder/OS.cpp
+++ b/libs/binder/OS.cpp
@@ -67,7 +67,7 @@
return RpcTransportCtxFactoryRaw::make();
}
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
const RpcTransportFd& socket, iovec* iovs, int niovs,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
if (ancillaryFds != nullptr && !ancillaryFds->empty()) {
@@ -112,7 +112,7 @@
return TEMP_FAILURE_RETRY(sendmsg(socket.fd.get(), &msg, MSG_NOSIGNAL));
}
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
const RpcTransportFd& socket, iovec* iovs, int niovs,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
if (ancillaryFds != nullptr) {
diff --git a/libs/binder/OS.h b/libs/binder/OS.h
index 0d38968..fecae31 100644
--- a/libs/binder/OS.h
+++ b/libs/binder/OS.h
@@ -33,11 +33,11 @@
std::unique_ptr<RpcTransportCtxFactory> makeDefaultRpcTransportCtxFactory();
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
const RpcTransportFd& socket, iovec* iovs, int niovs,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds);
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
const RpcTransportFd& socket, iovec* iovs, int niovs,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds);
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 7d6bcfc..ce6ef2b 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -46,8 +46,8 @@
#include "Utils.h"
#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
-#include <android_runtime/vm.h>
#include <jni.h>
+extern "C" JavaVM* AndroidRuntimeGetJavaVM();
#endif
namespace android {
@@ -408,10 +408,11 @@
"Unable to detach thread. No JavaVM, but it was present before!");
LOG_RPC_DETAIL("Detaching current thread from JVM");
- if (vm->DetachCurrentThread() != JNI_OK) {
+ int ret = vm->DetachCurrentThread();
+ if (ret == JNI_OK) {
mAttached = false;
} else {
- ALOGW("Unable to detach current thread from JVM");
+ ALOGW("Unable to detach current thread from JVM (%d)", ret);
}
}
diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp
index 1912d14..cd067bf 100644
--- a/libs/binder/RpcTransportRaw.cpp
+++ b/libs/binder/RpcTransportRaw.cpp
@@ -61,7 +61,8 @@
override {
bool sentFds = false;
auto send = [&](iovec* iovs, int niovs) -> ssize_t {
- int ret = sendMessageOnSocket(mSocket, iovs, niovs, sentFds ? nullptr : ancillaryFds);
+ ssize_t ret =
+ sendMessageOnSocket(mSocket, iovs, niovs, sentFds ? nullptr : ancillaryFds);
sentFds |= ret > 0;
return ret;
};
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 5880c0a..0fb1615 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -114,6 +114,12 @@
@nullable @utf8InCpp String updatableViaApex(@utf8InCpp String name);
/**
+ * Returns all instances which are updatable via the APEX. Instance names are fully qualified
+ * like `pack.age.IFoo/default`.
+ */
+ @utf8InCpp String[] getUpdatableNames(@utf8InCpp String apexName);
+
+ /**
* If connection info is available for the given instance, returns the ConnectionInfo
*/
@nullable ConnectionInfo getConnectionInfo(@utf8InCpp String name);
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 413c97f..79e771f 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -115,6 +115,12 @@
virtual std::optional<String16> updatableViaApex(const String16& name) = 0;
/**
+ * Returns all instances which are updatable via the APEX. Instance names are fully qualified
+ * like `pack.age.IFoo/default`.
+ */
+ virtual Vector<String16> getUpdatableNames(const String16& apexName) = 0;
+
+ /**
* If this instance has declared remote connection information, returns
* the ConnectionInfo.
*/
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
index 5baa4d7..e4a9f99 100644
--- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
+++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
@@ -24,23 +24,23 @@
// Starts an RPC server on a given port and a given root IBinder object.
// This function sets up the server and joins before returning.
-bool RunRpcServer(AIBinder* service, unsigned int port);
+bool RunVsockRpcServer(AIBinder* service, unsigned int port);
// Starts an RPC server on a given port and a given root IBinder object.
// This function sets up the server, calls readyCallback with a given param, and
// then joins before returning.
-bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
- void* param);
+bool RunVsockRpcServerCallback(AIBinder* service, unsigned int port,
+ void (*readyCallback)(void* param), void* param);
// Starts an RPC server on a given port and a given root IBinder factory.
-// RunRpcServerWithFactory acts like RunRpcServerCallback, but instead of
+// RunVsockRpcServerWithFactory acts like RunVsockRpcServerCallback, but instead of
// assigning single root IBinder object to all connections, factory is called
// whenever a client connects, making it possible to assign unique IBinder
// object to each client.
-bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
- void* factoryContext, unsigned int port);
+bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+ void* factoryContext, unsigned int port);
-AIBinder* RpcClient(unsigned int cid, unsigned int port);
+AIBinder* VsockRpcClient(unsigned int cid, unsigned int port);
// Connect to an RPC server with preconnected file descriptors.
//
@@ -50,5 +50,4 @@
// param will be passed to requestFd. Callers can use param to pass contexts to
// the requestFd function.
AIBinder* RpcPreconnectedClient(int (*requestFd)(void* param), void* param);
-
}
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
index a3d42b7..1f38bb9 100644
--- a/libs/binder/libbinder_rpc_unstable.cpp
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -30,8 +30,8 @@
extern "C" {
-bool RunRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
- void* factoryContext, unsigned int port) {
+bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
+ void* factoryContext, unsigned int port) {
auto server = RpcServer::make();
if (status_t status = server->setupVsockServer(port); status != OK) {
LOG(ERROR) << "Failed to set up vsock server with port " << port
@@ -52,8 +52,8 @@
return true;
}
-bool RunRpcServerCallback(AIBinder* service, unsigned int port, void (*readyCallback)(void* param),
- void* param) {
+bool RunVsockRpcServerCallback(AIBinder* service, unsigned int port,
+ void (*readyCallback)(void* param), void* param) {
auto server = RpcServer::make();
if (status_t status = server->setupVsockServer(port); status != OK) {
LOG(ERROR) << "Failed to set up vsock server with port " << port
@@ -70,11 +70,11 @@
return true;
}
-bool RunRpcServer(AIBinder* service, unsigned int port) {
- return RunRpcServerCallback(service, port, nullptr, nullptr);
+bool RunVsockRpcServer(AIBinder* service, unsigned int port) {
+ return RunVsockRpcServerCallback(service, port, nullptr, nullptr);
}
-AIBinder* RpcClient(unsigned int cid, unsigned int port) {
+AIBinder* VsockRpcClient(unsigned int cid, unsigned int port) {
auto session = RpcSession::make();
if (status_t status = session->setupVsockClient(cid, port); status != OK) {
LOG(ERROR) << "Failed to set up vsock client with CID " << cid << " and port " << port
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
index e856569..347831a 100644
--- a/libs/binder/libbinder_rpc_unstable.map.txt
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -1,8 +1,8 @@
LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
global:
- RunRpcServer;
- RunRpcServerCallback;
- RpcClient;
+ RunVsockRpcServer;
+ RunVsockRpcServerCallback;
+ VsockRpcClient;
RpcPreconnectedClient;
local:
*;
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index dfa8ea2..c234270 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -143,6 +143,17 @@
bool AServiceManager_isUpdatableViaApex(const char* instance) __INTRODUCED_IN(31);
/**
+ * Returns the APEX name if a service is declared as updatable via an APEX module.
+ *
+ * \param instance identifier of the service
+ * \param context to pass to callback
+ * \param callback taking the APEX name (e.g. 'com.android.foo') and context
+ */
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+ void (*callback)(const char*, void*))
+ __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
* Prevent lazy services without client from shutting down their process
*
* This should only be used if it is every eventually set to false. If a
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 259a736..32ca564 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -152,6 +152,11 @@
AParcel_unmarshal;
};
+LIBBINDER_NDK34 { # introduced=UpsideDownCake
+ global:
+ AServiceManager_getUpdatableApexName; # systemapi
+};
+
LIBBINDER_NDK_PLATFORM {
global:
AParcel_getAllowFds;
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index 7649a26..a12d0e9 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -113,6 +113,18 @@
sp<IServiceManager> sm = defaultServiceManager();
return sm->updatableViaApex(String16(instance)) != std::nullopt;
}
+void AServiceManager_getUpdatableApexName(const char* instance, void* context,
+ void (*callback)(const char*, void*)) {
+ CHECK_NE(instance, nullptr);
+ // context may be nullptr
+ CHECK_NE(callback, nullptr);
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ std::optional<String16> updatableViaApex = sm->updatableViaApex(String16(instance));
+ if (updatableViaApex.has_value()) {
+ callback(String8(updatableViaApex.value()).c_str(), context);
+ }
+}
void AServiceManager_forceLazyServicesPersist(bool persist) {
auto serviceRegistrar = android::binder::LazyServiceRegistrar::getInstance();
serviceRegistrar.forcePersist(persist);
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index 01b9472..e221e4c 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -33,13 +33,15 @@
#include <binder/IResultReceiver.h>
#include <binder/IServiceManager.h>
#include <binder/IShellCallback.h>
-
#include <sys/prctl.h>
+
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
+#include <optional>
#include <thread>
+
#include "android/binder_ibinder.h"
using namespace android;
@@ -337,6 +339,16 @@
EXPECT_EQ(isUpdatable, false);
}
+TEST(NdkBinder, GetUpdatableViaApex) {
+ std::optional<std::string> updatableViaApex;
+ AServiceManager_getUpdatableApexName(
+ "android.hardware.light.ILights/default", &updatableViaApex,
+ [](const char* apexName, void* context) {
+ *static_cast<std::optional<std::string>*>(context) = apexName;
+ });
+ EXPECT_EQ(updatableViaApex, std::nullopt) << *updatableViaApex;
+}
+
// This is too slow
TEST(NdkBinder, CheckLazyServiceShutDown) {
ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
diff --git a/libs/binder/rust/rpcbinder/src/client.rs b/libs/binder/rust/rpcbinder/src/client.rs
index 743800b..4343ff4 100644
--- a/libs/binder/rust/rpcbinder/src/client.rs
+++ b/libs/binder/rust/rpcbinder/src/client.rs
@@ -22,9 +22,9 @@
/// Connects to an RPC Binder server over vsock.
pub fn get_vsock_rpc_service(cid: u32, port: u32) -> Option<SpIBinder> {
- // SAFETY: AIBinder returned by RpcClient has correct reference count, and the ownership can
- // safely be taken by new_spibinder.
- unsafe { new_spibinder(binder_rpc_unstable_bindgen::RpcClient(cid, port)) }
+ // SAFETY: AIBinder returned by VsockRpcClient has correct reference count,
+ // and the ownership can safely be taken by new_spibinder.
+ unsafe { new_spibinder(binder_rpc_unstable_bindgen::VsockRpcClient(cid, port)) }
}
/// Connects to an RPC Binder server for a particular interface over vsock.
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index a5eea61..fb6b90c 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -23,4 +23,4 @@
get_preconnected_rpc_interface, get_preconnected_rpc_service, get_vsock_rpc_interface,
get_vsock_rpc_service,
};
-pub use server::{run_rpc_server, run_rpc_server_with_factory};
+pub use server::{run_vsock_rpc_server, run_vsock_rpc_server_with_factory};
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index aeb23c6..8009297 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -30,7 +30,7 @@
/// The current thread is joined to the binder thread pool to handle incoming messages.
///
/// Returns true if the server has shutdown normally, false if it failed in some way.
-pub fn run_rpc_server<F>(service: SpIBinder, port: u32, on_ready: F) -> bool
+pub fn run_vsock_rpc_server<F>(service: SpIBinder, port: u32, on_ready: F) -> bool
where
F: FnOnce(),
{
@@ -52,10 +52,10 @@
// SAFETY: Service ownership is transferring to the server and won't be valid afterward.
// Plus the binder objects are threadsafe.
- // RunRpcServerCallback does not retain a reference to `ready_callback` or `param`; it only
+ // RunVsockRpcServerCallback does not retain a reference to `ready_callback` or `param`; it only
// uses them before it returns, which is during the lifetime of `self`.
unsafe {
- binder_rpc_unstable_bindgen::RunRpcServerCallback(
+ binder_rpc_unstable_bindgen::RunVsockRpcServerCallback(
service,
port,
Some(Self::ready_callback),
@@ -69,7 +69,7 @@
}
unsafe extern "C" fn ready_callback(param: *mut raw::c_void) {
- // SAFETY: This is only ever called by `RunRpcServerCallback`, within the lifetime of the
+ // SAFETY: This is only ever called by `RunVsockRpcServerCallback`, within the lifetime of the
// `ReadyNotifier`, with `param` taking the value returned by `as_void_ptr` (so a properly
// aligned non-null pointer to an initialized instance).
let ready_notifier = param as *mut Self;
@@ -91,7 +91,7 @@
/// The current thread is joined to the binder thread pool to handle incoming messages.
///
/// Returns true if the server has shutdown normally, false if it failed in some way.
-pub fn run_rpc_server_with_factory(
+pub fn run_vsock_rpc_server_with_factory(
port: u32,
mut factory: impl FnMut(u32) -> Option<SpIBinder> + Send + Sync,
) -> bool {
@@ -100,18 +100,22 @@
let mut factory_ref: RpcServerFactoryRef = &mut factory;
let context = &mut factory_ref as *mut RpcServerFactoryRef as *mut raw::c_void;
- // SAFETY: `factory_wrapper` is only ever called by `RunRpcServerWithFactory`, with context
+ // SAFETY: `factory_wrapper` is only ever called by `RunVsockRpcServerWithFactory`, with context
// taking the pointer value above (so a properly aligned non-null pointer to an initialized
// `RpcServerFactoryRef`), within the lifetime of `factory_ref` (i.e. no more calls will be made
- // after `RunRpcServerWithFactory` returns).
+ // after `RunVsockRpcServerWithFactory` returns).
unsafe {
- binder_rpc_unstable_bindgen::RunRpcServerWithFactory(Some(factory_wrapper), context, port)
+ binder_rpc_unstable_bindgen::RunVsockRpcServerWithFactory(
+ Some(factory_wrapper),
+ context,
+ port,
+ )
}
}
unsafe extern "C" fn factory_wrapper(cid: u32, context: *mut raw::c_void) -> *mut AIBinder {
// SAFETY: `context` was created from an `&mut RpcServerFactoryRef` by
- // `run_rpc_server_with_factory`, and we are still within the lifetime of the value it is
+ // `run_vsock_rpc_server_with_factory`, and we are still within the lifetime of the value it is
// pointing to.
let factory_ptr = context as *mut RpcServerFactoryRef;
let factory = factory_ptr.as_mut().unwrap();
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 777f3c9..692cc95 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -156,6 +156,10 @@
std::optional<std::string>* _aidl_return) override {
return mImpl->updatableViaApex(name, _aidl_return);
}
+ android::binder::Status getUpdatableNames(const std::string& apexName,
+ std::vector<std::string>* _aidl_return) override {
+ return mImpl->getUpdatableNames(apexName, _aidl_return);
+ }
android::binder::Status getConnectionInfo(
const std::string& name,
std::optional<android::os::ConnectionInfo>* _aidl_return) override {
diff --git a/libs/binder/trusty/OS.cpp b/libs/binder/trusty/OS.cpp
index 397ff41..8ec9823 100644
--- a/libs/binder/trusty/OS.cpp
+++ b/libs/binder/trusty/OS.cpp
@@ -59,14 +59,14 @@
return RpcTransportCtxFactoryTipcTrusty::make();
}
-int sendMessageOnSocket(
+ssize_t sendMessageOnSocket(
const RpcTransportFd& /* socket */, iovec* /* iovs */, int /* niovs */,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /* ancillaryFds */) {
errno = ENOTSUP;
return -1;
}
-int receiveMessageFromSocket(
+ssize_t receiveMessageFromSocket(
const RpcTransportFd& /* socket */, iovec* /* iovs */, int /* niovs */,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /* ancillaryFds */) {
errno = ENOTSUP;
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index a6585c5..067ce17 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -208,5 +208,5 @@
cmdline = std::string(cmdline.c_str());
return cmdline == "zygote" || cmdline == "zygote64" || cmdline == "usap32" ||
- cmdline == "usap64";
+ cmdline == "usap64" || cmdline == "webview_zygote";
}
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 6c6d7f3..480ec79 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -78,6 +78,11 @@
return std::nullopt;
}
+Vector<String16> ServiceManager::getUpdatableNames(const String16& apexName) {
+ (void)apexName;
+ return {};
+}
+
std::optional<IServiceManager::ConnectionInfo> ServiceManager::getConnectionInfo(
const String16& name) {
(void)name;
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
index e0af5d4..ee0637e 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
@@ -52,6 +52,8 @@
std::optional<String16> updatableViaApex(const String16& name) override;
+ Vector<String16> getUpdatableNames(const String16& apexName) override;
+
std::optional<IServiceManager::ConnectionInfo> getConnectionInfo(const String16& name) override;
status_t registerForNotifications(const String16& name,
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 56b17ae..6c39bbf 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -177,8 +177,6 @@
"BitTube.cpp",
"BLASTBufferQueue.cpp",
- "BufferHubConsumer.cpp",
- "BufferHubProducer.cpp",
"BufferItemConsumer.cpp",
"ConsumerBase.cpp",
"CpuConsumer.cpp",
@@ -216,9 +214,6 @@
shared_libs: [
"libbinder",
- "libbufferhub",
- "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui.
- "libpdx_default_transport",
],
export_shared_lib_headers: [
@@ -229,24 +224,6 @@
"libgui_aidl_headers",
],
- // bufferhub is not used when building libgui for vendors
- target: {
- vendor: {
- cflags: [
- "-DNO_BUFFERHUB",
- ],
- exclude_srcs: [
- "BufferHubConsumer.cpp",
- "BufferHubProducer.cpp",
- ],
- exclude_shared_libs: [
- "libbufferhub",
- "libbufferhubqueue",
- "libpdx_default_transport",
- ],
- },
- },
-
aidl: {
export_aidl_headers: true,
},
@@ -276,7 +253,6 @@
min_sdk_version: "29",
cflags: [
- "-DNO_BUFFERHUB",
"-DNO_BINDER",
],
diff --git a/libs/gui/BufferHubConsumer.cpp b/libs/gui/BufferHubConsumer.cpp
deleted file mode 100644
index b5cdeb2..0000000
--- a/libs/gui/BufferHubConsumer.cpp
+++ /dev/null
@@ -1,161 +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 <gui/BufferHubConsumer.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubConsumer> BufferHubConsumer::Create(const std::shared_ptr<ConsumerQueue>& queue) {
- sp<BufferHubConsumer> consumer = new BufferHubConsumer;
- consumer->mQueue = queue;
- return consumer;
-}
-
-/* static */ sp<BufferHubConsumer> BufferHubConsumer::Create(ConsumerQueueParcelable parcelable) {
- if (!parcelable.IsValid()) {
- ALOGE("BufferHubConsumer::Create: Invalid consumer parcelable.");
- return nullptr;
- }
-
- sp<BufferHubConsumer> consumer = new BufferHubConsumer;
- consumer->mQueue = ConsumerQueue::Import(parcelable.TakeChannelHandle());
- return consumer;
-}
-
-status_t BufferHubConsumer::acquireBuffer(BufferItem* /*buffer*/, nsecs_t /*presentWhen*/,
- uint64_t /*maxFrameNumber*/) {
- ALOGE("BufferHubConsumer::acquireBuffer: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::detachBuffer(int /*slot*/) {
- ALOGE("BufferHubConsumer::detachBuffer: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::attachBuffer(int* /*outSlot*/, const sp<GraphicBuffer>& /*buffer*/) {
- ALOGE("BufferHubConsumer::attachBuffer: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::releaseBuffer(int /*buf*/, uint64_t /*frameNumber*/,
- EGLDisplay /*display*/, EGLSyncKHR /*fence*/,
- const sp<Fence>& /*releaseFence*/) {
- ALOGE("BufferHubConsumer::releaseBuffer: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::consumerConnect(const sp<IConsumerListener>& /*consumer*/,
- bool /*controlledByApp*/) {
- ALOGE("BufferHubConsumer::consumerConnect: not implemented.");
-
- // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
- // make IGraphicBufferConsumer_test happy.
- return NO_ERROR;
-}
-
-status_t BufferHubConsumer::consumerDisconnect() {
- ALOGE("BufferHubConsumer::consumerDisconnect: not implemented.");
-
- // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
- // make IGraphicBufferConsumer_test happy.
- return NO_ERROR;
-}
-
-status_t BufferHubConsumer::getReleasedBuffers(uint64_t* /*slotMask*/) {
- ALOGE("BufferHubConsumer::getReleasedBuffers: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {
- ALOGE("BufferHubConsumer::setDefaultBufferSize: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxBufferCount(int /*bufferCount*/) {
- ALOGE("BufferHubConsumer::setMaxBufferCount: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setMaxAcquiredBufferCount(int /*maxAcquiredBuffers*/) {
- ALOGE("BufferHubConsumer::setMaxAcquiredBufferCount: not implemented.");
-
- // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to
- // make IGraphicBufferConsumer_test happy.
- return NO_ERROR;
-}
-
-status_t BufferHubConsumer::setConsumerName(const String8& /*name*/) {
- ALOGE("BufferHubConsumer::setConsumerName: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferFormat(PixelFormat /*defaultFormat*/) {
- ALOGE("BufferHubConsumer::setDefaultBufferFormat: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setDefaultBufferDataSpace(android_dataspace /*defaultDataSpace*/) {
- ALOGE("BufferHubConsumer::setDefaultBufferDataSpace: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerUsageBits(uint64_t /*usage*/) {
- ALOGE("BufferHubConsumer::setConsumerUsageBits: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setConsumerIsProtected(bool /*isProtected*/) {
- ALOGE("BufferHubConsumer::setConsumerIsProtected: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::setTransformHint(uint32_t /*hint*/) {
- ALOGE("BufferHubConsumer::setTransformHint: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getSidebandStream(sp<NativeHandle>* /*outStream*/) const {
- ALOGE("BufferHubConsumer::getSidebandStream: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::getOccupancyHistory(
- bool /*forceFlush*/, std::vector<OccupancyTracker::Segment>* /*outHistory*/) {
- ALOGE("BufferHubConsumer::getOccupancyHistory: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::discardFreeBuffers() {
- ALOGE("BufferHubConsumer::discardFreeBuffers: not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubConsumer::dumpState(const String8& /*prefix*/, String8* /*outResult*/) const {
- ALOGE("BufferHubConsumer::dumpState: not implemented.");
- return INVALID_OPERATION;
-}
-
-IBinder* BufferHubConsumer::onAsBinder() {
- ALOGE("BufferHubConsumer::onAsBinder: BufferHubConsumer should never be used as an Binder "
- "object.");
- return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
deleted file mode 100644
index 1f71e23..0000000
--- a/libs/gui/BufferHubProducer.cpp
+++ /dev/null
@@ -1,868 +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 <dvr/dvr_api.h>
-#include <gui/BufferHubProducer.h>
-#include <inttypes.h>
-#include <log/log.h>
-#include <system/window.h>
-
-namespace android {
-
-using namespace dvr;
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) {
- sp<BufferHubProducer> producer = new BufferHubProducer;
- producer->queue_ = queue;
- return producer;
-}
-
-/* static */
-sp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) {
- if (!parcelable.IsValid()) {
- ALOGE("BufferHubProducer::Create: Invalid producer parcelable.");
- return nullptr;
- }
-
- sp<BufferHubProducer> producer = new BufferHubProducer;
- producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle());
- return producer;
-}
-
-status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
- ALOGV("requestBuffer: slot=%d", slot);
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("requestBuffer: BufferHubProducer has no connected producer");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= max_buffer_count_) {
- ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
- return BAD_VALUE;
- } else if (!buffers_[slot].mBufferState.isDequeued()) {
- ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot,
- buffers_[slot].mBufferState.string());
- return BAD_VALUE;
- } else if (buffers_[slot].mGraphicBuffer != nullptr) {
- ALOGE("requestBuffer: slot %d is not empty.", slot);
- return BAD_VALUE;
- } else if (buffers_[slot].mProducerBuffer == nullptr) {
- ALOGE("requestBuffer: slot %d is not dequeued.", slot);
- return BAD_VALUE;
- }
-
- const auto& producer_buffer = buffers_[slot].mProducerBuffer;
- sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
-
- buffers_[slot].mGraphicBuffer = graphic_buffer;
- buffers_[slot].mRequestBufferCalled = true;
-
- *buf = graphic_buffer;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) {
- ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers);
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (max_dequeued_buffers <= 0 ||
- max_dequeued_buffers >
- int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) {
- ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers,
- BufferHubQueue::kMaxQueueCapacity);
- return BAD_VALUE;
- }
-
- // The new dequeued_buffers count should not be violated by the number
- // of currently dequeued buffers.
- int dequeued_count = 0;
- for (const auto& buf : buffers_) {
- if (buf.mBufferState.isDequeued()) {
- dequeued_count++;
- }
- }
- if (dequeued_count > max_dequeued_buffers) {
- ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers"
- "count (%d) exceeds the current dequeued buffer count (%d)",
- max_dequeued_buffers, dequeued_count);
- return BAD_VALUE;
- }
-
- max_dequeued_buffer_count_ = max_dequeued_buffers;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAsyncMode(bool async) {
- if (async) {
- // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer
- // automatically and behaves differently from IGraphicBufferConsumer. Thus,
- // android::BufferQueue's async mode (a.k.a. allocating an additional buffer
- // to prevent dequeueBuffer from being blocking) technically does not apply
- // here.
- //
- // In Daydream, non-blocking producer side dequeue is guaranteed by careful
- // buffer consumer implementations. In another word, BufferHubQueue based
- // dequeueBuffer should never block whether setAsyncMode(true) is set or
- // not.
- //
- // See: IGraphicBufferProducer::setAsyncMode and
- // BufferQueueProducer::setAsyncMode for more about original implementation.
- ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be "
- "asynchronous. This call makes no effact.");
- return NO_ERROR;
- }
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width,
- uint32_t height, PixelFormat format, uint64_t usage,
- uint64_t* /*outBufferAge*/,
- FrameEventHistoryDelta* /* out_timestamps */) {
- ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage);
-
- status_t ret;
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("dequeueBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- const uint32_t kLayerCount = 1;
- if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) {
- // Lazy allocation. When the capacity of |queue_| has not reached
- // |max_dequeued_buffer_count_|, allocate new buffer.
- // TODO(jwcai) To save memory, the really reasonable thing to do is to go
- // over existing slots and find first existing one to dequeue.
- ret = AllocateBuffer(width, height, kLayerCount, format, usage);
- if (ret < 0) return ret;
- }
-
- size_t slot = 0;
- std::shared_ptr<ProducerBuffer> producer_buffer;
-
- for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
- LocalHandle fence;
- auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
- if (!buffer_status) return NO_MEMORY;
-
- producer_buffer = buffer_status.take();
- if (!producer_buffer) return NO_MEMORY;
-
- if (width == producer_buffer->width() && height == producer_buffer->height() &&
- uint32_t(format) == producer_buffer->format()) {
- // The producer queue returns a producer buffer matches the request.
- break;
- }
-
- // Needs reallocation.
- // TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
- ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
- "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
- "re-allocattion.",
- width, height, format, slot, producer_buffer->width(), producer_buffer->height(),
- producer_buffer->format());
- // Mark the slot as reallocating, so that later we can set
- // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
- buffers_[slot].mIsReallocating = true;
-
- // Remove the old buffer once the allocation before allocating its
- // replacement.
- RemoveBuffer(slot);
-
- // Allocate a new producer buffer with new buffer configs. Note that if
- // there are already multiple buffers in the queue, the next one returned
- // from |queue_->Dequeue| may not be the new buffer we just reallocated.
- // Retry up to BufferHubQueue::kMaxQueueCapacity times.
- ret = AllocateBuffer(width, height, kLayerCount, format, usage);
- if (ret < 0) return ret;
- }
-
- // With the BufferHub backed solution. Buffer slot returned from
- // |queue_->Dequeue| is guaranteed to avaiable for producer's use.
- // It's either in free state (if the buffer has never been used before) or
- // in queued state (if the buffer has been dequeued and queued back to
- // BufferHubQueue).
- LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() &&
- !buffers_[slot].mBufferState.isQueued()),
- "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot,
- buffers_[slot].mBufferState.string());
-
- buffers_[slot].mBufferState.freeQueued();
- buffers_[slot].mBufferState.dequeue();
- ALOGV("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.
- *out_fence = Fence::NO_FENCE;
- *out_slot = int(slot);
- ret = NO_ERROR;
-
- if (buffers_[slot].mIsReallocating) {
- ret |= BUFFER_NEEDS_REALLOCATION;
- buffers_[slot].mIsReallocating = false;
- }
-
- return ret;
-}
-
-status_t BufferHubProducer::detachBuffer(int slot) {
- ALOGV("detachBuffer: slot=%d", slot);
- std::unique_lock<std::mutex> lock(mutex_);
-
- return DetachBufferLocked(static_cast<size_t>(slot));
-}
-
-status_t BufferHubProducer::DetachBufferLocked(size_t slot) {
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("detachBuffer: BufferHubProducer is not connected.");
- return NO_INIT;
- }
-
- if (slot >= static_cast<size_t>(max_buffer_count_)) {
- ALOGE("detachBuffer: slot index %zu out of range [0, %d)", slot, max_buffer_count_);
- return BAD_VALUE;
- } else if (!buffers_[slot].mBufferState.isDequeued()) {
- ALOGE("detachBuffer: slot %zu is not owned by the producer (state = %s)", slot,
- buffers_[slot].mBufferState.string());
- return BAD_VALUE;
- } else if (!buffers_[slot].mRequestBufferCalled) {
- ALOGE("detachBuffer: buffer in slot %zu has not been requested", slot);
- return BAD_VALUE;
- }
- std::shared_ptr<ProducerBuffer> producer_buffer = queue_->GetBuffer(slot);
- if (producer_buffer == nullptr || producer_buffer->buffer() == nullptr) {
- ALOGE("detachBuffer: Invalid ProducerBuffer at slot %zu.", slot);
- return BAD_VALUE;
- }
- sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
- if (graphic_buffer == nullptr) {
- ALOGE("detachBuffer: Invalid GraphicBuffer at slot %zu.", slot);
- return BAD_VALUE;
- }
-
- // Remove the ProducerBuffer from the ProducerQueue.
- status_t error = RemoveBuffer(slot);
- if (error != NO_ERROR) {
- ALOGE("detachBuffer: Failed to remove buffer, slot=%zu, error=%d.", slot, error);
- return error;
- }
-
- // Here we need to convert the existing ProducerBuffer into a DetachedBufferHandle and inject
- // the handle into the GraphicBuffer object at the requested slot.
- auto status_or_handle = producer_buffer->Detach();
- if (!status_or_handle.ok()) {
- ALOGE("detachBuffer: Failed to detach from a ProducerBuffer at slot %zu, error=%d.", slot,
- status_or_handle.error());
- return BAD_VALUE;
- }
-
- // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
- // be directly backed by BufferHub.
- return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) {
- ALOGV("detachNextBuffer.");
-
- if (out_buffer == nullptr || out_fence == nullptr) {
- ALOGE("detachNextBuffer: Invalid parameter: out_buffer=%p, out_fence=%p", out_buffer,
- out_fence);
- return BAD_VALUE;
- }
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("detachNextBuffer: BufferHubProducer is not connected.");
- return NO_INIT;
- }
-
- // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, and detachBuffer in
- // sequence, except for two things:
- //
- // 1) It is unnecessary to know the dimensions, format, or usage of the next buffer, i.e. the
- // function just returns whatever ProducerBuffer is available from the ProducerQueue and no
- // buffer allocation or re-allocation will happen.
- // 2) It will not block, since if it cannot find an appropriate buffer to return, it will return
- // an error instead.
- size_t slot = 0;
- LocalHandle fence;
-
- // First, dequeue a ProducerBuffer from the ProducerQueue with no timeout. Report error
- // immediately if ProducerQueue::Dequeue() fails.
- auto status_or_buffer = queue_->Dequeue(/*timeout=*/0, &slot, &fence);
- if (!status_or_buffer.ok()) {
- ALOGE("detachNextBuffer: Failed to dequeue buffer, error=%d.", status_or_buffer.error());
- return NO_MEMORY;
- }
-
- std::shared_ptr<ProducerBuffer> producer_buffer = status_or_buffer.take();
- if (producer_buffer == nullptr) {
- ALOGE("detachNextBuffer: Dequeued buffer is null.");
- return NO_MEMORY;
- }
-
- // With the BufferHub backed solution, slot returned from |queue_->Dequeue| is guaranteed to
- // be available for producer's use. It's either in free state (if the buffer has never been used
- // before) or in queued state (if the buffer has been dequeued and queued back to
- // BufferHubQueue).
- if (!buffers_[slot].mBufferState.isFree() && !buffers_[slot].mBufferState.isQueued()) {
- ALOGE("detachNextBuffer: slot %zu is not free or queued, actual state: %s.", slot,
- buffers_[slot].mBufferState.string());
- return BAD_VALUE;
- }
- if (buffers_[slot].mProducerBuffer == nullptr) {
- ALOGE("detachNextBuffer: ProducerBuffer at slot %zu is null.", slot);
- return BAD_VALUE;
- }
- if (buffers_[slot].mProducerBuffer->id() != producer_buffer->id()) {
- ALOGE("detachNextBuffer: ProducerBuffer at slot %zu has mismatched id, actual: "
- "%d, expected: %d.",
- slot, buffers_[slot].mProducerBuffer->id(), producer_buffer->id());
- return BAD_VALUE;
- }
-
- ALOGV("detachNextBuffer: slot=%zu", slot);
- buffers_[slot].mBufferState.freeQueued();
- buffers_[slot].mBufferState.dequeue();
-
- // Second, request the buffer.
- sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
- buffers_[slot].mGraphicBuffer = producer_buffer->buffer()->buffer();
-
- // Finally, detach the buffer and then return.
- status_t error = DetachBufferLocked(slot);
- if (error == NO_ERROR) {
- *out_fence = new Fence(fence.Release());
- *out_buffer = graphic_buffer;
- }
- return error;
-}
-
-status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) {
- // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only
- // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer.
- ALOGV("queueBuffer: buffer=%p", buffer.get());
-
- if (out_slot == nullptr) {
- ALOGE("attachBuffer: out_slot cannot be NULL.");
- return BAD_VALUE;
- }
- if (buffer == nullptr) {
- ALOGE("attachBuffer: invalid GraphicBuffer.");
- return BAD_VALUE;
- }
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("attachBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- // Before attaching the buffer, caller is supposed to call
- // IGraphicBufferProducer::setGenerationNumber to inform the
- // BufferHubProducer the next generation number.
- if (buffer->getGenerationNumber() != generation_number_) {
- ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.",
- buffer->getGenerationNumber(), generation_number_);
- return BAD_VALUE;
- }
-
- // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can
- // be directly backed by BufferHub.
- return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input,
- QueueBufferOutput* output) {
- ALOGV("queueBuffer: slot %d", slot);
-
- if (output == nullptr) {
- return BAD_VALUE;
- }
-
- int64_t timestamp;
- bool is_auto_timestamp;
- android_dataspace dataspace;
- Rect crop(Rect::EMPTY_RECT);
- int scaling_mode;
- uint32_t transform;
- sp<Fence> fence;
-
- input.deflate(×tamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform,
- &fence);
-
- // Check input scaling mode is valid.
- switch (scaling_mode) {
- case NATIVE_WINDOW_SCALING_MODE_FREEZE:
- case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
- case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
- case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP:
- break;
- default:
- ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode);
- return BAD_VALUE;
- }
-
- // Check input fence is valid.
- if (fence == nullptr) {
- ALOGE("queueBuffer: fence is NULL");
- return BAD_VALUE;
- }
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("queueBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= max_buffer_count_) {
- ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
- return BAD_VALUE;
- } else if (!buffers_[slot].mBufferState.isDequeued()) {
- ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot,
- buffers_[slot].mBufferState.string());
- return BAD_VALUE;
- } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) {
- ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, "
- "mGraphicBuffer=%p)",
- slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get());
- return BAD_VALUE;
- }
-
- // Post the producer buffer with timestamp in the metadata.
- const auto& producer_buffer = buffers_[slot].mProducerBuffer;
-
- // Check input crop is not out of boundary of current buffer.
- Rect buffer_rect(producer_buffer->width(), producer_buffer->height());
- Rect cropped_rect(Rect::EMPTY_RECT);
- crop.intersect(buffer_rect, &cropped_rect);
- if (cropped_rect != crop) {
- ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot);
- return BAD_VALUE;
- }
-
- LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1);
-
- DvrNativeBufferMetadata meta_data;
- meta_data.timestamp = timestamp;
- meta_data.is_auto_timestamp = int32_t(is_auto_timestamp);
- meta_data.dataspace = int32_t(dataspace);
- meta_data.crop_left = crop.left;
- meta_data.crop_top = crop.top;
- meta_data.crop_right = crop.right;
- meta_data.crop_bottom = crop.bottom;
- meta_data.scaling_mode = int32_t(scaling_mode);
- meta_data.transform = int32_t(transform);
-
- producer_buffer->PostAsync(&meta_data, fence_fd);
- buffers_[slot].mBufferState.queue();
-
- output->width = producer_buffer->width();
- output->height = producer_buffer->height();
- output->transformHint = 0; // default value, we don't use it yet.
-
- // |numPendingBuffers| counts of the number of buffers that has been enqueued
- // by the producer but not yet acquired by the consumer. Due to the nature
- // of BufferHubQueue design, this is hard to trace from the producer's client
- // side, but it's safe to assume it's zero.
- output->numPendingBuffers = 0;
-
- // Note that we are not setting nextFrameNumber here as it seems to be only
- // used by surface flinger. See more at b/22802885, ag/791760.
- output->nextFrameNumber = 0;
-
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
- ALOGV(__FUNCTION__);
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ == kNoConnectedApi) {
- ALOGE("cancelBuffer: BufferQueue has no connected producer");
- return NO_INIT;
- }
-
- if (slot < 0 || slot >= max_buffer_count_) {
- ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_);
- return BAD_VALUE;
- } else if (!buffers_[slot].mBufferState.isDequeued()) {
- ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot,
- buffers_[slot].mBufferState.string());
- return BAD_VALUE;
- } else if (fence == nullptr) {
- ALOGE("cancelBuffer: fence is NULL");
- return BAD_VALUE;
- }
-
- auto producer_buffer = buffers_[slot].mProducerBuffer;
- queue_->Enqueue(producer_buffer, size_t(slot), 0U);
- buffers_[slot].mBufferState.cancel();
- buffers_[slot].mFence = fence;
- ALOGV("cancelBuffer: slot %d", slot);
-
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::query(int what, int* out_value) {
- ALOGV(__FUNCTION__);
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (out_value == nullptr) {
- ALOGE("query: out_value was NULL");
- return BAD_VALUE;
- }
-
- int value = 0;
- switch (what) {
- case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
- // TODO(b/36187402) This should be the maximum number of buffers that this
- // producer queue's consumer can acquire. Set to be at least one. Need to
- // find a way to set from the consumer side.
- value = kDefaultUndequeuedBuffers;
- break;
- case NATIVE_WINDOW_BUFFER_AGE:
- value = 0;
- break;
- case NATIVE_WINDOW_WIDTH:
- value = int32_t(queue_->default_width());
- break;
- case NATIVE_WINDOW_HEIGHT:
- value = int32_t(queue_->default_height());
- break;
- case NATIVE_WINDOW_FORMAT:
- value = int32_t(queue_->default_format());
- break;
- case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
- // BufferHubQueue is always operating in async mode, thus semantically
- // consumer can never be running behind. See BufferQueueCore.cpp core
- // for more information about the original meaning of this flag.
- value = 0;
- break;
- case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
- // TODO(jwcai) This is currently not implement as we don't need
- // IGraphicBufferConsumer parity.
- value = 0;
- break;
- case NATIVE_WINDOW_DEFAULT_DATASPACE:
- // TODO(jwcai) Return the default value android::BufferQueue is using as
- // there is no way dvr::ConsumerQueue can set it.
- value = 0; // HAL_DATASPACE_UNKNOWN
- break;
- case NATIVE_WINDOW_STICKY_TRANSFORM:
- // TODO(jwcai) Return the default value android::BufferQueue is using as
- // there is no way dvr::ConsumerQueue can set it.
- value = 0;
- break;
- case NATIVE_WINDOW_CONSUMER_IS_PROTECTED:
- // In Daydream's implementation, the consumer end (i.e. VR Compostior)
- // knows how to handle protected buffers.
- value = 1;
- break;
- default:
- return BAD_VALUE;
- }
-
- ALOGV("query: key=%d, v=%d", what, value);
- *out_value = value;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api,
- bool /* producer_controlled_by_app */,
- QueueBufferOutput* output) {
- // Consumer interaction are actually handled by buffer hub, and we need
- // to maintain consumer operations here. We only need to perform basic input
- // parameter checks here.
- ALOGV(__FUNCTION__);
-
- if (output == nullptr) {
- return BAD_VALUE;
- }
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (connected_api_ != kNoConnectedApi) {
- return BAD_VALUE;
- }
-
- if (!queue_->is_connected()) {
- ALOGE("BufferHubProducer::connect: This BufferHubProducer is not "
- "connected to bufferhud. Has it been taken out as a parcelable?");
- return BAD_VALUE;
- }
-
- switch (api) {
- case NATIVE_WINDOW_API_EGL:
- case NATIVE_WINDOW_API_CPU:
- case NATIVE_WINDOW_API_MEDIA:
- case NATIVE_WINDOW_API_CAMERA:
- connected_api_ = api;
-
- output->width = queue_->default_width();
- output->height = queue_->default_height();
-
- // default values, we don't use them yet.
- output->transformHint = 0;
- output->numPendingBuffers = 0;
- output->nextFrameNumber = 0;
- output->bufferReplaced = false;
-
- break;
- default:
- ALOGE("BufferHubProducer::connect: unknow API %d", api);
- return BAD_VALUE;
- }
-
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) {
- // Consumer interaction are actually handled by buffer hub, and we need
- // to maintain consumer operations here. We only need to perform basic input
- // parameter checks here.
- ALOGV(__FUNCTION__);
-
- std::unique_lock<std::mutex> lock(mutex_);
-
- if (kNoConnectedApi == connected_api_) {
- return NO_INIT;
- } else if (api != connected_api_) {
- return BAD_VALUE;
- }
-
- FreeAllBuffers();
- connected_api_ = kNoConnectedApi;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) {
- if (stream != nullptr) {
- // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's
- // metadata.
- ALOGE("SidebandStream is not currently supported.");
- return INVALID_OPERATION;
- }
- return NO_ERROR;
-}
-
-void BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */,
- PixelFormat /* format */, uint64_t /* usage */) {
- // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number
- // of buffers permitted by the current BufferQueue configuration (aka
- // |max_buffer_count_|).
- ALOGE("BufferHubProducer::allocateBuffers not implemented.");
-}
-
-status_t BufferHubProducer::allowAllocation(bool /* allow */) {
- ALOGE("BufferHubProducer::allowAllocation not implemented.");
- return INVALID_OPERATION;
-}
-
-status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) {
- ALOGV(__FUNCTION__);
-
- std::unique_lock<std::mutex> lock(mutex_);
- generation_number_ = generation_number;
- return NO_ERROR;
-}
-
-String8 BufferHubProducer::getConsumerName() const {
- // BufferHub based implementation could have one to many producer/consumer
- // relationship, thus |getConsumerName| from the producer side does not
- // make any sense.
- ALOGE("BufferHubProducer::getConsumerName not supported.");
- return String8("BufferHubQueue::StubConsumer");
-}
-
-status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) {
- if (shared_buffer_mode) {
- ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported.");
- // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow.
- return INVALID_OPERATION;
- }
- // Setting to default should just work as a no-op.
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) {
- if (auto_refresh) {
- ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported.");
- return INVALID_OPERATION;
- }
- // Setting to default should just work as a no-op.
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) {
- ALOGV(__FUNCTION__);
-
- std::unique_lock<std::mutex> lock(mutex_);
- dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000));
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */,
- sp<Fence>* /* out_fence */,
- float /*out_transform_matrix*/[16]) {
- ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented.");
- return INVALID_OPERATION;
-}
-
-void BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) {
- ALOGE("BufferHubProducer::getFrameTimestamps not implemented.");
-}
-
-status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const {
- ALOGV(__FUNCTION__);
-
- *out_id = unique_id_;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const {
- ALOGV(__FUNCTION__);
-
- // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
- *out_usage = 0;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) {
- if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE;
-
- if (connected_api_ != kNoConnectedApi) {
- ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has "
- "connected client. Must disconnect first.");
- return BAD_VALUE;
- }
-
- if (!queue_->is_connected()) {
- ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer "
- "is not connected to bufferhud. Has it been taken out as a "
- "parcelable?");
- return BAD_VALUE;
- }
-
- auto status = queue_->TakeAsParcelable();
- if (!status) {
- ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out "
- "ProducuerQueueParcelable from the producer queue, error: %s.",
- status.GetErrorMessage().c_str());
- return BAD_VALUE;
- }
-
- *out_parcelable = status.take();
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
- PixelFormat format, uint64_t usage) {
- auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage);
- if (!status) {
- ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s",
- status.GetErrorMessage().c_str());
- return NO_MEMORY;
- }
-
- size_t slot = status.get();
- auto producer_buffer = queue_->GetBuffer(slot);
-
- LOG_ALWAYS_FATAL_IF(producer_buffer == nullptr,
- "Failed to get the producer buffer at slot: %zu", slot);
-
- buffers_[slot].mProducerBuffer = producer_buffer;
-
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::RemoveBuffer(size_t slot) {
- auto status = queue_->RemoveBuffer(slot);
- if (!status) {
- ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer at slot: %zu, error: %s.",
- slot, status.GetErrorMessage().c_str());
- return INVALID_OPERATION;
- }
-
- // Reset in memory objects related the the buffer.
- buffers_[slot].mProducerBuffer = nullptr;
- buffers_[slot].mBufferState.detachProducer();
- buffers_[slot].mFence = Fence::NO_FENCE;
- buffers_[slot].mGraphicBuffer = nullptr;
- buffers_[slot].mRequestBufferCalled = false;
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::FreeAllBuffers() {
- for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
- // Reset in memory objects related the the buffer.
- buffers_[slot].mProducerBuffer = nullptr;
- buffers_[slot].mBufferState.reset();
- buffers_[slot].mFence = Fence::NO_FENCE;
- buffers_[slot].mGraphicBuffer = nullptr;
- buffers_[slot].mRequestBufferCalled = false;
- }
-
- auto status = queue_->FreeAllBuffers();
- if (!status) {
- ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on "
- "the queue: %s",
- status.GetErrorMessage().c_str());
- }
-
- if (queue_->capacity() != 0 || queue_->count() != 0) {
- LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed.");
- }
-
- return NO_ERROR;
-}
-
-status_t BufferHubProducer::exportToParcel(Parcel* parcel) {
- status_t res = TakeAsParcelable(&pending_producer_parcelable_);
- if (res != NO_ERROR) return res;
-
- if (!pending_producer_parcelable_.IsValid()) {
- ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object.");
- return BAD_VALUE;
- }
-
- res = parcel->writeUint32(USE_BUFFER_HUB);
- if (res != NO_ERROR) {
- ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res);
- return res;
- }
-
- return pending_producer_parcelable_.writeToParcel(parcel);
-}
-
-IBinder* BufferHubProducer::onAsBinder() {
- ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder "
- "object.");
- return nullptr;
-}
-
-} // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c1d92a2..66cad03 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -18,11 +18,6 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubConsumer.h>
-#include <gui/BufferHubProducer.h>
-#endif
-
#include <gui/BufferQueue.h>
#include <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
@@ -127,32 +122,4 @@
*outConsumer = consumer;
}
-#ifndef NO_BUFFERHUB
-void BufferQueue::createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
- sp<IGraphicBufferConsumer>* outConsumer) {
- LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL");
- LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL");
-
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
-
- dvr::ProducerQueueConfigBuilder configBuilder;
- std::shared_ptr<dvr::ProducerQueue> producerQueue =
- dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{});
- LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue.");
-
- std::shared_ptr<dvr::ConsumerQueue> consumerQueue = producerQueue->CreateConsumerQueue();
- LOG_ALWAYS_FATAL_IF(consumerQueue == nullptr, "BufferQueue: failed to create ConsumerQueue.");
-
- producer = BufferHubProducer::Create(producerQueue);
- consumer = BufferHubConsumer::Create(consumerQueue);
-
- LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer");
- LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer");
-
- *outProducer = producer;
- *outConsumer = consumer;
-}
-#endif
-
}; // namespace android
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 797069c..918ff2d 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -27,10 +27,6 @@
#include <binder/Parcel.h>
#include <binder/IInterface.h>
-#ifndef NO_BUFFERHUB
-#include <gui/BufferHubProducer.h>
-#endif
-
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
#include <gui/BufferQueueDefs.h>
@@ -1012,17 +1008,7 @@
}
case USE_BUFFER_HUB: {
ALOGE("createFromParcel: BufferHub not implemented.");
-#ifndef NO_BUFFERHUB
- dvr::ProducerQueueParcelable producerParcelable;
- res = producerParcelable.readFromParcel(parcel);
- if (res != NO_ERROR) {
- ALOGE("createFromParcel: Failed to read from parcel, error=%d", res);
- return nullptr;
- }
- return BufferHubProducer::Create(std::move(producerParcelable));
-#else
return nullptr;
-#endif
}
default: {
ALOGE("createFromParcel: Unexpected mgaic: 0x%x.", outMagic);
diff --git a/libs/gui/include/gui/BufferHubConsumer.h b/libs/gui/include/gui/BufferHubConsumer.h
deleted file mode 100644
index d380770..0000000
--- a/libs/gui/include/gui/BufferHubConsumer.h
+++ /dev/null
@@ -1,112 +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.
- */
-
-#ifndef ANDROID_GUI_BUFFERHUBCONSUMER_H_
-#define ANDROID_GUI_BUFFERHUBCONSUMER_H_
-
-#include <gui/IGraphicBufferConsumer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubConsumer : public IGraphicBufferConsumer {
-public:
- // Creates a BufferHubConsumer instance by importing an existing producer queue.
- static sp<BufferHubConsumer> Create(const std::shared_ptr<dvr::ConsumerQueue>& queue);
-
- // Creates a BufferHubConsumer instance by importing an existing producer
- // parcelable. Note that this call takes the ownership of the parcelable
- // object and is guaranteed to succeed if parcelable object is valid.
- static sp<BufferHubConsumer> Create(dvr::ConsumerQueueParcelable parcelable);
-
- // See |IGraphicBufferConsumer::acquireBuffer|
- status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen,
- uint64_t maxFrameNumber = 0) override;
-
- // See |IGraphicBufferConsumer::detachBuffer|
- status_t detachBuffer(int slot) override;
-
- // See |IGraphicBufferConsumer::attachBuffer|
- status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override;
-
- // See |IGraphicBufferConsumer::releaseBuffer|
- status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence,
- const sp<Fence>& releaseFence) override;
-
- // See |IGraphicBufferConsumer::consumerConnect|
- status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override;
-
- // See |IGraphicBufferConsumer::consumerDisconnect|
- status_t consumerDisconnect() override;
-
- // See |IGraphicBufferConsumer::getReleasedBuffers|
- status_t getReleasedBuffers(uint64_t* slotMask) override;
-
- // See |IGraphicBufferConsumer::setDefaultBufferSize|
- status_t setDefaultBufferSize(uint32_t w, uint32_t h) override;
-
- // See |IGraphicBufferConsumer::setMaxBufferCount|
- status_t setMaxBufferCount(int bufferCount) override;
-
- // See |IGraphicBufferConsumer::setMaxAcquiredBufferCount|
- status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override;
-
- // See |IGraphicBufferConsumer::setConsumerName|
- status_t setConsumerName(const String8& name) override;
-
- // See |IGraphicBufferConsumer::setDefaultBufferFormat|
- status_t setDefaultBufferFormat(PixelFormat defaultFormat) override;
-
- // See |IGraphicBufferConsumer::setDefaultBufferDataSpace|
- status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override;
-
- // See |IGraphicBufferConsumer::setConsumerUsageBits|
- status_t setConsumerUsageBits(uint64_t usage) override;
-
- // See |IGraphicBufferConsumer::setConsumerIsProtected|
- status_t setConsumerIsProtected(bool isProtected) override;
-
- // See |IGraphicBufferConsumer::setTransformHint|
- status_t setTransformHint(uint32_t hint) override;
-
- // See |IGraphicBufferConsumer::getSidebandStream|
- status_t getSidebandStream(sp<NativeHandle>* outStream) const override;
-
- // See |IGraphicBufferConsumer::getOccupancyHistory|
- status_t getOccupancyHistory(bool forceFlush,
- std::vector<OccupancyTracker::Segment>* outHistory) override;
-
- // See |IGraphicBufferConsumer::discardFreeBuffers|
- status_t discardFreeBuffers() override;
-
- // See |IGraphicBufferConsumer::dumpState|
- status_t dumpState(const String8& prefix, String8* outResult) const override;
-
- // BufferHubConsumer provides its own logic to cast to a binder object.
- IBinder* onAsBinder() override;
-
-private:
- // Private constructor to force use of |Create|.
- BufferHubConsumer() = default;
-
- // Concrete implementation backed by BufferHubBuffer.
- std::shared_ptr<dvr::ConsumerQueue> mQueue;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBCONSUMER_H_
diff --git a/libs/gui/include/gui/BufferHubProducer.h b/libs/gui/include/gui/BufferHubProducer.h
deleted file mode 100644
index 0e925ce..0000000
--- a/libs/gui/include/gui/BufferHubProducer.h
+++ /dev/null
@@ -1,223 +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.
- */
-
-#ifndef ANDROID_GUI_BUFFERHUBPRODUCER_H_
-#define ANDROID_GUI_BUFFERHUBPRODUCER_H_
-
-#include <gui/BufferSlot.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-
-namespace android {
-
-class BufferHubProducer : public IGraphicBufferProducer {
-public:
- static constexpr int kNoConnectedApi = -1;
-
- // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer
- // side logic doesn't limit the number of buffer it can acquire
- // simultaneously. We need a way for consumer logic to configure and enforce
- // that.
- static constexpr int kDefaultUndequeuedBuffers = 1;
-
- // Creates a BufferHubProducer instance by importing an existing prodcuer
- // queue.
- static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer);
-
- // Creates a BufferHubProducer instance by importing an existing prodcuer
- // parcelable. Note that this call takes the ownership of the parcelable
- // object and is guaranteed to succeed if parcelable object is valid.
- static sp<BufferHubProducer> Create(dvr::ProducerQueueParcelable parcelable);
-
- // See |IGraphicBufferProducer::requestBuffer|
- status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override;
-
- // For the BufferHub based implementation. All buffers in the queue are
- // allowed to be dequeued from the consumer side. It call always returns
- // 0 for |NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS| query. Thus setting
- // |max_dequeued_buffers| here can be considered the same as setting queue
- // capacity.
- //
- // See |IGraphicBufferProducer::setMaxDequeuedBufferCount| for more info
- status_t setMaxDequeuedBufferCount(int max_dequeued_buffers) override;
-
- // See |IGraphicBufferProducer::setAsyncMode|
- status_t setAsyncMode(bool async) override;
-
- // See |IGraphicBufferProducer::dequeueBuffer|
- status_t dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height,
- PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
- FrameEventHistoryDelta* outTimestamps) override;
-
- // See |IGraphicBufferProducer::detachBuffer|
- status_t detachBuffer(int slot) override;
-
- // See |IGraphicBufferProducer::detachNextBuffer|
- status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override;
-
- // See |IGraphicBufferProducer::attachBuffer|
- status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override;
-
- // See |IGraphicBufferProducer::queueBuffer|
- status_t queueBuffer(int slot, const QueueBufferInput& input,
- QueueBufferOutput* output) override;
-
- // See |IGraphicBufferProducer::cancelBuffer|
- status_t cancelBuffer(int slot, const sp<Fence>& fence) override;
-
- // See |IGraphicBufferProducer::query|
- status_t query(int what, int* out_value) override;
-
- // See |IGraphicBufferProducer::connect|
- status_t connect(const sp<IProducerListener>& listener, int api,
- bool producer_controlled_by_app, QueueBufferOutput* output) override;
-
- // See |IGraphicBufferProducer::disconnect|
- status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override;
-
- // See |IGraphicBufferProducer::setSidebandStream|
- status_t setSidebandStream(const sp<NativeHandle>& stream) override;
-
- // See |IGraphicBufferProducer::allocateBuffers|
- void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format,
- uint64_t usage) override;
-
- // See |IGraphicBufferProducer::allowAllocation|
- status_t allowAllocation(bool allow) override;
-
- // See |IGraphicBufferProducer::setGenerationNumber|
- status_t setGenerationNumber(uint32_t generation_number) override;
-
- // See |IGraphicBufferProducer::getConsumerName|
- String8 getConsumerName() const override;
-
- // See |IGraphicBufferProducer::setSharedBufferMode|
- status_t setSharedBufferMode(bool shared_buffer_mode) override;
-
- // See |IGraphicBufferProducer::setAutoRefresh|
- status_t setAutoRefresh(bool auto_refresh) override;
-
- // See |IGraphicBufferProducer::setDequeueTimeout|
- status_t setDequeueTimeout(nsecs_t timeout) override;
-
- // See |IGraphicBufferProducer::getLastQueuedBuffer|
- status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence,
- float out_transform_matrix[16]) override;
-
- // See |IGraphicBufferProducer::getFrameTimestamps|
- void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override;
-
- // See |IGraphicBufferProducer::getUniqueId|
- status_t getUniqueId(uint64_t* out_id) const override;
-
- // See |IGraphicBufferProducer::getConsumerUsage|
- status_t getConsumerUsage(uint64_t* out_usage) const override;
-
- // Takes out the current producer as a binder parcelable object. Note that the
- // producer must be disconnected to be exportable. After successful export,
- // the producer queue can no longer be connected again. Returns NO_ERROR when
- // takeout is successful and out_parcelable will hold the new parcelable
- // object. Also note that out_parcelable cannot be NULL and must points to an
- // invalid parcelable.
- status_t TakeAsParcelable(dvr::ProducerQueueParcelable* out_parcelable);
-
- IBinder* onAsBinder() override;
-
-protected:
- // See |IGraphicBufferProducer::exportToParcel|
- status_t exportToParcel(Parcel* parcel) override;
-
-private:
- using LocalHandle = pdx::LocalHandle;
-
- // Private constructor to force use of |Create|.
- BufferHubProducer() {}
-
- static uint64_t genUniqueId() {
- static std::atomic<uint32_t> counter{0};
- static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
- return id | counter++;
- }
-
- // Allocate new buffer through BufferHub and add it into |queue_| for
- // bookkeeping.
- status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
- PixelFormat format, uint64_t usage);
-
- // Remove a buffer via BufferHubRPC.
- status_t RemoveBuffer(size_t slot);
-
- // Free all buffers which are owned by the prodcuer. Note that if graphic
- // buffers are acquired by the consumer, we can't .
- status_t FreeAllBuffers();
-
- // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been
- // locked already.
- status_t DetachBufferLocked(size_t slot);
-
- // Concreate implementation backed by BufferHubBuffer.
- std::shared_ptr<dvr::ProducerQueue> queue_;
-
- // Mutex for thread safety.
- std::mutex mutex_;
-
- // Connect client API, should be one of the NATIVE_WINDOW_API_* flags.
- int connected_api_{kNoConnectedApi};
-
- // |max_buffer_count_| sets the capacity of the underlying buffer queue.
- int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity};
-
- // |max_dequeued_buffer_count_| set the maximum number of buffers that can
- // be dequeued at the same momment.
- int32_t max_dequeued_buffer_count_{1};
-
- // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
- // slot is not yet available. The timeout is stored in milliseconds.
- int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut};
-
- // |generation_number_| stores the current generation number of the attached
- // producer. Any attempt to attach a buffer with a different generation
- // number will fail.
- // TOOD(b/38137191) Currently not used as we don't support
- // IGraphicBufferProducer::detachBuffer.
- uint32_t generation_number_{0};
-
- // |buffers_| stores the buffers that have been dequeued from
- // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets
- // filled in with the result of |Dequeue|.
- // TODO(jwcai) The buffer allocated to a slot will also be replaced if the
- // requested buffer usage or geometry differs from that of the buffer
- // allocated to a slot.
- struct BufferHubSlot : public BufferSlot {
- BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
- // BufferSlot comes from android framework, using m prefix to comply with
- // the name convention with the reset of data fields from BufferSlot.
- std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
- bool mIsReallocating;
- };
- BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
-
- // A uniqueId used by IGraphicBufferProducer interface.
- const uint64_t unique_id_{genUniqueId()};
-
- // A pending parcelable object which keeps the bufferhub channel alive.
- dvr::ProducerQueueParcelable pending_producer_parcelable_;
-};
-
-} // namespace android
-
-#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_
diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h
index 91f80d2..690587f 100644
--- a/libs/gui/include/gui/BufferQueue.h
+++ b/libs/gui/include/gui/BufferQueue.h
@@ -82,12 +82,6 @@
sp<IGraphicBufferConsumer>* outConsumer,
bool consumerIsSurfaceFlinger = false);
-#ifndef NO_BUFFERHUB
- // Creates an IGraphicBufferProducer and IGraphicBufferConsumer pair backed by BufferHub.
- static void createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer,
- sp<IGraphicBufferConsumer>* outConsumer);
-#endif
-
BufferQueue() = delete; // Create through createBufferQueue
};
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index fc68ad2..fa54c7d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -92,39 +92,6 @@
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,
-// as opposed to adding more source files to this one.
-cc_test {
- name: "SurfaceParcelable_test",
- test_suites: ["device-tests"],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- srcs: [
- "SurfaceParcelable_test.cpp",
- ],
-
- shared_libs: [
- "liblog",
- "libbinder",
- "libcutils",
- "libgui",
- "libui",
- "libutils",
- "libbufferhubqueue", // TODO(b/70046255): Remove these once BufferHub is integrated into libgui.
- "libpdx_default_transport",
- ],
-
- header_libs: [
- "libdvr_headers",
- ],
-}
-
cc_test {
name: "SamplingDemo",
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 2af2fe1..3427731 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -42,10 +42,6 @@
#define TEST_CONTROLLED_BY_APP false
#define TEST_PRODUCER_USAGE_BITS (0)
-#ifndef USE_BUFFER_HUB_AS_BUFFER_QUEUE
-#define USE_BUFFER_HUB_AS_BUFFER_QUEUE 0
-#endif
-
namespace android {
namespace {
@@ -77,7 +73,6 @@
// Enums to control which IGraphicBufferProducer backend to test.
enum IGraphicBufferProducerTestCode {
USE_BUFFER_QUEUE_PRODUCER = 0,
- USE_BUFFER_HUB_PRODUCER,
};
}; // namespace anonymous
@@ -99,10 +94,6 @@
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
break;
}
- case USE_BUFFER_HUB_PRODUCER: {
- BufferQueue::createBufferHubQueue(&mProducer, &mConsumer);
- break;
- }
default: {
// Should never reach here.
LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam());
@@ -880,11 +871,6 @@
}
TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) {
- if (GetParam() == USE_BUFFER_HUB_PRODUCER) {
- // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true)
- return;
- }
-
ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1;
ASSERT_NO_FATAL_FAILURE(ConnectProducer());
ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true;
@@ -1117,14 +1103,7 @@
}
}
-#if USE_BUFFER_HUB_AS_BUFFER_QUEUE
-INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
- ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER));
-#else
-// TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can
-// pass all existing libgui tests.
INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest,
::testing::Values(USE_BUFFER_QUEUE_PRODUCER));
-#endif
} // namespace android
diff --git a/libs/gui/tests/SurfaceParcelable_test.cpp b/libs/gui/tests/SurfaceParcelable_test.cpp
deleted file mode 100644
index 686dc82..0000000
--- a/libs/gui/tests/SurfaceParcelable_test.cpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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 "SurfaceParcelable_test"
-
-#include <gtest/gtest.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/BufferQueue.h>
-#include <gui/view/Surface.h>
-#include <utils/Log.h>
-
-namespace android {
-
-static const String16 kTestServiceName = String16("SurfaceParcelableTestService");
-static const String16 kSurfaceName = String16("TEST_SURFACE");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-
-enum SurfaceParcelableTestServiceCode {
- CREATE_BUFFER_QUEUE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_BUFFER_HUB_SURFACE,
-};
-
-class SurfaceParcelableTestService : public BBinder {
-public:
- SurfaceParcelableTestService() {
- // BufferQueue
- BufferQueue::createBufferQueue(&mBufferQueueProducer, &mBufferQueueConsumer);
-
- // BufferHub
- dvr::ProducerQueueConfigBuilder configBuilder;
- mProducerQueue = dvr::ProducerQueue::Create(configBuilder.SetDefaultWidth(kBufferWidth)
- .SetDefaultHeight(kBufferHeight)
- .SetDefaultFormat(kBufferFormat)
- .Build(),
- dvr::UsagePolicy{});
- mBufferHubProducer = BufferHubProducer::Create(mProducerQueue);
- }
-
- ~SurfaceParcelableTestService() = default;
-
- virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply,
- uint32_t /*flags*/ = 0) {
- switch (code) {
- case CREATE_BUFFER_QUEUE_SURFACE: {
- view::Surface surfaceShim;
- surfaceShim.name = kSurfaceName;
- surfaceShim.graphicBufferProducer = mBufferQueueProducer;
- return surfaceShim.writeToParcel(reply);
- }
- case CREATE_BUFFER_HUB_SURFACE: {
- view::Surface surfaceShim;
- surfaceShim.name = kSurfaceName;
- surfaceShim.graphicBufferProducer = mBufferHubProducer;
- return surfaceShim.writeToParcel(reply);
- }
- default:
- return UNKNOWN_TRANSACTION;
- };
- }
-
-protected:
- sp<IGraphicBufferProducer> mBufferQueueProducer;
- sp<IGraphicBufferConsumer> mBufferQueueConsumer;
-
- std::shared_ptr<dvr::ProducerQueue> mProducerQueue;
- sp<IGraphicBufferProducer> mBufferHubProducer;
-};
-
-static int runBinderServer() {
- ProcessState::self()->startThreadPool();
-
- sp<IServiceManager> sm = defaultServiceManager();
- sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService;
- sm->addService(kTestServiceName, service, false);
-
- ALOGI("Binder server running...");
-
- while (true) {
- int stat, retval;
- retval = wait(&stat);
- if (retval == -1 && errno == ECHILD) {
- break;
- }
- }
-
- ALOGI("Binder server exiting...");
- return 0;
-}
-
-class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> {
-protected:
- virtual void SetUp() {
- mService = defaultServiceManager()->getService(kTestServiceName);
- if (mService == nullptr) {
- ALOGE("Failed to connect to the test service.");
- return;
- }
-
- ALOGI("Binder service is ready for client.");
- }
-
- status_t GetSurface(view::Surface* surfaceShim) {
- ALOGI("...Test: %d", GetParam());
-
- uint32_t opCode = GetParam();
- Parcel data;
- Parcel reply;
- status_t error = mService->transact(opCode, data, &reply);
- if (error != NO_ERROR) {
- ALOGE("Failed to get surface over binder, error=%d.", error);
- return error;
- }
-
- error = surfaceShim->readFromParcel(&reply);
- if (error != NO_ERROR) {
- ALOGE("Failed to get surface from parcel, error=%d.", error);
- return error;
- }
-
- return NO_ERROR;
- }
-
-private:
- sp<IBinder> mService;
-};
-
-TEST_P(SurfaceParcelableTest, SendOverBinder) {
- view::Surface surfaceShim;
- EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR);
- EXPECT_EQ(surfaceShim.name, kSurfaceName);
- EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr);
-}
-
-INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest,
- ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE));
-
-} // namespace android
-
-int main(int argc, char** argv) {
- pid_t pid = fork();
- if (pid == 0) {
- android::ProcessState::self()->startThreadPool();
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-
- } else {
- ALOGI("Test process pid: %d.", pid);
- return android::runBinderServer();
- }
-}
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index d7db6bd..cedc522 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -74,6 +74,9 @@
override_export_include_dirs: [
"include",
],
+ export_llndk_headers: [
+ "libarect_headers",
+ ],
},
export_include_dirs: [
"include",
@@ -108,16 +111,14 @@
],
header_libs: [
+ "libarect_headers",
"libnativebase_headers",
"libnativewindow_headers",
],
// headers we include in our public headers
- export_static_lib_headers: [
- "libarect",
- ],
-
export_header_lib_headers: [
+ "libarect_headers",
"libnativebase_headers",
],
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 0f771a9..98d9b94 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -155,6 +155,8 @@
],
defaults: [
+ "android.hardware.graphics.allocator-ndk_shared",
+ "android.hardware.graphics.common-ndk_shared",
"libui-defaults",
// Uncomment the following line to enable VALIDATE_REGIONS traces
//defaults: ["libui-validate-regions-defaults"],
@@ -164,8 +166,6 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.allocator@4.0",
- "android.hardware.graphics.allocator-V1-ndk",
- "android.hardware.graphics.common-V3-ndk",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
@@ -183,7 +183,6 @@
export_shared_lib_headers: [
"android.hardware.graphics.common@1.2",
- "android.hardware.graphics.common-V3-ndk",
"android.hardware.graphics.mapper@4.0",
"libgralloctypes",
],
diff --git a/libs/vibrator/Android.bp b/libs/vibrator/Android.bp
index 83c250a..2af51a7 100644
--- a/libs/vibrator/Android.bp
+++ b/libs/vibrator/Android.bp
@@ -21,31 +21,8 @@
default_applicable_licenses: ["frameworks_native_license"],
}
-cc_library {
- name: "libvibrator",
- vendor_available: true,
- double_loadable: true,
-
- shared_libs: [
- "libbinder",
- "liblog",
- "libutils",
- ],
-
- header_libs: [
- "libaudio_system_headers",
- ],
-
- aidl: {
- include_dirs: ["frameworks/base/core/java"],
- local_include_dirs: ["include/"],
- export_aidl_headers: true,
- },
-
- srcs: [
- ":libvibrator_aidl",
- "*.cpp",
- ],
+cc_defaults {
+ name: "libvibrator_defaults",
cflags: [
"-Wall",
@@ -64,3 +41,54 @@
},
},
}
+
+cc_library {
+ name: "libvibrator",
+ defaults: ["libvibrator_defaults"],
+
+ shared_libs: [
+ "libbinder",
+ "liblog",
+ "libutils",
+ ],
+
+ whole_static_libs: [
+ "libvibratorutils",
+ ],
+
+ header_libs: [
+ "libaudio_system_headers",
+ ],
+
+ aidl: {
+ include_dirs: ["frameworks/base/core/java"],
+ local_include_dirs: ["include/"],
+ export_aidl_headers: true,
+ },
+
+ srcs: [
+ ":libvibrator_aidl",
+ "ExternalVibration.cpp",
+ ],
+}
+
+cc_library {
+ name: "libvibratorutils",
+ defaults: ["libvibrator_defaults"],
+
+ vendor_available: true,
+ double_loadable: true,
+
+ shared_libs: [
+ "libutils",
+ ],
+
+ srcs: [
+ "ExternalVibrationUtils.cpp",
+ ],
+
+ visibility: [
+ "//frameworks/native/libs/vibrator",
+ "//frameworks/av/media/libeffects/hapticgenerator",
+ ],
+}
diff --git a/libs/vibrator/ExternalVibration.cpp b/libs/vibrator/ExternalVibration.cpp
index f6fc19e..ec90645 100644
--- a/libs/vibrator/ExternalVibration.cpp
+++ b/libs/vibrator/ExternalVibration.cpp
@@ -15,11 +15,22 @@
*/
#include <vibrator/ExternalVibration.h>
+#include <vibrator/ExternalVibrationUtils.h>
+#include <android/os/IExternalVibratorService.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <utils/Errors.h>
+
+// To guarantee if HapticScale enum has the same value as IExternalVibratorService
+static_assert(static_cast<int>(android::os::HapticScale::MUTE) == static_cast<int>(android::os::IExternalVibratorService::SCALE_MUTE));
+static_assert(static_cast<int>(android::os::HapticScale::VERY_LOW) == static_cast<int>(android::os::IExternalVibratorService::SCALE_VERY_LOW));
+static_assert(static_cast<int>(android::os::HapticScale::LOW) == static_cast<int>(android::os::IExternalVibratorService::SCALE_LOW));
+static_assert(static_cast<int>(android::os::HapticScale::NONE) == static_cast<int>(android::os::IExternalVibratorService::SCALE_NONE));
+static_assert(static_cast<int>(android::os::HapticScale::HIGH) == static_cast<int>(android::os::IExternalVibratorService::SCALE_HIGH));
+static_assert(static_cast<int>(android::os::HapticScale::VERY_HIGH) == static_cast<int>(android::os::IExternalVibratorService::SCALE_VERY_HIGH));
+
void writeAudioAttributes(const audio_attributes_t& attrs, android::Parcel* out) {
out->writeInt32(attrs.usage);
out->writeInt32(attrs.content_type);
diff --git a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
index 84357fc..c588bfd 100644
--- a/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
+++ b/libs/vibrator/include/vibrator/ExternalVibrationUtils.h
@@ -17,17 +17,17 @@
#ifndef ANDROID_EXTERNAL_VIBRATION_UTILS_H
#define ANDROID_EXTERNAL_VIBRATION_UTILS_H
-#include <android/os/IExternalVibratorService.h>
-
namespace android::os {
+// Copied from frameworks/base/core/java/android/os/IExternalVibratorService.aidl
+// The values are checked in ExternalVibration.cpp
enum class HapticScale {
- MUTE = IExternalVibratorService::SCALE_MUTE,
- VERY_LOW = IExternalVibratorService::SCALE_VERY_LOW,
- LOW = IExternalVibratorService::SCALE_LOW,
- NONE = IExternalVibratorService::SCALE_NONE,
- HIGH = IExternalVibratorService::SCALE_HIGH,
- VERY_HIGH = IExternalVibratorService::SCALE_VERY_HIGH,
+ MUTE = -100,
+ VERY_LOW = -2,
+ LOW = -1,
+ NONE = 0,
+ HIGH = 1,
+ VERY_HIGH = 2,
};
bool isValidHapticScale(HapticScale scale);
diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp
deleted file mode 100644
index e33e03b..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_native_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_benchmark {
- srcs: ["buffer_transport_benchmark.cpp"],
- shared_libs: [
- "libbase",
- "libbinder",
- "libcutils",
- "libdvr.google",
- "libgui",
- "liblog",
- "libhardware",
- "libui",
- "libutils",
- "libnativewindow",
- "libbufferhubqueue",
- "libpdx_default_transport",
- ],
- cflags: [
- "-DLOG_TAG=\"buffer_transport_benchmark\"",
- "-DTRACE=0",
- "-O2",
- "-Wall",
- "-Werror",
- ],
- name: "buffer_transport_benchmark",
-}
diff --git a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
deleted file mode 100644
index b6813eb..0000000
--- a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-#include <android-base/logging.h>
-#include <android/native_window.h>
-#include <benchmark/benchmark.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <dvr/dvr_api.h>
-#include <gui/BufferItem.h>
-#include <gui/BufferItemConsumer.h>
-#include <gui/Surface.h>
-#include <private/dvr/epoll_file_descriptor.h>
-#include <utils/Trace.h>
-
-#include <chrono>
-#include <functional>
-#include <iostream>
-#include <thread>
-#include <vector>
-
-#include <dlfcn.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/wait.h>
-
-// Use ALWAYS at the tag level. Control is performed manually during command
-// line processing.
-#ifdef ATRACE_TAG
-#undef ATRACE_TAG
-#endif
-#define ATRACE_TAG ATRACE_TAG_ALWAYS
-
-using namespace android;
-using ::benchmark::State;
-
-static const String16 kBinderService = String16("bufferTransport");
-static const uint32_t kBufferWidth = 100;
-static const uint32_t kBufferHeight = 1;
-static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-static const uint64_t kBufferUsage =
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-static const uint32_t kBufferLayer = 1;
-static const int kMaxAcquiredImages = 1;
-static const int kQueueDepth = 2; // We are double buffering for this test.
-static const size_t kMaxQueueCounts = 128;
-static const int kInvalidFence = -1;
-
-enum BufferTransportServiceCode {
- CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION,
-};
-
-// A binder services that minics a compositor that consumes buffers. It provides
-// one Binder interface to create a new Surface for buffer producer to write
-// into; while itself will carry out no-op buffer consuming by acquiring then
-// releasing the buffer immediately.
-class BufferTransportService : public BBinder {
- public:
- BufferTransportService() = default;
- ~BufferTransportService() = default;
-
- virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags = 0) {
- (void)flags;
- (void)data;
- switch (code) {
- case CREATE_BUFFER_QUEUE: {
- auto new_queue = std::make_shared<BufferQueueHolder>(this);
- reply->writeStrongBinder(
- IGraphicBufferProducer::asBinder(new_queue->producer));
- buffer_queues_.push_back(new_queue);
- return OK;
- }
- default:
- return UNKNOWN_TRANSACTION;
- };
- }
-
- private:
- struct FrameListener : public ConsumerBase::FrameAvailableListener {
- public:
- FrameListener(BufferTransportService* /*service*/,
- sp<BufferItemConsumer> buffer_item_consumer)
- : buffer_item_consumer_(buffer_item_consumer) {}
-
- void onFrameAvailable(const BufferItem& /*item*/) override {
- BufferItem buffer;
- status_t ret = 0;
- {
- ATRACE_NAME("AcquireBuffer");
- ret = buffer_item_consumer_->acquireBuffer(&buffer, /*presentWhen=*/0,
- /*waitForFence=*/false);
- }
-
- if (ret != OK) {
- LOG(ERROR) << "Failed to acquire next buffer.";
- return;
- }
-
- {
- ATRACE_NAME("ReleaseBuffer");
- ret = buffer_item_consumer_->releaseBuffer(buffer);
- }
-
- if (ret != OK) {
- LOG(ERROR) << "Failed to release buffer.";
- return;
- }
- }
-
- private:
- sp<BufferItemConsumer> buffer_item_consumer_;
- };
-
- struct BufferQueueHolder {
- explicit BufferQueueHolder(BufferTransportService* service) {
- BufferQueue::createBufferQueue(&producer, &consumer);
-
- sp<BufferItemConsumer> buffer_item_consumer =
- new BufferItemConsumer(consumer, kBufferUsage, kMaxAcquiredImages,
- /*controlledByApp=*/true);
- buffer_item_consumer->setName(String8("BinderBufferTransport"));
- frame_listener_ = new FrameListener(service, buffer_item_consumer);
- buffer_item_consumer->setFrameAvailableListener(frame_listener_);
- }
-
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
-
- private:
- sp<FrameListener> frame_listener_;
- };
-
- std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-// A virtual interfaces that abstracts the common BufferQueue operations, so
-// that the test suite can use the same test case to drive different types of
-// transport backends.
-class BufferTransport {
- public:
- virtual ~BufferTransport() {}
-
- virtual int Start() = 0;
- virtual sp<Surface> CreateSurface() = 0;
-};
-
-// Binder-based buffer transport backend.
-//
-// On Start() a new process will be swapned to run a Binder server that
-// actually consumes the buffer.
-// On CreateSurface() a new Binder BufferQueue will be created, which the
-// service holds the concrete binder node of the IGraphicBufferProducer while
-// sending the binder proxy to the client. In another word, the producer side
-// operations are carried out process while the consumer side operations are
-// carried out within the BufferTransportService's own process.
-class BinderBufferTransport : public BufferTransport {
- public:
- BinderBufferTransport() {}
-
- int Start() override {
- sp<IServiceManager> sm = defaultServiceManager();
- service_ = sm->getService(kBinderService);
- if (service_ == nullptr) {
- LOG(ERROR) << "Failed to get the benchmark service.";
- return -EIO;
- }
-
- LOG(INFO) << "Binder server is ready for client.";
- return 0;
- }
-
- sp<Surface> CreateSurface() override {
- Parcel data;
- Parcel reply;
- int error = service_->transact(CREATE_BUFFER_QUEUE, data, &reply);
- if (error != OK) {
- LOG(ERROR) << "Failed to get buffer queue over binder.";
- return nullptr;
- }
-
- sp<IBinder> binder;
- error = reply.readNullableStrongBinder(&binder);
- if (error != OK) {
- LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
- return nullptr;
- }
-
- auto producer = interface_cast<IGraphicBufferProducer>(binder);
- if (producer == nullptr) {
- LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder.";
- return nullptr;
- }
-
- sp<Surface> surface = new Surface(producer, /*controlledByApp=*/true);
-
- // Set buffer dimension.
- ANativeWindow* window = static_cast<ANativeWindow*>(surface.get());
- ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight,
- kBufferFormat);
-
- return surface;
- }
-
- private:
- sp<IBinder> service_;
-};
-
-class DvrApi {
- public:
- DvrApi() {
- handle_ = dlopen("libdvr.google.so", RTLD_NOW | RTLD_LOCAL);
- CHECK(handle_);
-
- auto dvr_get_api =
- reinterpret_cast<decltype(&dvrGetApi)>(dlsym(handle_, "dvrGetApi"));
- int ret = dvr_get_api(&api_, sizeof(api_), /*version=*/1);
-
- CHECK(ret == 0);
- }
-
- ~DvrApi() { dlclose(handle_); }
-
- const DvrApi_v1& Api() { return api_; }
-
- private:
- void* handle_ = nullptr;
- DvrApi_v1 api_;
-};
-
-// BufferHub/PDX-based buffer transport.
-//
-// On Start() a new thread will be swapned to run an epoll polling thread which
-// minics the behavior of a compositor. Similar to Binder-based backend, the
-// buffer available handler is also a no-op: Buffer gets acquired and released
-// immediately.
-// On CreateSurface() a pair of dvr::ProducerQueue and dvr::ConsumerQueue will
-// be created. The epoll thread holds on the consumer queue and dequeues buffer
-// from it; while the producer queue will be wrapped in a Surface and returned
-// to test suite.
-class BufferHubTransport : public BufferTransport {
- public:
- virtual ~BufferHubTransport() {
- stopped_.store(true);
- if (reader_thread_.joinable()) {
- reader_thread_.join();
- }
- }
-
- int Start() override {
- int ret = epoll_fd_.Create();
- if (ret < 0) {
- LOG(ERROR) << "Failed to create epoll fd: %s", strerror(-ret);
- return -1;
- }
-
- // Create the reader thread.
- reader_thread_ = std::thread([this]() {
- int ret = dvr_.Api().PerformanceSetSchedulerPolicy(0, "graphics");
- if (ret < 0) {
- LOG(ERROR) << "Failed to set scheduler policy, ret=" << ret;
- return;
- }
-
- stopped_.store(false);
- LOG(INFO) << "Reader Thread Running...";
-
- while (!stopped_.load()) {
- std::array<epoll_event, kMaxQueueCounts> events;
-
- // Don't sleep forever so that we will have a chance to wake up.
- const int ret = epoll_fd_.Wait(events.data(), events.size(),
- /*timeout=*/100);
- if (ret < 0) {
- LOG(ERROR) << "Error polling consumer queues.";
- continue;
- }
- if (ret == 0) {
- continue;
- }
-
- const int num_events = ret;
- for (int i = 0; i < num_events; i++) {
- uint32_t index = events[i].data.u32;
- dvr_.Api().ReadBufferQueueHandleEvents(
- buffer_queues_[index]->GetReadQueue());
- }
- }
-
- LOG(INFO) << "Reader Thread Exiting...";
- });
-
- return 0;
- }
-
- sp<Surface> CreateSurface() override {
- auto new_queue = std::make_shared<BufferQueueHolder>();
- if (!new_queue->IsReady()) {
- LOG(ERROR) << "Failed to create BufferHub-based BufferQueue.";
- return nullptr;
- }
-
- // Set buffer dimension.
- ANativeWindow_setBuffersGeometry(new_queue->GetSurface(), kBufferWidth,
- kBufferHeight, kBufferFormat);
-
- // Use the next position as buffer_queue index.
- uint32_t index = buffer_queues_.size();
- epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u32 = index}};
- int queue_fd =
- dvr_.Api().ReadBufferQueueGetEventFd(new_queue->GetReadQueue());
- const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, queue_fd, &event);
- if (ret < 0) {
- LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret)
- << ", consumer queue fd: " << queue_fd;
- return nullptr;
- }
-
- buffer_queues_.push_back(new_queue);
- ANativeWindow_acquire(new_queue->GetSurface());
- return static_cast<Surface*>(new_queue->GetSurface());
- }
-
- private:
- struct BufferQueueHolder {
- BufferQueueHolder() {
- int ret = 0;
- ret = dvr_.Api().WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferLayer,
- kBufferUsage, 0, sizeof(DvrNativeBufferMetadata), &write_queue_);
- if (ret < 0) {
- LOG(ERROR) << "Failed to create write buffer queue, ret=" << ret;
- return;
- }
-
- ret = dvr_.Api().WriteBufferQueueCreateReadQueue(write_queue_,
- &read_queue_);
- if (ret < 0) {
- LOG(ERROR) << "Failed to create read buffer queue, ret=" << ret;
- return;
- }
-
- ret = dvr_.Api().ReadBufferQueueSetBufferAvailableCallback(
- read_queue_, BufferAvailableCallback, this);
- if (ret < 0) {
- LOG(ERROR) << "Failed to create buffer available callback, ret=" << ret;
- return;
- }
-
- ret =
- dvr_.Api().WriteBufferQueueGetANativeWindow(write_queue_, &surface_);
- if (ret < 0) {
- LOG(ERROR) << "Failed to create surface, ret=" << ret;
- return;
- }
- }
-
- static void BufferAvailableCallback(void* context) {
- BufferQueueHolder* thiz = static_cast<BufferQueueHolder*>(context);
- thiz->HandleBufferAvailable();
- }
-
- DvrReadBufferQueue* GetReadQueue() { return read_queue_; }
-
- ANativeWindow* GetSurface() { return surface_; }
-
- bool IsReady() {
- return write_queue_ != nullptr && read_queue_ != nullptr &&
- surface_ != nullptr;
- }
-
- void HandleBufferAvailable() {
- int ret = 0;
- DvrNativeBufferMetadata meta;
- DvrReadBuffer* buffer = nullptr;
- DvrNativeBufferMetadata metadata;
- int acquire_fence = kInvalidFence;
-
- {
- ATRACE_NAME("AcquireBuffer");
- ret = dvr_.Api().ReadBufferQueueAcquireBuffer(
- read_queue_, 0, &buffer, &metadata, &acquire_fence);
- }
- if (ret < 0) {
- LOG(ERROR) << "Failed to acquire consumer buffer, error: " << ret;
- return;
- }
-
- if (buffer != nullptr) {
- ATRACE_NAME("ReleaseBuffer");
- ret = dvr_.Api().ReadBufferQueueReleaseBuffer(read_queue_, buffer,
- &meta, kInvalidFence);
- }
- if (ret < 0) {
- LOG(ERROR) << "Failed to release consumer buffer, error: " << ret;
- }
- }
-
- private:
- DvrWriteBufferQueue* write_queue_ = nullptr;
- DvrReadBufferQueue* read_queue_ = nullptr;
- ANativeWindow* surface_ = nullptr;
- };
-
- static DvrApi dvr_;
- std::atomic<bool> stopped_;
- std::thread reader_thread_;
-
- dvr::EpollFileDescriptor epoll_fd_;
- std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_;
-};
-
-DvrApi BufferHubTransport::dvr_ = {};
-
-enum TransportType {
- kBinderBufferTransport,
- kBufferHubTransport,
-};
-
-// Main test suite, which supports two transport backend: 1) BinderBufferQueue,
-// 2) BufferHubQueue. The test case drives the producer end of both transport
-// backend by queuing buffers into the buffer queue by using ANativeWindow API.
-class BufferTransportBenchmark : public ::benchmark::Fixture {
- public:
- void SetUp(State& state) override {
- if (state.thread_index == 0) {
- const int transport = state.range(0);
- switch (transport) {
- case kBinderBufferTransport:
- transport_.reset(new BinderBufferTransport);
- break;
- case kBufferHubTransport:
- transport_.reset(new BufferHubTransport);
- break;
- default:
- CHECK(false) << "Unknown test case.";
- break;
- }
-
- CHECK(transport_);
- const int ret = transport_->Start();
- CHECK_EQ(ret, 0);
-
- LOG(INFO) << "Transport backend running, transport=" << transport << ".";
-
- // Create surfaces for each thread.
- surfaces_.resize(state.threads);
- for (int i = 0; i < state.threads; i++) {
- // Common setup every thread needs.
- surfaces_[i] = transport_->CreateSurface();
- CHECK(surfaces_[i]);
-
- LOG(INFO) << "Surface initialized on thread " << i << ".";
- }
- }
- }
-
- void TearDown(State& state) override {
- if (state.thread_index == 0) {
- surfaces_.clear();
- transport_.reset();
- LOG(INFO) << "Tear down benchmark.";
- }
- }
-
- protected:
- std::unique_ptr<BufferTransport> transport_;
- std::vector<sp<Surface>> surfaces_;
-};
-
-BENCHMARK_DEFINE_F(BufferTransportBenchmark, Producers)(State& state) {
- ANativeWindow* window = nullptr;
- ANativeWindow_Buffer buffer;
- int32_t error = 0;
- double total_gain_buffer_us = 0;
- double total_post_buffer_us = 0;
- int iterations = 0;
-
- while (state.KeepRunning()) {
- if (window == nullptr) {
- CHECK(surfaces_[state.thread_index]);
- window = static_cast<ANativeWindow*>(surfaces_[state.thread_index].get());
-
- // Lock buffers a couple time from the queue, so that we have the buffer
- // allocated.
- for (int i = 0; i < kQueueDepth; i++) {
- error = ANativeWindow_lock(window, &buffer,
- /*inOutDirtyBounds=*/nullptr);
- CHECK_EQ(error, 0);
- error = ANativeWindow_unlockAndPost(window);
- CHECK_EQ(error, 0);
- }
- }
-
- {
- ATRACE_NAME("GainBuffer");
- auto t1 = std::chrono::high_resolution_clock::now();
- error = ANativeWindow_lock(window, &buffer,
- /*inOutDirtyBounds=*/nullptr);
- auto t2 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::micro> delta_us = t2 - t1;
- total_gain_buffer_us += delta_us.count();
- }
- CHECK_EQ(error, 0);
-
- {
- ATRACE_NAME("PostBuffer");
- auto t1 = std::chrono::high_resolution_clock::now();
- error = ANativeWindow_unlockAndPost(window);
- auto t2 = std::chrono::high_resolution_clock::now();
- std::chrono::duration<double, std::micro> delta_us = t2 - t1;
- total_post_buffer_us += delta_us.count();
- }
- CHECK_EQ(error, 0);
-
- iterations++;
- }
-
- state.counters["gain_buffer_us"] = ::benchmark::Counter(
- total_gain_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
- state.counters["post_buffer_us"] = ::benchmark::Counter(
- total_post_buffer_us / iterations, ::benchmark::Counter::kAvgThreads);
- state.counters["producer_us"] = ::benchmark::Counter(
- (total_gain_buffer_us + total_post_buffer_us) / iterations,
- ::benchmark::Counter::kAvgThreads);
-}
-
-BENCHMARK_REGISTER_F(BufferTransportBenchmark, Producers)
- ->Unit(::benchmark::kMicrosecond)
- ->Ranges({{kBinderBufferTransport, kBufferHubTransport}})
- ->ThreadRange(1, 32);
-
-static void runBinderServer() {
- ProcessState::self()->setThreadPoolMaxThreadCount(0);
- ProcessState::self()->startThreadPool();
-
- sp<IServiceManager> sm = defaultServiceManager();
- sp<BufferTransportService> service = new BufferTransportService;
- sm->addService(kBinderService, service, false);
-
- LOG(INFO) << "Binder server running...";
-
- while (true) {
- int stat, retval;
- retval = wait(&stat);
- if (retval == -1 && errno == ECHILD) {
- break;
- }
- }
-
- LOG(INFO) << "Service Exiting...";
-}
-
-// To run binder-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-// --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/0/"
-//
-// To run bufferhub-based benchmark, use:
-// adb shell buffer_transport_benchmark \
-// --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/1/"
-int main(int argc, char** argv) {
- bool tracing_enabled = false;
-
- // Parse arguments in addition to "--benchmark_filter" paramters.
- for (int i = 1; i < argc; i++) {
- if (std::string(argv[i]) == "--help") {
- std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl;
- std::cout << "\t--trace: Enable systrace logging." << std::endl;
- return 0;
- }
- if (std::string(argv[i]) == "--trace") {
- tracing_enabled = true;
- continue;
- }
- }
-
- // Setup ATRACE/systrace based on command line.
- atrace_setup();
- atrace_set_tracing_enabled(tracing_enabled);
-
- pid_t pid = fork();
- if (pid == 0) {
- // Child, i.e. the client side.
- ProcessState::self()->startThreadPool();
-
- ::benchmark::Initialize(&argc, argv);
- ::benchmark::RunSpecifiedBenchmarks();
- } else {
- LOG(INFO) << "Benchmark process pid: " << pid;
- runBinderServer();
- }
-}
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index 33a0d75..e373376 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -48,19 +48,3 @@
],
name: "buffer_hub_queue-test",
}
-
-cc_test {
- srcs: ["buffer_hub_queue_producer-test.cpp"],
- header_libs: header_libraries,
- static_libs: static_libraries,
- shared_libs: shared_libraries,
- cflags: [
- "-DLOG_TAG=\"buffer_hub_queue_producer-test\"",
- "-DTRACE=0",
- "-O0",
- "-g",
- "-Wall",
- "-Werror",
- ],
- name: "buffer_hub_queue_producer-test",
-}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
deleted file mode 100644
index fab1097..0000000
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-#include <base/logging.h>
-#include <gui/BufferHubProducer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <pdx/default_transport/channel_parcelable.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-using pdx::LocalHandle;
-
-namespace {
-
-// Default dimensions before setDefaultBufferSize is called by the consumer.
-constexpr uint32_t kDefaultWidth = 1;
-constexpr uint32_t kDefaultHeight = 1;
-
-// Default format before setDefaultBufferFormat is called by the consumer.
-constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-constexpr int kDefaultConsumerUsageBits = 0;
-
-// Default transform hint before setTransformHint is called by the consumer.
-constexpr uint32_t kDefaultTransformHint = 0;
-
-constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
-constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
-constexpr int kTestApiInvalid = 0xDEADBEEF;
-constexpr int kTestProducerUsageBits = 0;
-constexpr bool kTestControlledByApp = true;
-
-// Builder pattern to slightly vary *almost* correct input
-// -- avoids copying and pasting
-struct QueueBufferInputBuilder {
- IGraphicBufferProducer::QueueBufferInput build() {
- return IGraphicBufferProducer::QueueBufferInput(
- mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
- mTransform, mFence);
- }
-
- QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
- this->mTimestamp = timestamp;
- return *this;
- }
-
- QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
- this->mIsAutoTimestamp = isAutoTimestamp;
- return *this;
- }
-
- QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
- this->mDataSpace = dataSpace;
- return *this;
- }
-
- QueueBufferInputBuilder& setCrop(Rect crop) {
- this->mCrop = crop;
- return *this;
- }
-
- QueueBufferInputBuilder& setScalingMode(int scalingMode) {
- this->mScalingMode = scalingMode;
- return *this;
- }
-
- QueueBufferInputBuilder& setTransform(uint32_t transform) {
- this->mTransform = transform;
- return *this;
- }
-
- QueueBufferInputBuilder& setFence(sp<Fence> fence) {
- this->mFence = fence;
- return *this;
- }
-
- private:
- int64_t mTimestamp{1384888611};
- bool mIsAutoTimestamp{false};
- android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
- Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
- int mScalingMode{0};
- uint32_t mTransform{0};
- sp<Fence> mFence{Fence::NO_FENCE};
-};
-
-// This is a test that covers our implementation of bufferhubqueue-based
-// IGraphicBufferProducer.
-class BufferHubQueueProducerTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- const ::testing::TestInfo* const testInfo =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
- testInfo->name());
-
- auto config = ProducerQueueConfigBuilder().Build();
- auto queue = ProducerQueue::Create(config, UsagePolicy{});
- ASSERT_TRUE(queue != nullptr);
-
- mProducer = BufferHubProducer::Create(std::move(queue));
- ASSERT_TRUE(mProducer != nullptr);
- mSurface = new Surface(mProducer, true);
- ASSERT_TRUE(mSurface != nullptr);
- }
-
- // Connect to a producer in a 'correct' fashion.
- void ConnectProducer() {
- IGraphicBufferProducer::QueueBufferOutput output;
- // Can connect the first time.
- ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi,
- kTestControlledByApp, &output));
- }
-
- // Dequeue a buffer in a 'correct' fashion.
- // Precondition: Producer is connected.
- void DequeueBuffer(int* outSlot) {
- sp<Fence> fence;
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
- }
-
- void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
- ASSERT_NE(nullptr, outSlot);
- ASSERT_NE(nullptr, outFence);
-
- int ret = mProducer->dequeueBuffer(
- outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat,
- kTestProducerUsageBits, nullptr, nullptr);
- // BUFFER_NEEDS_REALLOCATION can be either on or off.
- ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);
-
- // Slot number should be in boundary.
- ASSERT_LE(0, *outSlot);
- ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
- }
-
- // Create a generic "valid" input for queueBuffer
- // -- uses the default buffer format, width, etc.
- static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
- return QueueBufferInputBuilder().build();
- }
-
- const sp<IProducerListener> kStubListener{new StubProducerListener};
-
- sp<BufferHubProducer> mProducer;
- sp<Surface> mSurface;
-};
-
-TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
- IGraphicBufferProducer::QueueBufferOutput output;
-
- // NULL output returns BAD_VALUE
- EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
- kTestControlledByApp, nullptr));
-
- // Invalid API returns bad value
- EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid,
- kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- // Can't connect when there is already a producer connected.
- IGraphicBufferProducer::QueueBufferOutput output;
- EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi,
- kTestControlledByApp, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- // Must disconnect with same API number
- EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
- // API must not be out of range
- EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- int32_t value = -1;
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
- EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));
-
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
- EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));
-
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
- EXPECT_EQ(kDefaultFormat, value);
-
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
- EXPECT_LE(0, value);
- EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value);
-
- EXPECT_EQ(OK,
- mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
- EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue
-
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
- EXPECT_EQ(kDefaultConsumerUsageBits, value);
-}
-
-TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- // One past the end of the last 'query' enum value. Update this if we add more
- // enums.
- const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;
-
- int value;
- // What was out of range
- EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
- EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
- EXPECT_EQ(BAD_VALUE,
- mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));
-
- // Some enums from window.h are 'invalid'
- EXPECT_EQ(BAD_VALUE,
- mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
- EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
- EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
- EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
- EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));
-
- // Value was NULL
- EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
-}
-
-TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
- int slot = -1;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- // Request the buffer (pre-requisite for queueing)
- sp<GraphicBuffer> buffer;
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- // A generic "valid" input
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- // Queue the buffer back into the BQ
- ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
- EXPECT_EQ(kDefaultWidth, output.width);
- EXPECT_EQ(kDefaultHeight, output.height);
- EXPECT_EQ(kDefaultTransformHint, output.transformHint);
-
- // BufferHubQueue delivers buffers to consumer immediately.
- EXPECT_EQ(0u, output.numPendingBuffers);
-
- // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
- // be a SurfaceFlinger specific optimization.
- EXPECT_EQ(0u, output.nextFrameNumber);
-
- // Buffer was not in the dequeued state
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test invalid slot number
-TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- // A generic "valid" input
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
- EXPECT_EQ(BAD_VALUE,
- mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
- input, &output));
-}
-
-// Slot was not in the dequeued state (all slots start out in Free state)
-TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
-}
-
-// Slot was enqueued without requesting a buffer
-TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
- int slot = -1;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test when fence was NULL
-TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
- int slot = -1;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- sp<GraphicBuffer> buffer;
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- sp<Fence> nullFence = NULL;
-
- IGraphicBufferProducer::QueueBufferInput input =
- QueueBufferInputBuilder().setFence(nullFence).build();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test scaling mode was invalid
-TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
- int slot = -1;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- sp<GraphicBuffer> buffer;
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- IGraphicBufferProducer::QueueBufferInput input =
- QueueBufferInputBuilder().setScalingMode(-1).build();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-
- input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-// Test crop rect is out of bounds of the buffer dimensions
-TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
- int slot = -1;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- sp<GraphicBuffer> buffer;
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- IGraphicBufferProducer::QueueBufferInput input =
- QueueBufferInputBuilder()
- .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
- .build();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
- int slot = -1;
- sp<Fence> fence;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
-
- // Should be able to cancel buffer after a dequeue.
- EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
- return;
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- int minUndequeuedBuffers;
- ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBuffers));
-
- const int minBuffers = 1;
- const int maxBuffers =
- BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
- ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
- ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers))
- << "bufferCount: " << minBuffers;
-
- // Should now be able to dequeue up to minBuffers times
- // Should now be able to dequeue up to maxBuffers times
- int slot = -1;
- for (int i = 0; i < minBuffers; ++i) {
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
- }
-
- ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers));
-
- // queue the first buffer to enable max dequeued buffer count checking
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
- sp<GraphicBuffer> buffer;
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
- ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
-
- sp<Fence> fence;
- for (int i = 0; i < maxBuffers; ++i) {
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
- }
-
- // Cancel a buffer, so we can decrease the buffer count
- ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence));
-
- // Should now be able to decrease the max dequeued count by 1
- ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
-}
-
-TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
-
- int minUndequeuedBuffers;
- ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBuffers));
-
- const int minBuffers = 1;
- const int maxBuffers =
- BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;
-
- ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false;
- // Buffer count was out of range
- EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
- << "bufferCount: " << 0;
- EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
- << "bufferCount: " << maxBuffers + 1;
-
- // Set max dequeue count to 2
- ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
- // Dequeue 2 buffers
- int slot = -1;
- sp<Fence> fence;
- for (int i = 0; i < 2; i++) {
- ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
- (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
- kDefaultHeight, kDefaultFormat,
- kTestProducerUsageBits,
- nullptr, nullptr)))
- << "slot: " << slot;
- }
-
- // Client has too many buffers dequeued
- EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
- << "bufferCount: " << minBuffers;
-}
-
-TEST_F(BufferHubQueueProducerTest,
- DisconnectedProducerReturnsError_dequeueBuffer) {
- int slot = -1;
- sp<Fence> fence;
-
- ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
- kDefaultHeight, kDefaultFormat,
- kTestProducerUsageBits,
- nullptr, nullptr));
-}
-
-TEST_F(BufferHubQueueProducerTest,
- DisconnectedProducerReturnsError_requestBuffer) {
- int slot = -1;
- sp<GraphicBuffer> buffer;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
-
- // Shouldn't be able to request buffer after disconnect.
- ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
- ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
-}
-
-TEST_F(BufferHubQueueProducerTest,
- DisconnectedProducerReturnsError_queueBuffer) {
- int slot = -1;
- sp<GraphicBuffer> buffer;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- // A generic "valid" input
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- // Shouldn't be able to queue buffer after disconnect.
- ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
- ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
-}
-
-TEST_F(BufferHubQueueProducerTest,
- DisconnectedProducerReturnsError_cancelBuffer) {
- int slot = -1;
- sp<GraphicBuffer> buffer;
-
- ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
- ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
-
- // Shouldn't be able to cancel buffer after disconnect.
- ASSERT_EQ(OK, mProducer->disconnect(kTestApi));
- ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
-}
-
-TEST_F(BufferHubQueueProducerTest, ConnectDisconnectReconnect) {
- int slot = -1;
- sp<GraphicBuffer> buffer;
- IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
- IGraphicBufferProducer::QueueBufferOutput output;
-
- EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
- constexpr int maxDequeuedBuffers = 1;
- int minUndequeuedBuffers;
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBuffers));
- EXPECT_EQ(OK, mProducer->setAsyncMode(false));
- EXPECT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers));
-
- int maxCapacity = maxDequeuedBuffers + minUndequeuedBuffers;
-
- // Dequeue, request, and queue all buffers.
- for (int i = 0; i < maxCapacity; i++) {
- EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
- EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
- EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- }
-
- // Disconnect then reconnect.
- EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
- EXPECT_NO_FATAL_FAILURE(ConnectProducer());
-
- // Dequeue, request, and queue all buffers.
- for (int i = 0; i < maxCapacity; i++) {
- EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
- EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
- EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- }
-
- EXPECT_EQ(OK, mProducer->disconnect(kTestApi));
-}
-
-TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) {
- // Connected producer cannot be taken out as a parcelable.
- EXPECT_NO_FATAL_FAILURE(ConnectProducer());
- ProducerQueueParcelable producer_parcelable;
- EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE);
-
- // Create a valid fake producer parcelable.
- auto fake_channel_parcelable =
- std::make_unique<pdx::default_transport::ChannelParcelable>(
- LocalHandle(0), LocalHandle(0), LocalHandle(0));
- EXPECT_TRUE(fake_channel_parcelable->IsValid());
- ProducerQueueParcelable fake_producer_parcelable(
- std::move(fake_channel_parcelable));
- EXPECT_TRUE(fake_producer_parcelable.IsValid());
-
- // Disconnect producer can be taken out, but only to an invalid parcelable.
- ASSERT_EQ(mProducer->disconnect(kTestApi), OK);
- EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE);
- EXPECT_FALSE(producer_parcelable.IsValid());
- EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK);
- EXPECT_TRUE(producer_parcelable.IsValid());
-
- // Should still be able to query buffer dimension after disconnect.
- int32_t value = -1;
- EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
- EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth);
-
- EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK);
- EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight);
-
- EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK);
- EXPECT_EQ(value, kDefaultFormat);
-
- // But connect to API will fail.
- IGraphicBufferProducer::QueueBufferOutput output;
- EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp,
- &output),
- BAD_VALUE);
-
- // Create a new producer from the parcelable and connect to kTestApi should
- // succeed.
- sp<BufferHubProducer> new_producer =
- BufferHubProducer::Create(std::move(producer_parcelable));
- ASSERT_TRUE(new_producer != nullptr);
- EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp,
- &output),
- OK);
-}
-
-} // namespace
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 96023dd..9dbeacb 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -33,87 +33,3 @@
],
min_sdk_version: "29",
}
-
-cc_library_headers {
- name: "libdvr_private_headers",
- export_include_dirs: ["."],
- vendor_available: false,
-}
-
-cflags = [
- "-DDVR_TRACKING_IMPLEMENTED=0",
- "-DLOG_TAG=\"libdvr\"",
- "-DTRACE=0",
- "-Wall",
- "-Werror",
-]
-
-srcs = [
- "dvr_api.cpp",
- "dvr_buffer.cpp",
- "dvr_buffer_queue.cpp",
- "dvr_configuration_data.cpp",
- "dvr_display_manager.cpp",
- "dvr_hardware_composer_client.cpp",
- "dvr_performance.cpp",
- "dvr_pose.cpp",
- "dvr_surface.cpp",
- "dvr_tracking.cpp",
-]
-
-static_libs = [
- "libbroadcastring",
- "libvrsensor",
- "libdisplay",
- "libvirtualtouchpadclient",
- "libvr_hwc-impl",
- "libvr_hwc-binder",
- "libgrallocusage",
- "libperformance",
-]
-
-shared_libs = [
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hidl.token@1.0-utils",
- "libbase",
- "libbufferhubqueue",
- "libbinder",
- "liblog",
- "libcutils",
- "libutils",
- "libnativewindow",
- "libgui",
- "libui",
- "libpdx_default_transport",
-]
-
-cc_library_shared {
- name: "libdvr.google",
- system_ext_specific: true,
- owner: "google",
- cflags: cflags,
- header_libs: ["libdvr_headers"],
- export_header_lib_headers: ["libdvr_headers"],
- srcs: srcs,
- static_libs: static_libs,
- shared_libs: shared_libs,
- version_script: "exported_apis.lds",
-}
-
-// Also build a static libdvr for linking into tests. The linker script
-// restricting function access in the shared lib makes it inconvenient to use in
-// test code.
-cc_library_static {
- name: "libdvr_static.google",
- owner: "google",
- cflags: cflags,
- header_libs: ["libdvr_headers"],
- export_header_lib_headers: ["libdvr_headers"],
- srcs: srcs,
- static_libs: static_libs,
- shared_libs: shared_libs,
-}
-
-subdirs = [
- "tests",
-]
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
deleted file mode 100644
index e099f6a..0000000
--- a/libs/vr/libdvr/dvr_api.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "include/dvr/dvr_api.h"
-
-#include <errno.h>
-#include <utils/Log.h>
-
-#include <algorithm>
-
-// Headers from libdvr
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_buffer_queue.h>
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_performance.h>
-#include <dvr/dvr_surface.h>
-#include <dvr/dvr_tracking.h>
-#include <dvr/dvr_vsync.h>
-
-// Headers not yet moved into libdvr.
-// TODO(jwcai) Move these once their callers are moved into Google3.
-#include <dvr/dvr_hardware_composer_client.h>
-#include <dvr/pose_client.h>
-#include <dvr/virtual_touchpad_client.h>
-
-extern "C" {
-
-int dvrGetApi(void* api, size_t struct_size, int version) {
- ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size,
- version);
- if (version == 1) {
- // New entry points are added at the end. If the caller's struct and
- // this library have different sizes, we define the entry points in common.
- // The caller is expected to handle unset entry points if necessary.
- size_t clamped_struct_size = std::min(struct_size, sizeof(DvrApi_v1));
- DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api);
-
-// Defines an API entry for V1 (no version suffix).
-#define DVR_V1_API_ENTRY(name) \
- do { \
- if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
- clamped_struct_size) { \
- dvr_api->name = dvr##name; \
- } \
- } while (0)
-
-#define DVR_V1_API_ENTRY_DEPRECATED(name) \
- do { \
- if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \
- clamped_struct_size) { \
- dvr_api->name = nullptr; \
- } \
- } while (0)
-
-#include "include/dvr/dvr_api_entries.h"
-
-// Undefine macro definitions to play nice with Google3 style rules.
-#undef DVR_V1_API_ENTRY
-#undef DVR_V1_API_ENTRY_DEPRECATED
-
- return 0;
- }
-
- ALOGE("dvrGetApi: Unknown API version=%d", version);
- return -EINVAL;
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
deleted file mode 100644
index c11706f..0000000
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "include/dvr/dvr_buffer.h"
-
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-#include <ui/GraphicBuffer.h>
-
-#include "dvr_internal.h"
-
-using namespace android;
-
-namespace android {
-namespace dvr {
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
- const std::shared_ptr<IonBuffer>& ion_buffer) {
- if (!ion_buffer)
- return nullptr;
- return new DvrBuffer{std::move(ion_buffer)};
-}
-
-} // namespace dvr
-} // namespace android
-
-namespace {
-
-int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer,
- AHardwareBuffer** hardware_buffer) {
- if (!hardware_buffer || !graphic_buffer) {
- return -EINVAL;
- }
- *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(graphic_buffer);
- AHardwareBuffer_acquire(*hardware_buffer);
- return 0;
-}
-
-} // anonymous namespace
-
-extern "C" {
-
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
- if (write_buffer != nullptr) {
- ALOGW_IF(
- write_buffer->slot != -1,
- "dvrWriteBufferDestroy: Destroying a buffer associated with a valid "
- "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
- dvrWriteBufferGetId(write_buffer));
- delete write_buffer;
- }
-}
-
-int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) {
- return write_buffer && write_buffer->write_buffer;
-}
-
-int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
- if (!write_buffer || !write_buffer->write_buffer)
- return -EINVAL;
-
- return write_buffer->write_buffer->id();
-}
-
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
- AHardwareBuffer** hardware_buffer) {
- if (!write_buffer || !write_buffer->write_buffer)
- return -EINVAL;
-
- return ConvertToAHardwareBuffer(
- write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) {
- if (read_buffer != nullptr) {
- ALOGW_IF(
- read_buffer->slot != -1,
- "dvrReadBufferDestroy: Destroying a buffer associated with a valid "
- "buffer queue slot. This may indicate possible leaks, buffer_id=%d.",
- dvrReadBufferGetId(read_buffer));
- delete read_buffer;
- }
-}
-
-int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) {
- return read_buffer && read_buffer->read_buffer;
-}
-
-int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
- if (!read_buffer || !read_buffer->read_buffer)
- return -EINVAL;
-
- return read_buffer->read_buffer->id();
-}
-
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
- AHardwareBuffer** hardware_buffer) {
- if (!read_buffer || !read_buffer->read_buffer)
- return -EINVAL;
-
- return ConvertToAHardwareBuffer(
- read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer);
-}
-
-void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
-
-int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
- AHardwareBuffer** hardware_buffer) {
- if (!buffer || !buffer->buffer || !hardware_buffer) {
- return -EINVAL;
- }
-
- return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(),
- hardware_buffer);
-}
-
-// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
-int dvrBufferGlobalLayoutVersionGet() {
- return android::dvr::kSharedBufferLayoutVersion;
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
deleted file mode 100644
index 1ca653c..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ /dev/null
@@ -1,552 +0,0 @@
-#include "include/dvr/dvr_api.h"
-#include "include/dvr/dvr_buffer_queue.h"
-
-#include <android/native_window.h>
-#include <gui/BufferHubProducer.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using namespace android;
-using android::dvr::BufferHubBase;
-using android::dvr::ConsumerBuffer;
-using android::dvr::ConsumerQueue;
-using android::dvr::ProducerBuffer;
-using android::dvr::ProducerQueue;
-using android::dvr::ProducerQueueConfigBuilder;
-using android::dvr::UsagePolicy;
-
-extern "C" {
-
-DvrWriteBufferQueue::DvrWriteBufferQueue(
- const std::shared_ptr<ProducerQueue>& producer_queue)
- : producer_queue_(producer_queue),
- width_(producer_queue->default_width()),
- height_(producer_queue->default_height()),
- format_(producer_queue->default_format()) {}
-
-int DvrWriteBufferQueue::GetNativeWindow(ANativeWindow** out_window) {
- if (native_window_ == nullptr) {
- // Lazy creation of |native_window|, as not everyone is using
- // DvrWriteBufferQueue as an external surface.
- sp<IGraphicBufferProducer> gbp = BufferHubProducer::Create(producer_queue_);
- native_window_ = new Surface(gbp, true);
- }
-
- *out_window = static_cast<ANativeWindow*>(native_window_.get());
- return 0;
-}
-
-int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
- std::unique_ptr<ConsumerQueue> consumer_queue =
- producer_queue_->CreateConsumerQueue();
- if (consumer_queue == nullptr) {
- ALOGE(
- "DvrWriteBufferQueue::CreateReadQueue: Failed to create consumer queue "
- "from producer queue: queue_id=%d.", producer_queue_->id());
- return -ENOMEM;
- }
-
- *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
- return 0;
-}
-
-int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer,
- int* out_fence_fd) {
- DvrNativeBufferMetadata meta;
- DvrWriteBuffer* buffer = nullptr;
- int fence_fd = -1;
- if (const int ret = GainBuffer(timeout, &buffer, &meta, &fence_fd))
- return ret;
- if (!buffer)
- return -ENOMEM;
-
- write_buffers_[buffer->slot].reset(buffer);
- write_buffer->write_buffer = std::move(buffer->write_buffer);
- *out_fence_fd = fence_fd;
- return 0;
-}
-
-int DvrWriteBufferQueue::GainBuffer(int timeout,
- DvrWriteBuffer** out_write_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd) {
- size_t slot;
- pdx::LocalHandle release_fence;
-
- // Need to retry N+1 times, where N is total number of buffers in the queue.
- // As in the worst case, we will dequeue all N buffers and reallocate them, on
- // the {N+1}th dequeue, we are guaranteed to get a buffer with new dimension.
- size_t max_retries = 1 + producer_queue_->capacity();
- size_t retry = 0;
-
- for (; retry < max_retries; retry++) {
- auto buffer_status =
- producer_queue_->Dequeue(timeout, &slot, out_meta, &release_fence);
- if (!buffer_status) {
- ALOGE_IF(buffer_status.error() != ETIMEDOUT,
- "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer: %s",
- buffer_status.GetErrorMessage().c_str());
- return -buffer_status.error();
- }
-
- if (write_buffers_[slot] == nullptr) {
- // Lazy initialization of a write_buffers_ slot. Note that a slot will
- // only be dynamically allocated once during the entire cycle life of a
- // queue.
- write_buffers_[slot] = std::make_unique<DvrWriteBuffer>();
- write_buffers_[slot]->slot = slot;
- }
-
- LOG_ALWAYS_FATAL_IF(
- write_buffers_[slot]->write_buffer,
- "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot);
- write_buffers_[slot]->write_buffer = std::move(buffer_status.take());
-
- const auto& producer_buffer = write_buffers_[slot]->write_buffer;
- if (!producer_buffer)
- return -ENOMEM;
-
- if (width_ == producer_buffer->width() &&
- height_ == producer_buffer->height() &&
- format_ == producer_buffer->format()) {
- // Producer queue returns a buffer matches the current request.
- break;
- }
-
- // Needs reallocation. Note that if there are already multiple available
- // buffers in the queue, the next one returned from |queue_->Dequeue| may
- // still have the old buffer dimension or format. Retry up to N+1 times or
- // until we dequeued a buffer with new configuration.
- ALOGD_IF(TRACE,
- "DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu "
- "(w=%u, h=%u, fmt=%u) is different from the buffer returned "
- "(w=%u, h=%u, fmt=%u). Need re-allocation.",
- slot, width_, height_, format_, producer_buffer->width(),
- producer_buffer->height(), producer_buffer->format());
-
- // Currently, we are not storing |layer_count| and |usage| in queue
- // configuration. Copy those setup from the last buffer dequeued before we
- // remove it.
- uint32_t old_layer_count = producer_buffer->layer_count();
- uint64_t old_usage = producer_buffer->usage();
-
- // Allocate a new producer buffer with new buffer configs. Note that if
- // there are already multiple available buffers in the queue, the next one
- // returned from |queue_->Dequeue| may still have the old buffer dimension
- // or format. Retry up to BufferHubQueue::kMaxQueueCapacity times or until
- // we dequeued a buffer with new configuration.
- auto remove_status = producer_queue_->RemoveBuffer(slot);
- if (!remove_status) {
- ALOGE("DvrWriteBufferQueue::Dequeue: Failed to remove buffer: %s",
- remove_status.GetErrorMessage().c_str());
- return -remove_status.error();
- }
- // Make sure that the previously allocated buffer is dereferenced from
- // write_buffers_ array.
- write_buffers_[slot]->write_buffer = nullptr;
-
- auto allocate_status = producer_queue_->AllocateBuffer(
- width_, height_, old_layer_count, format_, old_usage);
- if (!allocate_status) {
- ALOGE("DvrWriteBufferQueue::Dequeue: Failed to allocate buffer: %s",
- allocate_status.GetErrorMessage().c_str());
- return -allocate_status.error();
- }
- }
-
- if (retry >= max_retries) {
- ALOGE(
- "DvrWriteBufferQueue::Dequeue: Failed to re-allocate buffer after "
- "resizing.");
- return -ENOMEM;
- }
-
- *out_write_buffer = write_buffers_[slot].release();
- *out_fence_fd = release_fence.Release();
-
- return 0;
-}
-
-int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer,
- const DvrNativeBufferMetadata* meta,
- int ready_fence_fd) {
- // Some basic sanity checks before we put the buffer back into a slot.
- size_t slot = static_cast<size_t>(write_buffer->slot);
- LOG_FATAL_IF(
- (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()),
- "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
- if (write_buffers_[slot] != nullptr) {
- ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot);
- return -EINVAL;
- }
- if (write_buffer->write_buffer == nullptr) {
- ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer.");
- return -EINVAL;
- }
- if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) {
- ALOGE(
- "DvrWriteBufferQueue::PostBuffer: Buffer to be posted does not "
- "belong to this buffer queue. Posting buffer: id=%d, buffer in "
- "queue: id=%d",
- write_buffer->write_buffer->id(), producer_queue_->GetBufferId(slot));
- return -EINVAL;
- }
-
- write_buffer->write_buffer->SetQueueIndex(next_post_index_++);
- pdx::LocalHandle fence(ready_fence_fd);
- const int ret = write_buffer->write_buffer->PostAsync(meta, fence);
- if (ret < 0) {
- ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d",
- ret);
- return ret;
- }
-
- // Put the DvrWriteBuffer pointer back into its slot for reuse.
- write_buffers_[slot].reset(write_buffer);
- // It's import to reset the write buffer client now. It should stay invalid
- // until next GainBuffer on the same slot.
- write_buffers_[slot]->write_buffer = nullptr;
- return 0;
-}
-
-int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) {
- if (width == 0 || height == 0) {
- ALOGE(
- "DvrWriteBufferQueue::ResizeBuffer: invalid buffer dimension: w=%u, "
- "h=%u.",
- width, height);
- return -EINVAL;
- }
-
- width_ = width;
- height_ = height;
- return 0;
-}
-
-int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format,
- uint32_t layer_count, uint64_t usage,
- size_t capacity, size_t metadata_size,
- DvrWriteBufferQueue** out_write_queue) {
- if (!out_write_queue)
- return -EINVAL;
-
- auto config_builder = ProducerQueueConfigBuilder()
- .SetDefaultWidth(width)
- .SetDefaultHeight(height)
- .SetDefaultFormat(format)
- .SetMetadataSize(metadata_size);
- std::unique_ptr<ProducerQueue> producer_queue =
- ProducerQueue::Create(config_builder.Build(), UsagePolicy{});
- if (!producer_queue) {
- ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue.");
- return -ENOMEM;
- }
-
- auto status = producer_queue->AllocateBuffers(width, height, layer_count,
- format, usage, capacity);
- if (!status.ok()) {
- ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers.");
- return -ENOMEM;
- }
-
- *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue));
- return 0;
-}
-
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
- delete write_queue;
-}
-
-ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
- if (!write_queue)
- return -EINVAL;
-
- return write_queue->capacity();
-}
-
-int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) {
- if (!write_queue)
- return -EINVAL;
-
- return write_queue->id();
-}
-
-int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
- ANativeWindow** out_window) {
- if (!write_queue || !out_window)
- return -EINVAL;
-
- return write_queue->GetNativeWindow(out_window);
-}
-
-int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
- DvrReadBufferQueue** out_read_queue) {
- if (!write_queue || !out_read_queue)
- return -EINVAL;
-
- return write_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
- DvrWriteBuffer** out_write_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd) {
- if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd)
- return -EINVAL;
-
- return write_queue->GainBuffer(timeout, out_write_buffer, out_meta,
- out_fence_fd);
-}
-
-int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
- DvrWriteBuffer* write_buffer,
- const DvrNativeBufferMetadata* meta,
- int ready_fence_fd) {
- if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta)
- return -EINVAL;
-
- return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd);
-}
-
-int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
- uint32_t width, uint32_t height) {
- if (!write_queue)
- return -EINVAL;
-
- return write_queue->ResizeBuffer(width, height);
-}
-
-// ReadBufferQueue
-
-DvrReadBufferQueue::DvrReadBufferQueue(
- const std::shared_ptr<ConsumerQueue>& consumer_queue)
- : consumer_queue_(consumer_queue) {}
-
-int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) {
- std::unique_ptr<ConsumerQueue> consumer_queue =
- consumer_queue_->CreateConsumerQueue();
- if (consumer_queue == nullptr) {
- ALOGE(
- "DvrReadBufferQueue::CreateReadQueue: Failed to create consumer queue "
- "from producer queue: queue_id=%d.", consumer_queue_->id());
- return -ENOMEM;
- }
-
- *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue));
- return 0;
-}
-
-int DvrReadBufferQueue::AcquireBuffer(int timeout,
- DvrReadBuffer** out_read_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd) {
- size_t slot;
- pdx::LocalHandle acquire_fence;
- auto buffer_status =
- consumer_queue_->Dequeue(timeout, &slot, out_meta, &acquire_fence);
- if (!buffer_status) {
- ALOGE_IF(buffer_status.error() != ETIMEDOUT,
- "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer: %s",
- buffer_status.GetErrorMessage().c_str());
- return -buffer_status.error();
- }
-
- if (read_buffers_[slot] == nullptr) {
- // Lazy initialization of a read_buffers_ slot. Note that a slot will only
- // be dynamically allocated once during the entire cycle life of a queue.
- read_buffers_[slot] = std::make_unique<DvrReadBuffer>();
- read_buffers_[slot]->slot = slot;
- }
-
- LOG_FATAL_IF(
- read_buffers_[slot]->read_buffer,
- "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot);
- read_buffers_[slot]->read_buffer = std::move(buffer_status.take());
-
- *out_read_buffer = read_buffers_[slot].release();
- *out_fence_fd = acquire_fence.Release();
-
- return 0;
-}
-
-int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer,
- const DvrNativeBufferMetadata* meta,
- int release_fence_fd) {
- // Some basic sanity checks before we put the buffer back into a slot.
- size_t slot = static_cast<size_t>(read_buffer->slot);
- LOG_FATAL_IF(
- (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()),
- "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot);
-
- if (read_buffers_[slot] != nullptr) {
- ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot);
- return -EINVAL;
- }
- if (read_buffer->read_buffer == nullptr) {
- ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer.");
- return -EINVAL;
- }
- if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) {
- if (consumer_queue_->GetBufferId(slot) > 0) {
- ALOGE(
- "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
- "belong to this queue (queue_id=%d): attempting to release buffer "
- "(buffer_id=%d) at slot %d which holds a different buffer "
- "(buffer_id=%d).",
- consumer_queue_->id(), read_buffer->read_buffer->id(),
- static_cast<int>(slot), consumer_queue_->GetBufferId(slot));
- } else {
- ALOGI(
- "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not "
- "belong to this queue (queue_id=%d): attempting to release buffer "
- "(buffer_id=%d) at slot %d which is empty.",
- consumer_queue_->id(), read_buffer->read_buffer->id(),
- static_cast<int>(slot));
- }
- }
-
- pdx::LocalHandle fence(release_fence_fd);
- int ret = read_buffer->read_buffer->ReleaseAsync(meta, fence);
- if (ret < 0) {
- ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d",
- ret);
- return ret;
- }
-
- // Put the DvrReadBuffer pointer back into its slot for reuse.
- read_buffers_[slot].reset(read_buffer);
- // It's import to reset the read buffer client now. It should stay invalid
- // until next AcquireBuffer on the same slot.
- read_buffers_[slot]->read_buffer = nullptr;
- return 0;
-}
-
-void DvrReadBufferQueue::SetBufferAvailableCallback(
- DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
- if (callback == nullptr) {
- consumer_queue_->SetBufferAvailableCallback(nullptr);
- } else {
- consumer_queue_->SetBufferAvailableCallback(
- [callback, context]() { callback(context); });
- }
-}
-
-void DvrReadBufferQueue::SetBufferRemovedCallback(
- DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
- if (callback == nullptr) {
- consumer_queue_->SetBufferRemovedCallback(nullptr);
- } else {
- consumer_queue_->SetBufferRemovedCallback(
- [callback, context](const std::shared_ptr<BufferHubBase>& buffer) {
- // When buffer is removed from the queue, the slot is already invalid.
- auto read_buffer = std::make_unique<DvrReadBuffer>();
- read_buffer->read_buffer =
- std::static_pointer_cast<ConsumerBuffer>(buffer);
- callback(read_buffer.release(), context);
- });
- }
-}
-
-int DvrReadBufferQueue::HandleEvents() {
- // TODO(jwcai) Probably should change HandleQueueEvents to return Status.
- consumer_queue_->HandleQueueEvents();
- return 0;
-}
-
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
- delete read_queue;
-}
-
-ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
- if (!read_queue)
- return -EINVAL;
-
- return read_queue->capacity();
-}
-
-int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) {
- if (!read_queue)
- return -EINVAL;
-
- return read_queue->id();
-}
-
-int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue) {
- if (!read_queue)
- return -EINVAL;
-
- return read_queue->event_fd();
-}
-
-int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
- DvrReadBufferQueue** out_read_queue) {
- if (!read_queue || !out_read_queue)
- return -EINVAL;
-
- return read_queue->CreateReadQueue(out_read_queue);
-}
-
-int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
- DvrReadBuffer* read_buffer, int* out_fence_fd,
- void* out_meta, size_t meta_size_bytes) {
- if (!read_queue || !read_buffer || !out_fence_fd)
- return -EINVAL;
-
- if (meta_size_bytes != 0 && !out_meta)
- return -EINVAL;
-
- return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta,
- meta_size_bytes);
-}
-
-int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
- DvrReadBuffer** out_read_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd) {
- if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd)
- return -EINVAL;
-
- return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta,
- out_fence_fd);
-}
-
-int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
- DvrReadBuffer* read_buffer,
- const DvrNativeBufferMetadata* meta,
- int release_fence_fd) {
- if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta)
- return -EINVAL;
-
- return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd);
-}
-
-int dvrReadBufferQueueSetBufferAvailableCallback(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferAvailableCallback callback, void* context) {
- if (!read_queue)
- return -EINVAL;
-
- read_queue->SetBufferAvailableCallback(callback, context);
- return 0;
-}
-
-int dvrReadBufferQueueSetBufferRemovedCallback(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferRemovedCallback callback, void* context) {
- if (!read_queue)
- return -EINVAL;
-
- read_queue->SetBufferRemovedCallback(callback, context);
- return 0;
-}
-
-int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue) {
- if (!read_queue)
- return -EINVAL;
-
- return read_queue->HandleEvents();
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h
deleted file mode 100644
index e53a686..0000000
--- a/libs/vr/libdvr/dvr_buffer_queue_internal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-#define ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
-
-#include <gui/Surface.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <sys/cdefs.h>
-
-#include <array>
-#include <memory>
-
-#include "dvr_internal.h"
-
-struct ANativeWindow;
-
-typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
- void* context);
-
-struct DvrWriteBufferQueue {
- using BufferHubQueue = android::dvr::BufferHubQueue;
- using ProducerQueue = android::dvr::ProducerQueue;
-
- // Create a concrete object for DvrWriteBufferQueue.
- //
- // @param producer_queue The BufferHub's ProducerQueue that is used to back
- // this DvrWriteBufferQueue, must not be NULL.
- explicit DvrWriteBufferQueue(
- const std::shared_ptr<ProducerQueue>& producer_queue);
-
- int id() const { return producer_queue_->id(); }
- uint32_t width() const { return width_; };
- uint32_t height() const { return height_; };
- uint32_t format() const { return format_; };
- size_t capacity() const { return producer_queue_->capacity(); }
- const std::shared_ptr<ProducerQueue>& producer_queue() const {
- return producer_queue_;
- }
-
- int GetNativeWindow(ANativeWindow** out_window);
- int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
- int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd);
- int GainBuffer(int timeout, DvrWriteBuffer** out_write_buffer,
- DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
- int PostBuffer(DvrWriteBuffer* write_buffer,
- const DvrNativeBufferMetadata* meta, int ready_fence_fd);
- int ResizeBuffer(uint32_t width, uint32_t height);
-
- private:
- std::shared_ptr<ProducerQueue> producer_queue_;
- std::array<std::unique_ptr<DvrWriteBuffer>, BufferHubQueue::kMaxQueueCapacity>
- write_buffers_;
-
- int64_t next_post_index_ = 0;
- uint32_t width_;
- uint32_t height_;
- uint32_t format_;
-
- android::sp<android::Surface> native_window_;
-};
-
-struct DvrReadBufferQueue {
- using BufferHubQueue = android::dvr::BufferHubQueue;
- using ConsumerQueue = android::dvr::ConsumerQueue;
-
- explicit DvrReadBufferQueue(
- const std::shared_ptr<ConsumerQueue>& consumer_queue);
-
- int id() const { return consumer_queue_->id(); }
- int event_fd() const { return consumer_queue_->queue_fd(); }
- size_t capacity() const { return consumer_queue_->capacity(); }
-
- int CreateReadQueue(DvrReadBufferQueue** out_read_queue);
- int Dequeue(int timeout, DvrReadBuffer* read_buffer, int* out_fence_fd,
- void* out_meta, size_t user_metadata_size);
- int AcquireBuffer(int timeout, DvrReadBuffer** out_read_buffer,
- DvrNativeBufferMetadata* out_meta, int* out_fence_fd);
- int ReleaseBuffer(DvrReadBuffer* read_buffer,
- const DvrNativeBufferMetadata* meta, int release_fence_fd);
- void SetBufferAvailableCallback(
- DvrReadBufferQueueBufferAvailableCallback callback, void* context);
- void SetBufferRemovedCallback(
- DvrReadBufferQueueBufferRemovedCallback callback, void* context);
- int HandleEvents();
-
- private:
- std::shared_ptr<ConsumerQueue> consumer_queue_;
- std::array<std::unique_ptr<DvrReadBuffer>, BufferHubQueue::kMaxQueueCapacity>
- read_buffers_;
-};
-
-#endif // ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_configuration_data.cpp b/libs/vr/libdvr/dvr_configuration_data.cpp
deleted file mode 100644
index df0d54e..0000000
--- a/libs/vr/libdvr/dvr_configuration_data.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "include/dvr/dvr_configuration_data.h"
-
-#include <private/dvr/display_client.h>
-
-using android::dvr::display::ConfigFileType;
-using android::dvr::display::DisplayClient;
-
-extern "C" {
-
-int dvrConfigurationDataGet(int config_type, uint8_t** data,
- size_t* data_size) {
- if (!data || !data_size) {
- return -EINVAL;
- }
-
- auto client = DisplayClient::Create();
- if (!client) {
- ALOGE("dvrGetGlobalBuffer: Failed to create display client!");
- return -ECOMM;
- }
-
- ConfigFileType config_file_type = static_cast<ConfigFileType>(config_type);
- auto config_data_status =
- client->GetConfigurationData(config_file_type);
-
- if (!config_data_status) {
- return -config_data_status.error();
- }
-
- *data_size = config_data_status.get().size();
- *data = new uint8_t[*data_size];
- std::copy_n(config_data_status.get().begin(), *data_size, *data);
- return 0;
-}
-
-void dvrConfigurationDataDestroy(uint8_t* data) {
- delete[] data;
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp
deleted file mode 100644
index 7f631e3..0000000
--- a/libs/vr/libdvr/dvr_display_manager.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-#include "include/dvr/dvr_display_manager.h"
-
-#include <dvr/dvr_buffer.h>
-#include <pdx/rpc/variant.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/display_client.h>
-#include <private/dvr/display_manager_client.h>
-
-#include "dvr_internal.h"
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerBuffer;
-using android::dvr::display::DisplayManagerClient;
-using android::dvr::display::SurfaceAttribute;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceState;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Extracts type and value from the attribute Variant and writes them into the
-// respective fields of DvrSurfaceAttribute.
-struct AttributeVisitor {
- DvrSurfaceAttribute* attribute;
-
- void operator()(int32_t value) {
- attribute->value.int32_value = value;
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
- }
- void operator()(int64_t value) {
- attribute->value.int64_value = value;
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
- }
- void operator()(bool value) {
- attribute->value.bool_value = value;
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
- }
- void operator()(float value) {
- attribute->value.float_value = value;
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
- }
- void operator()(const std::array<float, 2>& value) {
- std::copy(value.cbegin(), value.cend(), attribute->value.float2_value);
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
- }
- void operator()(const std::array<float, 3>& value) {
- std::copy(value.cbegin(), value.cend(), attribute->value.float3_value);
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
- }
- void operator()(const std::array<float, 4>& value) {
- std::copy(value.cbegin(), value.cend(), attribute->value.float4_value);
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
- }
- void operator()(const std::array<float, 8>& value) {
- std::copy(value.cbegin(), value.cend(), attribute->value.float8_value);
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
- }
- void operator()(const std::array<float, 16>& value) {
- std::copy(value.cbegin(), value.cend(), attribute->value.float16_value);
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
- }
- void operator()(EmptyVariant) {
- attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
- }
-};
-
-size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes,
- DvrSurfaceAttribute* attributes,
- size_t max_count) {
- size_t count = 0;
- for (const auto& attribute : surface_attributes) {
- if (count >= max_count)
- break;
-
- // Copy the key and extract the Variant value using a visitor.
- attributes[count].key = attribute.first;
- attribute.second.Visit(AttributeVisitor{&attributes[count]});
- count++;
- }
-
- return count;
-}
-
-} // anonymous namespace
-
-extern "C" {
-
-struct DvrDisplayManager {
- std::unique_ptr<DisplayManagerClient> client;
-};
-
-struct DvrSurfaceState {
- std::vector<SurfaceState> state;
-};
-
-int dvrDisplayManagerCreate(DvrDisplayManager** client_out) {
- if (!client_out)
- return -EINVAL;
-
- auto client = DisplayManagerClient::Create();
- if (!client) {
- ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!");
- return -EIO;
- }
-
- *client_out = new DvrDisplayManager{std::move(client)};
- return 0;
-}
-
-void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; }
-
-int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) {
- if (!client)
- return -EINVAL;
-
- return client->client->event_fd();
-}
-
-int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
- int in_events, int* out_events) {
- if (!client || !out_events)
- return -EINVAL;
-
- auto status = client->client->GetEventMask(in_events);
- if (!status)
- return -status.error();
-
- *out_events = status.get();
- return 0;
-}
-
-int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
- DvrSurfaceState* state) {
- if (!client || !state)
- return -EINVAL;
-
- auto status = client->client->GetSurfaceState();
- if (!status)
- return -status.error();
-
- state->state = status.take();
- return 0;
-}
-
-int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
- int surface_id, int queue_id,
- DvrReadBufferQueue** queue_out) {
- if (!client || !queue_out)
- return -EINVAL;
-
- auto status = client->client->GetSurfaceQueue(surface_id, queue_id);
- if (!status) {
- ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
- }
-
- *queue_out = new DvrReadBufferQueue(status.take());
- return 0;
-}
-
-int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) {
- if (!surface_state_out)
- return -EINVAL;
-
- *surface_state_out = new DvrSurfaceState{};
- return 0;
-}
-
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) {
- delete surface_state;
-}
-
-int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
- size_t* count_out) {
- if (!surface_state)
- return -EINVAL;
-
- *count_out = surface_state->state.size();
- return 0;
-}
-
-int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
- size_t surface_index,
- DvrSurfaceUpdateFlags* flags_out) {
- if (!surface_state || surface_index >= surface_state->state.size())
- return -EINVAL;
-
- *flags_out = surface_state->state[surface_index].update_flags;
- return 0;
-}
-
-int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
- size_t surface_index, int* surface_id_out) {
- if (!surface_state || surface_index >= surface_state->state.size())
- return -EINVAL;
-
- *surface_id_out = surface_state->state[surface_index].surface_id;
- return 0;
-}
-
-int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
- size_t surface_index, int* process_id_out) {
- if (!surface_state || surface_index >= surface_state->state.size())
- return -EINVAL;
-
- *process_id_out = surface_state->state[surface_index].process_id;
- return 0;
-}
-
-int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
- size_t surface_index, size_t* count_out) {
- if (!surface_state || surface_index >= surface_state->state.size())
- return -EINVAL;
-
- *count_out = surface_state->state[surface_index].queue_ids.size();
- return 0;
-}
-
-ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
- size_t surface_index, int* queue_ids,
- size_t max_count) {
- if (!surface_state || surface_index >= surface_state->state.size())
- return -EINVAL;
-
- size_t i;
- const auto& state = surface_state->state[surface_index];
- for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) {
- queue_ids[i] = state.queue_ids[i];
- }
-
- return i;
-}
-
-int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
- size_t surface_index, int* z_order_out) {
- if (!surface_state || surface_index >= surface_state->state.size() ||
- !z_order_out) {
- return -EINVAL;
- }
-
- *z_order_out = surface_state->state[surface_index].GetZOrder();
- return 0;
-}
-
-int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
- size_t surface_index, bool* visible_out) {
- if (!surface_state || surface_index >= surface_state->state.size() ||
- !visible_out) {
- return -EINVAL;
- }
-
- *visible_out = surface_state->state[surface_index].GetVisible();
- return 0;
-}
-
-int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
- size_t surface_index, size_t* count_out) {
- if (!surface_state || surface_index >= surface_state->state.size() ||
- !count_out) {
- return -EINVAL;
- }
-
- *count_out = surface_state->state[surface_index].surface_attributes.size();
- return 0;
-}
-
-ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
- size_t surface_index,
- DvrSurfaceAttribute* attributes,
- size_t max_count) {
- if (!surface_state || surface_index >= surface_state->state.size() ||
- !attributes) {
- return -EINVAL;
- }
-
- return ConvertSurfaceAttributes(
- surface_state->state[surface_index].surface_attributes, attributes,
- max_count);
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp
deleted file mode 100644
index 4e87cf6..0000000
--- a/libs/vr/libdvr/dvr_hardware_composer_client.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-#include "include/dvr/dvr_hardware_composer_client.h"
-
-#include <android/dvr/IVrComposer.h>
-#include <android/dvr/BnVrComposerCallback.h>
-#include <android/hardware_buffer.h>
-#include <binder/IServiceManager.h>
-#include <private/android/AHardwareBufferHelpers.h>
-
-#include <functional>
-#include <memory>
-#include <mutex>
-
-struct DvrHwcFrame {
- android::dvr::ComposerView::Frame frame;
-};
-
-namespace {
-
-class HwcCallback : public android::dvr::BnVrComposerCallback {
- public:
- using CallbackFunction = std::function<int(DvrHwcFrame*)>;
-
- explicit HwcCallback(const CallbackFunction& callback);
- ~HwcCallback() override;
-
- // Reset the callback. This needs to be done early to avoid use after free
- // accesses from binder thread callbacks.
- void Shutdown();
-
- std::unique_ptr<DvrHwcFrame> DequeueFrame();
-
- private:
- // android::dvr::BnVrComposerCallback:
- android::binder::Status onNewFrame(
- const android::dvr::ParcelableComposerFrame& frame,
- android::dvr::ParcelableUniqueFd* fence) override;
-
- // Protects the |callback_| from uses from multiple threads. During shutdown
- // there may be in-flight frame update events. In those cases the callback
- // access needs to be protected otherwise binder threads may access an invalid
- // callback.
- std::mutex mutex_;
- CallbackFunction callback_;
-
- HwcCallback(const HwcCallback&) = delete;
- void operator=(const HwcCallback&) = delete;
-};
-
-HwcCallback::HwcCallback(const CallbackFunction& callback)
- : callback_(callback) {}
-
-HwcCallback::~HwcCallback() {}
-
-void HwcCallback::Shutdown() {
- std::lock_guard<std::mutex> guard(mutex_);
- callback_ = nullptr;
-}
-
-android::binder::Status HwcCallback::onNewFrame(
- const android::dvr::ParcelableComposerFrame& frame,
- android::dvr::ParcelableUniqueFd* fence) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- if (!callback_) {
- fence->set_fence(android::base::unique_fd());
- return android::binder::Status::ok();
- }
-
- std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame());
- dvr_frame->frame = frame.frame();
-
- fence->set_fence(android::base::unique_fd(callback_(dvr_frame.release())));
- return android::binder::Status::ok();
-}
-
-} // namespace
-
-struct DvrHwcClient {
- android::sp<android::dvr::IVrComposer> composer;
- android::sp<HwcCallback> callback;
-};
-
-DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) {
- std::unique_ptr<DvrHwcClient> client(new DvrHwcClient());
-
- android::sp<android::IServiceManager> sm(android::defaultServiceManager());
- client->composer = android::interface_cast<android::dvr::IVrComposer>(
- sm->getService(android::dvr::IVrComposer::SERVICE_NAME()));
- if (!client->composer.get())
- return nullptr;
-
- client->callback = new HwcCallback(std::bind(callback, data,
- std::placeholders::_1));
- android::binder::Status status = client->composer->registerObserver(
- client->callback);
- if (!status.isOk())
- return nullptr;
-
- return client.release();
-}
-
-void dvrHwcClientDestroy(DvrHwcClient* client) {
- client->composer->clearObserver();
-
- // NOTE: Deleting DvrHwcClient* isn't enough since DvrHwcClient::callback is a
- // shared pointer that could be referenced from a binder thread. But the
- // client callback isn't valid past this calls so that needs to be reset.
- client->callback->Shutdown();
-
- delete client;
-}
-
-void dvrHwcFrameDestroy(DvrHwcFrame* frame) {
- delete frame;
-}
-
-DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) {
- return frame->frame.display_id;
-}
-
-int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) {
- return frame->frame.display_width;
-}
-
-int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) {
- return frame->frame.display_height;
-}
-
-bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) {
- return frame->frame.removed;
-}
-
-size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) {
- return frame->frame.layers.size();
-}
-
-uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) {
- return static_cast<uint32_t>(frame->frame.active_config);
-}
-
-uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) {
- return static_cast<uint32_t>(frame->frame.color_mode);
-}
-
-void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
- int32_t* out_hint) {
- *out_hint = frame->frame.color_transform_hint;
- memcpy(out_matrix, frame->frame.color_transform,
- sizeof(frame->frame.color_transform));
-}
-
-uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) {
- return static_cast<uint32_t>(frame->frame.power_mode);
-}
-
-uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) {
- return static_cast<uint32_t>(frame->frame.vsync_enabled);
-}
-
-DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].id;
-}
-
-AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
- size_t layer_index) {
- AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer(
- frame->frame.layers[layer_index].buffer.get());
- AHardwareBuffer_acquire(buffer);
- return buffer;
-}
-
-int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].fence->dup();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
- size_t layer_index) {
- return DvrHwcRecti{
- frame->frame.layers[layer_index].display_frame.left,
- frame->frame.layers[layer_index].display_frame.top,
- frame->frame.layers[layer_index].display_frame.right,
- frame->frame.layers[layer_index].display_frame.bottom,
- };
-}
-
-DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) {
- return DvrHwcRectf{
- frame->frame.layers[layer_index].crop.left,
- frame->frame.layers[layer_index].crop.top,
- frame->frame.layers[layer_index].crop.right,
- frame->frame.layers[layer_index].crop.bottom,
- };
-}
-
-DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
- size_t layer_index) {
- return static_cast<DvrHwcBlendMode>(
- frame->frame.layers[layer_index].blend_mode);
-}
-
-float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].alpha;
-}
-
-uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].type;
-}
-
-uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
- size_t layer_index) {
- return frame->frame.layers[layer_index].app_id;
-}
-
-uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].z_order;
-}
-
-void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
- int32_t* out_x, int32_t* out_y) {
- *out_x = frame->frame.layers[layer_index].cursor_x;
- *out_y = frame->frame.layers[layer_index].cursor_y;
-}
-
-uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].transform;
-}
-
-uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) {
- return frame->frame.layers[layer_index].dataspace;
-}
-
-uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) {
- const auto& color = frame->frame.layers[layer_index].color;
- return color.r | (static_cast<uint32_t>(color.g) << 8) |
- (static_cast<uint32_t>(color.b) << 16) |
- (static_cast<uint32_t>(color.a) << 24);
-}
-
-uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
- size_t layer_index) {
- return frame->frame.layers[layer_index].visible_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
- size_t layer_index, size_t index) {
- return DvrHwcRecti{
- frame->frame.layers[layer_index].visible_regions[index].left,
- frame->frame.layers[layer_index].visible_regions[index].top,
- frame->frame.layers[layer_index].visible_regions[index].right,
- frame->frame.layers[layer_index].visible_regions[index].bottom,
- };
-}
-
-uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
- size_t layer_index) {
- return frame->frame.layers[layer_index].damaged_regions.size();
-}
-
-DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
- size_t layer_index, size_t index) {
- return DvrHwcRecti{
- frame->frame.layers[layer_index].damaged_regions[index].left,
- frame->frame.layers[layer_index].damaged_regions[index].top,
- frame->frame.layers[layer_index].damaged_regions[index].right,
- frame->frame.layers[layer_index].damaged_regions[index].bottom,
- };
-}
diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h
deleted file mode 100644
index f845cd8..0000000
--- a/libs/vr/libdvr/dvr_internal.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef ANDROID_DVR_INTERNAL_H_
-#define ANDROID_DVR_INTERNAL_H_
-
-#include <sys/cdefs.h>
-
-#include <memory>
-
-extern "C" {
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-
-} // extern "C"
-
-namespace android {
-namespace dvr {
-
-class IonBuffer;
-
-DvrBuffer* CreateDvrBufferFromIonBuffer(
- const std::shared_ptr<IonBuffer>& ion_buffer);
-
-} // namespace dvr
-} // namespace android
-
-extern "C" {
-
-struct DvrWriteBuffer {
- // The slot nubmer of the buffer, a valid slot number must be in the range of
- // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
- // DvrWriteBuffer acquired from a DvrWriteBufferQueue.
- int32_t slot = -1;
-
- std::shared_ptr<android::dvr::ProducerBuffer> write_buffer;
-};
-
-struct DvrReadBuffer {
- // The slot nubmer of the buffer, a valid slot number must be in the range of
- // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for
- // DvrReadBuffer acquired from a DvrReadBufferQueue.
- int32_t slot = -1;
-
- std::shared_ptr<android::dvr::ConsumerBuffer> read_buffer;
-};
-
-struct DvrBuffer {
- std::shared_ptr<android::dvr::IonBuffer> buffer;
-};
-
-} // extern "C"
-
-#endif // ANDROID_DVR_INTERNAL_H_
diff --git a/libs/vr/libdvr/dvr_performance.cpp b/libs/vr/libdvr/dvr_performance.cpp
deleted file mode 100644
index 599101f..0000000
--- a/libs/vr/libdvr/dvr_performance.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "include/dvr/dvr_performance.h"
-
-#include <private/dvr/performance_client.h>
-
-using android::dvr::PerformanceClient;
-
-extern "C" {
-
-int dvrPerformanceSetSchedulerPolicy(pid_t task_id,
- const char* scheduler_policy) {
- int error;
- if (auto client = PerformanceClient::Create(&error))
- return client->SetSchedulerPolicy(task_id, scheduler_policy);
- else
- return error;
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_pose.cpp b/libs/vr/libdvr/dvr_pose.cpp
deleted file mode 100644
index c379ef5..0000000
--- a/libs/vr/libdvr/dvr_pose.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "include/dvr/dvr_pose.h"
-
-#include <memory>
-
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/pose_client_internal.h>
-
-#include "dvr_buffer_queue_internal.h"
-
-using android::dvr::ConsumerQueue;
-
-int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type,
- DvrReadBufferQueue** queue_out) {
- if (!client || !queue_out)
- return -EINVAL;
-
- ConsumerQueue* consumer_queue;
- int status = android::dvr::dvrPoseClientGetDataReaderHandle(client,
- data_type,
- &consumer_queue);
- if (status != 0) {
- ALOGE("dvrPoseClientGetDataReader: Failed to get queue: %d", status);
- return status;
- }
-
- std::shared_ptr<ConsumerQueue> consumer_queue_ptr{consumer_queue};
- *queue_out = new DvrReadBufferQueue(consumer_queue_ptr);
- return 0;
-}
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
deleted file mode 100644
index 0c7ec01..0000000
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-#include "include/dvr/dvr_surface.h"
-
-#include <inttypes.h>
-
-#include <pdx/rpc/variant.h>
-#include <private/android/AHardwareBufferHelpers.h>
-#include <private/dvr/display_client.h>
-
-#include "dvr_buffer_queue_internal.h"
-#include "dvr_internal.h"
-
-using android::AHardwareBuffer_convertToGrallocUsageBits;
-using android::dvr::display::DisplayClient;
-using android::dvr::display::Surface;
-using android::dvr::display::SurfaceAttributes;
-using android::dvr::display::SurfaceAttributeValue;
-using android::pdx::rpc::EmptyVariant;
-
-namespace {
-
-// Sets the Variant |destination| to the target std::array type and copies the C
-// array into it. Unsupported std::array configurations will fail to compile.
-template <typename T, std::size_t N>
-void ArrayCopy(SurfaceAttributeValue* destination, const T (&source)[N]) {
- using ArrayType = std::array<T, N>;
- *destination = ArrayType{};
- std::copy(std::begin(source), std::end(source),
- std::get<ArrayType>(*destination).begin());
-}
-
-bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes,
- size_t attribute_count,
- SurfaceAttributes* surface_attributes,
- size_t* error_index) {
- for (size_t i = 0; i < attribute_count; i++) {
- SurfaceAttributeValue value;
- switch (attributes[i].value.type) {
- case DVR_SURFACE_ATTRIBUTE_TYPE_INT32:
- value = attributes[i].value.int32_value;
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_INT64:
- value = attributes[i].value.int64_value;
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL:
- // bool_value is defined in an extern "C" block, which makes it look
- // like an int to C++. Use a cast to assign the correct type to the
- // Variant type SurfaceAttributeValue.
- value = static_cast<bool>(attributes[i].value.bool_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT:
- value = attributes[i].value.float_value;
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2:
- ArrayCopy(&value, attributes[i].value.float2_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3:
- ArrayCopy(&value, attributes[i].value.float3_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4:
- ArrayCopy(&value, attributes[i].value.float4_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8:
- ArrayCopy(&value, attributes[i].value.float8_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16:
- ArrayCopy(&value, attributes[i].value.float16_value);
- break;
- case DVR_SURFACE_ATTRIBUTE_TYPE_NONE:
- value = EmptyVariant{};
- break;
- default:
- *error_index = i;
- return false;
- }
-
- surface_attributes->emplace(attributes[i].key, value);
- }
-
- return true;
-}
-
-} // anonymous namespace
-
-extern "C" {
-
-struct DvrSurface {
- std::unique_ptr<Surface> surface;
-};
-
-int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
- size_t attribute_count, DvrSurface** out_surface) {
- if (out_surface == nullptr) {
- ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface);
- return -EINVAL;
- }
-
- size_t error_index;
- SurfaceAttributes surface_attributes;
- if (!ConvertSurfaceAttributes(attributes, attribute_count,
- &surface_attributes, &error_index)) {
- ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64,
- attributes[error_index].value.type);
- return -EINVAL;
- }
-
- auto status = Surface::CreateSurface(surface_attributes);
- if (!status) {
- ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
- }
-
- *out_surface = new DvrSurface{status.take()};
- return 0;
-}
-
-void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; }
-
-int dvrSurfaceGetId(DvrSurface* surface) {
- return surface->surface->surface_id();
-}
-
-int dvrSurfaceSetAttributes(DvrSurface* surface,
- const DvrSurfaceAttribute* attributes,
- size_t attribute_count) {
- if (surface == nullptr || attributes == nullptr) {
- ALOGE(
- "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p "
- "attribute_count=%zu",
- surface, attributes, attribute_count);
- return -EINVAL;
- }
-
- size_t error_index;
- SurfaceAttributes surface_attributes;
- if (!ConvertSurfaceAttributes(attributes, attribute_count,
- &surface_attributes, &error_index)) {
- ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64,
- attributes[error_index].value.type);
- return -EINVAL;
- }
-
- auto status = surface->surface->SetAttributes(surface_attributes);
- if (!status) {
- ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
- }
-
- return 0;
-}
-
-int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
- uint32_t height, uint32_t format,
- uint32_t layer_count, uint64_t usage,
- size_t capacity, size_t metadata_size,
- DvrWriteBufferQueue** out_writer) {
- if (surface == nullptr || out_writer == nullptr) {
- ALOGE(
- "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, "
- "out_writer=%p.",
- surface, out_writer);
- return -EINVAL;
- }
-
- auto status = surface->surface->CreateQueue(
- width, height, layer_count, format, usage, capacity, metadata_size);
- if (!status) {
- ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
- }
-
- *out_writer = new DvrWriteBufferQueue(status.take());
- return 0;
-}
-
-int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
- DvrBuffer** buffer_out) {
- if (!buffer_out)
- return -EINVAL;
-
- int error;
- auto client = DisplayClient::Create(&error);
- if (!client) {
- ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s",
- strerror(-error));
- return error;
- }
-
- uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
-
- auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage);
- if (!buffer_status) {
- ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s",
- buffer_status.GetErrorMessage().c_str());
- return -buffer_status.error();
- }
-
- *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take());
- return 0;
-}
-
-int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) {
- int error;
- auto client = DisplayClient::Create(&error);
- if (!client) {
- ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s",
- strerror(-error));
- return error;
- }
-
- auto buffer_status = client->DeleteGlobalBuffer(key);
- if (!buffer_status) {
- ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s",
- buffer_status.GetErrorMessage().c_str());
- return -buffer_status.error();
- }
-
- return 0;
-}
-
-int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) {
- if (!out_buffer)
- return -EINVAL;
-
- int error;
- auto client = DisplayClient::Create(&error);
- if (!client) {
- ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s",
- strerror(-error));
- return error;
- }
-
- auto status = client->GetGlobalBuffer(key);
- if (!status) {
- return -status.error();
- }
- *out_buffer = CreateDvrBufferFromIonBuffer(status.take());
- return 0;
-}
-
-int dvrGetNativeDisplayMetrics(size_t sizeof_metrics,
- DvrNativeDisplayMetrics* metrics) {
- ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics),
- "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api "
- "header is out of date.");
-
- auto client = DisplayClient::Create();
- if (!client) {
- ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!");
- return -ECOMM;
- }
-
- if (metrics == nullptr) {
- ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null");
- return -EINVAL;
- }
-
- auto status = client->GetDisplayMetrics();
-
- if (!status) {
- return -status.error();
- }
-
- if (sizeof_metrics >= 20) {
- metrics->display_width = status.get().display_width;
- metrics->display_height = status.get().display_height;
- metrics->display_x_dpi = status.get().display_x_dpi;
- metrics->display_y_dpi = status.get().display_y_dpi;
- metrics->vsync_period_ns = status.get().vsync_period_ns;
- }
-
- return 0;
-}
-
-} // extern "C"
diff --git a/libs/vr/libdvr/dvr_tracking.cpp b/libs/vr/libdvr/dvr_tracking.cpp
deleted file mode 100644
index 73addc9..0000000
--- a/libs/vr/libdvr/dvr_tracking.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "include/dvr/dvr_tracking.h"
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#if !DVR_TRACKING_IMPLEMENTED
-
-extern "C" {
-
-// This file provides the stub implementation of dvrTrackingXXX APIs. On
-// platforms that implement these APIs, set -DDVR_TRACKING_IMPLEMENTED=1 in the
-// build file.
-int dvrTrackingCameraCreate(DvrTrackingCamera**) {
- ALOGE("dvrTrackingCameraCreate is not implemented.");
- return -ENOSYS;
-}
-
-void dvrTrackingCameraDestroy(DvrTrackingCamera*) {
- ALOGE("dvrTrackingCameraDestroy is not implemented.");
-}
-
-int dvrTrackingCameraStart(DvrTrackingCamera*, DvrWriteBufferQueue*) {
- ALOGE("dvrTrackingCameraCreate is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingCameraStop(DvrTrackingCamera*) {
- ALOGE("dvrTrackingCameraCreate is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorCreate(DvrTrackingFeatureExtractor**) {
- ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
- return -ENOSYS;
-}
-
-void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor*) {
- ALOGE("dvrTrackingFeatureExtractorDestroy is not implemented.");
-}
-
-int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor*,
- DvrTrackingFeatureCallback, void*) {
- ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor*) {
- ALOGE("dvrTrackingFeatureExtractorCreate is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingFeatureExtractorProcessBuffer(DvrTrackingFeatureExtractor*,
- DvrReadBuffer*,
- const DvrTrackingBufferMetadata*,
- bool*) {
- ALOGE("dvrTrackingFeatureExtractorProcessBuffer is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingSensorsCreate(DvrTrackingSensors**, const char*) {
- ALOGE("dvrTrackingSensorsCreate is not implemented.");
- return -ENOSYS;
-}
-
-void dvrTrackingSensorsDestroy(DvrTrackingSensors*) {
- ALOGE("dvrTrackingSensorsDestroy is not implemented.");
-}
-
-int dvrTrackingSensorsStart(DvrTrackingSensors*, DvrTrackingSensorEventCallback,
- void*) {
- ALOGE("dvrTrackingStart is not implemented.");
- return -ENOSYS;
-}
-
-int dvrTrackingSensorsStop(DvrTrackingSensors*) {
- ALOGE("dvrTrackingStop is not implemented.");
- return -ENOSYS;
-}
-
-} // extern "C"
-
-#endif // DVR_TRACKING_IMPLEMENTED
diff --git a/libs/vr/libdvr/exported_apis.lds b/libs/vr/libdvr/exported_apis.lds
deleted file mode 100644
index 5ecb498..0000000
--- a/libs/vr/libdvr/exported_apis.lds
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- global:
- # Whitelist the function to load the dvr api.
- dvrGetApi;
-
- local:
- # Hide everything else.
- *;
-};
diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp
deleted file mode 100644
index fe7feb8..0000000
--- a/libs/vr/libdvr/tests/Android.bp
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_native_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_test {
- srcs: [
- "dvr_display_manager-test.cpp",
- "dvr_named_buffer-test.cpp",
- "dvr_tracking-test.cpp",
- ],
-
- header_libs: ["libdvr_headers"],
- static_libs: [
- "libdvr_static.google",
- "libchrome",
- "libdvrcommon",
- "libdisplay",
- "libbroadcastring",
- ],
- shared_libs: [
- "libbase",
- "libbinder",
- "libbufferhubqueue",
- "libcutils",
- "libgui",
- "liblog",
- "libhardware",
- "libui",
- "libutils",
- "libnativewindow",
- "libpdx_default_transport",
- ],
- cflags: [
- "-DDVR_TRACKING_IMPLEMENTED=0",
- "-DLOG_TAG=\"dvr_api-test\"",
- "-DTRACE=0",
- "-Wno-missing-field-initializers",
- "-O0",
- "-g",
- ],
- name: "dvr_api-test",
-}
-
-cc_test {
- name: "dvr_buffer_queue-test",
-
- // Includes the dvr_api.h header. Tests should only include "dvr_api.h",
- // and shall only get access to |dvrGetApi|, as other symbols are hidden
- // from the library.
- include_dirs: ["frameworks/native/libs/vr/libdvr/include"],
-
- srcs: ["dvr_buffer_queue-test.cpp"],
-
- shared_libs: [
- "libandroid",
- "liblog",
- ],
-
- cflags: [
- "-DTRACE=0",
- "-O2",
- "-g",
- ],
-
- // DTS Should only link to NDK libraries.
- sdk_version: "26",
- stl: "c++_static",
-}
-
-cc_test {
- name: "dvr_display-test",
-
- include_dirs: [
- "frameworks/native/libs/vr/libdvr/include",
- "frameworks/native/libs/nativewindow/include",
- ],
-
- srcs: ["dvr_display-test.cpp"],
-
- shared_libs: [
- "libandroid",
- "liblog",
- ],
-
- cflags: [
- "-DTRACE=0",
- "-O2",
- "-g",
- ],
-
- // DTS Should only link to NDK libraries.
- sdk_version: "26",
- stl: "c++_static",
-}
diff --git a/libs/vr/libdvr/tests/dvr_api_test.h b/libs/vr/libdvr/tests/dvr_api_test.h
deleted file mode 100644
index 5d2ec28..0000000
--- a/libs/vr/libdvr/tests/dvr_api_test.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <dlfcn.h>
-#include <dvr/dvr_api.h>
-
-#include <gtest/gtest.h>
-
-/** DvrTestBase loads the libdvr.so at runtime and get the Dvr API version 1. */
-class DvrApiTest : public ::testing::Test {
- protected:
- void SetUp() override {
- int flags = RTLD_NOW | RTLD_LOCAL;
-
- // Here we need to ensure that libdvr is loaded with RTLD_NODELETE flag set
- // (so that calls to `dlclose` don't actually unload the library). This is a
- // workaround for an Android NDK bug. See more detail:
- // https://github.com/android-ndk/ndk/issues/360
- flags |= RTLD_NODELETE;
- platform_handle_ = dlopen("libdvr.google.so", flags);
- ASSERT_NE(nullptr, platform_handle_) << "Dvr shared library missing.";
-
- auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>(
- dlsym(platform_handle_, "dvrGetApi"));
- ASSERT_NE(nullptr, dvr_get_api) << "Platform library missing dvrGetApi.";
-
- ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0)
- << "Unable to find compatible Dvr API.";
- }
-
- void TearDown() override {
- if (platform_handle_ != nullptr) {
- dlclose(platform_handle_);
- }
- }
-
- void* platform_handle_ = nullptr;
- DvrApi_v1 api_;
-};
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
deleted file mode 100644
index df06097..0000000
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-#include <android/log.h>
-#include <android/native_window.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_buffer_queue.h>
-
-#include <gtest/gtest.h>
-
-#include <array>
-#include <unordered_map>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_buffer_queue-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-#ifndef ALOGD_IF
-#define ALOGD_IF(cond, ...) \
- ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0)
-#endif
-
-namespace {
-
-static constexpr uint32_t kBufferWidth = 100;
-static constexpr uint32_t kBufferHeight = 1;
-static constexpr uint32_t kLayerCount = 1;
-static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB;
-static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN;
-static constexpr size_t kQueueCapacity = 3;
-
-class DvrBufferQueueTest : public DvrApiTest {
- public:
- static void BufferAvailableCallback(void* context) {
- DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
- thiz->HandleBufferAvailable();
- }
-
- static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
- DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
- thiz->HandleBufferRemoved(buffer);
- }
-
- protected:
- void TearDown() override {
- if (write_queue_ != nullptr) {
- api_.WriteBufferQueueDestroy(write_queue_);
- write_queue_ = nullptr;
- }
- DvrApiTest::TearDown();
- }
-
- void HandleBufferAvailable() {
- buffer_available_count_ += 1;
- ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
- }
-
- void HandleBufferRemoved(DvrReadBuffer* buffer) {
- buffer_removed_count_ += 1;
- ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
- buffer_removed_count_);
- }
-
- DvrWriteBufferQueue* write_queue_ = nullptr;
- int buffer_available_count_{0};
- int buffer_removed_count_{0};
-};
-
-TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- api_.WriteBufferQueueDestroy(write_queue_);
- write_queue_ = nullptr;
-}
-
-TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- size_t capacity = api_.WriteBufferQueueGetCapacity(write_queue_);
-
- ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
- ASSERT_EQ(kQueueCapacity, capacity);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- DvrReadBufferQueue* read_queue = nullptr;
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, read_queue);
-
- api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- DvrReadBufferQueue* read_queue1 = nullptr;
- DvrReadBufferQueue* read_queue2 = nullptr;
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
-
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, read_queue1);
-
- ret = api_.ReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, read_queue2);
- ASSERT_NE(read_queue1, read_queue2);
-
- api_.ReadBufferQueueDestroy(read_queue1);
- api_.ReadBufferQueueDestroy(read_queue2);
-}
-
-TEST_F(DvrBufferQueueTest, GainBuffer) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(ret, 0);
-
- DvrWriteBuffer* wb = nullptr;
- EXPECT_FALSE(api_.WriteBufferIsValid(wb));
-
- DvrNativeBufferMetadata meta;
- int fence_fd = -1;
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta,
- &fence_fd);
- ASSERT_EQ(ret, 0);
- EXPECT_EQ(fence_fd, -1);
- EXPECT_NE(wb, nullptr);
- EXPECT_TRUE(api_.WriteBufferIsValid(wb));
-}
-
-TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(ret, 0);
-
- DvrReadBufferQueue* read_queue = nullptr;
- DvrReadBuffer* rb = nullptr;
- DvrWriteBuffer* wb = nullptr;
- DvrNativeBufferMetadata meta1;
- DvrNativeBufferMetadata meta2;
- int fence_fd = -1;
-
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
- ASSERT_EQ(ret, 0);
- ASSERT_NE(read_queue, nullptr);
-
- api_.ReadBufferQueueSetBufferAvailableCallback(
- read_queue, &BufferAvailableCallback, this);
-
- // Gain buffer for writing.
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
- &meta1, &fence_fd);
- ASSERT_EQ(ret, 0);
- ASSERT_NE(wb, nullptr);
- ASSERT_TRUE(api_.WriteBufferIsValid(wb));
- ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
- wb, fence_fd);
- close(fence_fd);
-
- // Post buffer to the read_queue.
- meta1.timestamp = 42;
- ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
- ASSERT_EQ(ret, 0);
- ASSERT_FALSE(api_.WriteBufferIsValid(wb));
- wb = nullptr;
-
- // Acquire buffer for reading.
- ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
- &meta2, &fence_fd);
- ASSERT_EQ(ret, 0);
- ASSERT_NE(rb, nullptr);
-
- // Dequeue is successfully, BufferAvailableCallback should be fired once.
- ASSERT_EQ(buffer_available_count_, 1);
- ASSERT_TRUE(api_.ReadBufferIsValid(rb));
-
- // Metadata should be passed along from producer to consumer properly.
- ASSERT_EQ(meta1.timestamp, meta2.timestamp);
-
- ALOGD_IF(TRACE,
- "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
- fence_fd);
- close(fence_fd);
-
- // Release buffer to the write_queue.
- ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
- /*release_fence_fd=*/-1);
- ASSERT_EQ(ret, 0);
- ASSERT_FALSE(api_.ReadBufferIsValid(rb));
- rb = nullptr;
-
- // TODO(b/34387835) Currently buffer allocation has to happen after all queues
- // are initialized.
- size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
-
- ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
- ASSERT_EQ(kQueueCapacity, capacity);
-
- api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, GetANativeWindow) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- /*capacity=*/0, /*user_metadata_size=*/0, &write_queue_);
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, write_queue_);
-
- ANativeWindow* window = nullptr;
- ret = api_.WriteBufferQueueGetANativeWindow(write_queue_, &window);
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, window);
-
- uint32_t width = ANativeWindow_getWidth(window);
- uint32_t height = ANativeWindow_getHeight(window);
- uint32_t format = ANativeWindow_getFormat(window);
- ASSERT_EQ(kBufferWidth, width);
- ASSERT_EQ(kBufferHeight, height);
- ASSERT_EQ(kBufferFormat, format);
-}
-
-// Create buffer queue of three buffers and dequeue three buffers out of it.
-// Before each dequeue operation, we resize the buffer queue and expect the
-// queue always return buffer with desired dimension.
-TEST_F(DvrBufferQueueTest, ResizeBuffer) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- int fence_fd = -1;
-
- DvrNativeBufferMetadata meta;
- DvrReadBufferQueue* read_queue = nullptr;
- DvrWriteBuffer* wb1 = nullptr;
- DvrWriteBuffer* wb2 = nullptr;
- DvrWriteBuffer* wb3 = nullptr;
- AHardwareBuffer* ahb1 = nullptr;
- AHardwareBuffer* ahb2 = nullptr;
- AHardwareBuffer* ahb3 = nullptr;
- AHardwareBuffer_Desc buffer_desc;
-
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, read_queue);
-
- api_.ReadBufferQueueSetBufferRemovedCallback(read_queue,
- &BufferRemovedCallback, this);
-
- // Handle all pending events on the read queue.
- ret = api_.ReadBufferQueueHandleEvents(read_queue);
- ASSERT_EQ(0, ret);
-
- size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue);
- ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
- ASSERT_EQ(kQueueCapacity, capacity);
-
- // Resize before dequeuing.
- constexpr uint32_t w1 = 10;
- ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
- ASSERT_EQ(0, ret);
-
- // Gain first buffer for writing. All buffers will be resized.
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1,
- &meta, &fence_fd);
- ASSERT_EQ(0, ret);
- ASSERT_TRUE(api_.WriteBufferIsValid(wb1));
- ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
- close(fence_fd);
-
- // Check the buffer dimension.
- ret = api_.WriteBufferGetAHardwareBuffer(wb1, &ahb1);
- ASSERT_EQ(0, ret);
- AHardwareBuffer_describe(ahb1, &buffer_desc);
- ASSERT_EQ(w1, buffer_desc.width);
- ASSERT_EQ(kBufferHeight, buffer_desc.height);
- AHardwareBuffer_release(ahb1);
-
- // For the first resize, all buffers are reallocated.
- int expected_buffer_removed_count = kQueueCapacity;
- ret = api_.ReadBufferQueueHandleEvents(read_queue);
- ASSERT_EQ(0, ret);
- ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
- // Resize the queue. We are testing with blob format, keep height to be 1.
- constexpr uint32_t w2 = 20;
- ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
- ASSERT_EQ(0, ret);
-
- // The next buffer we dequeued should have new width.
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2,
- &meta, &fence_fd);
- ASSERT_EQ(0, ret);
- ASSERT_TRUE(api_.WriteBufferIsValid(wb2));
- ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
- fence_fd);
- close(fence_fd);
-
- // Check the buffer dimension, should be new width
- ret = api_.WriteBufferGetAHardwareBuffer(wb2, &ahb2);
- ASSERT_EQ(0, ret);
- AHardwareBuffer_describe(ahb2, &buffer_desc);
- ASSERT_EQ(w2, buffer_desc.width);
- AHardwareBuffer_release(ahb2);
-
- // For the second resize, all but one buffers are reallocated.
- expected_buffer_removed_count += (kQueueCapacity - 1);
- ret = api_.ReadBufferQueueHandleEvents(read_queue);
- ASSERT_EQ(0, ret);
- ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
- // Resize the queue for the third time.
- constexpr uint32_t w3 = 30;
- ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
- ASSERT_EQ(0, ret);
-
- // The next buffer we dequeued should have new width.
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3,
- &meta, &fence_fd);
- ASSERT_EQ(0, ret);
- ASSERT_TRUE(api_.WriteBufferIsValid(wb3));
- ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
- fence_fd);
- close(fence_fd);
-
- // Check the buffer dimension, should be new width
- ret = api_.WriteBufferGetAHardwareBuffer(wb3, &ahb3);
- ASSERT_EQ(0, ret);
- AHardwareBuffer_describe(ahb3, &buffer_desc);
- ASSERT_EQ(w3, buffer_desc.width);
- AHardwareBuffer_release(ahb3);
-
- // For the third resize, all but two buffers are reallocated.
- expected_buffer_removed_count += (kQueueCapacity - 2);
- ret = api_.ReadBufferQueueHandleEvents(read_queue);
- ASSERT_EQ(0, ret);
- ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);
-
- api_.ReadBufferQueueDestroy(read_queue);
-}
-
-TEST_F(DvrBufferQueueTest, ReadQueueEventFd) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- DvrReadBufferQueue* read_queue = nullptr;
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
-
- ASSERT_EQ(0, ret);
- ASSERT_NE(nullptr, read_queue);
-
- int event_fd = api_.ReadBufferQueueGetEventFd(read_queue);
- ASSERT_GT(event_fd, 0);
-}
-
-// Verifies a Dvr{Read,Write}BufferQueue contains the same set of
-// Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id,
-// the corresponding AHardwareBuffer handle stays the same.
-TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(0, ret);
-
- int fence_fd = -1;
- DvrReadBufferQueue* read_queue = nullptr;
- EXPECT_EQ(0, api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue));
-
- // Read buffers.
- std::array<DvrReadBuffer*, kQueueCapacity> rbs;
- // Write buffers.
- std::array<DvrWriteBuffer*, kQueueCapacity> wbs;
- // Buffer metadata.
- std::array<DvrNativeBufferMetadata, kQueueCapacity> metas;
- // Hardware buffers for Read buffers.
- std::unordered_map<int, AHardwareBuffer*> rhbs;
- // Hardware buffers for Write buffers.
- std::unordered_map<int, AHardwareBuffer*> whbs;
-
- constexpr int kNumTests = 100;
-
- // This test runs the following operations many many times. Thus we prefer to
- // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output.
- std::function<void(size_t i)> Gain = [&](size_t i) {
- int ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10,
- &wbs[i], &metas[i], &fence_fd);
- ASSERT_EQ(ret, 0);
- ASSERT_LT(fence_fd, 0); // expect invalid fence.
- ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
- int buffer_id = api_.WriteBufferGetId(wbs[i]);
- ASSERT_GT(buffer_id, 0);
-
- AHardwareBuffer* hb = nullptr;
- ASSERT_EQ(0, api_.WriteBufferGetAHardwareBuffer(wbs[i], &hb));
-
- auto whb_it = whbs.find(buffer_id);
- if (whb_it == whbs.end()) {
- // If this is a new buffer id, check that total number of unique
- // hardware buffers won't exceed queue capacity.
- ASSERT_LT(whbs.size(), kQueueCapacity);
- whbs.emplace(buffer_id, hb);
- } else {
- // If this is a buffer id we have seen before, check that the
- // buffer_id maps to the same AHardwareBuffer handle.
- ASSERT_EQ(hb, whb_it->second);
- }
- };
-
- std::function<void(size_t i)> Post = [&](size_t i) {
- ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i]));
-
- metas[i].timestamp++;
- int ret = api_.WriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i],
- /*fence=*/-1);
- ASSERT_EQ(ret, 0);
- };
-
- std::function<void(size_t i)> Acquire = [&](size_t i) {
- int ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10,
- &rbs[i], &metas[i], &fence_fd);
- ASSERT_EQ(ret, 0);
- ASSERT_LT(fence_fd, 0); // expect invalid fence.
- ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
- int buffer_id = api_.ReadBufferGetId(rbs[i]);
- ASSERT_GT(buffer_id, 0);
-
- AHardwareBuffer* hb = nullptr;
- ASSERT_EQ(0, api_.ReadBufferGetAHardwareBuffer(rbs[i], &hb));
-
- auto rhb_it = rhbs.find(buffer_id);
- if (rhb_it == rhbs.end()) {
- // If this is a new buffer id, check that total number of unique hardware
- // buffers won't exceed queue capacity.
- ASSERT_LT(rhbs.size(), kQueueCapacity);
- rhbs.emplace(buffer_id, hb);
- } else {
- // If this is a buffer id we have seen before, check that the buffer_id
- // maps to the same AHardwareBuffer handle.
- ASSERT_EQ(hb, rhb_it->second);
- }
- };
-
- std::function<void(size_t i)> Release = [&](size_t i) {
- ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i]));
-
- int ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i],
- /*release_fence_fd=*/-1);
- ASSERT_EQ(ret, 0);
- };
-
- // Scenario one:
- for (int i = 0; i < kNumTests; i++) {
- // Gain all write buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Gain(i));
- }
- // Post all write buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Post(i));
- }
- // Acquire all read buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Acquire(i));
- }
- // Release all read buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Release(i));
- }
- }
-
- // Scenario two:
- for (int i = 0; i < kNumTests; i++) {
- // Gain and post all write buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Gain(i));
- ASSERT_NO_FATAL_FAILURE(Post(i));
- }
- // Acquire and release all read buffers.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Acquire(i));
- ASSERT_NO_FATAL_FAILURE(Release(i));
- }
- }
-
- // Scenario three:
- for (int i = 0; i < kNumTests; i++) {
- // Gain all write buffers then post them in reversed order.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Gain(i));
- }
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i));
- }
-
- // Acquire all write buffers then release them in reversed order.
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Acquire(i));
- }
- for (size_t i = 0; i < kQueueCapacity; i++) {
- ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i));
- }
- }
-}
-
-TEST_F(DvrBufferQueueTest, ConsumerReleaseAfterProducerDestroy) {
- int ret = api_.WriteBufferQueueCreate(
- kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage,
- kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_);
- ASSERT_EQ(ret, 0);
-
- DvrReadBufferQueue* read_queue = nullptr;
- DvrReadBuffer* rb = nullptr;
- DvrWriteBuffer* wb = nullptr;
- DvrNativeBufferMetadata meta1;
- DvrNativeBufferMetadata meta2;
- int fence_fd = -1;
-
- ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
- ASSERT_EQ(ret, 0);
-
- api_.ReadBufferQueueSetBufferAvailableCallback(
- read_queue, &BufferAvailableCallback, this);
-
- // Gain buffer for writing.
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb,
- &meta1, &fence_fd);
- ASSERT_EQ(ret, 0);
- close(fence_fd);
-
- // Post buffer to the read_queue.
- ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1);
- ASSERT_EQ(ret, 0);
- wb = nullptr;
-
- // Acquire buffer for reading.
- ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb,
- &meta2, &fence_fd);
- ASSERT_EQ(ret, 0);
- close(fence_fd);
-
- // Destroy the write buffer queue and make sure the reader queue is picking
- // these events up.
- api_.WriteBufferQueueDestroy(write_queue_);
- ret = api_.ReadBufferQueueHandleEvents(read_queue);
- ASSERT_EQ(0, ret);
-
- // Release buffer to the write_queue.
- ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2,
- /*release_fence_fd=*/-1);
- ASSERT_EQ(ret, 0);
- rb = nullptr;
-
- api_.ReadBufferQueueDestroy(read_queue);
-}
-
-} // namespace
diff --git a/libs/vr/libdvr/tests/dvr_display-test.cpp b/libs/vr/libdvr/tests/dvr_display-test.cpp
deleted file mode 100644
index c72f940..0000000
--- a/libs/vr/libdvr/tests/dvr_display-test.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <android/log.h>
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-#define LOG_TAG "dvr_display-test"
-
-#ifndef ALOGD
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
-#endif
-
-class DvrDisplayTest : public DvrApiTest {
- protected:
- void SetUp() override {
- DvrApiTest::SetUp();
- int ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics_),
- &display_metrics_);
- ASSERT_EQ(ret, 0) << "Failed to get display metrics.";
- ALOGD(
- "display_width: %d, display_height: %d, display_x_dpi: %d, "
- "display_y_dpi: %d, vsync_period_ns: %d.",
- display_metrics_.display_width, display_metrics_.display_height,
- display_metrics_.display_x_dpi, display_metrics_.display_y_dpi,
- display_metrics_.vsync_period_ns);
- }
-
- void TearDown() override {
- if (write_queue_ != nullptr) {
- api_.WriteBufferQueueDestroy(write_queue_);
- write_queue_ = nullptr;
- }
- if (direct_surface_ != nullptr) {
- api_.SurfaceDestroy(direct_surface_);
- direct_surface_ = nullptr;
- }
- DvrApiTest::TearDown();
- }
-
- /* Convert a write buffer to an android hardware buffer and fill in
- * color_textures evenly to the buffer.
- * AssertionError if the width of the buffer is not equal to the input width,
- * AssertionError if the height of the buffer is not equal to the input
- * height.
- */
- void FillWriteBuffer(DvrWriteBuffer* write_buffer,
- const std::vector<uint32_t>& color_textures,
- uint32_t width, uint32_t height);
-
- // Write buffer queue properties.
- static constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
- AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
- static constexpr size_t kMetadataSize = 0;
- static constexpr int kTimeoutMs = 1000; // Time for getting buffer.
- uint32_t kLayerCount = 1;
- DvrWriteBufferQueue* write_queue_ = nullptr;
- DvrSurface* direct_surface_ = nullptr;
-
- // Device display properties.
- DvrNativeDisplayMetrics display_metrics_;
-};
-
-TEST_F(DvrDisplayTest, DisplayWithOneBuffer) {
- // Create a direct surface.
- std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
- {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
- .value.int32_value = 10},
- {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- };
- int ret =
- api_.SurfaceCreate(direct_surface_attributes.data(),
- direct_surface_attributes.size(), &direct_surface_);
- ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
- // Create a buffer queue with the direct surface.
- constexpr size_t kCapacity = 1;
- uint32_t width = display_metrics_.display_width;
- uint32_t height = display_metrics_.display_height;
- ret = api_.SurfaceCreateWriteBufferQueue(
- direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
- kMetadataSize, &write_queue_);
- EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
- ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
- // Get buffer from WriteBufferQueue.
- DvrWriteBuffer* write_buffer = nullptr;
- DvrNativeBufferMetadata out_meta;
- int out_fence_fd = -1;
- ret = api_.WriteBufferQueueGainBuffer(write_queue_, kTimeoutMs, &write_buffer,
- &out_meta, &out_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to get the buffer.";
- ASSERT_NE(nullptr, write_buffer) << "Gained buffer should not be null.";
-
- // Color the write buffer.
- FillWriteBuffer(write_buffer,
- {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000},
- width, height);
-
- // Post buffer.
- int ready_fence_fd = -1;
- ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
- ready_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
- sleep(5); // For visual check on the device under test.
- // Should observe three primary colors on the screen center.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithDoubleBuffering) {
- // Create a direct surface.
- std::vector<DvrSurfaceAttribute> direct_surface_attributes = {
- {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
- .value.int32_value = 10},
- {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- };
- int ret =
- api_.SurfaceCreate(direct_surface_attributes.data(),
- direct_surface_attributes.size(), &direct_surface_);
- ASSERT_EQ(ret, 0) << "Failed to create direct surface.";
-
- // Create a buffer queue with the direct surface.
- constexpr size_t kCapacity = 2;
- uint32_t width = display_metrics_.display_width;
- uint32_t height = display_metrics_.display_height;
- ret = api_.SurfaceCreateWriteBufferQueue(
- direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity,
- kMetadataSize, &write_queue_);
- EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
- ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null.";
-
- int num_display_cycles_in_5s = 5 / (display_metrics_.vsync_period_ns / 1e9);
- ALOGD("The number of display cycles: %d", num_display_cycles_in_5s);
- int bufferhub_id_prev_write_buffer = -1;
- for (int i = 0; i < num_display_cycles_in_5s; ++i) {
- // Get a buffer from the WriteBufferQueue.
- DvrWriteBuffer* write_buffer = nullptr;
- DvrNativeBufferMetadata out_meta;
- int out_fence_fd = -1;
- ret = api_.WriteBufferQueueGainBuffer(
- write_queue_, kTimeoutMs, &write_buffer, &out_meta, &out_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to get the a write buffer.";
- ASSERT_NE(nullptr, write_buffer) << "The gained buffer should not be null.";
-
- int bufferhub_id = api_.WriteBufferGetId(write_buffer);
- ALOGD("Display cycle: %d, bufferhub id of the write buffer: %d", i,
- bufferhub_id);
- EXPECT_NE(bufferhub_id_prev_write_buffer, bufferhub_id)
- << "Double buffering should be using the two buffers in turns, not "
- "reusing the same write buffer.";
- bufferhub_id_prev_write_buffer = bufferhub_id;
-
- // Color the write buffer.
- if (i % 2) {
- FillWriteBuffer(write_buffer, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
- height);
- } else {
- FillWriteBuffer(write_buffer, {0xff00ff00, 0xff0000ff, 0xffff0000}, width,
- height);
- }
-
- // Post the write buffer.
- int ready_fence_fd = -1;
- ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta,
- ready_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to post the buffer.";
- }
- // Should observe blinking screen in secondary colors
- // although it is actually displaying primary colors.
-}
-
-TEST_F(DvrDisplayTest, DisplayWithTwoHardwareLayers) {
- // Create the direct_surface_0 of z order 10 and direct_surface_1 of z
- // order 11.
- DvrSurface* direct_surface_0 = nullptr;
- std::vector<DvrSurfaceAttribute> direct_surface_0_attributes = {
- {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
- .value.int32_value = 10},
- {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- };
- int ret =
- api_.SurfaceCreate(direct_surface_0_attributes.data(),
- direct_surface_0_attributes.size(), &direct_surface_0);
- EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
- DvrSurface* direct_surface_1 = nullptr;
- std::vector<DvrSurfaceAttribute> direct_surface_1_attributes = {
- {.key = DVR_SURFACE_ATTRIBUTE_DIRECT,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
- .value.int32_value = 11},
- {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE,
- .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- .value.bool_value = true},
- };
- ret =
- api_.SurfaceCreate(direct_surface_1_attributes.data(),
- direct_surface_1_attributes.size(), &direct_surface_1);
- EXPECT_EQ(ret, 0) << "Failed to create direct surface.";
-
- // Create a buffer queue for each of the direct surfaces.
- constexpr size_t kCapacity = 1;
- uint32_t width = display_metrics_.display_width;
- uint32_t height = display_metrics_.display_height;
-
- DvrWriteBufferQueue* write_queue_0 = nullptr;
- ret = api_.SurfaceCreateWriteBufferQueue(
- direct_surface_0, width, height, kFormat, kLayerCount, kUsage, kCapacity,
- kMetadataSize, &write_queue_0);
- EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
- EXPECT_NE(nullptr, write_queue_0) << "Write buffer queue should not be null.";
-
- DvrWriteBufferQueue* write_queue_1 = nullptr;
- ret = api_.SurfaceCreateWriteBufferQueue(
- direct_surface_1, width, height, kFormat, kLayerCount, kUsage, kCapacity,
- kMetadataSize, &write_queue_1);
- EXPECT_EQ(0, ret) << "Failed to create buffer queue.";
- EXPECT_NE(nullptr, write_queue_1) << "Write buffer queue should not be null.";
-
- // Get a buffer from each of the write buffer queues.
- DvrWriteBuffer* write_buffer_0 = nullptr;
- DvrNativeBufferMetadata out_meta_0;
- int out_fence_fd = -1;
- ret = api_.WriteBufferQueueGainBuffer(
- write_queue_0, kTimeoutMs, &write_buffer_0, &out_meta_0, &out_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to get the buffer.";
- EXPECT_NE(nullptr, write_buffer_0) << "Gained buffer should not be null.";
-
- DvrWriteBuffer* write_buffer_1 = nullptr;
- DvrNativeBufferMetadata out_meta_1;
- out_fence_fd = -1;
- ret = api_.WriteBufferQueueGainBuffer(
- write_queue_1, kTimeoutMs, &write_buffer_1, &out_meta_1, &out_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to get the buffer.";
- EXPECT_NE(nullptr, write_buffer_1) << "Gained buffer should not be null.";
-
- // Color the write buffers.
- FillWriteBuffer(write_buffer_0, {0xffff0000, 0xff00ff00, 0xff0000ff}, width,
- height);
- FillWriteBuffer(write_buffer_1, {0x7f00ff00, 0x7f0000ff, 0x7fff0000}, width,
- height);
-
- // Post buffers.
- int ready_fence_fd = -1;
- ret = api_.WriteBufferQueuePostBuffer(write_queue_0, write_buffer_0,
- &out_meta_0, ready_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
- ready_fence_fd = -1;
- ret = api_.WriteBufferQueuePostBuffer(write_queue_1, write_buffer_1,
- &out_meta_1, ready_fence_fd);
- EXPECT_EQ(0, ret) << "Failed to post the buffer.";
-
- sleep(5); // For visual check on the device under test.
- // Should observe three secondary colors.
-
- // Test finished. Clean up buffers and surfaces.
- if (write_queue_0 != nullptr) {
- api_.WriteBufferQueueDestroy(write_queue_0);
- write_queue_0 = nullptr;
- }
- if (write_queue_1 != nullptr) {
- api_.WriteBufferQueueDestroy(write_queue_1);
- write_queue_1 = nullptr;
- }
- if (direct_surface_0 != nullptr) {
- api_.SurfaceDestroy(direct_surface_0);
- }
- if (direct_surface_1 != nullptr) {
- api_.SurfaceDestroy(direct_surface_1);
- }
-}
-
-void DvrDisplayTest::FillWriteBuffer(
- DvrWriteBuffer* write_buffer, const std::vector<uint32_t>& color_textures,
- uint32_t width, uint32_t height) {
- uint32_t num_colors = color_textures.size();
- // Convert the first write buffer to an android hardware buffer.
- AHardwareBuffer* ah_buffer = nullptr;
- int ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer);
- ASSERT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer.";
- ASSERT_NE(nullptr, ah_buffer) << "AHardware buffer should not be null.";
- AHardwareBuffer_Desc ah_buffer_describe;
- AHardwareBuffer_describe(ah_buffer, &ah_buffer_describe);
- ASSERT_EQ(ah_buffer_describe.format, kFormat)
- << "The format of the android hardware buffer is wrong.";
- ASSERT_EQ(ah_buffer_describe.layers, kLayerCount)
- << "The obtained android hardware buffer should have 2 layers.";
- ASSERT_EQ(ah_buffer_describe.width, width)
- << "The obtained android hardware buffer width is wrong.";
- ASSERT_EQ(ah_buffer_describe.height, height)
- << "The obtained android hardware buffer height is wrong.";
- // Change the content of the android hardware buffer.
- void* buffer_data = nullptr;
- int32_t fence = -1;
- ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN,
- fence, nullptr, &buffer_data);
- ASSERT_EQ(0, ret) << "Failed to lock the hardware buffer.";
- ASSERT_NE(nullptr, buffer_data) << "Buffer data should not be null.";
-
- uint32_t num_pixels = width * height / num_colors;
- for (uint32_t color_index = 0; color_index < num_colors - 1; ++color_index) {
- uint32_t color_texture = color_textures[color_index];
- for (uint32_t i = 0; i < num_pixels; ++i) {
- memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
- (i + num_pixels * color_index) *
- sizeof(color_texture)),
- &color_texture, sizeof(color_texture));
- }
- }
- uint32_t color_texture = color_textures[num_colors - 1];
- uint32_t num_colored_pixels = num_pixels * (num_colors - 1);
- num_pixels = width * height - num_colored_pixels;
- for (uint32_t i = 0; i < num_pixels; ++i) {
- memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) +
- (i + num_colored_pixels) *
- sizeof(color_texture)),
- &color_texture, sizeof(color_texture));
- }
- fence = -1;
- ret = AHardwareBuffer_unlock(ah_buffer, &fence);
- EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer.";
-
- // Release the android hardware buffer.
- AHardwareBuffer_release(ah_buffer);
-}
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
deleted file mode 100644
index 07e2121..0000000
--- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
+++ /dev/null
@@ -1,891 +0,0 @@
-#include <android-base/properties.h>
-#include <base/logging.h>
-#include <cutils/properties.h>
-#include <gtest/gtest.h>
-#include <log/log.h>
-#include <poll.h>
-
-#include <android/hardware_buffer.h>
-
-#include <algorithm>
-#include <array>
-#include <set>
-#include <thread>
-#include <vector>
-
-#include <dvr/dvr_configuration_data.h>
-#include <dvr/dvr_deleter.h>
-#include <dvr/dvr_display_manager.h>
-#include <dvr/dvr_surface.h>
-
-#include <pdx/status.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-using ::testing::Test;
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, nullptr_t) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int32_t value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32;
- attribute.value.int32_value = value;
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int64_t value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64;
- attribute.value.int64_value = value;
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, bool value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL;
- attribute.value.bool_value = value;
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, float value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT;
- attribute.value.float_value = value;
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
- const std::array<float, 2>& value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2;
- std::copy(value.begin(), value.end(), attribute.value.float2_value);
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
- const std::array<float, 3>& value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3;
- std::copy(value.begin(), value.end(), attribute.value.float3_value);
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
- const std::array<float, 4>& value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4;
- std::copy(value.begin(), value.end(), attribute.value.float4_value);
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
- const std::array<float, 8>& value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8;
- std::copy(value.begin(), value.end(), attribute.value.float8_value);
- return attribute;
-}
-
-DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key,
- const std::array<float, 16>& value) {
- DvrSurfaceAttribute attribute;
- attribute.key = key;
- attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16;
- std::copy(value.begin(), value.end(), attribute.value.float16_value);
- return attribute;
-}
-
-Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false,
- int32_t z_order = 0) {
- DvrSurface* surface = nullptr;
- DvrSurfaceAttribute attributes[] = {
- MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order),
- MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)};
-
- const int ret = dvrSurfaceCreate(
- attributes, std::extent<decltype(attributes)>::value, &surface);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {UniqueDvrSurface(surface)};
-}
-
-Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
- const UniqueDvrSurface& surface, uint32_t width, uint32_t height,
- uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity,
- size_t metadata_size) {
- DvrWriteBufferQueue* queue;
- const int ret = dvrSurfaceCreateWriteBufferQueue(
- surface.get(), width, height, format, layer_count, usage, capacity,
- metadata_size, &queue);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {UniqueDvrWriteBufferQueue(queue)};
-}
-
-Status<std::vector<uint8_t>> GetConfigData(int config_type) {
- uint8_t* data = nullptr;
- size_t data_size = 0;
- int error = dvrConfigurationDataGet(config_type, &data, &data_size);
- if (error < 0) {
- return ErrorStatus(-error);
- }
-
- if (!data || data_size == 0) {
- return ErrorStatus(EINVAL);
- }
- std::vector<uint8_t> data_result(data, data + data_size);
- dvrConfigurationDataDestroy(data);
- std::string s(data, data + data_size);
- return {std::move(data_result)};
-}
-
-class TestDisplayManager {
- public:
- TestDisplayManager(UniqueDvrDisplayManager display_manager,
- UniqueDvrSurfaceState surface_state)
- : display_manager_(std::move(display_manager)),
- surface_state_(std::move(surface_state)) {
- const int fd = dvrDisplayManagerGetEventFd(display_manager_.get());
- LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd);
- display_manager_event_fd_ = fd;
- }
-
- Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id,
- int queue_id) {
- DvrReadBufferQueue* queue;
- const int ret = dvrDisplayManagerGetReadBufferQueue(
- display_manager_.get(), surface_id, queue_id, &queue);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {UniqueDvrReadBufferQueue(queue)};
- }
-
- Status<void> UpdateSurfaceState() {
- const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(),
- surface_state_.get());
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {};
- }
-
- enum : int { kTimeoutMs = 10000 }; // 10s
-
- Status<void> WaitForUpdate(int timeout_ms = kTimeoutMs) {
- if (display_manager_event_fd_ < 0)
- return ErrorStatus(-display_manager_event_fd_);
-
- pollfd pfd = {display_manager_event_fd_, POLLIN, 0};
- const int count = poll(&pfd, 1, timeout_ms);
- if (count < 0)
- return ErrorStatus(errno);
- else if (count == 0)
- return ErrorStatus(ETIMEDOUT);
-
- int events;
- const int ret = dvrDisplayManagerTranslateEpollEventMask(
- display_manager_.get(), pfd.revents, &events);
- if (ret < 0)
- return ErrorStatus(-ret);
- else if (events & POLLIN)
- return UpdateSurfaceState();
- else
- return ErrorStatus(EPROTO);
- }
-
- Status<size_t> GetSurfaceCount() {
- size_t count = 0;
- const int ret =
- dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {count};
- }
-
- Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) {
- DvrSurfaceUpdateFlags update_flags;
- const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(),
- surface_index, &update_flags);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {update_flags};
- }
-
- Status<int> GetSurfaceId(size_t surface_index) {
- int surface_id;
- const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(),
- surface_index, &surface_id);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {surface_id};
- }
-
- Status<int> GetProcessId(size_t surface_index) {
- int process_id;
- const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(),
- surface_index, &process_id);
- if (ret < 0)
- return ErrorStatus(-ret);
- else
- return {process_id};
- }
-
- Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) {
- std::vector<DvrSurfaceAttribute> attributes;
- size_t count = 0;
- const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(),
- surface_index, &count);
- if (ret < 0)
- return ErrorStatus(-ret);
-
- attributes.resize(count);
- const ssize_t return_count = dvrSurfaceStateGetAttributes(
- surface_state_.get(), surface_index, attributes.data(), count);
- if (return_count < 0)
- return ErrorStatus(-return_count);
-
- attributes.resize(return_count);
- return {std::move(attributes)};
- }
-
- Status<std::vector<int>> GetQueueIds(size_t surface_index) {
- std::vector<int> queue_ids;
- size_t count = 0;
- const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(),
- surface_index, &count);
- if (ret < 0)
- return ErrorStatus(-ret);
-
- if (count > 0) {
- queue_ids.resize(count);
- const ssize_t return_count = dvrSurfaceStateGetQueueIds(
- surface_state_.get(), surface_index, queue_ids.data(), count);
- if (return_count < 0)
- return ErrorStatus(-return_count);
-
- queue_ids.resize(return_count);
- }
-
- return {std::move(queue_ids)};
- }
-
- private:
- UniqueDvrDisplayManager display_manager_;
- UniqueDvrSurfaceState surface_state_;
-
- // Owned by object in display_manager_, do not explicitly close.
- int display_manager_event_fd_;
-
- TestDisplayManager(const TestDisplayManager&) = delete;
- void operator=(const TestDisplayManager&) = delete;
-};
-
-class DvrDisplayManagerTest : public Test {
- protected:
- void SetUp() override {
- int ret;
- DvrDisplayManager* display_manager;
- DvrSurfaceState* surface_state;
-
- ret = dvrDisplayManagerCreate(&display_manager);
- ASSERT_EQ(0, ret) << "Failed to create display manager client";
- ASSERT_NE(nullptr, display_manager);
-
- ret = dvrSurfaceStateCreate(&surface_state);
- ASSERT_EQ(0, ret) << "Failed to create surface state object";
- ASSERT_NE(nullptr, surface_state);
-
- manager_.reset(
- new TestDisplayManager(UniqueDvrDisplayManager(display_manager),
- UniqueDvrSurfaceState(surface_state)));
- }
- void TearDown() override {}
-
- std::unique_ptr<TestDisplayManager> manager_;
-};
-
-// TODO(eieio): Consider moving these somewhere more central because they are
-// broadly useful.
-
-template <typename T>
-testing::AssertionResult StatusOk(const char* status_expression,
- const Status<T>& status) {
- if (!status.ok()) {
- return testing::AssertionFailure()
- << "(" << status_expression
- << ") expected to indicate success but actually contains error ("
- << status.error() << ")";
- } else {
- return testing::AssertionSuccess();
- }
-}
-
-template <typename T>
-testing::AssertionResult StatusError(const char* status_expression,
- const Status<T>& status) {
- if (status.ok()) {
- return testing::AssertionFailure()
- << "(" << status_expression
- << ") expected to indicate error but instead indicates success.";
- } else {
- return testing::AssertionSuccess();
- }
-}
-
-template <typename T>
-testing::AssertionResult StatusHasError(const char* status_expression,
- const char* /*error_code_expression*/,
- const Status<T>& status,
- int error_code) {
- if (status.ok()) {
- return StatusError(status_expression, status);
- } else if (status.error() != error_code) {
- return testing::AssertionFailure()
- << "(" << status_expression << ") expected to indicate error ("
- << error_code << ") but actually indicates error (" << status.error()
- << ")";
- } else {
- return testing::AssertionSuccess();
- }
-}
-
-template <typename T, typename U>
-testing::AssertionResult StatusHasValue(const char* status_expression,
- const char* /*value_expression*/,
- const Status<T>& status,
- const U& value) {
- if (!status.ok()) {
- return StatusOk(status_expression, status);
- } else if (status.get() != value) {
- return testing::AssertionFailure()
- << "(" << status_expression << ") expected to contain value ("
- << testing::PrintToString(value) << ") but actually contains value ("
- << testing::PrintToString(status.get()) << ")";
- } else {
- return testing::AssertionSuccess();
- }
-}
-
-template <typename T, typename Op>
-testing::AssertionResult StatusPred(const char* status_expression,
- const char* pred_expression,
- const Status<T>& status, Op pred) {
- if (!status.ok()) {
- return StatusOk(status_expression, status);
- } else if (!pred(status.get())) {
- return testing::AssertionFailure()
- << status_expression << " value ("
- << testing::PrintToString(status.get())
- << ") failed to pass predicate " << pred_expression;
- } else {
- return testing::AssertionSuccess();
- }
-}
-
-#define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status)
-#define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status)
-
-#define ASSERT_STATUS_ERROR_VALUE(value, status) \
- ASSERT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define ASSERT_STATUS_EQ(value, status) \
- ASSERT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status)
-#define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status)
-
-#define EXPECT_STATUS_ERROR_VALUE(value, status) \
- EXPECT_PRED_FORMAT2(StatusHasError, status, value)
-
-#define EXPECT_STATUS_EQ(value, status) \
- EXPECT_PRED_FORMAT2(StatusHasValue, status, value)
-
-#define EXPECT_STATUS_PRED(pred, status) \
- EXPECT_PRED_FORMAT2(StatusPred, status, pred)
-
-#if 0
-// Verify utility predicate/macro functionality. This section is commented out
-// because it is designed to fail in some cases to validate the helpers.
-TEST_F(Test, ExpectVoid) {
- Status<void> status_error{ErrorStatus{EINVAL}};
- Status<void> status_ok{};
-
- EXPECT_STATUS_ERROR(status_error);
- EXPECT_STATUS_ERROR(status_ok);
- EXPECT_STATUS_OK(status_error);
- EXPECT_STATUS_OK(status_ok);
-
- EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
- EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
- EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
- EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-}
-
-TEST_F(Test, ExpectInt) {
- Status<int> status_error{ErrorStatus{EINVAL}};
- Status<int> status_ok{10};
-
- EXPECT_STATUS_ERROR(status_error);
- EXPECT_STATUS_ERROR(status_ok);
- EXPECT_STATUS_OK(status_error);
- EXPECT_STATUS_OK(status_ok);
-
- EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error);
- EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error);
- EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok);
- EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok);
-
- EXPECT_STATUS_EQ(10, status_error);
- EXPECT_STATUS_EQ(20, status_error);
- EXPECT_STATUS_EQ(10, status_ok);
- EXPECT_STATUS_EQ(20, status_ok);
-
- auto pred1 = [](const auto& value) { return value < 15; };
- auto pred2 = [](const auto& value) { return value > 5; };
- auto pred3 = [](const auto& value) { return value > 15; };
- auto pred4 = [](const auto& value) { return value < 5; };
-
- EXPECT_STATUS_PRED(pred1, status_error);
- EXPECT_STATUS_PRED(pred2, status_error);
- EXPECT_STATUS_PRED(pred3, status_error);
- EXPECT_STATUS_PRED(pred4, status_error);
- EXPECT_STATUS_PRED(pred1, status_ok);
- EXPECT_STATUS_PRED(pred2, status_ok);
- EXPECT_STATUS_PRED(pred3, status_ok);
- EXPECT_STATUS_PRED(pred4, status_ok);
-}
-#endif
-
-TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) {
- // Get surface state and verify there are no surfaces.
- ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
- ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
- // Get flags for invalid surface index.
- EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0));
-
- // Create an application surface.
- auto surface_status = CreateApplicationSurface();
- ASSERT_STATUS_OK(surface_status);
- UniqueDvrSurface surface = surface_status.take();
- ASSERT_NE(nullptr, surface.get());
-
- const int surface_id = dvrSurfaceGetId(surface.get());
- ASSERT_GE(surface_id, 0);
-
- // Now there should be one new surface.
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Verify the new surface flag is set.
- auto check_flags = [](const auto& value) {
- return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE;
- };
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- // Verify the surface id matches.
- EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0));
-
- // Verify the owning process of the surface.
- EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0));
-
- surface.reset();
-
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) {
- // Get surface state and verify there are no surfaces.
- ASSERT_STATUS_OK(manager_->UpdateSurfaceState());
- ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount());
-
- // Get attributes for an invalid surface index.
- EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0));
-
- const bool kInitialVisibility = true;
- const int32_t kInitialZOrder = 10;
- auto surface_status =
- CreateApplicationSurface(kInitialVisibility, kInitialZOrder);
- ASSERT_STATUS_OK(surface_status);
- auto surface = surface_status.take();
- ASSERT_NE(nullptr, surface.get());
-
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Check the initial attribute values.
- auto attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- auto attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), 2u);
-
- std::set<int32_t> actual_keys;
- std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
- // Collect all the keys in attributes that match the expected keys.
- auto compare_keys = [](const auto& attributes, const auto& expected_keys) {
- std::set<int32_t> keys;
- for (const auto& attribute : attributes) {
- if (expected_keys.find(attribute.key) != expected_keys.end())
- keys.emplace(attribute.key);
- }
- return keys;
- };
-
- // If the sets match then attributes contained at least the expected keys,
- // even if other keys were also present.
- actual_keys = compare_keys(attributes, expected_keys);
- EXPECT_EQ(expected_keys, actual_keys);
-
- std::vector<DvrSurfaceAttribute> attributes_to_set = {
- MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, 0)};
-
- // Test invalid args.
- EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(nullptr, attributes_to_set.data(),
- attributes_to_set.size()));
- EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(surface.get(), nullptr,
- attributes_to_set.size()));
-
- // Test attribute change events.
- ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
- attributes_to_set.size()));
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
-
- // Verify the attributes changed flag is set.
- auto check_flags = [](const auto& value) {
- return value & DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED;
- };
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), 2u);
-
- expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
- actual_keys.clear();
- actual_keys = compare_keys(attributes, expected_keys);
- EXPECT_EQ(expected_keys, actual_keys);
-
- // Test setting and then deleting an attribute.
- const DvrSurfaceAttributeKey kUserKey = 1;
- attributes_to_set = {MakeAttribute(kUserKey, 1024)};
-
- ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
- attributes_to_set.size()));
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), 2u);
-
- expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
- kUserKey};
-
- actual_keys.clear();
- actual_keys = compare_keys(attributes, expected_keys);
- EXPECT_EQ(expected_keys, actual_keys);
-
- // Delete the attribute.
- attributes_to_set = {MakeAttribute(kUserKey, nullptr)};
-
- ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
- attributes_to_set.size()));
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), 2u);
-
- expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE,
- kUserKey};
-
- actual_keys.clear();
- actual_keys = compare_keys(attributes, expected_keys);
- EXPECT_NE(expected_keys, actual_keys);
-
- // Test deleting a reserved attribute.
- attributes_to_set = {MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, nullptr)};
-
- EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
- attributes_to_set.size()));
-
- // Failed attribute operations should not trigger update events.
- const int kTimeoutMs = 100; // 0.1s
- EXPECT_STATUS_ERROR_VALUE(ETIMEDOUT, manager_->WaitForUpdate(kTimeoutMs));
-
- attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), 2u);
-
- expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- DVR_SURFACE_ATTRIBUTE_VISIBLE};
-
- actual_keys.clear();
- actual_keys = compare_keys(attributes, expected_keys);
- EXPECT_EQ(expected_keys, actual_keys);
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceAttributeTypes) {
- // Create an application surface.
- auto surface_status = CreateApplicationSurface();
- ASSERT_STATUS_OK(surface_status);
- UniqueDvrSurface surface = surface_status.take();
- ASSERT_NE(nullptr, surface.get());
-
- enum : std::int32_t {
- kInt32Key = 1,
- kInt64Key,
- kBoolKey,
- kFloatKey,
- kFloat2Key,
- kFloat3Key,
- kFloat4Key,
- kFloat8Key,
- kFloat16Key,
- };
-
- const std::vector<DvrSurfaceAttribute> attributes_to_set = {
- MakeAttribute(kInt32Key, int32_t{0}),
- MakeAttribute(kInt64Key, int64_t{0}),
- MakeAttribute(kBoolKey, false),
- MakeAttribute(kFloatKey, 0.0f),
- MakeAttribute(kFloat2Key, std::array<float, 2>{{1.0f, 2.0f}}),
- MakeAttribute(kFloat3Key, std::array<float, 3>{{3.0f, 4.0f, 5.0f}}),
- MakeAttribute(kFloat4Key, std::array<float, 4>{{6.0f, 7.0f, 8.0f, 9.0f}}),
- MakeAttribute(kFloat8Key,
- std::array<float, 8>{{10.0f, 11.0f, 12.0f, 13.0f, 14.0f,
- 15.0f, 16.0f, 17.0f}}),
- MakeAttribute(kFloat16Key, std::array<float, 16>{
- {18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f,
- 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f,
- 30.0f, 31.0f, 32.0f, 33.0f}})};
-
- EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(),
- attributes_to_set.size()));
-
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- auto attribute_status = manager_->GetAttributes(0);
- ASSERT_STATUS_OK(attribute_status);
- auto attributes = attribute_status.take();
- EXPECT_GE(attributes.size(), attributes_to_set.size());
-
- auto HasAttribute = [](const auto& attributes,
- DvrSurfaceAttributeKey key) -> bool {
- for (const auto& attribute : attributes) {
- if (attribute.key == key)
- return true;
- }
- return false;
- };
- auto AttributeType =
- [](const auto& attributes,
- DvrSurfaceAttributeKey key) -> DvrSurfaceAttributeType {
- for (const auto& attribute : attributes) {
- if (attribute.key == key)
- return attribute.value.type;
- }
- return DVR_SURFACE_ATTRIBUTE_TYPE_NONE;
- };
-
- ASSERT_TRUE(HasAttribute(attributes, kInt32Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT32,
- AttributeType(attributes, kInt32Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kInt64Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT64,
- AttributeType(attributes, kInt64Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kBoolKey));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_BOOL,
- AttributeType(attributes, kBoolKey));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloatKey));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT,
- AttributeType(attributes, kFloatKey));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloat2Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2,
- AttributeType(attributes, kFloat2Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloat3Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3,
- AttributeType(attributes, kFloat3Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloat4Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4,
- AttributeType(attributes, kFloat4Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloat8Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8,
- AttributeType(attributes, kFloat8Key));
-
- ASSERT_TRUE(HasAttribute(attributes, kFloat16Key));
- EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16,
- AttributeType(attributes, kFloat16Key));
-}
-
-TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) {
- // Create an application surface.
- auto surface_status = CreateApplicationSurface();
- ASSERT_STATUS_OK(surface_status);
- UniqueDvrSurface surface = surface_status.take();
- ASSERT_NE(nullptr, surface.get());
-
- const int surface_id = dvrSurfaceGetId(surface.get());
- ASSERT_GE(surface_id, 0);
- // Get surface state and verify there is one surface.
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Verify there are no queues for the surface recorded in the state
- // snapshot.
- EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0));
-
- // Create a new queue in the surface.
- auto write_queue_status = CreateSurfaceQueue(
- surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1,
- AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
- ASSERT_STATUS_OK(write_queue_status);
- UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
- ASSERT_NE(nullptr, write_queue.get());
-
- const int queue_id = dvrWriteBufferQueueGetId(write_queue.get());
- ASSERT_GE(queue_id, 0);
-
- // Update surface state.
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Verify the buffers changed flag is set.
- auto check_flags = [](const auto& value) {
- return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED;
- };
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- auto queue_ids_status = manager_->GetQueueIds(0);
- ASSERT_STATUS_OK(queue_ids_status);
-
- auto queue_ids = queue_ids_status.take();
- ASSERT_EQ(1u, queue_ids.size());
- EXPECT_EQ(queue_id, queue_ids[0]);
-
- auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id);
- ASSERT_STATUS_OK(read_queue_status);
- UniqueDvrReadBufferQueue read_queue = read_queue_status.take();
- ASSERT_NE(nullptr, read_queue.get());
- EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get()));
-
- write_queue.reset();
-
- // Verify that destroying the queue generates a surface update event.
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Verify that the buffers changed flag is set.
- EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0));
-
- // Verify that the queue ids reflect the change.
- queue_ids_status = manager_->GetQueueIds(0);
- ASSERT_STATUS_OK(queue_ids_status);
-
- queue_ids = queue_ids_status.take();
- ASSERT_EQ(0u, queue_ids.size());
-}
-
-TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) {
- // Create an application surface.
- auto surface_status = CreateApplicationSurface();
- ASSERT_STATUS_OK(surface_status);
- UniqueDvrSurface surface = surface_status.take();
- ASSERT_NE(nullptr, surface.get());
-
- // Get surface state and verify there is one surface.
- ASSERT_STATUS_OK(manager_->WaitForUpdate());
- ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
-
- // Create a new queue in the surface.
- const uint32_t kLayerCount = 3;
- auto write_queue_status = CreateSurfaceQueue(
- surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount,
- AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0);
- ASSERT_STATUS_OK(write_queue_status);
- UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
- ASSERT_NE(nullptr, write_queue.get());
-
- DvrWriteBuffer* buffer = nullptr;
- DvrNativeBufferMetadata metadata;
- int fence_fd = -1;
- int error = dvrWriteBufferQueueGainBuffer(write_queue.get(), /*timeout=*/1000,
- &buffer, &metadata, &fence_fd);
- ASSERT_EQ(0, error);
-
- AHardwareBuffer* hardware_buffer = nullptr;
- error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer);
- ASSERT_EQ(0, error);
-
- AHardwareBuffer_Desc desc = {};
- AHardwareBuffer_describe(hardware_buffer, &desc);
- ASSERT_EQ(kLayerCount, desc.layers);
-
- AHardwareBuffer_release(hardware_buffer);
- dvrWriteBufferDestroy(buffer);
-}
-
-TEST_F(Test, ConfigurationData) {
- // TODO(hendrikw): Move this test and GetConfigData helper function out of the
- // display manager tests.
- auto data1 = GetConfigData(-1);
- ASSERT_STATUS_ERROR(data1);
-
- const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics";
-
- // This should be run on devices with and without built in metrics.
- bool has_metric = !base::GetProperty(kDvrLensMetricsProperty, "").empty();
- auto data2 = GetConfigData(DVR_CONFIGURATION_DATA_LENS_METRICS);
- if (has_metric) {
- ASSERT_STATUS_OK(data2);
- ASSERT_NE(0u, data2.get().size());
- } else {
- ASSERT_STATUS_ERROR(data2);
- }
-}
-
-} // namespace
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
deleted file mode 100644
index 5c837e7..0000000
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-#include <android/hardware_buffer.h>
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_config.h>
-#include <dvr/dvr_shared_buffers.h>
-#include <dvr/dvr_surface.h>
-#include <system/graphics.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-TEST(DvrGlobalBufferTest, TestGlobalBuffersSameName) {
- const DvrGlobalBufferKey buffer_key = 101;
- DvrBuffer* buffer1 = nullptr;
- int ret1 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer1);
- ASSERT_EQ(0, ret1);
- ASSERT_NE(nullptr, buffer1);
-
- DvrBuffer* buffer2 = nullptr;
- int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2);
- ASSERT_EQ(0, ret2);
- ASSERT_NE(nullptr, buffer2);
-
- AHardwareBuffer* hardware_buffer1 = nullptr;
- int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
- ASSERT_EQ(0, e1);
- ASSERT_NE(nullptr, hardware_buffer1);
-
- AHardwareBuffer* hardware_buffer2 = nullptr;
- int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
- ASSERT_EQ(0, e2);
- ASSERT_NE(nullptr, hardware_buffer2);
-
- AHardwareBuffer_Desc desc1 = {};
- AHardwareBuffer_describe(hardware_buffer1, &desc1);
- AHardwareBuffer_Desc desc2 = {};
- AHardwareBuffer_describe(hardware_buffer2, &desc2);
- ASSERT_EQ(desc1.width, 10u);
- ASSERT_EQ(desc1.height, 1u);
- ASSERT_EQ(desc1.layers, 1u);
- ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB);
- ASSERT_EQ(desc1.usage, 0u);
- ASSERT_EQ(desc2.width, 10u);
- ASSERT_EQ(desc2.height, 1u);
- ASSERT_EQ(desc2.layers, 1u);
- ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB);
- ASSERT_EQ(desc2.usage, 0u);
-
- dvrBufferDestroy(buffer1);
- dvrBufferDestroy(buffer2);
-
- DvrBuffer* buffer3 = nullptr;
- int e3 = dvrGetGlobalBuffer(buffer_key, &buffer3);
- ASSERT_NE(nullptr, buffer3);
- ASSERT_EQ(0, e3);
-
- AHardwareBuffer* hardware_buffer3 = nullptr;
- int e4 = dvrBufferGetAHardwareBuffer(buffer3, &hardware_buffer3);
- ASSERT_EQ(0, e4);
- ASSERT_NE(nullptr, hardware_buffer3);
-
- AHardwareBuffer_Desc desc3 = {};
- AHardwareBuffer_describe(hardware_buffer3, &desc3);
- ASSERT_EQ(desc3.width, 10u);
- ASSERT_EQ(desc3.height, 1u);
- ASSERT_EQ(desc3.layers, 1u);
- ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB);
- ASSERT_EQ(desc3.usage, 0u);
-
- dvrBufferDestroy(buffer3);
-
- AHardwareBuffer_release(hardware_buffer1);
- AHardwareBuffer_release(hardware_buffer2);
- AHardwareBuffer_release(hardware_buffer3);
-}
-
-TEST(DvrGlobalBufferTest, TestMultipleGlobalBuffers) {
- const DvrGlobalBufferKey buffer_key1 = 102;
- const DvrGlobalBufferKey buffer_key2 = 103;
- DvrBuffer* setup_buffer1 = nullptr;
- int ret1 = dvrSetupGlobalBuffer(buffer_key1, 10, 0, &setup_buffer1);
- ASSERT_EQ(0, ret1);
- ASSERT_NE(nullptr, setup_buffer1);
- dvrBufferDestroy(setup_buffer1);
-
- DvrBuffer* setup_buffer2 = nullptr;
- int ret2 = dvrSetupGlobalBuffer(buffer_key2, 10, 0, &setup_buffer2);
- ASSERT_EQ(0, ret2);
- ASSERT_NE(nullptr, setup_buffer2);
- dvrBufferDestroy(setup_buffer2);
-
- DvrBuffer* buffer1 = nullptr;
- int e1 = dvrGetGlobalBuffer(buffer_key1, &buffer1);
- ASSERT_NE(nullptr, buffer1);
- ASSERT_EQ(0, e1);
- dvrBufferDestroy(buffer1);
-
- DvrBuffer* buffer2 = nullptr;
- int e2 = dvrGetGlobalBuffer(buffer_key2, &buffer2);
- ASSERT_NE(nullptr, buffer2);
- ASSERT_EQ(0, e2);
- dvrBufferDestroy(buffer2);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferUsage) {
- const DvrGlobalBufferKey buffer_key = 100;
-
- // Set usage to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE. We use this because
- // internally AHARDWAREBUFFER_USAGE_VIDEO_ENCODE is converted to
- // GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, and these two values are different.
- // If all is good, when we get the AHardwareBuffer, it should be converted
- // back to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE.
- const uint64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE;
-
- DvrBuffer* setup_buffer = nullptr;
- int e1 = dvrSetupGlobalBuffer(buffer_key, 10, usage, &setup_buffer);
- ASSERT_NE(nullptr, setup_buffer);
- ASSERT_EQ(0, e1);
-
- AHardwareBuffer* hardware_buffer = nullptr;
- int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
- ASSERT_EQ(0, e2);
- ASSERT_NE(nullptr, hardware_buffer);
-
- AHardwareBuffer_Desc desc = {};
- AHardwareBuffer_describe(hardware_buffer, &desc);
- ASSERT_EQ(usage, desc.usage);
-
- dvrBufferDestroy(setup_buffer);
- AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferCarriesData) {
- const DvrGlobalBufferKey buffer_name = 110;
-
- uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- constexpr size_t size = 1024 * sizeof(uint64_t);
- constexpr uint64_t value = 0x123456787654321;
-
- {
- // Allocate some data and set it to something.
- DvrBuffer* setup_buffer = nullptr;
- int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
- ASSERT_NE(nullptr, setup_buffer);
- ASSERT_EQ(0, e1);
-
- AHardwareBuffer* hardware_buffer = nullptr;
- int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
- ASSERT_EQ(0, e2);
- ASSERT_NE(nullptr, hardware_buffer);
-
- void* buffer;
- int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
- ASSERT_EQ(0, e3);
- ASSERT_NE(nullptr, buffer);
- // Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
- uint64_t* data = static_cast<uint64_t*>(buffer);
- constexpr size_t num_values = size / sizeof(uint64_t);
- for (size_t i = 0; i < num_values; ++i) {
- data[i] = value;
- }
-
- int32_t fence = -1;
- int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
- ASSERT_EQ(0, e4);
-
- dvrBufferDestroy(setup_buffer);
- AHardwareBuffer_release(hardware_buffer);
- }
-
- {
- // Get the buffer and check that all the data is still present.
- DvrBuffer* setup_buffer = nullptr;
- int e1 = dvrGetGlobalBuffer(buffer_name, &setup_buffer);
- ASSERT_NE(nullptr, setup_buffer);
- ASSERT_EQ(0, e1);
-
- AHardwareBuffer* hardware_buffer = nullptr;
- int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
- ASSERT_EQ(0, e2);
- ASSERT_NE(nullptr, hardware_buffer);
-
- void* buffer;
- int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
- ASSERT_EQ(0, e3);
- ASSERT_NE(nullptr, buffer);
- // Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
- uint64_t* data = static_cast<uint64_t*>(buffer);
- constexpr size_t num_values = size / sizeof(uint64_t);
- bool is_equal = true;
- for (size_t i = 0; i < num_values; ++i) {
- is_equal &= (data[i] == value);
- }
- ASSERT_TRUE(is_equal);
-
- int32_t fence = -1;
- int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
- ASSERT_EQ(0, e4);
-
- dvrBufferDestroy(setup_buffer);
- AHardwareBuffer_release(hardware_buffer);
- }
-}
-
-TEST(DvrGlobalBufferTest, TestGlobalBufferZeroed) {
- const DvrGlobalBufferKey buffer_name = 120;
-
- // Allocate 1MB and check that it is all zeros.
- uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
- constexpr size_t size = 1024 * 1024;
- DvrBuffer* setup_buffer = nullptr;
- int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer);
- ASSERT_NE(nullptr, setup_buffer);
- ASSERT_EQ(0, e1);
-
- AHardwareBuffer* hardware_buffer = nullptr;
- int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer);
- ASSERT_EQ(0, e2);
- ASSERT_NE(nullptr, hardware_buffer);
-
- void* buffer;
- int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer);
- ASSERT_EQ(0, e3);
- ASSERT_NE(nullptr, buffer);
- // Verify that the buffer pointer is at least 16 byte aligned.
- ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1));
-
- uint64_t* data = static_cast<uint64_t*>(buffer);
- constexpr size_t num_values = size / sizeof(uint64_t);
- uint64_t zero = 0;
- for (size_t i = 0; i < num_values; ++i) {
- zero |= data[i];
- }
- ASSERT_EQ(0U, zero);
-
- int32_t fence = -1;
- int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence);
- ASSERT_EQ(0, e4);
-
- dvrBufferDestroy(setup_buffer);
- AHardwareBuffer_release(hardware_buffer);
-}
-
-TEST(DvrGlobalBufferTest, TestVrflingerConfigBuffer) {
- const DvrGlobalBufferKey buffer_name =
- DvrGlobalBuffers::kVrFlingerConfigBufferKey;
-
- // First delete any existing buffer so we can test the failure case.
- dvrDeleteGlobalBuffer(buffer_name);
-
- const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY;
-
- size_t correct_size = DvrConfigRing::MemorySize();
- size_t wrong_size = DvrConfigRing::MemorySize(0);
-
- // Setup an invalid config buffer (too small) and assert that it fails.
- DvrBuffer* setup_buffer = nullptr;
- int e1 = dvrSetupGlobalBuffer(buffer_name, wrong_size, usage, &setup_buffer);
- ASSERT_EQ(nullptr, setup_buffer);
- ASSERT_GT(0, e1);
-
- // Setup a correct config buffer.
- int e2 =
- dvrSetupGlobalBuffer(buffer_name, correct_size, usage, &setup_buffer);
- ASSERT_NE(nullptr, setup_buffer);
- ASSERT_EQ(0, e2);
-
- dvrBufferDestroy(setup_buffer);
-}
-
-} // namespace
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdvr/tests/dvr_tracking-test.cpp b/libs/vr/libdvr/tests/dvr_tracking-test.cpp
deleted file mode 100644
index 3b6d6e1..0000000
--- a/libs/vr/libdvr/tests/dvr_tracking-test.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <android/log.h>
-#include <gtest/gtest.h>
-
-#include "dvr_api_test.h"
-
-namespace {
-
-class DvrTrackingTest : public DvrApiTest {};
-
-#if DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, Implemented) {
- ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
- ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
- ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
- ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateFailsForInvalidInput) {
- int ret;
- ret = api_.TrackingCameraCreate(nullptr);
- EXPECT_EQ(ret, -EINVAL);
-
- DvrTrackingCamera* camera = reinterpret_cast<DvrTrackingCamera*>(42);
- ret = api_.TrackingCameraCreate(&camera);
- EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, CameraCreateDestroy) {
- DvrTrackingCamera* camera = nullptr;
- int ret = api_.TrackingCameraCreate(&camera);
-
- EXPECT_EQ(ret, 0);
- ASSERT_TRUE(camera != nullptr);
-
- api_.TrackingCameraDestroy(camera);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateFailsForInvalidInput) {
- int ret;
- ret = api_.TrackingFeatureExtractorCreate(nullptr);
- EXPECT_EQ(ret, -EINVAL);
-
- DvrTrackingFeatureExtractor* camera =
- reinterpret_cast<DvrTrackingFeatureExtractor*>(42);
- ret = api_.TrackingFeatureExtractorCreate(&camera);
- EXPECT_EQ(ret, -EINVAL);
-}
-
-TEST_F(DvrTrackingTest, FeatureExtractorCreateDestroy) {
- DvrTrackingFeatureExtractor* camera = nullptr;
- int ret = api_.TrackingFeatureExtractorCreate(&camera);
-
- EXPECT_EQ(ret, 0);
- ASSERT_TRUE(camera != nullptr);
-
- api_.TrackingFeatureExtractorDestroy(camera);
-}
-
-#else // !DVR_TRACKING_IMPLEMENTED
-
-TEST_F(DvrTrackingTest, NotImplemented) {
- ASSERT_TRUE(api_.TrackingCameraCreate != nullptr);
- ASSERT_TRUE(api_.TrackingCameraDestroy != nullptr);
- ASSERT_TRUE(api_.TrackingCameraStart != nullptr);
- ASSERT_TRUE(api_.TrackingCameraStop != nullptr);
-
- EXPECT_EQ(api_.TrackingCameraCreate(nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingCameraStart(nullptr, nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingCameraStop(nullptr), -ENOSYS);
-
- ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr);
- ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr);
-
- EXPECT_EQ(api_.TrackingFeatureExtractorCreate(nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingFeatureExtractorStart(nullptr, nullptr, nullptr),
- -ENOSYS);
- EXPECT_EQ(api_.TrackingFeatureExtractorStop(nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingFeatureExtractorProcessBuffer(nullptr, nullptr,
- nullptr, nullptr),
- -ENOSYS);
-
- ASSERT_TRUE(api_.TrackingSensorsCreate != nullptr);
- ASSERT_TRUE(api_.TrackingSensorsDestroy != nullptr);
- ASSERT_TRUE(api_.TrackingSensorsStart != nullptr);
- ASSERT_TRUE(api_.TrackingSensorsStop != nullptr);
-
- EXPECT_EQ(api_.TrackingSensorsCreate(nullptr, nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingSensorsStart(nullptr, nullptr, nullptr), -ENOSYS);
- EXPECT_EQ(api_.TrackingSensorsStop(nullptr), -ENOSYS);
-}
-
-#endif // DVR_TRACKING_IMPLEMENTED
-
-} // namespace
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
index b3d6f74..e0ba946 100644
--- a/opengl/libs/EGL/getProcAddress.cpp
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -118,70 +118,27 @@
: "rax", "cc" \
);
-#elif defined(__mips64)
+#elif defined(__riscv)
+ #define API_ENTRY(_api) __attribute__((noinline)) _api
- #define API_ENTRY(_api) __attribute__((noinline)) _api
-
- #define CALL_GL_EXTENSION_API(_api, ...) \
- register unsigned int _t0 asm("$12"); \
- register unsigned int _fn asm("$25"); \
- register unsigned int _tls asm("$3"); \
- asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- "rdhwr %[tls], $29\n\t" \
- "ld %[t0], %[OPENGL_API](%[tls])\n\t" \
- "beqz %[t0], 1f\n\t" \
- " move %[fn], $ra\n\t" \
- "ld %[t0], %[API](%[t0])\n\t" \
- "beqz %[t0], 1f\n\t" \
- " nop\n\t" \
- "move %[fn], %[t0]\n\t" \
- "1:\n\t" \
- "jalr $0, %[fn]\n\t" \
- " nop\n\t" \
- ".set pop\n\t" \
- : [fn] "=c"(_fn), \
- [tls] "=&r"(_tls), \
- [t0] "=&r"(_t0) \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \
- [API] "I"(__builtin_offsetof(gl_hooks_t, \
- ext.extensions[_api])) \
- : \
- );
-
-#elif defined(__mips__)
-
- #define API_ENTRY(_api) __attribute__((noinline)) _api
-
- #define CALL_GL_EXTENSION_API(_api, ...) \
- register unsigned int _t0 asm("$8"); \
- register unsigned int _fn asm("$25"); \
- register unsigned int _tls asm("$3"); \
- asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- ".set mips32r2\n\t" \
- "rdhwr %[tls], $29\n\t" \
- "lw %[t0], %[OPENGL_API](%[tls])\n\t" \
- "beqz %[t0], 1f\n\t" \
- " move %[fn], $ra\n\t" \
- "lw %[t0], %[API](%[t0])\n\t" \
- "beqz %[t0], 1f\n\t" \
- " nop\n\t" \
- "move %[fn], %[t0]\n\t" \
- "1:\n\t" \
- "jalr $0, %[fn]\n\t" \
- " nop\n\t" \
- ".set pop\n\t" \
- : [fn] "=c"(_fn), \
- [tls] "=&r"(_tls), \
- [t0] "=&r"(_t0) \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \
- [API] "I"(__builtin_offsetof(gl_hooks_t, \
- ext.extensions[_api])) \
- : \
- );
+ #define CALL_GL_EXTENSION_API(_api) \
+ asm volatile( \
+ "mv t0, tp\n" \
+ "li t1, %[tls]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "beqz t0, 1f\n" \
+ "li t1, %[api]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "jalr x0, t0\n" \
+ "1: ret\n" \
+ : \
+ : [tls] "i" (TLS_SLOT_OPENGL_API * sizeof(void*)), \
+ [api] "i" (__builtin_offsetof(gl_hooks_t, \
+ ext.extensions[_api])) \
+ : "t0", "t1" \
+ );
#endif
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 65f50f5..5bd5c14 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -191,73 +191,44 @@
: \
);
-#elif defined(__mips64)
+#elif defined(__riscv)
#define API_ENTRY(_api) __attribute__((naked,noinline)) _api
- // t0: $12
- // fn: $25
- // tls: $3
- // v0: $2
- #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
- asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- "rdhwr $3, $29\n\t" \
- "ld $12, %[OPENGL_API]($3)\n\t" \
- "beqz $12, 1f\n\t" \
- " move $25, $ra\n\t" \
- "ld $12, %[API]($12)\n\t" \
- "beqz $12, 1f\n\t" \
- " nop\n\t" \
- "move $25, $12\n\t" \
- "1:\n\t" \
- "jalr $0, $25\n\t" \
- " move $2, $0\n\t" \
- ".set pop\n\t" \
- : \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
- [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
- : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", \
- "$10", "$11", "$12", "$25" \
- );
-
- #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
- #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
- #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
- // t0: $8
- // fn: $25
- // tls: $3
- // v0: $2
#define CALL_GL_API_INTERNAL_CALL(_api, ...) \
asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- ".set mips32r2\n\t" \
- "rdhwr $3, $29\n\t" \
- "lw $3, %[OPENGL_API]($3)\n\t" \
- "beqz $3, 1f\n\t" \
- " move $25,$ra\n\t" \
- "lw $3, %[API]($3)\n\t" \
- "beqz $3, 1f\n\t" \
- " nop\n\t" \
- "move $25, $3\n\t" \
- "1:\n\t" \
- "jalr $0, $25\n\t" \
- " move $2, $0\n\t" \
- ".set pop\n\t" \
+ "mv t0, tp\n" \
+ "li t1, %[tls]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "beqz t0, 1f\n" \
+ "li t1, %[api]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "jalr x0, t0\n" \
+ "1:\n" \
: \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \
- [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
- : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25" \
+ : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)), \
+ [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+ : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", \
+ "a5", "t6", "t3", "t4", "t5", "t6" \
);
- #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
- #define CALL_GL_API_INTERNAL_DO_RETURN
+ #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+ asm volatile( \
+ "li a0, 0\n" \
+ : \
+ : \
+ : "a0" \
+ );
+
+ #define CALL_GL_API_INTERNAL_DO_RETURN \
+ asm volatile( \
+ "ret\n" \
+ : \
+ : \
+ : \
+ );
#endif
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index bacd4b4..64c0f97 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -247,73 +247,44 @@
: \
);
-#elif defined(__mips64)
+#elif defined(__riscv)
#define API_ENTRY(_api) __attribute__((naked,noinline)) _api
- // t0: $12
- // fn: $25
- // tls: $3
- // v0: $2
- #define CALL_GL_API_INTERNAL_CALL(_api, ...) \
- asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- "rdhwr $3, $29\n\t" \
- "ld $12, %[OPENGL_API]($3)\n\t" \
- "beqz $12, 1f\n\t" \
- " move $25, $ra\n\t" \
- "ld $12, %[API]($12)\n\t" \
- "beqz $12, 1f\n\t" \
- " nop\n\t" \
- "move $25, $12\n\t" \
- "1:\n\t" \
- "jalr $0, $25\n\t" \
- " move $2, $0\n\t" \
- ".set pop\n\t" \
- : \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*sizeof(void*)),\
- [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
- : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", \
- "$10", "$11", "$12", "$25" \
- );
-
- #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
- #define CALL_GL_API_INTERNAL_DO_RETURN
-
-#elif defined(__mips__)
-
- #define API_ENTRY(_api) __attribute__((naked,noinline)) _api
-
- // t0: $8
- // fn: $25
- // tls: $3
- // v0: $2
#define CALL_GL_API_INTERNAL_CALL(_api, ...) \
asm volatile( \
- ".set push\n\t" \
- ".set noreorder\n\t" \
- ".set mips32r2\n\t" \
- "rdhwr $3, $29\n\t" \
- "lw $3, %[OPENGL_API]($3)\n\t" \
- "beqz $3, 1f\n\t" \
- " move $25,$ra\n\t" \
- "lw $3, %[API]($3)\n\t" \
- "beqz $3, 1f\n\t" \
- " nop\n\t" \
- "move $25, $3\n\t" \
- "1:\n\t" \
- "jalr $0, $25\n\t" \
- " move $2, $0\n\t" \
- ".set pop\n\t" \
+ "mv t0, tp\n" \
+ "li t1, %[tls]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "beqz t0, 1f\n" \
+ "li t1, %[api]\n" \
+ "add t0, t0, t1\n" \
+ "ld t0, 0(t0)\n" \
+ "jalr x0, t0\n" \
+ "1:\n" \
: \
- : [OPENGL_API] "I"(TLS_SLOT_OPENGL_API*4), \
- [API] "I"(__builtin_offsetof(gl_hooks_t, gl._api)) \
- : "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$25" \
+ : [tls] "i"(TLS_SLOT_OPENGL_API*sizeof(void *)), \
+ [api] "i"(__builtin_offsetof(gl_hooks_t, gl._api)) \
+ : "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", \
+ "a5", "t6", "t3", "t4", "t5", "t6" \
);
- #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE
- #define CALL_GL_API_INTERNAL_DO_RETURN
+ #define CALL_GL_API_INTERNAL_SET_RETURN_VALUE \
+ asm volatile( \
+ "li a0, 0\n" \
+ : \
+ : \
+ : "a0" \
+ );
+
+ #define CALL_GL_API_INTERNAL_DO_RETURN \
+ asm volatile( \
+ "ret\n" \
+ : \
+ : \
+ : \
+ );
#endif
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e9fbf6e..e234ed0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -7564,7 +7564,7 @@
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
const int uid = ipc->getCallingUid();
- if ((uid != AID_GRAPHICS) &&
+ if ((uid != AID_GRAPHICS) && (uid != AID_SYSTEM) &&
!PermissionCache::checkPermission(sControlDisplayBrightness, pid, uid)) {
ALOGE("Permission Denial: can't control brightness pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;