Merge "Revert "Revert "libbinder_ndk: toString never goes to empty stri...""
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index ee1c63a..12de33f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -194,6 +194,8 @@
static const std::string TOMBSTONE_FILE_PREFIX = "tombstone_";
static const std::string ANR_DIR = "/data/anr/";
static const std::string ANR_FILE_PREFIX = "anr_";
+static const std::string SHUTDOWN_CHECKPOINTS_DIR = "/data/system/shutdown-checkpoints/";
+static const std::string SHUTDOWN_CHECKPOINTS_FILE_PREFIX = "checkpoints-";
// TODO: temporary variables and functions used during C++ refactoring
@@ -1109,6 +1111,16 @@
RunCommand("IP6TABLES RAW", {"ip6tables", "-t", "raw", "-L", "-nvx"});
}
+static void DumpShutdownCheckpoints() {
+ const bool shutdown_checkpoints_dumped = AddDumps(
+ ds.shutdown_checkpoints_.begin(), ds.shutdown_checkpoints_.end(),
+ "SHUTDOWN CHECKPOINTS", false /* add_to_zip */);
+ if (!shutdown_checkpoints_dumped) {
+ printf("*** NO SHUTDOWN CHECKPOINTS to dump in %s\n\n",
+ SHUTDOWN_CHECKPOINTS_DIR.c_str());
+ }
+}
+
static void DumpDynamicPartitionInfo() {
if (!::android::base::GetBoolProperty("ro.boot.dynamic_partitions", false)) {
return;
@@ -1701,6 +1713,8 @@
DoKmsg();
+ DumpShutdownCheckpoints();
+
DumpIpAddrAndRules();
dump_route_tables();
@@ -1855,6 +1869,8 @@
if (!PropertiesHelper::IsDryRun()) {
ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX);
ds.anr_data_ = GetDumpFds(ANR_DIR, ANR_FILE_PREFIX);
+ ds.shutdown_checkpoints_ = GetDumpFds(
+ SHUTDOWN_CHECKPOINTS_DIR, SHUTDOWN_CHECKPOINTS_FILE_PREFIX);
}
ds.AddDir(RECOVERY_DIR, true);
@@ -2907,6 +2923,7 @@
}
tombstone_data_.clear();
anr_data_.clear();
+ shutdown_checkpoints_.clear();
// Instead of shutdown the pool, we delete temporary files directly since
// shutdown blocking the call.
@@ -3190,6 +3207,7 @@
tombstone_data_.clear();
anr_data_.clear();
+ shutdown_checkpoints_.clear();
return (consent_callback_ != nullptr &&
consent_callback_->getResult() == UserConsentResult::UNAVAILABLE)
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 66f84cb..7ffe80e 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -499,6 +499,9 @@
// List of open ANR dump files.
std::vector<DumpData> anr_data_;
+ // List of open shutdown checkpoint files.
+ std::vector<DumpData> shutdown_checkpoints_;
+
// A thread pool to execute dump tasks simultaneously if the parallel run is enabled.
std::unique_ptr<android::os::dumpstate::DumpPool> dump_pool_;
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 61f931e..1386660 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -48,17 +48,6 @@
}
cc_binary {
- name: "servicemanager.microdroid",
- defaults: ["servicemanager_defaults"],
- init_rc: ["servicemanager.microdroid.rc"],
- srcs: ["main.cpp"],
- bootstrap: true,
- // Prevent this from being installed when running tests in this directory.
- // This is okay because microdorid build rule can bundle this anyway.
- installable: false,
-}
-
-cc_binary {
name: "servicemanager.recovery",
stem: "servicemanager",
recovery: true,
diff --git a/cmds/servicemanager/servicemanager.microdroid.rc b/cmds/servicemanager/servicemanager.microdroid.rc
deleted file mode 100644
index 8819e1e..0000000
--- a/cmds/servicemanager/servicemanager.microdroid.rc
+++ /dev/null
@@ -1,8 +0,0 @@
-service servicemanager /system/bin/servicemanager.microdroid
- class core
- user system
- group system readproc
- critical
- onrestart setprop servicemanager.ready false
- onrestart restart apexd
- shutdown critical
diff --git a/include/android/sensor.h b/include/android/sensor.h
index eef69f4..ba81bc8 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -596,12 +596,15 @@
float accuracy;
} AHeadingEvent;
+// LINT.IfChange
/**
* Information that describes a sensor event, refer to
* <a href="/reference/android/hardware/SensorEvent">SensorEvent</a> for additional
* documentation.
+ *
+ * NOTE: changes to this struct has to be backward compatible and reflected in
+ * sensors_event_t
*/
-/* NOTE: changes to this struct has to be backward compatible */
typedef struct ASensorEvent {
int32_t version; /* sizeof(struct ASensorEvent) */
int32_t sensor; /** The sensor that generates this event */
@@ -646,6 +649,7 @@
uint32_t flags;
int32_t reserved1[3];
} ASensorEvent;
+// LINT.ThenChange (hardware/libhardware/include/hardware/sensors.h)
struct ASensorManager;
/**
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 11c8e5d..7770374 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -45,11 +45,11 @@
#define IF_LOG_TRANSACTIONS() if (false)
#define IF_LOG_COMMANDS() if (false)
-#define LOG_REMOTEREFS(...)
+#define LOG_REMOTEREFS(...)
#define IF_LOG_REMOTEREFS() if (false)
-#define LOG_THREADPOOL(...)
-#define LOG_ONEWAY(...)
+#define LOG_THREADPOOL(...)
+#define LOG_ONEWAY(...)
#else
@@ -394,14 +394,92 @@
// context, so we don't abort
}
+constexpr uint32_t encodeExplicitIdentity(bool hasExplicitIdentity, pid_t callingPid) {
+ uint32_t as_unsigned = static_cast<uint32_t>(callingPid);
+ if (hasExplicitIdentity) {
+ return as_unsigned | (1 << 30);
+ } else {
+ return as_unsigned & ~(1 << 30);
+ }
+}
+
+constexpr int64_t packCallingIdentity(bool hasExplicitIdentity, uid_t callingUid,
+ pid_t callingPid) {
+ // Calling PID is a 32-bit signed integer, but doesn't consume the entire 32 bit space.
+ // To future-proof this and because we have extra capacity, we decided to also support -1,
+ // since this constant is used to represent invalid UID in other places of the system.
+ // Thus, we pack hasExplicitIdentity into the 2nd bit from the left. This allows us to
+ // preserve the (left-most) bit for the sign while also encoding the value of
+ // hasExplicitIdentity.
+ // 32b | 1b | 1b | 30b
+ // token = [ calling uid | calling pid(sign) | has explicit identity | calling pid(rest) ]
+ uint64_t token = (static_cast<uint64_t>(callingUid) << 32) |
+ encodeExplicitIdentity(hasExplicitIdentity, callingPid);
+ return static_cast<int64_t>(token);
+}
+
+constexpr bool unpackHasExplicitIdentity(int64_t token) {
+ return static_cast<int32_t>(token) & (1 << 30);
+}
+
+constexpr uid_t unpackCallingUid(int64_t token) {
+ return static_cast<uid_t>(token >> 32);
+}
+
+constexpr pid_t unpackCallingPid(int64_t token) {
+ int32_t encodedPid = static_cast<int32_t>(token);
+ if (encodedPid & (1 << 31)) {
+ return encodedPid | (1 << 30);
+ } else {
+ return encodedPid & ~(1 << 30);
+ }
+}
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, 9999)) == true,
+ "pack true hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(true, 1000, 9999)) == 1000, "pack true uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(true, 1000, 9999)) == 9999, "pack true pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, 9999)) == false,
+ "pack false hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(false, 1000, 9999)) == 1000, "pack false uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(false, 1000, 9999)) == 9999, "pack false pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(true, 1000, -1)) == true,
+ "pack true (negative) hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(true, 1000, -1)) == 1000,
+ "pack true (negative) uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(true, 1000, -1)) == -1,
+ "pack true (negative) pid");
+
+static_assert(unpackHasExplicitIdentity(packCallingIdentity(false, 1000, -1)) == false,
+ "pack false (negative) hasExplicit");
+
+static_assert(unpackCallingUid(packCallingIdentity(false, 1000, -1)) == 1000,
+ "pack false (negative) uid");
+
+static_assert(unpackCallingPid(packCallingIdentity(false, 1000, -1)) == -1,
+ "pack false (negative) pid");
+
int64_t IPCThreadState::clearCallingIdentity()
{
// ignore mCallingSid for legacy reasons
- int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+ int64_t token = packCallingIdentity(mHasExplicitIdentity, mCallingUid, mCallingPid);
clearCaller();
+ mHasExplicitIdentity = true;
return token;
}
+bool IPCThreadState::hasExplicitIdentity() {
+ return mHasExplicitIdentity;
+}
+
void IPCThreadState::setStrictModePolicy(int32_t policy)
{
mStrictModePolicy = policy;
@@ -474,9 +552,10 @@
void IPCThreadState::restoreCallingIdentity(int64_t token)
{
- mCallingUid = (int)(token>>32);
+ mCallingUid = unpackCallingUid(token);
mCallingSid = nullptr; // not enough data to restore
- mCallingPid = (int)token;
+ mCallingPid = unpackCallingPid(token);
+ mHasExplicitIdentity = unpackHasExplicitIdentity(token);
}
void IPCThreadState::clearCaller()
@@ -889,6 +968,7 @@
mCallRestriction(mProcess->mCallRestriction) {
pthread_setspecific(gTLS, this);
clearCaller();
+ mHasExplicitIdentity = false;
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
}
@@ -1279,6 +1359,7 @@
const pid_t origPid = mCallingPid;
const char* origSid = mCallingSid;
const uid_t origUid = mCallingUid;
+ const bool origHasExplicitIdentity = mHasExplicitIdentity;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
const int32_t origWorkSource = mWorkSource;
@@ -1292,6 +1373,7 @@
mCallingPid = tr.sender_pid;
mCallingSid = reinterpret_cast<const char*>(tr_secctx.secctx);
mCallingUid = tr.sender_euid;
+ mHasExplicitIdentity = false;
mLastTransactionBinderFlags = tr.flags;
// ALOGI(">>>> TRANSACT from pid %d sid %s uid %d\n", mCallingPid,
@@ -1367,6 +1449,7 @@
mCallingPid = origPid;
mCallingSid = origSid;
mCallingUid = origUid;
+ mHasExplicitIdentity = origHasExplicitIdentity;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
mWorkSource = origWorkSource;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 4b07608..ee081c4 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -614,11 +614,14 @@
if (status_t status = readInt32(&fdIndex); status != OK) {
return status;
}
- const auto& oldFd = otherRpcFields->mFds->at(fdIndex);
+ int oldFd = toRawFd(otherRpcFields->mFds->at(fdIndex));
// To match kernel binder behavior, we always dup, even if the
// FD was unowned in the source parcel.
- rpcFields->mFds->emplace_back(
- base::unique_fd(fcntl(toRawFd(oldFd), F_DUPFD_CLOEXEC, 0)));
+ int newFd = -1;
+ if (status_t status = dupFileDescriptor(oldFd, &newFd); status != OK) {
+ ALOGW("Failed to duplicate file descriptor %d: %s", oldFd, strerror(-status));
+ }
+ rpcFields->mFds->emplace_back(base::unique_fd(newFd));
// Fixup the index in the data.
mDataPos = newDataPos + 4;
if (status_t status = writeInt32(rpcFields->mFds->size() - 1); status != OK) {
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index c01e92f..65b77c6 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -139,6 +139,7 @@
int64_t clearCallingIdentity();
// Restores PID/UID (not SID)
void restoreCallingIdentity(int64_t token);
+ bool hasExplicitIdentity();
status_t setupPolling(int* fd);
status_t handlePolledCommands();
@@ -241,6 +242,7 @@
bool mPropagateWorkSource;
bool mIsLooper;
bool mIsFlushing;
+ bool mHasExplicitIdentity;
int32_t mStrictModePolicy;
int32_t mLastTransactionBinderFlags;
CallRestriction mCallRestriction;
diff --git a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
index dd177af..f08bde8 100644
--- a/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
+++ b/libs/binder/include_rpc_unstable/binder_rpc_unstable.hpp
@@ -17,20 +17,41 @@
#pragma once
#include <sys/socket.h>
+#include <stdint.h>
extern "C" {
struct AIBinder;
+struct ARpcServer;
// 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 RunVsockRpcServer(AIBinder* service, unsigned int port);
+// Returns an opaque handle to the running server instance, or null if the server
+// could not be started.
+[[nodiscard]] ARpcServer* ARpcServer_newVsock(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 RunVsockRpcServerCallback(AIBinder* service, unsigned int port,
- void (*readyCallback)(void* param), void* param);
+// Starts a Unix domain RPC server with a given init-managed Unix domain `name`
+// and a given root IBinder object.
+// The socket should be created in init.rc with the same `name`.
+// Returns an opaque handle to the running server instance, or null if the server
+// could not be started.
+[[nodiscard]] ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name);
+
+// Runs ARpcServer_join() in a background thread. Immediately returns.
+void ARpcServer_start(ARpcServer* server);
+
+// Joins the thread of a running RpcServer instance. At any given point, there
+// can only be one thread calling ARpcServer_join().
+// If a client needs to actively terminate join, call ARpcServer_shutdown() in
+// a separate thread.
+void ARpcServer_join(ARpcServer* server);
+
+// Shuts down any running ARpcServer_join().
+void ARpcServer_shutdown(ARpcServer* server);
+
+// Frees the ARpcServer handle and drops the reference count on the underlying
+// RpcServer instance. The handle must not be reused afterwards.
+// This automatically calls ARpcServer_shutdown().
+void ARpcServer_free(ARpcServer* server);
// Starts an RPC server on a given port and a given root IBinder factory.
// RunVsockRpcServerWithFactory acts like RunVsockRpcServerCallback, but instead of
@@ -42,15 +63,6 @@
AIBinder* VsockRpcClient(unsigned int cid, unsigned int port);
-// Starts a Unix domain RPC server with a given init-managed Unix domain `name` and
-// a given root IBinder object.
-// The socket should be created in init.rc with the same `name`.
-//
-// This function sets up the server, calls readyCallback with a given param, and
-// then joins before returning.
-bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name,
- void (*readyCallback)(void* param), void* param);
-
// Gets the service via the RPC binder with Unix domain socket with the given
// Unix socket `name`.
// The final Unix domain socket path name is /dev/socket/`name`.
diff --git a/libs/binder/libbinder_rpc_unstable.cpp b/libs/binder/libbinder_rpc_unstable.cpp
index 9edb3b6..f55c779 100644
--- a/libs/binder/libbinder_rpc_unstable.cpp
+++ b/libs/binder/libbinder_rpc_unstable.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <binder_rpc_unstable.hpp>
+
#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <android/binder_libbinder.h>
@@ -25,23 +27,32 @@
using android::OK;
using android::RpcServer;
using android::RpcSession;
+using android::sp;
using android::status_t;
using android::statusToString;
using android::base::unique_fd;
-extern "C" {
+// Opaque handle for RpcServer.
+struct ARpcServer {};
-void RunRpcServer(android::sp<RpcServer>& server, AIBinder* service,
- void (*readyCallback)(void* param), void* param) {
- server->setRootObject(AIBinder_toPlatformBinder(service));
-
- if (readyCallback) readyCallback(param);
- server->join();
-
- // Shutdown any open sessions since server failed.
- (void)server->shutdown();
+static sp<RpcServer> toRpcServer(ARpcServer* handle) {
+ auto ref = reinterpret_cast<RpcServer*>(handle);
+ return sp<RpcServer>::fromExisting(ref);
}
+static ARpcServer* createRpcServerHandle(sp<RpcServer>& server) {
+ auto ref = server.get();
+ ref->incStrong(ref);
+ return reinterpret_cast<ARpcServer*>(ref);
+}
+
+static void freeRpcServerHandle(ARpcServer* handle) {
+ auto ref = reinterpret_cast<RpcServer*>(handle);
+ ref->decStrong(ref);
+}
+
+extern "C" {
+
bool RunVsockRpcServerWithFactory(AIBinder* (*factory)(unsigned int cid, void* context),
void* factoryContext, unsigned int port) {
auto server = RpcServer::make();
@@ -64,20 +75,47 @@
return true;
}
-bool RunVsockRpcServerCallback(AIBinder* service, unsigned int port,
- void (*readyCallback)(void* param), void* param) {
+ARpcServer* ARpcServer_newVsock(AIBinder* service, 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
<< " error: " << statusToString(status).c_str();
- return false;
+ return nullptr;
}
- RunRpcServer(server, service, readyCallback, param);
- return true;
+ server->setRootObject(AIBinder_toPlatformBinder(service));
+ return createRpcServerHandle(server);
}
-bool RunVsockRpcServer(AIBinder* service, unsigned int port) {
- return RunVsockRpcServerCallback(service, port, nullptr, nullptr);
+ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name) {
+ auto server = RpcServer::make();
+ auto fd = unique_fd(android_get_control_socket(name));
+ if (!fd.ok()) {
+ LOG(ERROR) << "Failed to get fd for the socket:" << name;
+ return nullptr;
+ }
+ if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) {
+ LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name
+ << " error: " << statusToString(status).c_str();
+ return nullptr;
+ }
+ server->setRootObject(AIBinder_toPlatformBinder(service));
+ return createRpcServerHandle(server);
+}
+
+void ARpcServer_start(ARpcServer* handle) {
+ toRpcServer(handle)->start();
+}
+
+void ARpcServer_join(ARpcServer* handle) {
+ toRpcServer(handle)->join();
+}
+
+void ARpcServer_shutdown(ARpcServer* handle) {
+ toRpcServer(handle)->shutdown();
+}
+
+void ARpcServer_free(ARpcServer* handle) {
+ freeRpcServerHandle(handle);
}
AIBinder* VsockRpcClient(unsigned int cid, unsigned int port) {
@@ -90,23 +128,6 @@
return AIBinder_fromPlatformBinder(session->getRootObject());
}
-bool RunInitUnixDomainRpcServer(AIBinder* service, const char* name,
- void (*readyCallback)(void* param), void* param) {
- auto server = RpcServer::make();
- auto fd = unique_fd(android_get_control_socket(name));
- if (!fd.ok()) {
- LOG(ERROR) << "Failed to get fd for the socket:" << name;
- return false;
- }
- if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) {
- LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name
- << " error: " << statusToString(status).c_str();
- return false;
- }
- RunRpcServer(server, service, readyCallback, param);
- return true;
-}
-
AIBinder* UnixDomainRpcClient(const char* name) {
std::string pathname(name);
pathname = ANDROID_SOCKET_DIR "/" + pathname;
diff --git a/libs/binder/libbinder_rpc_unstable.map.txt b/libs/binder/libbinder_rpc_unstable.map.txt
index f9c7bcf..1bc2416 100644
--- a/libs/binder/libbinder_rpc_unstable.map.txt
+++ b/libs/binder/libbinder_rpc_unstable.map.txt
@@ -1,9 +1,12 @@
LIBBINDER_RPC_UNSTABLE_SHIM { # platform-only
global:
- RunVsockRpcServer;
- RunVsockRpcServerCallback;
+ ARpcServer_free;
+ ARpcServer_join;
+ ARpcServer_newInitUnixDomain;
+ ARpcServer_newVsock;
+ ARpcServer_shutdown;
+ ARpcServer_start;
VsockRpcClient;
- RunInitUnixDomainRpcServer;
UnixDomainRpcClient;
RpcPreconnectedClient;
local:
diff --git a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
index 81975e7..9949de2 100644
--- a/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_cpp/android/binder_interface_utils.h
@@ -196,6 +196,10 @@
bool isRemote() override final { return false; }
+ static std::string makeServiceName(std::string_view instance) {
+ return INTERFACE::descriptor + ("/" + std::string(instance));
+ }
+
protected:
/**
* This function should only be called by asBinder. Otherwise, there is a possibility of
diff --git a/libs/binder/ndk/include_platform/android/binder_manager.h b/libs/binder/ndk/include_platform/android/binder_manager.h
index c234270..ad4188f 100644
--- a/libs/binder/ndk/include_platform/android/binder_manager.h
+++ b/libs/binder/ndk/include_platform/android/binder_manager.h
@@ -68,6 +68,7 @@
*
* \param instance identifier of the service used to lookup the service.
*/
+[[deprecated("this polls 5s, use AServiceManager_waitForService or AServiceManager_checkService")]]
__attribute__((warn_unused_result)) AIBinder* AServiceManager_getService(const char* instance)
__INTRODUCED_IN(29);
@@ -108,6 +109,67 @@
__INTRODUCED_IN(31);
/**
+ * Function to call when a service is registered. The instance is passed as well as
+ * ownership of the binder named 'registered'.
+ *
+ * WARNING: a lock is held when this method is called in order to prevent races with
+ * AServiceManager_NotificationRegistration_delete. Do not make synchronous binder calls when
+ * implementing this method to avoid deadlocks.
+ *
+ * \param instance instance name of service registered
+ * \param registered ownership-passed instance of service registered
+ * \param cookie data passed during registration for notifications
+ */
+typedef void (*AServiceManager_onRegister)(const char* instance, AIBinder* registered,
+ void* cookie);
+
+/**
+ * Represents a registration to servicemanager which can be cleared anytime.
+ */
+struct AServiceManager_NotificationRegistration;
+
+/**
+ * Get notifications when a service is registered. If the service is already registered,
+ * you will immediately get a notification.
+ *
+ * WARNING: it is strongly recommended to use AServiceManager_waitForService API instead.
+ * That API will wait synchronously, which is what you usually want in cases, including
+ * using some feature or during boot up. There is a history of bugs where waiting for
+ * notifications like this races with service startup. Also, when this API is used, a service
+ * bug will result in silent failure (rather than a debuggable deadlock). Furthermore, there
+ * is a history of this API being used to know when a service is up as a proxy for whethre
+ * that service should be started. This should only be used if you are intending to get
+ * ahold of the service as a client. For lazy services, whether a service is registered
+ * should not be used as a proxy for when it should be registered, which is only known
+ * by the real client.
+ *
+ * WARNING: if you use this API, you must also ensure that you check missing services are
+ * started and crash otherwise. If service failures are ignored, the system rots.
+ *
+ * \param instance name of service to wait for notifications about
+ * \param onRegister callback for when service is registered
+ * \param cookie data associated with this callback
+ *
+ * \return the token for this registration. Deleting this token will unregister.
+ */
+__attribute__((warn_unused_result)) AServiceManager_NotificationRegistration*
+AServiceManager_registerForServiceNotifications(const char* instance,
+ AServiceManager_onRegister onRegister, void* cookie)
+ __INTRODUCED_IN(34);
+
+/**
+ * Unregister for notifications and delete the object.
+ *
+ * After this method is called, the callback is guaranteed to no longer be invoked. This will block
+ * until any in-progress onRegister callbacks have completed. It is therefore safe to immediately
+ * destroy the void* cookie that was registered when this method returns.
+ *
+ * \param notification object to dismiss
+ */
+void AServiceManager_NotificationRegistration_delete(
+ AServiceManager_NotificationRegistration* notification) __INTRODUCED_IN(34);
+
+/**
* Check if a service is declared (e.g. VINTF manifest).
*
* \param instance identifier of the service.
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 32ca564..5c7005c 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -155,6 +155,8 @@
LIBBINDER_NDK34 { # introduced=UpsideDownCake
global:
AServiceManager_getUpdatableApexName; # systemapi
+ AServiceManager_registerForServiceNotifications; # systemapi llndk
+ AServiceManager_NotificationRegistration_delete; # systemapi llndk
};
LIBBINDER_NDK_PLATFORM {
diff --git a/libs/binder/ndk/service_manager.cpp b/libs/binder/ndk/service_manager.cpp
index a12d0e9..e107c83 100644
--- a/libs/binder/ndk/service_manager.cpp
+++ b/libs/binder/ndk/service_manager.cpp
@@ -28,6 +28,7 @@
using ::android::IServiceManager;
using ::android::sp;
using ::android::status_t;
+using ::android::statusToString;
using ::android::String16;
using ::android::String8;
@@ -86,6 +87,67 @@
AIBinder_incStrong(ret.get());
return ret.get();
}
+typedef void (*AServiceManager_onRegister)(const char* instance, AIBinder* registered,
+ void* cookie);
+
+struct AServiceManager_NotificationRegistration
+ : public IServiceManager::LocalRegistrationCallback {
+ std::mutex m;
+ const char* instance = nullptr;
+ void* cookie = nullptr;
+ AServiceManager_onRegister onRegister = nullptr;
+
+ virtual void onServiceRegistration(const String16& smInstance, const sp<IBinder>& binder) {
+ std::lock_guard<std::mutex> l(m);
+ if (onRegister == nullptr) return;
+
+ CHECK_EQ(String8(smInstance), instance);
+
+ sp<AIBinder> ret = ABpBinder::lookupOrCreateFromBinder(binder);
+ AIBinder_incStrong(ret.get());
+
+ onRegister(instance, ret.get(), cookie);
+ }
+
+ void clear() {
+ std::lock_guard<std::mutex> l(m);
+ instance = nullptr;
+ cookie = nullptr;
+ onRegister = nullptr;
+ }
+};
+
+__attribute__((warn_unused_result)) AServiceManager_NotificationRegistration*
+AServiceManager_registerForServiceNotifications(const char* instance,
+ AServiceManager_onRegister onRegister,
+ void* cookie) {
+ CHECK_NE(instance, nullptr);
+ CHECK_NE(onRegister, nullptr) << instance;
+ // cookie can be nullptr
+
+ auto cb = sp<AServiceManager_NotificationRegistration>::make();
+ cb->instance = instance;
+ cb->onRegister = onRegister;
+ cb->cookie = cookie;
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ if (status_t res = sm->registerForNotifications(String16(instance), cb); res != STATUS_OK) {
+ LOG(ERROR) << "Failed to register for service notifications for " << instance << ": "
+ << statusToString(res);
+ return nullptr;
+ }
+
+ cb->incStrong(nullptr);
+ return cb.get();
+}
+
+void AServiceManager_NotificationRegistration_delete(
+ AServiceManager_NotificationRegistration* notification) {
+ CHECK_NE(notification, nullptr);
+ notification->clear();
+ notification->decStrong(nullptr);
+}
+
bool AServiceManager_isDeclared(const char* instance) {
if (instance == nullptr) {
return false;
diff --git a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
index e221e4c..9d5ef68 100644
--- a/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
+++ b/libs/binder/ndk/tests/libbinder_ndk_unit_test.cpp
@@ -254,6 +254,47 @@
AIBinder_decStrong(binder);
}
+struct ServiceData {
+ std::string instance;
+ ndk::SpAIBinder binder;
+
+ static void fillOnRegister(const char* instance, AIBinder* binder, void* cookie) {
+ ServiceData* d = reinterpret_cast<ServiceData*>(cookie);
+ d->instance = instance;
+ d->binder = ndk::SpAIBinder(binder);
+ }
+};
+
+TEST(NdkBinder, RegisterForServiceNotificationsNonExisting) {
+ ServiceData data;
+ auto* notif = AServiceManager_registerForServiceNotifications(
+ "DOES_NOT_EXIST", ServiceData::fillOnRegister, (void*)&data);
+ ASSERT_NE(notif, nullptr);
+
+ sleep(1); // give us a chance to fail
+ AServiceManager_NotificationRegistration_delete(notif);
+
+ // checking after deleting to avoid needing a mutex over the data - otherwise
+ // in an environment w/ multiple threads, you would need to guard access
+ EXPECT_EQ(data.instance, "");
+ EXPECT_EQ(data.binder, nullptr);
+}
+
+TEST(NdkBinder, RegisterForServiceNotificationsExisting) {
+ ServiceData data;
+ auto* notif = AServiceManager_registerForServiceNotifications(
+ kExistingNonNdkService, ServiceData::fillOnRegister, (void*)&data);
+ ASSERT_NE(notif, nullptr);
+
+ sleep(1); // give us a chance to fail
+ AServiceManager_NotificationRegistration_delete(notif);
+
+ // checking after deleting to avoid needing a mutex over the data - otherwise
+ // in an environment w/ multiple threads, you would need to guard access
+ EXPECT_EQ(data.instance, kExistingNonNdkService);
+ EXPECT_EQ(data.binder, ndk::SpAIBinder(AServiceManager_checkService(kExistingNonNdkService)));
+}
+
TEST(NdkBinder, UnimplementedDump) {
sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
ASSERT_NE(foo, nullptr);
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 738d16a..afd414a 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -17,7 +17,6 @@
rustlibs: [
"libbinder_ndk_sys",
"libdowncast_rs",
- "liblazy_static",
"liblibc",
],
host_supported: true,
@@ -160,7 +159,6 @@
rustlibs: [
"libbinder_ndk_sys",
"libdowncast_rs",
- "liblazy_static",
"liblibc",
],
}
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 9771cc9..f70ebfc 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -19,6 +19,7 @@
"libbinder_rpc_unstable_bindgen_sys",
"libbinder_rs",
"libdowncast_rs",
+ "libforeign_types",
"liblibc",
"liblog_rust",
],
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index 89a49a4..1b719aa 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -23,6 +23,4 @@
get_preconnected_rpc_interface, get_preconnected_rpc_service, get_unix_domain_rpc_interface,
get_unix_domain_rpc_service, get_vsock_rpc_interface, get_vsock_rpc_service,
};
-pub use server::{
- run_init_unix_domain_rpc_server, run_vsock_rpc_server, run_vsock_rpc_server_with_factory,
-};
+pub use server::{run_vsock_rpc_server_with_factory, RpcServer, RpcServerRef};
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index b350a13..42f5567 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -18,114 +18,89 @@
unstable_api::{AIBinder, AsNative},
SpIBinder,
};
+use binder_rpc_unstable_bindgen::ARpcServer;
+use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
+use std::io::{Error, ErrorKind};
use std::{ffi::CString, os::raw, ptr::null_mut};
-/// Runs a binder RPC server, serving the supplied binder service implementation on the given vsock
-/// port.
-///
-/// If and when the server is ready for connections (it is listening on the port), `on_ready` is
-/// called to allow appropriate action to be taken - e.g. to notify clients that they may now
-/// attempt to connect.
-///
-/// 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_vsock_rpc_server<F>(service: SpIBinder, port: u32, on_ready: F) -> bool
-where
- F: FnOnce(),
-{
- let mut ready_notifier = ReadyNotifier(Some(on_ready));
- ready_notifier.run_vsock_server(service, port)
+foreign_type! {
+ type CType = binder_rpc_unstable_bindgen::ARpcServer;
+ fn drop = binder_rpc_unstable_bindgen::ARpcServer_free;
+
+ /// A type that represents a foreign instance of RpcServer.
+ #[derive(Debug)]
+ pub struct RpcServer;
+ /// A borrowed RpcServer.
+ pub struct RpcServerRef;
}
-/// Runs a binder RPC server, serving the supplied binder service implementation on the given
-/// socket file name. The socket should be initialized in init.rc with the same name.
-///
-/// If and when the server is ready for connections, `on_ready` is called to allow appropriate
-/// action to be taken - e.g. to notify clients that they may now attempt to connect.
-///
-/// 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_init_unix_domain_rpc_server<F>(
- service: SpIBinder,
- socket_name: &str,
- on_ready: F,
-) -> bool
-where
- F: FnOnce(),
-{
- let mut ready_notifier = ReadyNotifier(Some(on_ready));
- ready_notifier.run_init_unix_domain_server(service, socket_name)
-}
+/// SAFETY - The opaque handle can be cloned freely.
+unsafe impl Send for RpcServer {}
+/// SAFETY - The underlying C++ RpcServer class is thread-safe.
+unsafe impl Sync for RpcServer {}
-struct ReadyNotifier<F>(Option<F>)
-where
- F: FnOnce();
-
-impl<F> ReadyNotifier<F>
-where
- F: FnOnce(),
-{
- fn run_vsock_server(&mut self, mut service: SpIBinder, port: u32) -> bool {
+impl RpcServer {
+ /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+ /// vsock port.
+ pub fn new_vsock(mut service: SpIBinder, port: u32) -> Result<RpcServer, Error> {
let service = service.as_native_mut();
- let param = self.as_void_ptr();
// SAFETY: Service ownership is transferring to the server and won't be valid afterward.
// Plus the binder objects are threadsafe.
- // 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::RunVsockRpcServerCallback(
- service,
- port,
- Some(Self::ready_callback),
- param,
- )
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newVsock(service, port))
}
}
- fn run_init_unix_domain_server(&mut self, mut service: SpIBinder, socket_name: &str) -> bool {
+ /// Creates a binder RPC server, serving the supplied binder service implementation on the given
+ /// socket file name. The socket should be initialized in init.rc with the same name.
+ pub fn new_init_unix_domain(
+ mut service: SpIBinder,
+ socket_name: &str,
+ ) -> Result<RpcServer, Error> {
let socket_name = match CString::new(socket_name) {
Ok(s) => s,
Err(e) => {
log::error!("Cannot convert {} to CString. Error: {:?}", socket_name, e);
- return false;
+ return Err(Error::from(ErrorKind::InvalidInput));
}
};
let service = service.as_native_mut();
- let param = self.as_void_ptr();
// SAFETY: Service ownership is transferring to the server and won't be valid afterward.
// Plus the binder objects are threadsafe.
- // RunInitUnixDomainRpcServer 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::RunInitUnixDomainRpcServer(
+ Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newInitUnixDomain(
service,
socket_name.as_ptr(),
- Some(Self::ready_callback),
- param,
- )
+ ))
}
}
- fn as_void_ptr(&mut self) -> *mut raw::c_void {
- self as *mut _ as *mut raw::c_void
- }
-
- unsafe extern "C" fn ready_callback(param: *mut raw::c_void) {
- // 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;
- ready_notifier.as_mut().unwrap().notify()
- }
-
- fn notify(&mut self) {
- if let Some(on_ready) = self.0.take() {
- on_ready();
+ unsafe fn checked_from_ptr(ptr: *mut ARpcServer) -> Result<RpcServer, Error> {
+ if ptr.is_null() {
+ return Err(Error::new(ErrorKind::Other, "Failed to start server"));
}
+ Ok(RpcServer::from_ptr(ptr))
+ }
+}
+
+impl RpcServerRef {
+ /// Starts a new background thread and calls join(). Returns immediately.
+ pub fn start(&self) {
+ unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
+ }
+
+ /// Joins the RpcServer thread. The call blocks until the server terminates.
+ /// This must be called from exactly one thread.
+ pub fn join(&self) {
+ unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
+ }
+
+ /// Shuts down the running RpcServer. Can be called multiple times and from
+ /// multiple threads. Called automatically during drop().
+ pub fn shutdown(&self) {
+ unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) };
}
}
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index dee05d0..6f686fb 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -22,7 +22,6 @@
use crate::proxy::SpIBinder;
use crate::sys;
-use lazy_static::lazy_static;
use std::convert::TryFrom;
use std::ffi::{c_void, CStr, CString};
use std::fs::File;
@@ -508,10 +507,8 @@
_private: (),
}
-lazy_static! {
- // Count of how many LazyServiceGuard objects are in existence.
- static ref GUARD_COUNT: Mutex<u64> = Mutex::new(0);
-}
+// Count of how many LazyServiceGuard objects are in existence.
+static GUARD_COUNT: Mutex<u64> = Mutex::new(0);
impl LazyServiceGuard {
/// Create a new LazyServiceGuard to prevent the service manager prematurely killing this
diff --git a/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs b/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs
index d2bfde1..a2d48b6 100644
--- a/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs
+++ b/libs/binder/rust/tests/parcel_fuzzer/read_utils.rs
@@ -16,9 +16,9 @@
use binder::binder_impl::BorrowedParcel;
use binder::{ParcelFileDescriptor, Parcelable, SpIBinder};
-use binderReadParcelIface::aidl::EmptyParcelable::EmptyParcelable;
-use binderReadParcelIface::aidl::GenericDataParcelable::GenericDataParcelable;
-use binderReadParcelIface::aidl::SingleDataParcelable::SingleDataParcelable;
+use binderReadParcelIface::aidl::parcelables::EmptyParcelable::EmptyParcelable;
+use binderReadParcelIface::aidl::parcelables::GenericDataParcelable::GenericDataParcelable;
+use binderReadParcelIface::aidl::parcelables::SingleDataParcelable::SingleDataParcelable;
macro_rules! read_parcel_interface {
($data_type:ty) => {
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 68a827b..02aa45f 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -913,6 +913,33 @@
EXPECT_EQ(status.transactionError(), BAD_VALUE) << status;
}
+TEST_P(BinderRpc, AppendInvalidFd) {
+ auto proc = createRpcTestSocketServerProcess({
+ .clientFileDescriptorTransportMode = RpcSession::FileDescriptorTransportMode::UNIX,
+ .serverSupportedFileDescriptorTransportModes =
+ {RpcSession::FileDescriptorTransportMode::UNIX},
+ });
+
+ int badFd = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 0);
+ ASSERT_NE(badFd, -1);
+
+ // Close the file descriptor so it becomes invalid for dup
+ close(badFd);
+
+ Parcel p1;
+ p1.markForBinder(proc.rootBinder);
+ p1.writeInt32(3);
+ EXPECT_EQ(OK, p1.writeFileDescriptor(badFd, false));
+
+ Parcel pRaw;
+ pRaw.markForBinder(proc.rootBinder);
+ EXPECT_EQ(OK, pRaw.appendFrom(&p1, 0, p1.dataSize()));
+
+ pRaw.setDataPosition(0);
+ EXPECT_EQ(3, pRaw.readInt32());
+ ASSERT_EQ(-1, pRaw.readFileDescriptor());
+}
+
TEST_P(BinderRpc, WorksWithLibbinderNdkPing) {
if constexpr (!kEnableSharedLibs) {
GTEST_SKIP() << "Test disabled because Binder was built as a static library";
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 61a2412..35866ad 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -12,13 +12,14 @@
host_supported: true,
unstable: true,
srcs: [
- "EmptyParcelable.aidl",
- "SingleDataParcelable.aidl",
- "GenericDataParcelable.aidl",
+ "parcelables/EmptyParcelable.aidl",
+ "parcelables/SingleDataParcelable.aidl",
+ "parcelables/GenericDataParcelable.aidl",
],
backend: {
java: {
- enabled: false,
+ enabled: true,
+ platform_apis: true,
},
rust: {
enabled: true,
diff --git a/libs/binder/tests/parcel_fuzzer/EmptyParcelable.aidl b/libs/binder/tests/parcel_fuzzer/EmptyParcelable.aidl
deleted file mode 100644
index 96d6223..0000000
--- a/libs/binder/tests/parcel_fuzzer/EmptyParcelable.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (C) 2022 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.
- */
-
-parcelable EmptyParcelable{
-}
\ No newline at end of file
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 9dac2c9..768fbe1 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -16,9 +16,9 @@
#define FUZZ_LOG_TAG "binder"
#include "binder.h"
-#include "EmptyParcelable.h"
-#include "GenericDataParcelable.h"
-#include "SingleDataParcelable.h"
+#include "parcelables/EmptyParcelable.h"
+#include "parcelables/GenericDataParcelable.h"
+#include "parcelables/SingleDataParcelable.h"
#include "util.h"
#include <android-base/hex.h>
@@ -359,19 +359,19 @@
},
[] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call readFromParcel() with status for EmptyParcelable";
- EmptyParcelable emptyParcelable{};
+ parcelables::EmptyParcelable emptyParcelable{};
status_t status = emptyParcelable.readFromParcel(&p);
FUZZ_LOG() << " status: " << status;
},
[] (const ::android::Parcel& p , FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call readFromParcel() with status for SingleDataParcelable";
- SingleDataParcelable singleDataParcelable;
+ parcelables::SingleDataParcelable singleDataParcelable;
status_t status = singleDataParcelable.readFromParcel(&p);
FUZZ_LOG() <<" status: " << status;
},
[] (const ::android::Parcel& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to call readFromParcel() with status for GenericDataParcelable";
- GenericDataParcelable genericDataParcelable;
+ parcelables::GenericDataParcelable genericDataParcelable;
status_t status = genericDataParcelable.readFromParcel(&p);
FUZZ_LOG() <<" status: " << status;
},
diff --git a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
index af773a0..53e7de4 100644
--- a/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder_ndk.cpp
@@ -16,9 +16,9 @@
#define FUZZ_LOG_TAG "binder_ndk"
#include "binder_ndk.h"
-#include "aidl/EmptyParcelable.h"
-#include "aidl/GenericDataParcelable.h"
-#include "aidl/SingleDataParcelable.h"
+#include "aidl/parcelables/EmptyParcelable.h"
+#include "aidl/parcelables/GenericDataParcelable.h"
+#include "aidl/parcelables/SingleDataParcelable.h"
#include <android/binder_parcel_utils.h>
#include <android/binder_parcelable_utils.h>
@@ -183,19 +183,19 @@
[](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read parcel using readFromParcel for EmptyParcelable";
- aidl::EmptyParcelable emptyParcelable;
+ aidl::parcelables::EmptyParcelable emptyParcelable;
binder_status_t status = emptyParcelable.readFromParcel(p.aParcel());
FUZZ_LOG() << "status: " << status;
},
[](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read parcel using readFromParcel for SingleDataParcelable";
- aidl::SingleDataParcelable singleDataParcelable;
+ aidl::parcelables::SingleDataParcelable singleDataParcelable;
binder_status_t status = singleDataParcelable.readFromParcel(p.aParcel());
FUZZ_LOG() << "status: " << status;
},
[](const NdkParcelAdapter& p, FuzzedDataProvider& /*provider*/) {
FUZZ_LOG() << "about to read parcel using readFromParcel for GenericDataParcelable";
- aidl::GenericDataParcelable genericDataParcelable;
+ aidl::parcelables::GenericDataParcelable genericDataParcelable;
binder_status_t status = genericDataParcelable.readFromParcel(p.aParcel());
FUZZ_LOG() << "status: " << status;
},
diff --git a/libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl b/libs/binder/tests/parcel_fuzzer/parcelables/EmptyParcelable.aidl
similarity index 92%
copy from libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl
copy to libs/binder/tests/parcel_fuzzer/parcelables/EmptyParcelable.aidl
index d62891b..1216250 100644
--- a/libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl
+++ b/libs/binder/tests/parcel_fuzzer/parcelables/EmptyParcelable.aidl
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-parcelable SingleDataParcelable{
- int data;
+package parcelables;
+parcelable EmptyParcelable {
}
\ No newline at end of file
diff --git a/libs/binder/tests/parcel_fuzzer/GenericDataParcelable.aidl b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
similarity index 97%
rename from libs/binder/tests/parcel_fuzzer/GenericDataParcelable.aidl
rename to libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
index fc2542b..f1079e9 100644
--- a/libs/binder/tests/parcel_fuzzer/GenericDataParcelable.aidl
+++ b/libs/binder/tests/parcel_fuzzer/parcelables/GenericDataParcelable.aidl
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package parcelables;
parcelable GenericDataParcelable {
int data;
diff --git a/libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl b/libs/binder/tests/parcel_fuzzer/parcelables/SingleDataParcelable.aidl
similarity index 96%
rename from libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl
rename to libs/binder/tests/parcel_fuzzer/parcelables/SingleDataParcelable.aidl
index d62891b..0187168 100644
--- a/libs/binder/tests/parcel_fuzzer/SingleDataParcelable.aidl
+++ b/libs/binder/tests/parcel_fuzzer/parcelables/SingleDataParcelable.aidl
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package parcelables;
parcelable SingleDataParcelable{
int data;
diff --git a/libs/binder/trusty/include/log/log.h b/libs/binder/trusty/include/log/log.h
index bf877a3..d88d18a 100644
--- a/libs/binder/trusty/include/log/log.h
+++ b/libs/binder/trusty/include/log/log.h
@@ -120,3 +120,7 @@
do { \
TLOGE("android_errorWriteLog: tag:%x subTag:%s\n", tag, subTag); \
} while (0)
+
+extern "C" inline void __assert(const char* file, int line, const char* str) {
+ LOG_ALWAYS_FATAL("%s:%d: assertion \"%s\" failed", file, line, str);
+}
diff --git a/libs/fakeservicemanager/ServiceManager.cpp b/libs/fakeservicemanager/ServiceManager.cpp
index 480ec79..1109ad8 100644
--- a/libs/fakeservicemanager/ServiceManager.cpp
+++ b/libs/fakeservicemanager/ServiceManager.cpp
@@ -36,6 +36,9 @@
status_t ServiceManager::addService(const String16& name, const sp<IBinder>& service,
bool /*allowIsolated*/,
int /*dumpsysFlags*/) {
+ if (service == nullptr) {
+ return UNEXPECTED_NULL;
+ }
mNameToService[name] = service;
return NO_ERROR;
}
@@ -103,4 +106,8 @@
std::vector<IServiceManager::ServiceDebugInfo> ret;
return ret;
}
+
+void ServiceManager::clear() {
+ mNameToService.clear();
+}
} // namespace android
diff --git a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
index ee0637e..ba6bb7d 100644
--- a/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
+++ b/libs/fakeservicemanager/include/fakeservicemanager/ServiceManager.h
@@ -64,6 +64,9 @@
std::vector<IServiceManager::ServiceDebugInfo> getServiceDebugInfo() override;
+ // Clear all of the registered services
+ void clear();
+
private:
std::map<String16, sp<IBinder>> mNameToService;
};
diff --git a/libs/fakeservicemanager/test_sm.cpp b/libs/fakeservicemanager/test_sm.cpp
index 71e5abe..8682c1c 100644
--- a/libs/fakeservicemanager/test_sm.cpp
+++ b/libs/fakeservicemanager/test_sm.cpp
@@ -50,6 +50,12 @@
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
}
+TEST(AddService, SadNullBinder) {
+ auto sm = new ServiceManager();
+ EXPECT_EQ(sm->addService(String16("foo"), nullptr, false /*allowIsolated*/,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), android::UNEXPECTED_NULL);
+}
+
TEST(AddService, HappyOverExistingService) {
auto sm = new ServiceManager();
EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
@@ -58,6 +64,15 @@
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
}
+TEST(AddService, HappyClearAddedService) {
+ auto sm = new ServiceManager();
+ EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
+ IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
+ EXPECT_NE(sm->getService(String16("foo")), nullptr);
+ sm->clear();
+ EXPECT_EQ(sm->getService(String16("foo")), nullptr);
+}
+
TEST(GetService, HappyHappy) {
auto sm = new ServiceManager();
sp<IBinder> service = getBinder();
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 6b544b2..3b13708 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1107,9 +1107,12 @@
ATRACE_CALL();
auto& mapper = GraphicBufferMapper::get();
mapper.setDataspace(buffer->handle, static_cast<ui::Dataspace>(queueBufferInput.dataSpace));
- mapper.setSmpte2086(buffer->handle, queueBufferInput.getHdrMetadata().getSmpte2086());
- mapper.setCta861_3(buffer->handle, queueBufferInput.getHdrMetadata().getCta8613());
- mapper.setSmpte2094_40(buffer->handle, queueBufferInput.getHdrMetadata().getHdr10Plus());
+ if (mHdrMetadataIsSet & HdrMetadata::SMPTE2086)
+ mapper.setSmpte2086(buffer->handle, queueBufferInput.getHdrMetadata().getSmpte2086());
+ if (mHdrMetadataIsSet & HdrMetadata::CTA861_3)
+ mapper.setCta861_3(buffer->handle, queueBufferInput.getHdrMetadata().getCta8613());
+ if (mHdrMetadataIsSet & HdrMetadata::HDR10PLUS)
+ mapper.setSmpte2094_40(buffer->handle, queueBufferInput.getHdrMetadata().getHdr10Plus());
}
void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
@@ -2250,6 +2253,7 @@
int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) {
ALOGV("Surface::setBuffersSmpte2086Metadata");
Mutex::Autolock lock(mMutex);
+ mHdrMetadataIsSet |= HdrMetadata::SMPTE2086;
if (metadata) {
mHdrMetadata.smpte2086 = *metadata;
mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086;
@@ -2262,6 +2266,7 @@
int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) {
ALOGV("Surface::setBuffersCta8613Metadata");
Mutex::Autolock lock(mMutex);
+ mHdrMetadataIsSet |= HdrMetadata::CTA861_3;
if (metadata) {
mHdrMetadata.cta8613 = *metadata;
mHdrMetadata.validTypes |= HdrMetadata::CTA861_3;
@@ -2274,6 +2279,7 @@
int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
ALOGV("Surface::setBuffersBlobMetadata");
Mutex::Autolock lock(mMutex);
+ mHdrMetadataIsSet |= HdrMetadata::HDR10PLUS;
if (size > 0) {
mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index ab9ebaa..862a4ad 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -462,6 +462,11 @@
// queue operation. There is no HDR metadata by default.
HdrMetadata mHdrMetadata;
+ // mHdrMetadataIsSet is a bitfield to track which HDR metadata has been set.
+ // Prevent Surface from resetting HDR metadata that was set on a bufer when
+ // HDR metadata is not set on this Surface.
+ uint32_t mHdrMetadataIsSet{0};
+
// mCrop is the crop rectangle that will be used for the next buffer
// that gets queued. It is set by calling setCrop.
Rect mCrop;
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index 4127f7c..f646bd4 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -64,9 +64,10 @@
}
bool shouldDisregardTransformation(uint32_t source) {
- // Do not apply any transformations to axes from joysticks or touchpads.
+ // Do not apply any transformations to axes from joysticks, touchpads, or relative mice.
return isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK) ||
- isFromSource(source, AINPUT_SOURCE_CLASS_POSITION);
+ isFromSource(source, AINPUT_SOURCE_CLASS_POSITION) ||
+ isFromSource(source, AINPUT_SOURCE_MOUSE_RELATIVE);
}
bool shouldDisregardOffset(uint32_t source) {
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index a92016b..4b31246 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -715,10 +715,10 @@
}
TEST_F(MotionEventTest, JoystickAndTouchpadAreNotTransformed) {
- constexpr static std::array kNonTransformedSources = {std::pair(AINPUT_SOURCE_TOUCHPAD,
- AMOTION_EVENT_ACTION_DOWN),
- std::pair(AINPUT_SOURCE_JOYSTICK,
- AMOTION_EVENT_ACTION_MOVE)};
+ constexpr static std::array kNonTransformedSources =
+ {std::pair(AINPUT_SOURCE_TOUCHPAD, AMOTION_EVENT_ACTION_DOWN),
+ std::pair(AINPUT_SOURCE_JOYSTICK, AMOTION_EVENT_ACTION_MOVE),
+ std::pair(AINPUT_SOURCE_MOUSE_RELATIVE, AMOTION_EVENT_ACTION_MOVE)};
// Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
ui::Transform transform(ui::Transform::ROT_90, 800, 400);
transform.set(transform.tx() + 20, transform.ty() + 40);
@@ -738,7 +738,7 @@
TEST_F(MotionEventTest, NonPointerSourcesAreNotTranslated) {
constexpr static std::array kNonPointerSources = {std::pair(AINPUT_SOURCE_TRACKBALL,
AMOTION_EVENT_ACTION_DOWN),
- std::pair(AINPUT_SOURCE_MOUSE_RELATIVE,
+ std::pair(AINPUT_SOURCE_TOUCH_NAVIGATION,
AMOTION_EVENT_ACTION_MOVE)};
// Create a rotate-90 transform with an offset (like a window which isn't fullscreen).
ui::Transform transform(ui::Transform::ROT_90, 800, 400);
diff --git a/libs/sensor/Android.bp b/libs/sensor/Android.bp
index 2b93c6e..b6b9cc4 100644
--- a/libs/sensor/Android.bp
+++ b/libs/sensor/Android.bp
@@ -21,9 +21,10 @@
default_applicable_licenses: ["frameworks_native_license"],
}
-cc_library_shared {
+cc_library {
name: "libsensor",
+ host_supported: true,
cflags: [
"-Wall",
"-Werror",
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
deleted file mode 100644
index 0bda798..0000000
--- a/libs/vr/libbufferhubqueue/Android.bp
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2016 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"],
-}
-
-sourceFiles = [
- "buffer_hub_queue_client.cpp",
- "buffer_hub_queue_parcelable.cpp",
-]
-
-includeFiles = [
- "include",
-]
-
-staticLibraries = [
- "libbufferhub",
-]
-
-sharedLibraries = [
- "libbinder",
- "libcutils",
- "liblog",
- "libui",
- "libutils",
- "libpdx_default_transport",
-]
-
-headerLibraries = [
- "libdvr_headers",
- "libnativebase_headers",
-]
-
-cc_library_shared {
- name: "libbufferhubqueue",
- cflags: [
- "-DLOG_TAG=\"libbufferhubqueue\"",
- "-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- "-Wall",
- "-Werror",
- "-Wno-format",
- "-Wno-unused-parameter",
- "-Wno-unused-variable",
- ],
- srcs: sourceFiles,
- export_include_dirs: includeFiles,
- export_static_lib_headers: staticLibraries,
- static_libs: staticLibraries,
- shared_libs: sharedLibraries,
- header_libs: headerLibraries,
-}
-
-subdirs = ["benchmarks", "tests"]
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
deleted file mode 100644
index 2d3fa4a..0000000
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ /dev/null
@@ -1,823 +0,0 @@
-#include "include/private/dvr/buffer_hub_queue_client.h"
-
-#include <inttypes.h>
-#include <log/log.h>
-#include <poll.h>
-#include <sys/epoll.h>
-
-#include <array>
-
-#include <pdx/default_transport/client_channel.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/file_handle.h>
-#include <pdx/trace.h>
-
-#define RETRY_EINTR(fnc_call) \
- ([&]() -> decltype(fnc_call) { \
- decltype(fnc_call) result; \
- do { \
- result = (fnc_call); \
- } while (result == -1 && errno == EINTR); \
- return result; \
- })()
-
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-std::pair<int32_t, int32_t> Unstuff(uint64_t value) {
- return {static_cast<int32_t>(value >> 32),
- static_cast<int32_t>(value & ((1ull << 32) - 1))};
-}
-
-uint64_t Stuff(int32_t a, int32_t b) {
- const uint32_t ua = static_cast<uint32_t>(a);
- const uint32_t ub = static_cast<uint32_t>(b);
- return (static_cast<uint64_t>(ua) << 32) | static_cast<uint64_t>(ub);
-}
-
-} // anonymous namespace
-
-BufferHubQueue::BufferHubQueue(LocalChannelHandle channel_handle)
- : Client{pdx::default_transport::ClientChannel::Create(
- std::move(channel_handle))} {
- Initialize();
-}
-
-BufferHubQueue::BufferHubQueue(const std::string& endpoint_path)
- : Client{
- pdx::default_transport::ClientChannelFactory::Create(endpoint_path)} {
- Initialize();
-}
-
-void BufferHubQueue::Initialize() {
- int ret = epoll_fd_.Create();
- if (ret < 0) {
- ALOGE("BufferHubQueue::BufferHubQueue: Failed to create epoll fd: %s",
- strerror(-ret));
- return;
- }
-
- epoll_event event = {
- .events = EPOLLIN | EPOLLET,
- .data = {.u64 = Stuff(-1, BufferHubQueue::kEpollQueueEventIndex)}};
- ret = epoll_fd_.Control(EPOLL_CTL_ADD, event_fd(), &event);
- if (ret < 0) {
- ALOGE("%s: Failed to add event fd to epoll set: %s", __FUNCTION__,
- strerror(-ret));
- }
-}
-
-Status<void> BufferHubQueue::ImportQueue() {
- auto status = InvokeRemoteMethod<BufferHubRPC::GetQueueInfo>();
- if (!status) {
- ALOGE("%s: Failed to import queue: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- return ErrorStatus(status.error());
- } else {
- SetupQueue(status.get());
- return {};
- }
-}
-
-void BufferHubQueue::SetupQueue(const QueueInfo& queue_info) {
- is_async_ = queue_info.producer_config.is_async;
- default_width_ = queue_info.producer_config.default_width;
- default_height_ = queue_info.producer_config.default_height;
- default_format_ = queue_info.producer_config.default_format;
- user_metadata_size_ = queue_info.producer_config.user_metadata_size;
- id_ = queue_info.id;
-}
-
-std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() {
- if (auto status = CreateConsumerQueueHandle(/*silent*/ false))
- return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take()));
- else
- return nullptr;
-}
-
-std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateSilentConsumerQueue() {
- if (auto status = CreateConsumerQueueHandle(/*silent*/ true))
- return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take()));
- else
- return nullptr;
-}
-
-Status<LocalChannelHandle> BufferHubQueue::CreateConsumerQueueHandle(
- bool silent) {
- auto status = InvokeRemoteMethod<BufferHubRPC::CreateConsumerQueue>(silent);
- if (!status) {
- ALOGE(
- "BufferHubQueue::CreateConsumerQueue: Failed to create consumer queue: "
- "%s",
- status.GetErrorMessage().c_str());
- return ErrorStatus(status.error());
- }
-
- return status;
-}
-
-pdx::Status<ConsumerQueueParcelable>
-BufferHubQueue::CreateConsumerQueueParcelable(bool silent) {
- auto status = CreateConsumerQueueHandle(silent);
- if (!status)
- return status.error_status();
-
- // A temporary consumer queue client to pull its channel parcelable.
- auto consumer_queue =
- std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take()));
- ConsumerQueueParcelable queue_parcelable(
- consumer_queue->GetChannel()->TakeChannelParcelable());
-
- if (!queue_parcelable.IsValid()) {
- ALOGE("%s: Failed to create consumer queue parcelable.", __FUNCTION__);
- return ErrorStatus(EINVAL);
- }
-
- return {std::move(queue_parcelable)};
-}
-
-bool BufferHubQueue::WaitForBuffers(int timeout) {
- ATRACE_NAME("BufferHubQueue::WaitForBuffers");
- std::array<epoll_event, kMaxEvents> events;
-
- // Loop at least once to check for hangups.
- do {
- ALOGD_IF(
- TRACE,
- "BufferHubQueue::WaitForBuffers: queue_id=%d count=%zu capacity=%zu",
- id(), count(), capacity());
-
- // If there is already a buffer then just check for hangup without waiting.
- const int ret = epoll_fd_.Wait(events.data(), events.size(),
- count() == 0 ? timeout : 0);
-
- if (ret == 0) {
- ALOGI_IF(TRACE,
- "BufferHubQueue::WaitForBuffers: No events before timeout: "
- "queue_id=%d",
- id());
- return count() != 0;
- }
-
- if (ret < 0 && ret != -EINTR) {
- ALOGE("%s: Failed to wait for buffers: %s", __FUNCTION__, strerror(-ret));
- return false;
- }
-
- const int num_events = ret;
-
- // A BufferQueue's epoll fd tracks N+1 events, where there are N events,
- // one for each buffer in the queue, and one extra event for the queue
- // client itself.
- for (int i = 0; i < num_events; i++) {
- int32_t event_fd;
- int32_t index;
- std::tie(event_fd, index) = Unstuff(events[i].data.u64);
-
- PDX_TRACE_FORMAT(
- "epoll_event|queue_id=%d;num_events=%d;event_index=%d;event_fd=%d;"
- "slot=%d|",
- id(), num_events, i, event_fd, index);
-
- ALOGD_IF(TRACE,
- "BufferHubQueue::WaitForBuffers: event %d: event_fd=%d index=%d",
- i, event_fd, index);
-
- if (is_buffer_event_index(index)) {
- HandleBufferEvent(static_cast<size_t>(index), event_fd,
- events[i].events);
- } else if (is_queue_event_index(index)) {
- HandleQueueEvent(events[i].events);
- } else {
- ALOGW(
- "BufferHubQueue::WaitForBuffers: Unknown event type event_fd=%d "
- "index=%d",
- event_fd, index);
- }
- }
- } while (count() == 0 && capacity() > 0 && !hung_up());
-
- return count() != 0;
-}
-
-Status<void> BufferHubQueue::HandleBufferEvent(size_t slot, int event_fd,
- int poll_events) {
- ATRACE_NAME("BufferHubQueue::HandleBufferEvent");
- if (!buffers_[slot]) {
- ALOGW("BufferHubQueue::HandleBufferEvent: Invalid buffer slot: %zu", slot);
- return ErrorStatus(ENOENT);
- }
-
- auto status = buffers_[slot]->GetEventMask(poll_events);
- if (!status) {
- ALOGW("BufferHubQueue::HandleBufferEvent: Failed to get event mask: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- const int events = status.get();
- PDX_TRACE_FORMAT(
- "buffer|queue_id=%d;buffer_id=%d;slot=%zu;event_fd=%d;poll_events=%x;"
- "events=%d|",
- id(), buffers_[slot]->id(), slot, event_fd, poll_events, events);
-
- if (events & EPOLLIN) {
- return Enqueue({buffers_[slot], slot, buffers_[slot]->GetQueueIndex()});
- } else if (events & EPOLLHUP) {
- ALOGW(
- "BufferHubQueue::HandleBufferEvent: Received EPOLLHUP event: slot=%zu "
- "event_fd=%d buffer_id=%d",
- slot, buffers_[slot]->event_fd(), buffers_[slot]->id());
- return RemoveBuffer(slot);
- } else {
- ALOGW(
- "BufferHubQueue::HandleBufferEvent: Unknown event, slot=%zu, epoll "
- "events=%d",
- slot, events);
- }
-
- return {};
-}
-
-Status<void> BufferHubQueue::HandleQueueEvent(int poll_event) {
- ATRACE_NAME("BufferHubQueue::HandleQueueEvent");
- auto status = GetEventMask(poll_event);
- if (!status) {
- ALOGW("BufferHubQueue::HandleQueueEvent: Failed to get event mask: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- const int events = status.get();
- if (events & EPOLLIN) {
- // Note that after buffer imports, if |count()| still returns 0, epoll
- // wait will be tried again to acquire the newly imported buffer.
- auto buffer_status = OnBufferAllocated();
- if (!buffer_status) {
- ALOGE("%s: Failed to import buffer: %s", __FUNCTION__,
- buffer_status.GetErrorMessage().c_str());
- }
- } else if (events & EPOLLHUP) {
- ALOGD_IF(TRACE, "%s: hang up event!", __FUNCTION__);
- hung_up_ = true;
- } else {
- ALOGW("%s: Unknown epoll events=%x", __FUNCTION__, events);
- }
-
- return {};
-}
-
-Status<void> BufferHubQueue::AddBuffer(
- const std::shared_ptr<BufferHubBase>& buffer, size_t slot) {
- ALOGD_IF(TRACE, "%s: buffer_id=%d slot=%zu", __FUNCTION__, buffer->id(),
- slot);
-
- if (is_full()) {
- ALOGE("%s: queue is at maximum capacity: %zu", __FUNCTION__, capacity_);
- return ErrorStatus(E2BIG);
- }
-
- if (buffers_[slot]) {
- // Replace the buffer if the slot is occupied. This could happen when the
- // producer side replaced the slot with a newly allocated buffer. Remove the
- // buffer before setting up with the new one.
- auto remove_status = RemoveBuffer(slot);
- if (!remove_status)
- return remove_status.error_status();
- }
-
- for (const auto& event_source : buffer->GetEventSources()) {
- epoll_event event = {.events = event_source.event_mask | EPOLLET,
- .data = {.u64 = Stuff(buffer->event_fd(), slot)}};
- const int ret =
- epoll_fd_.Control(EPOLL_CTL_ADD, event_source.event_fd, &event);
- if (ret < 0) {
- ALOGE("%s: Failed to add buffer to epoll set: %s", __FUNCTION__,
- strerror(-ret));
- return ErrorStatus(-ret);
- }
- }
-
- buffers_[slot] = buffer;
- capacity_++;
- return {};
-}
-
-Status<void> BufferHubQueue::RemoveBuffer(size_t slot) {
- ALOGD_IF(TRACE, "%s: slot=%zu", __FUNCTION__, slot);
-
- if (buffers_[slot]) {
- for (const auto& event_source : buffers_[slot]->GetEventSources()) {
- const int ret =
- epoll_fd_.Control(EPOLL_CTL_DEL, event_source.event_fd, nullptr);
- if (ret < 0) {
- ALOGE("%s: Failed to remove buffer from epoll set: %s", __FUNCTION__,
- strerror(-ret));
- return ErrorStatus(-ret);
- }
- }
-
- // Trigger OnBufferRemoved callback if registered.
- if (on_buffer_removed_)
- on_buffer_removed_(buffers_[slot]);
-
- buffers_[slot] = nullptr;
- capacity_--;
- }
-
- return {};
-}
-
-Status<void> BufferHubQueue::Enqueue(Entry entry) {
- if (!is_full()) {
- // Find and remove the enqueued buffer from unavailable_buffers_slot if
- // exist.
- auto enqueued_buffer_iter = std::find_if(
- unavailable_buffers_slot_.begin(), unavailable_buffers_slot_.end(),
- [&entry](size_t slot) -> bool { return slot == entry.slot; });
- if (enqueued_buffer_iter != unavailable_buffers_slot_.end()) {
- unavailable_buffers_slot_.erase(enqueued_buffer_iter);
- }
-
- available_buffers_.push(std::move(entry));
-
- // Trigger OnBufferAvailable callback if registered.
- if (on_buffer_available_)
- on_buffer_available_();
-
- return {};
- } else {
- ALOGE("%s: Buffer queue is full!", __FUNCTION__);
- return ErrorStatus(E2BIG);
- }
-}
-
-Status<std::shared_ptr<BufferHubBase>> BufferHubQueue::Dequeue(int timeout,
- size_t* slot) {
- ALOGD_IF(TRACE, "%s: count=%zu, timeout=%d", __FUNCTION__, count(), timeout);
-
- PDX_TRACE_FORMAT("%s|count=%zu|", __FUNCTION__, count());
-
- if (count() == 0) {
- if (!WaitForBuffers(timeout))
- return ErrorStatus(ETIMEDOUT);
- }
-
- auto& entry = available_buffers_.top();
- PDX_TRACE_FORMAT("buffer|buffer_id=%d;slot=%zu|", entry.buffer->id(),
- entry.slot);
-
- std::shared_ptr<BufferHubBase> buffer = std::move(entry.buffer);
- *slot = entry.slot;
-
- available_buffers_.pop();
- unavailable_buffers_slot_.push_back(*slot);
-
- return {std::move(buffer)};
-}
-
-void BufferHubQueue::SetBufferAvailableCallback(
- BufferAvailableCallback callback) {
- on_buffer_available_ = callback;
-}
-
-void BufferHubQueue::SetBufferRemovedCallback(BufferRemovedCallback callback) {
- on_buffer_removed_ = callback;
-}
-
-pdx::Status<void> BufferHubQueue::FreeAllBuffers() {
- // Clear all available buffers.
- while (!available_buffers_.empty())
- available_buffers_.pop();
-
- pdx::Status<void> last_error; // No error.
- // Clear all buffers this producer queue is tracking.
- for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
- if (buffers_[slot] != nullptr) {
- auto status = RemoveBuffer(slot);
- if (!status) {
- ALOGE(
- "ProducerQueue::FreeAllBuffers: Failed to remove buffer at "
- "slot=%zu.",
- slot);
- last_error = status.error_status();
- }
- }
- }
-
- return last_error;
-}
-
-ProducerQueue::ProducerQueue(LocalChannelHandle handle)
- : BASE(std::move(handle)) {
- auto status = ImportQueue();
- if (!status) {
- ALOGE("ProducerQueue::ProducerQueue: Failed to import queue: %s",
- status.GetErrorMessage().c_str());
- Close(-status.error());
- }
-}
-
-ProducerQueue::ProducerQueue(const ProducerQueueConfig& config,
- const UsagePolicy& usage)
- : BASE(BufferHubRPC::kClientPath) {
- auto status =
- InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(config, usage);
- if (!status) {
- ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s",
- status.GetErrorMessage().c_str());
- Close(-status.error());
- return;
- }
-
- SetupQueue(status.get());
-}
-
-Status<std::vector<size_t>> ProducerQueue::AllocateBuffers(
- uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t buffer_count) {
- if (buffer_count == 0) {
- return {std::vector<size_t>()};
- }
-
- if (capacity() + buffer_count > kMaxQueueCapacity) {
- ALOGE(
- "ProducerQueue::AllocateBuffers: queue is at capacity: %zu, cannot "
- "allocate %zu more buffer(s).",
- capacity(), buffer_count);
- return ErrorStatus(E2BIG);
- }
-
- Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
- InvokeRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
- width, height, layer_count, format, usage, buffer_count);
- if (!status) {
- ALOGE("ProducerQueue::AllocateBuffers: failed to allocate buffers: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- auto buffer_handle_slots = status.take();
- LOG_ALWAYS_FATAL_IF(buffer_handle_slots.size() != buffer_count,
- "BufferHubRPC::ProducerQueueAllocateBuffers should "
- "return %zu buffer handle(s), but returned %zu instead.",
- buffer_count, buffer_handle_slots.size());
-
- std::vector<size_t> buffer_slots;
- buffer_slots.reserve(buffer_count);
-
- // Bookkeeping for each buffer.
- for (auto& hs : buffer_handle_slots) {
- auto& buffer_handle = hs.first;
- size_t buffer_slot = hs.second;
-
- // Note that import might (though very unlikely) fail. If so, buffer_handle
- // will be closed and included in returned buffer_slots.
- if (AddBuffer(ProducerBuffer::Import(std::move(buffer_handle)),
- buffer_slot)) {
- ALOGD_IF(TRACE, "ProducerQueue::AllocateBuffers: new buffer at slot: %zu",
- buffer_slot);
- buffer_slots.push_back(buffer_slot);
- }
- }
-
- if (buffer_slots.size() != buffer_count) {
- // Error out if the count of imported buffer(s) is not correct.
- ALOGE(
- "ProducerQueue::AllocateBuffers: requested to import %zu "
- "buffers, but actually imported %zu buffers.",
- buffer_count, buffer_slots.size());
- return ErrorStatus(ENOMEM);
- }
-
- return {std::move(buffer_slots)};
-}
-
-Status<size_t> ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height,
- uint32_t layer_count,
- uint32_t format, uint64_t usage) {
- // We only allocate one buffer at a time.
- constexpr size_t buffer_count = 1;
- auto status =
- AllocateBuffers(width, height, layer_count, format, usage, buffer_count);
- if (!status) {
- ALOGE("ProducerQueue::AllocateBuffer: Failed to allocate buffer: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- return {status.get()[0]};
-}
-
-Status<void> ProducerQueue::AddBuffer(
- const std::shared_ptr<ProducerBuffer>& buffer, size_t slot) {
- ALOGD_IF(TRACE, "ProducerQueue::AddBuffer: queue_id=%d buffer_id=%d slot=%zu",
- id(), buffer->id(), slot);
- // For producer buffer, we need to enqueue the newly added buffer
- // immediately. Producer queue starts with all buffers in available state.
- auto status = BufferHubQueue::AddBuffer(buffer, slot);
- if (!status)
- return status;
-
- return BufferHubQueue::Enqueue({buffer, slot, 0ULL});
-}
-
-Status<size_t> ProducerQueue::InsertBuffer(
- const std::shared_ptr<ProducerBuffer>& buffer) {
- if (buffer == nullptr ||
- !BufferHubDefs::isClientGained(buffer->buffer_state(),
- buffer->client_state_mask())) {
- ALOGE(
- "ProducerQueue::InsertBuffer: Can only insert a buffer when it's in "
- "gained state.");
- return ErrorStatus(EINVAL);
- }
-
- auto status_or_slot =
- InvokeRemoteMethod<BufferHubRPC::ProducerQueueInsertBuffer>(
- buffer->cid());
- if (!status_or_slot) {
- ALOGE(
- "ProducerQueue::InsertBuffer: Failed to insert producer buffer: "
- "buffer_cid=%d, error: %s.",
- buffer->cid(), status_or_slot.GetErrorMessage().c_str());
- return status_or_slot.error_status();
- }
-
- size_t slot = status_or_slot.get();
-
- // Note that we are calling AddBuffer() from the base class to explicitly
- // avoid Enqueue() the ProducerBuffer.
- auto status = BufferHubQueue::AddBuffer(buffer, slot);
- if (!status) {
- ALOGE("ProducerQueue::InsertBuffer: Failed to add buffer: %s.",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
- return {slot};
-}
-
-Status<void> ProducerQueue::RemoveBuffer(size_t slot) {
- auto status =
- InvokeRemoteMethod<BufferHubRPC::ProducerQueueRemoveBuffer>(slot);
- if (!status) {
- ALOGE("%s: Failed to remove producer buffer: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- return BufferHubQueue::RemoveBuffer(slot);
-}
-
-Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue(
- int timeout, size_t* slot, LocalHandle* release_fence) {
- DvrNativeBufferMetadata canonical_meta;
- return Dequeue(timeout, slot, &canonical_meta, release_fence);
-}
-
-pdx::Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue(
- int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
- pdx::LocalHandle* release_fence, bool gain_posted_buffer) {
- ATRACE_NAME("ProducerQueue::Dequeue");
- if (slot == nullptr || out_meta == nullptr || release_fence == nullptr) {
- ALOGE("%s: Invalid parameter.", __FUNCTION__);
- return ErrorStatus(EINVAL);
- }
-
- std::shared_ptr<ProducerBuffer> buffer;
- Status<std::shared_ptr<BufferHubBase>> dequeue_status =
- BufferHubQueue::Dequeue(timeout, slot);
- if (dequeue_status.ok()) {
- buffer = std::static_pointer_cast<ProducerBuffer>(dequeue_status.take());
- } else {
- if (gain_posted_buffer) {
- Status<std::shared_ptr<ProducerBuffer>> dequeue_unacquired_status =
- ProducerQueue::DequeueUnacquiredBuffer(slot);
- if (!dequeue_unacquired_status.ok()) {
- ALOGE("%s: DequeueUnacquiredBuffer returned error: %d", __FUNCTION__,
- dequeue_unacquired_status.error());
- return dequeue_unacquired_status.error_status();
- }
- buffer = dequeue_unacquired_status.take();
- } else {
- return dequeue_status.error_status();
- }
- }
- const int ret =
- buffer->GainAsync(out_meta, release_fence, gain_posted_buffer);
- if (ret < 0 && ret != -EALREADY)
- return ErrorStatus(-ret);
-
- return {std::move(buffer)};
-}
-
-Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::DequeueUnacquiredBuffer(
- size_t* slot) {
- if (unavailable_buffers_slot_.size() < 1) {
- ALOGE(
- "%s: Failed to dequeue un-acquired buffer. All buffer(s) are in "
- "acquired state if exist.",
- __FUNCTION__);
- return ErrorStatus(ENOMEM);
- }
-
- // Find the first buffer that is not in acquired state from
- // unavailable_buffers_slot_.
- for (auto iter = unavailable_buffers_slot_.begin();
- iter != unavailable_buffers_slot_.end(); iter++) {
- std::shared_ptr<ProducerBuffer> buffer = ProducerQueue::GetBuffer(*iter);
- if (buffer == nullptr) {
- ALOGE("%s failed. Buffer slot %d is null.", __FUNCTION__,
- static_cast<int>(*slot));
- return ErrorStatus(EIO);
- }
- if (!BufferHubDefs::isAnyClientAcquired(buffer->buffer_state())) {
- *slot = *iter;
- unavailable_buffers_slot_.erase(iter);
- unavailable_buffers_slot_.push_back(*slot);
- ALOGD("%s: Producer queue dequeue unacquired buffer in slot %d",
- __FUNCTION__, static_cast<int>(*slot));
- return {std::move(buffer)};
- }
- }
- ALOGE(
- "%s: Failed to dequeue un-acquired buffer. No un-acquired buffer exist.",
- __FUNCTION__);
- return ErrorStatus(EBUSY);
-}
-
-pdx::Status<ProducerQueueParcelable> ProducerQueue::TakeAsParcelable() {
- if (capacity() != 0) {
- ALOGE(
- "%s: producer queue can only be taken out as a parcelable when empty. "
- "Current queue capacity: %zu",
- __FUNCTION__, capacity());
- return ErrorStatus(EINVAL);
- }
-
- std::unique_ptr<pdx::ClientChannel> channel = TakeChannel();
- ProducerQueueParcelable queue_parcelable(channel->TakeChannelParcelable());
-
- // Here the queue parcelable is returned and holds the underlying system
- // resources backing the queue; while the original client channel of this
- // producer queue is destroyed in place so that this client can no longer
- // provide producer operations.
- return {std::move(queue_parcelable)};
-}
-
-/*static */
-std::unique_ptr<ConsumerQueue> ConsumerQueue::Import(
- LocalChannelHandle handle) {
- return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(std::move(handle)));
-}
-
-ConsumerQueue::ConsumerQueue(LocalChannelHandle handle)
- : BufferHubQueue(std::move(handle)) {
- auto status = ImportQueue();
- if (!status) {
- ALOGE("%s: Failed to import queue: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- Close(-status.error());
- }
-
- auto import_status = ImportBuffers();
- if (import_status) {
- ALOGI("%s: Imported %zu buffers.", __FUNCTION__, import_status.get());
- } else {
- ALOGE("%s: Failed to import buffers: %s", __FUNCTION__,
- import_status.GetErrorMessage().c_str());
- }
-}
-
-Status<size_t> ConsumerQueue::ImportBuffers() {
- auto status = InvokeRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>();
- if (!status) {
- if (status.error() == EBADR) {
- ALOGI("%s: Queue is silent, no buffers imported.", __FUNCTION__);
- return {0};
- } else {
- ALOGE("%s: Failed to import consumer buffer: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
- }
-
- int ret;
- Status<void> last_error;
- size_t imported_buffers_count = 0;
-
- auto buffer_handle_slots = status.take();
- for (auto& buffer_handle_slot : buffer_handle_slots) {
- ALOGD_IF(TRACE, ": buffer_handle=%d", __FUNCTION__,
- buffer_handle_slot.first.value());
-
- std::unique_ptr<ConsumerBuffer> consumer_buffer =
- ConsumerBuffer::Import(std::move(buffer_handle_slot.first));
- if (!consumer_buffer) {
- ALOGE("%s: Failed to import buffer: slot=%zu", __FUNCTION__,
- buffer_handle_slot.second);
- last_error = ErrorStatus(EPIPE);
- continue;
- }
-
- auto add_status =
- AddBuffer(std::move(consumer_buffer), buffer_handle_slot.second);
- if (!add_status) {
- ALOGE("%s: Failed to add buffer: %s", __FUNCTION__,
- add_status.GetErrorMessage().c_str());
- last_error = add_status;
- } else {
- imported_buffers_count++;
- }
- }
-
- if (imported_buffers_count > 0)
- return {imported_buffers_count};
- else
- return last_error.error_status();
-}
-
-Status<void> ConsumerQueue::AddBuffer(
- const std::shared_ptr<ConsumerBuffer>& buffer, size_t slot) {
- ALOGD_IF(TRACE, "%s: queue_id=%d buffer_id=%d slot=%zu", __FUNCTION__, id(),
- buffer->id(), slot);
- return BufferHubQueue::AddBuffer(buffer, slot);
-}
-
-Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue(
- int timeout, size_t* slot, void* meta, size_t user_metadata_size,
- LocalHandle* acquire_fence) {
- if (user_metadata_size != user_metadata_size_) {
- ALOGE(
- "%s: Metadata size (%zu) for the dequeuing buffer does not match "
- "metadata size (%zu) for the queue.",
- __FUNCTION__, user_metadata_size, user_metadata_size_);
- return ErrorStatus(EINVAL);
- }
-
- DvrNativeBufferMetadata canonical_meta;
- auto status = Dequeue(timeout, slot, &canonical_meta, acquire_fence);
- if (!status)
- return status.error_status();
-
- if (meta && user_metadata_size) {
- void* metadata_src =
- reinterpret_cast<void*>(canonical_meta.user_metadata_ptr);
- if (metadata_src) {
- memcpy(meta, metadata_src, user_metadata_size);
- } else {
- ALOGW("%s: no user-defined metadata.", __FUNCTION__);
- }
- }
-
- return status;
-}
-
-Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue(
- int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
- pdx::LocalHandle* acquire_fence) {
- ATRACE_NAME("ConsumerQueue::Dequeue");
- if (slot == nullptr || out_meta == nullptr || acquire_fence == nullptr) {
- ALOGE("%s: Invalid parameter.", __FUNCTION__);
- return ErrorStatus(EINVAL);
- }
-
- auto status = BufferHubQueue::Dequeue(timeout, slot);
- if (!status)
- return status.error_status();
-
- auto buffer = std::static_pointer_cast<ConsumerBuffer>(status.take());
- const int ret = buffer->AcquireAsync(out_meta, acquire_fence);
- if (ret < 0)
- return ErrorStatus(-ret);
-
- return {std::move(buffer)};
-}
-
-Status<void> ConsumerQueue::OnBufferAllocated() {
- ALOGD_IF(TRACE, "%s: queue_id=%d", __FUNCTION__, id());
-
- auto status = ImportBuffers();
- if (!status) {
- ALOGE("%s: Failed to import buffers: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- return ErrorStatus(status.error());
- } else if (status.get() == 0) {
- ALOGW("%s: No new buffers allocated!", __FUNCTION__);
- return ErrorStatus(ENOBUFS);
- } else {
- ALOGD_IF(TRACE, "%s: Imported %zu consumer buffers.", __FUNCTION__,
- status.get());
- return {};
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp
deleted file mode 100644
index f705749..0000000
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "include/private/dvr/buffer_hub_queue_parcelable.h"
-
-#include <binder/Parcel.h>
-#include <pdx/default_transport/channel_parcelable.h>
-
-namespace android {
-namespace dvr {
-
-template <BufferHubQueueParcelableMagic Magic>
-bool BufferHubQueueParcelable<Magic>::IsValid() const {
- return !!channel_parcelable_ && channel_parcelable_->IsValid();
-}
-
-template <BufferHubQueueParcelableMagic Magic>
-pdx::LocalChannelHandle BufferHubQueueParcelable<Magic>::TakeChannelHandle() {
- if (!IsValid()) {
- ALOGE(
- "BufferHubQueueParcelable::TakeChannelHandle: Invalid channel parcel.");
- return {}; // Returns an empty channel handle.
- }
-
- // Take channel handle out of the parcelable and reset the parcelable.
- pdx::LocalChannelHandle handle = channel_parcelable_->TakeChannelHandle();
- // Now channel_parcelable_ should already be invalid, but reset it to release
- // the invalid parcelable object from unique_ptr.
- channel_parcelable_ = nullptr;
- return handle;
-}
-
-template <BufferHubQueueParcelableMagic Magic>
-status_t BufferHubQueueParcelable<Magic>::writeToParcel(Parcel* parcel) const {
- if (!IsValid()) {
- ALOGE("BufferHubQueueParcelable::writeToParcel: Invalid channel.");
- return -EINVAL;
- }
-
- status_t res = parcel->writeUint32(Magic);
- if (res != OK) {
- ALOGE("BufferHubQueueParcelable::writeToParcel: Cannot write magic.");
- return res;
- }
-
- return channel_parcelable_->writeToParcel(parcel);
-}
-
-template <BufferHubQueueParcelableMagic Magic>
-status_t BufferHubQueueParcelable<Magic>::readFromParcel(const Parcel* parcel) {
- if (IsValid()) {
- ALOGE(
- "BufferHubQueueParcelable::readFromParcel: This parcelable object has "
- "been initialized already.");
- return -EINVAL;
- }
-
- uint32_t out_magic = 0;
- status_t res = OK;
-
- res = parcel->readUint32(&out_magic);
- if (res != OK)
- return res;
-
- if (out_magic != Magic) {
- ALOGE(
- "BufferHubQueueParcelable::readFromParcel: Unexpected magic: 0x%x, "
- "epxected: 0x%x",
- out_magic, Magic);
- return -EINVAL;
- }
-
- // (Re)Alocate channel parcelable object.
- channel_parcelable_ =
- std::make_unique<pdx::default_transport::ChannelParcelable>();
- return channel_parcelable_->readFromParcel(parcel);
-}
-
-template class BufferHubQueueParcelable<
- BufferHubQueueParcelableMagic::Producer>;
-template class BufferHubQueueParcelable<
- BufferHubQueueParcelableMagic::Consumer>;
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
deleted file mode 100644
index 74b4b3d..0000000
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ /dev/null
@@ -1,476 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
-#define ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
-
-#include <ui/BufferQueueDefs.h>
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-#endif
-
-// The following headers are included without checking every warning.
-// TODO(b/72172820): Remove the workaround once we have enforced -Weverything
-// in these headers and their dependencies.
-#include <pdx/client.h>
-#include <pdx/status.h>
-#include <private/dvr/buffer_hub_queue_parcelable.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/epoll_file_descriptor.h>
-#include <private/dvr/producer_buffer.h>
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-#include <memory>
-#include <queue>
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-class ConsumerQueue;
-
-// |BufferHubQueue| manages a queue of |BufferHubBase|s. Buffers are
-// automatically re-requeued when released by the remote side.
-class BufferHubQueue : public pdx::Client {
- public:
- using BufferAvailableCallback = std::function<void()>;
- using BufferRemovedCallback =
- std::function<void(const std::shared_ptr<BufferHubBase>&)>;
-
- virtual ~BufferHubQueue() {}
-
- // Creates a new consumer queue that is attached to the producer. Returns
- // a new consumer queue client or nullptr on failure.
- std::unique_ptr<ConsumerQueue> CreateConsumerQueue();
-
- // Creates a new consumer queue that is attached to the producer. This queue
- // sets each of its imported consumer buffers to the ignored state to avoid
- // participation in lifecycle events.
- std::unique_ptr<ConsumerQueue> CreateSilentConsumerQueue();
-
- // Returns whether the buffer queue is in async mode.
- bool is_async() const { return is_async_; }
-
- // Returns the default buffer width of this buffer queue.
- uint32_t default_width() const { return default_width_; }
-
- // Returns the default buffer height of this buffer queue.
- uint32_t default_height() const { return default_height_; }
-
- // Returns the default buffer format of this buffer queue.
- uint32_t default_format() const { return default_format_; }
-
- // Creates a new consumer in handle form for immediate transport over RPC.
- pdx::Status<pdx::LocalChannelHandle> CreateConsumerQueueHandle(
- bool silent = false);
-
- // Creates a new consumer in parcelable form for immediate transport over
- // Binder.
- pdx::Status<ConsumerQueueParcelable> CreateConsumerQueueParcelable(
- bool silent = false);
-
- // Returns the number of buffers avaiable for dequeue.
- size_t count() const { return available_buffers_.size(); }
-
- // Returns the total number of buffers that the queue is tracking.
- size_t capacity() const { return capacity_; }
-
- // Returns the size of metadata structure associated with this queue.
- size_t metadata_size() const { return user_metadata_size_; }
-
- // Returns whether the buffer queue is full.
- bool is_full() const {
- return available_buffers_.size() >= kMaxQueueCapacity;
- }
-
- // Returns whether the buffer queue is connected to bufferhubd.
- bool is_connected() const { return !!GetChannel(); }
-
- int GetBufferId(size_t slot) const {
- return (slot < buffers_.size() && buffers_[slot]) ? buffers_[slot]->id()
- : -1;
- }
-
- std::shared_ptr<BufferHubBase> GetBuffer(size_t slot) const {
- return buffers_[slot];
- }
-
- pdx::Status<int> GetEventMask(int events) {
- if (auto* client_channel = GetChannel()) {
- return client_channel->GetEventMask(events);
- } else {
- return pdx::ErrorStatus(EINVAL);
- }
- }
-
- // Returns an fd that signals pending queue events using
- // EPOLLIN/POLLIN/readible. Either HandleQueueEvents or WaitForBuffers may be
- // called to handle pending queue events.
- int queue_fd() const { return epoll_fd_.Get(); }
-
- // Handles any pending events, returning available buffers to the queue and
- // reaping disconnected buffers. Returns true if successful, false if an error
- // occurred.
- bool HandleQueueEvents() { return WaitForBuffers(0); }
-
- // Set buffer event callbacks, which are std::function wrappers. The caller is
- // responsible for ensuring the validity of these callbacks' callable targets.
- void SetBufferAvailableCallback(BufferAvailableCallback callback);
- void SetBufferRemovedCallback(BufferRemovedCallback callback);
-
- // The queue tracks at most this many buffers.
- static constexpr size_t kMaxQueueCapacity =
- android::BufferQueueDefs::NUM_BUFFER_SLOTS;
-
- static constexpr int kNoTimeOut = -1;
-
- int id() const { return id_; }
- bool hung_up() const { return hung_up_; }
-
- protected:
- explicit BufferHubQueue(pdx::LocalChannelHandle channel);
- explicit BufferHubQueue(const std::string& endpoint_path);
-
- // Imports the queue parameters by querying BufferHub for the parameters for
- // this channel.
- pdx::Status<void> ImportQueue();
-
- // Sets up the queue with the given parameters.
- void SetupQueue(const QueueInfo& queue_info);
-
- // Register a buffer for management by the queue. Used by subclasses to add a
- // buffer to internal bookkeeping.
- pdx::Status<void> AddBuffer(const std::shared_ptr<BufferHubBase>& buffer,
- size_t slot);
-
- // Called by ProducerQueue::RemoveBuffer and ConsumerQueue::RemoveBuffer only
- // to deregister a buffer for epoll and internal bookkeeping.
- virtual pdx::Status<void> RemoveBuffer(size_t slot);
-
- // Free all buffers that belongs to this queue. Can only be called from
- // producer side.
- virtual pdx::Status<void> FreeAllBuffers();
-
- // Dequeue a buffer from the free queue, blocking until one is available. The
- // timeout argument specifies the number of milliseconds that |Dequeue()| will
- // block. Specifying a timeout of -1 causes Dequeue() to block indefinitely,
- // while specifying a timeout equal to zero cause Dequeue() to return
- // immediately, even if no buffers are available.
- pdx::Status<std::shared_ptr<BufferHubBase>> Dequeue(int timeout,
- size_t* slot);
-
- // Waits for buffers to become available and adds them to the available queue.
- bool WaitForBuffers(int timeout);
-
- pdx::Status<void> HandleBufferEvent(size_t slot, int event_fd,
- int poll_events);
- pdx::Status<void> HandleQueueEvent(int poll_events);
-
- // Entry in the priority queue of available buffers that stores related
- // per-buffer data.
- struct Entry {
- Entry() : slot(0) {}
- Entry(const std::shared_ptr<BufferHubBase>& in_buffer, size_t in_slot,
- uint64_t in_index)
- : buffer(in_buffer), slot(in_slot), index(in_index) {}
- Entry(const std::shared_ptr<BufferHubBase>& in_buffer,
- std::unique_ptr<uint8_t[]> in_metadata, pdx::LocalHandle in_fence,
- size_t in_slot)
- : buffer(in_buffer),
- metadata(std::move(in_metadata)),
- fence(std::move(in_fence)),
- slot(in_slot) {}
- Entry(Entry&&) = default;
- Entry& operator=(Entry&&) = default;
-
- std::shared_ptr<BufferHubBase> buffer;
- std::unique_ptr<uint8_t[]> metadata;
- pdx::LocalHandle fence;
- size_t slot;
- uint64_t index;
- };
-
- struct EntryComparator {
- bool operator()(const Entry& lhs, const Entry& rhs) {
- return lhs.index > rhs.index;
- }
- };
-
- // Enqueues a buffer to the available list (Gained for producer or Acquireed
- // for consumer).
- pdx::Status<void> Enqueue(Entry entry);
-
- // Called when a buffer is allocated remotely.
- virtual pdx::Status<void> OnBufferAllocated() { return {}; }
-
- // Size of the metadata that buffers in this queue cary.
- size_t user_metadata_size_{0};
-
- // Buffers and related data that are available for dequeue.
- std::priority_queue<Entry, std::vector<Entry>, EntryComparator>
- available_buffers_;
-
- // Slot of the buffers that are not available for normal dequeue. For example,
- // the slot of posted or acquired buffers in the perspective of a producer.
- std::vector<size_t> unavailable_buffers_slot_;
-
- private:
- void Initialize();
-
- // Special epoll data field indicating that the epoll event refers to the
- // queue.
- static constexpr int64_t kEpollQueueEventIndex = -1;
-
- static constexpr size_t kMaxEvents = 128;
-
- // The u64 data field of an epoll event is interpreted as int64_t:
- // When |index| >= 0 and |index| < kMaxQueueCapacity it refers to a specific
- // element of |buffers_| as a direct index;
- static bool is_buffer_event_index(int64_t index) {
- return index >= 0 &&
- index < static_cast<int64_t>(BufferHubQueue::kMaxQueueCapacity);
- }
-
- // When |index| == kEpollQueueEventIndex it refers to the queue itself.
- static bool is_queue_event_index(int64_t index) {
- return index == BufferHubQueue::kEpollQueueEventIndex;
- }
-
- // Whether the buffer queue is operating in Async mode.
- // From GVR's perspective of view, this means a buffer can be acquired
- // asynchronously by the compositor.
- // From Android Surface's perspective of view, this is equivalent to
- // IGraphicBufferProducer's async mode. When in async mode, a producer
- // will never block even if consumer is running slow.
- bool is_async_{false};
-
- // Default buffer width that is set during ProducerQueue's creation.
- uint32_t default_width_{1};
-
- // Default buffer height that is set during ProducerQueue's creation.
- uint32_t default_height_{1};
-
- // Default buffer format that is set during ProducerQueue's creation.
- uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888
-
- // Tracks the buffers belonging to this queue. Buffers are stored according to
- // "slot" in this vector. Each slot is a logical id of the buffer within this
- // queue regardless of its queue position or presence in the ring buffer.
- std::array<std::shared_ptr<BufferHubBase>, kMaxQueueCapacity> buffers_;
-
- // Keeps track with how many buffers have been added into the queue.
- size_t capacity_{0};
-
- // Epoll fd used to manage buffer events.
- EpollFileDescriptor epoll_fd_;
-
- // Flag indicating that the other side hung up. For ProducerQueues this
- // triggers when BufferHub dies or explicitly closes the queue channel. For
- // ConsumerQueues this can either mean the same or that the ProducerQueue on
- // the other end hung up.
- bool hung_up_{false};
-
- // Global id for the queue that is consistent across processes.
- int id_{-1};
-
- // Buffer event callbacks
- BufferAvailableCallback on_buffer_available_;
- BufferRemovedCallback on_buffer_removed_;
-
- BufferHubQueue(const BufferHubQueue&) = delete;
- void operator=(BufferHubQueue&) = delete;
-};
-
-class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> {
- public:
- // Usage bits in |usage_set_mask| will be automatically masked on. Usage bits
- // in |usage_clear_mask| will be automatically masked off. Note that
- // |usage_set_mask| and |usage_clear_mask| may conflict with each other, but
- // |usage_set_mask| takes precedence over |usage_clear_mask|. All buffer
- // allocation through this producer queue shall not have any of the usage bits
- // in |usage_deny_set_mask| set. Allocation calls violating this will be
- // rejected. All buffer allocation through this producer queue must have all
- // the usage bits in |usage_deny_clear_mask| set. Allocation calls violating
- // this will be rejected. Note that |usage_deny_set_mask| and
- // |usage_deny_clear_mask| shall not conflict with each other. Such
- // configuration will be treated as invalid input on creation.
- static std::unique_ptr<ProducerQueue> Create(
- const ProducerQueueConfig& config, const UsagePolicy& usage) {
- return BASE::Create(config, usage);
- }
-
- // Import a ProducerQueue from a channel handle.
- static std::unique_ptr<ProducerQueue> Import(pdx::LocalChannelHandle handle) {
- return BASE::Create(std::move(handle));
- }
-
- // Get a producer buffer. Note that the method doesn't check whether the
- // buffer slot has a valid buffer that has been allocated already. When no
- // buffer has been imported before it returns nullptr; otherwise it returns
- // a shared pointer to a ProducerBuffer.
- std::shared_ptr<ProducerBuffer> GetBuffer(size_t slot) const {
- return std::static_pointer_cast<ProducerBuffer>(
- BufferHubQueue::GetBuffer(slot));
- }
-
- // Batch allocate buffers. Once allocated, producer buffers are automatically
- // enqueue'd into the ProducerQueue and available to use (i.e. in GAINED
- // state). Upon success, returns a list of slots for each buffer allocated.
- pdx::Status<std::vector<size_t>> AllocateBuffers(
- uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t buffer_count);
-
- // Allocate producer buffer to populate the queue. Once allocated, a producer
- // buffer is automatically enqueue'd into the ProducerQueue and available to
- // use (i.e. in GAINED state). Upon success, returns the slot number for the
- // buffer allocated.
- pdx::Status<size_t> AllocateBuffer(uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format,
- uint64_t usage);
-
- // Add a producer buffer to populate the queue. Once added, a producer buffer
- // is available to use (i.e. in GAINED state).
- pdx::Status<void> AddBuffer(const std::shared_ptr<ProducerBuffer>& buffer,
- size_t slot);
-
- // Inserts a ProducerBuffer into the queue. On success, the method returns the
- // |slot| number where the new buffer gets inserted. Note that the buffer
- // being inserted should be in Gain'ed state prior to the call and it's
- // considered as already Dequeued when the function returns.
- pdx::Status<size_t> InsertBuffer(
- const std::shared_ptr<ProducerBuffer>& buffer);
-
- // Remove producer buffer from the queue.
- pdx::Status<void> RemoveBuffer(size_t slot) override;
-
- // Free all buffers on this producer queue.
- pdx::Status<void> FreeAllBuffers() override {
- return BufferHubQueue::FreeAllBuffers();
- }
-
- // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
- // and caller should call Post() once it's done writing to release the buffer
- // to the consumer side.
- // @return a buffer in gained state, which was originally in released state.
- pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue(
- int timeout, size_t* slot, pdx::LocalHandle* release_fence);
-
- // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
- // and caller should call Post() once it's done writing to release the buffer
- // to the consumer side.
- //
- // @param timeout to dequeue a buffer.
- // @param slot is the slot of the output ProducerBuffer.
- // @param release_fence for gaining a buffer.
- // @param out_meta metadata of the output buffer.
- // @param gain_posted_buffer whether to gain posted buffer if no released
- // buffer is available to gain.
- // @return a buffer in gained state, which was originally in released state if
- // gain_posted_buffer is false, or in posted/released state if
- // gain_posted_buffer is true.
- // TODO(b/112007999): gain_posted_buffer true is only used to prevent
- // libdvrtracking from starving when there are non-responding clients. This
- // gain_posted_buffer param can be removed once libdvrtracking start to use
- // the new AHardwareBuffer API.
- pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue(
- int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
- pdx::LocalHandle* release_fence, bool gain_posted_buffer = false);
-
- // Enqueues a producer buffer in the queue.
- pdx::Status<void> Enqueue(const std::shared_ptr<ProducerBuffer>& buffer,
- size_t slot, uint64_t index) {
- return BufferHubQueue::Enqueue({buffer, slot, index});
- }
-
- // Takes out the current producer queue as a binder parcelable object. Note
- // that the queue must be empty to be exportable. After successful export, the
- // producer queue client should no longer be used.
- pdx::Status<ProducerQueueParcelable> TakeAsParcelable();
-
- private:
- friend BASE;
-
- // Constructors are automatically exposed through ProducerQueue::Create(...)
- // static template methods inherited from ClientBase, which take the same
- // arguments as the constructors.
- explicit ProducerQueue(pdx::LocalChannelHandle handle);
- ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage);
-
- // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
- // and caller should call Post() once it's done writing to release the buffer
- // to the consumer side.
- //
- // @param slot the slot of the returned buffer.
- // @return a buffer in gained state, which was originally in posted state or
- // released state.
- pdx::Status<std::shared_ptr<ProducerBuffer>> DequeueUnacquiredBuffer(
- size_t* slot);
-};
-
-class ConsumerQueue : public BufferHubQueue {
- public:
- // Get a consumer buffer. Note that the method doesn't check whether the
- // buffer slot has a valid buffer that has been imported already. When no
- // buffer has been imported before it returns nullptr; otherwise returns a
- // shared pointer to a ConsumerBuffer.
- std::shared_ptr<ConsumerBuffer> GetBuffer(size_t slot) const {
- return std::static_pointer_cast<ConsumerBuffer>(
- BufferHubQueue::GetBuffer(slot));
- }
-
- // Import a ConsumerQueue from a channel handle. |ignore_on_import| controls
- // whether or not buffers are set to be ignored when imported. This may be
- // used to avoid participation in the buffer lifecycle by a consumer queue
- // that is only used to spawn other consumer queues, such as in an
- // intermediate service.
- static std::unique_ptr<ConsumerQueue> Import(pdx::LocalChannelHandle handle);
-
- // Import newly created buffers from the service side.
- // Returns number of buffers successfully imported or an error.
- pdx::Status<size_t> ImportBuffers();
-
- // Dequeue a consumer buffer to read. The returned buffer in |Acquired|'ed
- // mode, and caller should call Releasse() once it's done writing to release
- // the buffer to the producer side. |meta| is passed along from BufferHub,
- // The user of ProducerBuffer is responsible with making sure that the
- // Dequeue() is done with the corect metadata type and size with those used
- // when the buffer is orignally created.
- template <typename Meta>
- pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
- int timeout, size_t* slot, Meta* meta, pdx::LocalHandle* acquire_fence) {
- return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence);
- }
- pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
- int timeout, size_t* slot, pdx::LocalHandle* acquire_fence) {
- return Dequeue(timeout, slot, nullptr, 0, acquire_fence);
- }
-
- pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
- int timeout, size_t* slot, void* meta, size_t user_metadata_size,
- pdx::LocalHandle* acquire_fence);
- pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
- int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
- pdx::LocalHandle* acquire_fence);
-
- private:
- friend BufferHubQueue;
-
- explicit ConsumerQueue(pdx::LocalChannelHandle handle);
-
- // Add a consumer buffer to populate the queue. Once added, a consumer buffer
- // is NOT available to use until the producer side |Post| it. |WaitForBuffers|
- // will catch the |Post| and |Acquire| the buffer to make it available for
- // consumer.
- pdx::Status<void> AddBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
- size_t slot);
-
- pdx::Status<void> OnBufferAllocated() override;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
deleted file mode 100644
index 36ab5f6..0000000
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_
-#define ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_
-
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-#endif
-
-// The following headers are included without checking every warning.
-// TODO(b/72172820): Remove the workaround once we have enforced -Weverything
-// in these headers and their dependencies.
-#include <pdx/channel_parcelable.h>
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-namespace android {
-namespace dvr {
-
-enum BufferHubQueueParcelableMagic : uint32_t {
- Producer = 0x62687170, // 'bhqp'
- Consumer = 0x62687163, // 'bhqc'
-};
-
-template <BufferHubQueueParcelableMagic Magic>
-class BufferHubQueueParcelable : public Parcelable {
- public:
- BufferHubQueueParcelable() = default;
-
- BufferHubQueueParcelable(BufferHubQueueParcelable&& other) noexcept = default;
- BufferHubQueueParcelable& operator=(BufferHubQueueParcelable&& other) noexcept {
- channel_parcelable_ = std::move(other.channel_parcelable_);
- return *this;
- }
-
- // Constructs an parcelable contains the channel parcelable.
- explicit BufferHubQueueParcelable(
- std::unique_ptr<pdx::ChannelParcelable> channel_parcelable)
- : channel_parcelable_(std::move(channel_parcelable)) {}
-
- BufferHubQueueParcelable(const BufferHubQueueParcelable&) = delete;
- void operator=(const BufferHubQueueParcelable&) = delete;
-
- bool IsValid() const;
-
- // Returns a channel handle constructed from this parcelable object and takes
- // the ownership of all resources from the parcelable object.
- pdx::LocalChannelHandle TakeChannelHandle();
-
- // Serializes the queue parcelable into the given parcel. Note that no system
- // resources are getting duplicated, nor did the parcel takes ownership of the
- // queue parcelable. Thus, the parcelable object must remain valid for the
- // lifetime of the parcel.
- status_t writeToParcel(Parcel* parcel) const override;
-
- // Deserialize the queue parcelable from the given parcel. Note that system
- // resources are duplicated from the parcel into the queue parcelable. Returns
- // error if the targeting parcelable object is already valid.
- status_t readFromParcel(const Parcel* parcel) override;
-
- private:
- std::unique_ptr<pdx::ChannelParcelable> channel_parcelable_;
-};
-
-using ProducerQueueParcelable =
- BufferHubQueueParcelable<BufferHubQueueParcelableMagic::Producer>;
-using ConsumerQueueParcelable =
- BufferHubQueueParcelable<BufferHubQueueParcelableMagic::Consumer>;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
deleted file mode 100644
index 2f14f7c..0000000
--- a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_
-#define ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_
-
-#include <android-base/unique_fd.h>
-#include <log/log.h>
-#include <sys/epoll.h>
-
-namespace android {
-namespace dvr {
-
-class EpollFileDescriptor {
- public:
- static const int CTL_ADD = EPOLL_CTL_ADD;
- static const int CTL_MOD = EPOLL_CTL_MOD;
- static const int CTL_DEL = EPOLL_CTL_DEL;
-
- EpollFileDescriptor() : fd_(-1) {}
-
- // Constructs an EpollFileDescriptor from an integer file descriptor and
- // takes ownership.
- explicit EpollFileDescriptor(int fd) : fd_(fd) {}
-
- bool IsValid() const { return fd_.get() >= 0; }
-
- int Create() {
- if (IsValid()) {
- ALOGW("epoll fd has already been created.");
- return -EALREADY;
- }
-
- fd_.reset(epoll_create1(EPOLL_CLOEXEC));
-
- if (fd_.get() < 0)
- return -errno;
- else
- return 0;
- }
-
- int Control(int op, int target_fd, epoll_event* ev) {
- if (epoll_ctl(fd_.get(), op, target_fd, ev) < 0)
- return -errno;
- else
- return 0;
- }
-
- int Wait(epoll_event* events, int maxevents, int timeout) {
- int ret = epoll_wait(fd_.get(), events, maxevents, timeout);
-
- if (ret < 0)
- return -errno;
- else
- return ret;
- }
-
- int Get() const { return fd_.get(); }
-
- private:
- base::unique_fd fd_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
deleted file mode 100644
index e373376..0000000
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ /dev/null
@@ -1,50 +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"],
-}
-
-header_libraries = [
- "libdvr_headers",
-]
-
-shared_libraries = [
- "libbase",
- "libbinder",
- "libbufferhubqueue",
- "libcutils",
- "libgui",
- "liblog",
- "libhardware",
- "libui",
- "libutils",
- "libnativewindow",
- "libpdx_default_transport",
-]
-
-static_libraries = [
- "libchrome",
- "libdvrcommon",
- "libperformance",
-]
-
-cc_test {
- srcs: ["buffer_hub_queue-test.cpp"],
- header_libs: header_libraries,
- static_libs: static_libraries,
- shared_libs: shared_libraries,
- cflags: [
- "-DLOG_TAG=\"buffer_hub_queue-test\"",
- "-DTRACE=0",
- "-O0",
- "-g",
- "-Wall",
- "-Werror",
- "-Wno-error=sign-compare", // to fix later
- ],
- name: "buffer_hub_queue-test",
-}
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
deleted file mode 100644
index 6ae603b..0000000
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ /dev/null
@@ -1,1083 +0,0 @@
-#include <base/logging.h>
-#include <binder/Parcel.h>
-#include <dvr/dvr_api.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-
-#include <gtest/gtest.h>
-#include <poll.h>
-#include <sys/eventfd.h>
-
-#include <vector>
-
-// Enable/disable debug logging.
-#define TRACE 0
-
-namespace android {
-namespace dvr {
-
-using pdx::LocalChannelHandle;
-using pdx::LocalHandle;
-
-namespace {
-
-constexpr uint32_t kBufferWidth = 100;
-constexpr uint32_t kBufferHeight = 1;
-constexpr uint32_t kBufferLayerCount = 1;
-constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
-constexpr int kTimeoutMs = 100;
-constexpr int kNoTimeout = 0;
-
-class BufferHubQueueTest : public ::testing::Test {
- public:
- bool CreateProducerQueue(const ProducerQueueConfig& config,
- const UsagePolicy& usage) {
- producer_queue_ = ProducerQueue::Create(config, usage);
- return producer_queue_ != nullptr;
- }
-
- bool CreateConsumerQueue() {
- if (producer_queue_) {
- consumer_queue_ = producer_queue_->CreateConsumerQueue();
- return consumer_queue_ != nullptr;
- } else {
- return false;
- }
- }
-
- bool CreateQueues(const ProducerQueueConfig& config,
- const UsagePolicy& usage) {
- return CreateProducerQueue(config, usage) && CreateConsumerQueue();
- }
-
- void AllocateBuffer(size_t* slot_out = nullptr) {
- // Create producer buffer.
- auto status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
- kBufferLayerCount,
- kBufferFormat, kBufferUsage);
-
- ASSERT_TRUE(status.ok());
- size_t slot = status.take();
- if (slot_out)
- *slot_out = slot;
- }
-
- bool WaitAndHandleOnce(BufferHubQueue* queue, int timeout_ms) {
- pollfd pfd{queue->queue_fd(), POLLIN, 0};
- int ret;
- do {
- ret = poll(&pfd, 1, timeout_ms);
- } while (ret == -1 && errno == EINTR);
-
- if (ret < 0) {
- ALOGW("Failed to poll queue %d's event fd, error: %s.", queue->id(),
- strerror(errno));
- return false;
- } else if (ret == 0) {
- return false;
- }
- return queue->HandleQueueEvents();
- }
-
- protected:
- ProducerQueueConfigBuilder config_builder_;
- std::unique_ptr<ProducerQueue> producer_queue_;
- std::unique_ptr<ConsumerQueue> consumer_queue_;
-};
-
-TEST_F(BufferHubQueueTest, TestDequeue) {
- const int64_t nb_dequeue_times = 16;
-
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- // Allocate only one buffer.
- AllocateBuffer();
-
- // But dequeue multiple times.
- for (int64_t i = 0; i < nb_dequeue_times; i++) {
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
-
- // Producer gains a buffer.
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // Producer posts the buffer.
- mi.index = i;
- EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0);
-
- // Consumer acquires a buffer.
- auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage();
- auto c1 = c1_status.take();
- ASSERT_NE(c1, nullptr);
- EXPECT_EQ(mi.index, i);
- EXPECT_EQ(mo.index, i);
-
- // Consumer releases the buffer.
- EXPECT_EQ(c1->ReleaseAsync(&mi, LocalHandle()), 0);
- }
-}
-
-TEST_F(BufferHubQueueTest,
- TestDequeuePostedBufferIfNoAvailableReleasedBuffer_withConsumerBuffer) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- // Allocate 3 buffers to use.
- const size_t test_queue_capacity = 3;
- for (int64_t i = 0; i < test_queue_capacity; i++) {
- AllocateBuffer();
- }
- EXPECT_EQ(producer_queue_->capacity(), test_queue_capacity);
-
- size_t producer_slot, consumer_slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
-
- // Producer posts 2 buffers and remember their posted sequence.
- std::deque<size_t> posted_slots;
- for (int64_t i = 0; i < 2; i++) {
- auto p1_status =
- producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // Producer should not be gaining posted buffer when there are still
- // available buffers to gain.
- auto found_iter =
- std::find(posted_slots.begin(), posted_slots.end(), producer_slot);
- EXPECT_EQ(found_iter, posted_slots.end());
- posted_slots.push_back(producer_slot);
-
- // Producer posts the buffer.
- mi.index = i;
- EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle()));
- }
-
- // Consumer acquires one buffer.
- auto c1_status =
- consumer_queue_->Dequeue(kTimeoutMs, &consumer_slot, &mo, &fence);
- EXPECT_TRUE(c1_status.ok());
- auto c1 = c1_status.take();
- ASSERT_NE(c1, nullptr);
- // Consumer should get the oldest posted buffer. No checks here.
- // posted_slots[0] should be in acquired state now.
- EXPECT_EQ(mo.index, 0);
- // Consumer releases the buffer.
- EXPECT_EQ(c1->ReleaseAsync(&mi, LocalHandle()), 0);
- // posted_slots[0] should be in released state now.
-
- // Producer gain and post 2 buffers.
- for (int64_t i = 0; i < 2; i++) {
- auto p1_status =
- producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // The gained buffer should be the one in released state or the one haven't
- // been use.
- EXPECT_NE(posted_slots[1], producer_slot);
-
- mi.index = i + 2;
- EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle()));
- }
-
- // Producer gains a buffer.
- auto p1_status =
- producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // The gained buffer should be the oldest posted buffer.
- EXPECT_EQ(posted_slots[1], producer_slot);
-
- // Producer posts the buffer.
- mi.index = 4;
- EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle()));
-}
-
-TEST_F(BufferHubQueueTest,
- TestDequeuePostedBufferIfNoAvailableReleasedBuffer_noConsumerBuffer) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- // Allocate 4 buffers to use.
- const size_t test_queue_capacity = 4;
- for (int64_t i = 0; i < test_queue_capacity; i++) {
- AllocateBuffer();
- }
- EXPECT_EQ(producer_queue_->capacity(), test_queue_capacity);
-
- // Post all allowed buffers and remember their posted sequence.
- std::deque<size_t> posted_slots;
- for (int64_t i = 0; i < test_queue_capacity; i++) {
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
-
- // Producer gains a buffer.
- auto p1_status =
- producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence, true);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // Producer should not be gaining posted buffer when there are still
- // available buffers to gain.
- auto found_iter = std::find(posted_slots.begin(), posted_slots.end(), slot);
- EXPECT_EQ(found_iter, posted_slots.end());
- posted_slots.push_back(slot);
-
- // Producer posts the buffer.
- mi.index = i;
- EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0);
- }
-
- // Gain posted buffers in sequence.
- const int64_t nb_dequeue_all_times = 2;
- for (int j = 0; j < nb_dequeue_all_times; ++j) {
- for (int i = 0; i < test_queue_capacity; ++i) {
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
-
- // Producer gains a buffer.
- auto p1_status =
- producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence, true);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // The gained buffer should be the oldest posted buffer.
- EXPECT_EQ(posted_slots[i], slot);
-
- // Producer posts the buffer.
- mi.index = i + test_queue_capacity * (j + 1);
- EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0);
- }
- }
-}
-
-TEST_F(BufferHubQueueTest, TestProducerConsumer) {
- const size_t kBufferCount = 16;
- size_t slot;
- DvrNativeBufferMetadata mi, mo;
- LocalHandle fence;
-
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- for (size_t i = 0; i < kBufferCount; i++) {
- AllocateBuffer();
-
- // Producer queue has all the available buffers on initialize.
- ASSERT_EQ(producer_queue_->count(), i + 1);
- ASSERT_EQ(producer_queue_->capacity(), i + 1);
-
- // Consumer queue has no avaiable buffer on initialize.
- ASSERT_EQ(consumer_queue_->count(), 0U);
- // Consumer queue does not import buffers until a dequeue is issued.
- ASSERT_EQ(consumer_queue_->capacity(), i);
- // Dequeue returns timeout since no buffer is ready to consumer, but
- // this implicitly triggers buffer import and bump up |capacity|.
- auto status = consumer_queue_->Dequeue(kNoTimeout, &slot, &mo, &fence);
- ASSERT_FALSE(status.ok());
- ASSERT_EQ(ETIMEDOUT, status.error());
- ASSERT_EQ(consumer_queue_->capacity(), i + 1);
- }
-
- // Use eventfd as a stand-in for a fence.
- LocalHandle post_fence(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-
- for (size_t i = 0; i < kBufferCount; i++) {
- // First time there is no buffer available to dequeue.
- auto consumer_status =
- consumer_queue_->Dequeue(kNoTimeout, &slot, &mo, &fence);
- ASSERT_FALSE(consumer_status.ok());
- ASSERT_EQ(consumer_status.error(), ETIMEDOUT);
-
- // Make sure Producer buffer is POSTED so that it's ready to Accquire
- // in the consumer's Dequeue() function.
- auto producer_status =
- producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- auto producer = producer_status.take();
- ASSERT_NE(nullptr, producer);
-
- mi.index = static_cast<int64_t>(i);
- ASSERT_EQ(producer->PostAsync(&mi, post_fence), 0);
-
- // Second time the just the POSTED buffer should be dequeued.
- consumer_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(consumer_status.ok());
- EXPECT_TRUE(fence.IsValid());
-
- auto consumer = consumer_status.take();
- ASSERT_NE(nullptr, consumer);
- ASSERT_EQ(mi.index, mo.index);
- }
-}
-
-TEST_F(BufferHubQueueTest, TestInsertBuffer) {
- ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
-
- consumer_queue_ = producer_queue_->CreateConsumerQueue();
- ASSERT_TRUE(consumer_queue_ != nullptr);
- EXPECT_EQ(producer_queue_->capacity(), 0);
- EXPECT_EQ(consumer_queue_->capacity(), 0);
-
- std::shared_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage, 0);
- ASSERT_TRUE(p1 != nullptr);
- ASSERT_EQ(p1->GainAsync(), 0);
-
- // Inserting a posted buffer will fail.
- DvrNativeBufferMetadata meta;
- EXPECT_EQ(p1->PostAsync(&meta, LocalHandle()), 0);
- auto status_or_slot = producer_queue_->InsertBuffer(p1);
- EXPECT_FALSE(status_or_slot.ok());
- EXPECT_EQ(status_or_slot.error(), EINVAL);
-
- // Inserting a gained buffer will succeed.
- std::shared_ptr<ProducerBuffer> p2 = ProducerBuffer::Create(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage);
- ASSERT_EQ(p2->GainAsync(), 0);
- ASSERT_TRUE(p2 != nullptr);
- status_or_slot = producer_queue_->InsertBuffer(p2);
- EXPECT_TRUE(status_or_slot.ok()) << status_or_slot.GetErrorMessage();
- // This is the first buffer inserted, should take slot 0.
- size_t slot = status_or_slot.get();
- EXPECT_EQ(slot, 0);
-
- // Wait and expect the consumer to kick up the newly inserted buffer.
- WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs);
- EXPECT_EQ(consumer_queue_->capacity(), 1ULL);
-}
-
-TEST_F(BufferHubQueueTest, TestRemoveBuffer) {
- ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
- DvrNativeBufferMetadata mo;
-
- // Allocate buffers.
- const size_t kBufferCount = 4u;
- for (size_t i = 0; i < kBufferCount; i++) {
- AllocateBuffer();
- }
- ASSERT_EQ(kBufferCount, producer_queue_->count());
- ASSERT_EQ(kBufferCount, producer_queue_->capacity());
-
- consumer_queue_ = producer_queue_->CreateConsumerQueue();
- ASSERT_NE(nullptr, consumer_queue_);
-
- // Check that buffers are correctly imported on construction.
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
- EXPECT_EQ(0u, consumer_queue_->count());
-
- // Dequeue all the buffers and keep track of them in an array. This prevents
- // the producer queue ring buffer ref counts from interfering with the tests.
- struct Entry {
- std::shared_ptr<ProducerBuffer> buffer;
- LocalHandle fence;
- size_t slot;
- };
- std::array<Entry, kBufferCount> buffers;
-
- for (size_t i = 0; i < kBufferCount; i++) {
- Entry* entry = &buffers[i];
- auto producer_status =
- producer_queue_->Dequeue(kTimeoutMs, &entry->slot, &mo, &entry->fence);
- ASSERT_TRUE(producer_status.ok());
- entry->buffer = producer_status.take();
- ASSERT_NE(nullptr, entry->buffer);
- }
-
- // Remove a buffer and make sure both queues reflect the change.
- ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[0].slot));
- EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity());
-
- // As long as the removed buffer is still alive the consumer queue won't know
- // its gone.
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
- EXPECT_FALSE(consumer_queue_->HandleQueueEvents());
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
-
- // Release the removed buffer.
- buffers[0].buffer = nullptr;
-
- // Now the consumer queue should know it's gone.
- EXPECT_FALSE(WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs));
- ASSERT_EQ(kBufferCount - 1, consumer_queue_->capacity());
-
- // Allocate a new buffer. This should take the first empty slot.
- size_t slot;
- AllocateBuffer(&slot);
- ALOGE_IF(TRACE, "ALLOCATE %zu", slot);
- EXPECT_EQ(buffers[0].slot, slot);
- EXPECT_EQ(kBufferCount, producer_queue_->capacity());
-
- // The consumer queue should pick up the new buffer.
- EXPECT_EQ(kBufferCount - 1, consumer_queue_->capacity());
- EXPECT_FALSE(consumer_queue_->HandleQueueEvents());
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
-
- // Remove and allocate a buffer.
- ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[1].slot));
- EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity());
- buffers[1].buffer = nullptr;
-
- AllocateBuffer(&slot);
- ALOGE_IF(TRACE, "ALLOCATE %zu", slot);
- EXPECT_EQ(buffers[1].slot, slot);
- EXPECT_EQ(kBufferCount, producer_queue_->capacity());
-
- // The consumer queue should pick up the new buffer but the count shouldn't
- // change.
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
- EXPECT_FALSE(consumer_queue_->HandleQueueEvents());
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
-
- // Remove and allocate a buffer, but don't free the buffer right away.
- ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[2].slot));
- EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity());
-
- AllocateBuffer(&slot);
- ALOGE_IF(TRACE, "ALLOCATE %zu", slot);
- EXPECT_EQ(buffers[2].slot, slot);
- EXPECT_EQ(kBufferCount, producer_queue_->capacity());
-
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
- EXPECT_FALSE(consumer_queue_->HandleQueueEvents());
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
-
- // Release the producer buffer to trigger a POLLHUP event for an already
- // removed buffer.
- buffers[2].buffer = nullptr;
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
- EXPECT_FALSE(consumer_queue_->HandleQueueEvents());
- EXPECT_EQ(kBufferCount, consumer_queue_->capacity());
-}
-
-TEST_F(BufferHubQueueTest, TestMultipleConsumers) {
- // ProducerConfigureBuilder doesn't set Metadata{size}, which means there
- // is no metadata associated with this BufferQueue's buffer.
- ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
-
- // Allocate buffers.
- const size_t kBufferCount = 4u;
- for (size_t i = 0; i < kBufferCount; i++) {
- AllocateBuffer();
- }
- ASSERT_EQ(kBufferCount, producer_queue_->count());
-
- // Build a silent consumer queue to test multi-consumer queue features.
- auto silent_queue = producer_queue_->CreateSilentConsumerQueue();
- ASSERT_NE(nullptr, silent_queue);
-
- // Check that silent queue doesn't import buffers on creation.
- EXPECT_EQ(silent_queue->capacity(), 0U);
-
- // Dequeue and post a buffer.
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
- auto producer_status =
- producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(producer_status.ok());
- auto producer_buffer = producer_status.take();
- ASSERT_NE(producer_buffer, nullptr);
- EXPECT_EQ(producer_buffer->PostAsync(&mi, {}), 0);
- // After post, check the number of remaining available buffers.
- EXPECT_EQ(producer_queue_->count(), kBufferCount - 1);
-
- // Currently we expect no buffer to be available prior to calling
- // WaitForBuffers/HandleQueueEvents.
- // TODO(eieio): Note this behavior may change in the future.
- EXPECT_EQ(silent_queue->count(), 0U);
- EXPECT_FALSE(silent_queue->HandleQueueEvents());
- EXPECT_EQ(silent_queue->count(), 0U);
-
- // Build a new consumer queue to test multi-consumer queue features.
- consumer_queue_ = silent_queue->CreateConsumerQueue();
- ASSERT_NE(consumer_queue_, nullptr);
-
- // Check that buffers are correctly imported on construction.
- EXPECT_EQ(consumer_queue_->capacity(), kBufferCount);
- // Buffers are only imported, but their availability is not checked until
- // first call to Dequeue().
- EXPECT_EQ(consumer_queue_->count(), 0U);
-
- // Reclaim released/ignored buffers.
- EXPECT_EQ(producer_queue_->count(), kBufferCount - 1);
-
- usleep(10000);
- WaitAndHandleOnce(producer_queue_.get(), kTimeoutMs);
- EXPECT_EQ(producer_queue_->count(), kBufferCount - 1);
-
- // Post another buffer.
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(producer_status.ok());
- producer_buffer = producer_status.take();
- ASSERT_NE(producer_buffer, nullptr);
- EXPECT_EQ(producer_buffer->PostAsync(&mi, {}), 0);
-
- // Verify that the consumer queue receives it.
- size_t consumer_queue_count = consumer_queue_->count();
- WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs);
- EXPECT_GT(consumer_queue_->count(), consumer_queue_count);
-
- // Save the current consumer queue buffer count to compare after the dequeue.
- consumer_queue_count = consumer_queue_->count();
-
- // Dequeue and acquire/release (discard) buffers on the consumer end.
- auto consumer_status =
- consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(consumer_status.ok());
- auto consumer_buffer = consumer_status.take();
- ASSERT_NE(consumer_buffer, nullptr);
- consumer_buffer->Discard();
-
- // Buffer should be returned to the producer queue without being handled by
- // the silent consumer queue.
- EXPECT_LT(consumer_queue_->count(), consumer_queue_count);
- EXPECT_EQ(producer_queue_->count(), kBufferCount - 2);
-
- WaitAndHandleOnce(producer_queue_.get(), kTimeoutMs);
- EXPECT_EQ(producer_queue_->count(), kBufferCount - 1);
-}
-
-struct TestUserMetadata {
- char a;
- int32_t b;
- int64_t c;
-};
-
-constexpr uint64_t kUserMetadataSize =
- static_cast<uint64_t>(sizeof(TestUserMetadata));
-
-TEST_F(BufferHubQueueTest, TestUserMetadata) {
- ASSERT_TRUE(CreateQueues(
- config_builder_.SetMetadata<TestUserMetadata>().Build(), UsagePolicy{}));
-
- AllocateBuffer();
-
- std::vector<TestUserMetadata> user_metadata_list = {
- {'0', 0, 0}, {'1', 10, 3333}, {'@', 123, 1000000000}};
-
- for (auto user_metadata : user_metadata_list) {
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
-
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // TODO(b/69469185): Test against metadata from consumer once we implement
- // release metadata properly.
- // EXPECT_EQ(mo.user_metadata_ptr, 0U);
- // EXPECT_EQ(mo.user_metadata_size, 0U);
-
- mi.user_metadata_size = kUserMetadataSize;
- mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata);
- EXPECT_EQ(p1->PostAsync(&mi, {}), 0);
- auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage();
- auto c1 = c1_status.take();
- ASSERT_NE(c1, nullptr);
-
- EXPECT_EQ(mo.user_metadata_size, kUserMetadataSize);
- auto out_user_metadata =
- reinterpret_cast<TestUserMetadata*>(mo.user_metadata_ptr);
- EXPECT_EQ(user_metadata.a, out_user_metadata->a);
- EXPECT_EQ(user_metadata.b, out_user_metadata->b);
- EXPECT_EQ(user_metadata.c, out_user_metadata->c);
-
- // When release, empty metadata is also legit.
- mi.user_metadata_size = 0U;
- mi.user_metadata_ptr = 0U;
- c1->ReleaseAsync(&mi, {});
- }
-}
-
-TEST_F(BufferHubQueueTest, TestUserMetadataMismatch) {
- ASSERT_TRUE(CreateQueues(
- config_builder_.SetMetadata<TestUserMetadata>().Build(), UsagePolicy{}));
-
- AllocateBuffer();
-
- TestUserMetadata user_metadata;
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- EXPECT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // Post with mismatched user metadata size will fail. But the producer buffer
- // itself should stay untouched.
- mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata);
- mi.user_metadata_size = kUserMetadataSize + 1;
- EXPECT_EQ(p1->PostAsync(&mi, {}), -E2BIG);
- // Post with the exact same user metdata size can success.
- mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata);
- mi.user_metadata_size = kUserMetadataSize;
- EXPECT_EQ(p1->PostAsync(&mi, {}), 0);
-}
-
-TEST_F(BufferHubQueueTest, TestEnqueue) {
- ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
- UsagePolicy{}));
- AllocateBuffer();
-
- size_t slot;
- LocalHandle fence;
- DvrNativeBufferMetadata mo;
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(nullptr, p1);
-
- producer_queue_->Enqueue(p1, slot, 0ULL);
- auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_FALSE(c1_status.ok());
-}
-
-TEST_F(BufferHubQueueTest, TestAllocateBuffer) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- size_t ps1;
- AllocateBuffer();
- LocalHandle fence;
- DvrNativeBufferMetadata mi, mo;
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &ps1, &mo, &fence);
- ASSERT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_NE(p1, nullptr);
-
- // producer queue is exhausted
- size_t ps2;
- auto p2_status = producer_queue_->Dequeue(kTimeoutMs, &ps2, &mo, &fence);
- ASSERT_FALSE(p2_status.ok());
- ASSERT_EQ(ETIMEDOUT, p2_status.error());
-
- // dynamically add buffer.
- AllocateBuffer();
- ASSERT_EQ(producer_queue_->count(), 1U);
- ASSERT_EQ(producer_queue_->capacity(), 2U);
-
- // now we can dequeue again
- p2_status = producer_queue_->Dequeue(kTimeoutMs, &ps2, &mo, &fence);
- ASSERT_TRUE(p2_status.ok());
- auto p2 = p2_status.take();
- ASSERT_NE(p2, nullptr);
- ASSERT_EQ(producer_queue_->count(), 0U);
- // p1 and p2 should have different slot number
- ASSERT_NE(ps1, ps2);
-
- // Consumer queue does not import buffers until |Dequeue| or |ImportBuffers|
- // are called. So far consumer_queue_ should be empty.
- ASSERT_EQ(consumer_queue_->count(), 0U);
-
- int64_t seq = 1;
- mi.index = seq;
- ASSERT_EQ(p1->PostAsync(&mi, {}), 0);
-
- size_t cs1, cs2;
- auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &cs1, &mo, &fence);
- ASSERT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage();
- auto c1 = c1_status.take();
- ASSERT_NE(c1, nullptr);
- ASSERT_EQ(consumer_queue_->count(), 0U);
- ASSERT_EQ(consumer_queue_->capacity(), 2U);
- ASSERT_EQ(cs1, ps1);
-
- ASSERT_EQ(p2->PostAsync(&mi, {}), 0);
- auto c2_status = consumer_queue_->Dequeue(kTimeoutMs, &cs2, &mo, &fence);
- ASSERT_TRUE(c2_status.ok());
- auto c2 = c2_status.take();
- ASSERT_NE(c2, nullptr);
- ASSERT_EQ(cs2, ps2);
-}
-
-TEST_F(BufferHubQueueTest, TestAllocateTwoBuffers) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
- ASSERT_EQ(producer_queue_->capacity(), 0);
- auto status = producer_queue_->AllocateBuffers(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage, /*buffer_count=*/2);
- ASSERT_TRUE(status.ok());
- std::vector<size_t> buffer_slots = status.take();
- ASSERT_EQ(buffer_slots.size(), 2);
- ASSERT_EQ(producer_queue_->capacity(), 2);
-}
-
-TEST_F(BufferHubQueueTest, TestAllocateZeroBuffers) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
- ASSERT_EQ(producer_queue_->capacity(), 0);
- auto status = producer_queue_->AllocateBuffers(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage, /*buffer_count=*/0);
- ASSERT_TRUE(status.ok());
- std::vector<size_t> buffer_slots = status.take();
- ASSERT_EQ(buffer_slots.size(), 0);
- ASSERT_EQ(producer_queue_->capacity(), 0);
-}
-
-TEST_F(BufferHubQueueTest, TestUsageSetMask) {
- const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(
- CreateQueues(config_builder_.Build(), UsagePolicy{set_mask, 0, 0, 0}));
-
- // When allocation, leave out |set_mask| from usage bits on purpose.
- auto status = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage & ~set_mask);
- ASSERT_TRUE(status.ok());
-
- LocalHandle fence;
- size_t slot;
- DvrNativeBufferMetadata mo;
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_EQ(p1->usage() & set_mask, set_mask);
-}
-
-TEST_F(BufferHubQueueTest, TestUsageClearMask) {
- const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(
- CreateQueues(config_builder_.Build(), UsagePolicy{0, clear_mask, 0, 0}));
-
- // When allocation, add |clear_mask| into usage bits on purpose.
- auto status = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage | clear_mask);
- ASSERT_TRUE(status.ok());
-
- LocalHandle fence;
- size_t slot;
- DvrNativeBufferMetadata mo;
- auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(p1_status.ok());
- auto p1 = p1_status.take();
- ASSERT_EQ(p1->usage() & clear_mask, 0U);
-}
-
-TEST_F(BufferHubQueueTest, TestUsageDenySetMask) {
- const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
- UsagePolicy{0, 0, deny_set_mask, 0}));
-
- // Now that |deny_set_mask| is illegal, allocation without those bits should
- // be able to succeed.
- auto status = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage & ~deny_set_mask);
- ASSERT_TRUE(status.ok());
-
- // While allocation with those bits should fail.
- status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
- kBufferLayerCount, kBufferFormat,
- kBufferUsage | deny_set_mask);
- ASSERT_FALSE(status.ok());
- ASSERT_EQ(EINVAL, status.error());
-}
-
-TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) {
- const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
- UsagePolicy{0, 0, 0, deny_clear_mask}));
-
- // Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are
- // mandatory), allocation with those bits should be able to succeed.
- auto status = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
- kBufferUsage | deny_clear_mask);
- ASSERT_TRUE(status.ok());
-
- // While allocation without those bits should fail.
- status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
- kBufferLayerCount, kBufferFormat,
- kBufferUsage & ~deny_clear_mask);
- ASSERT_FALSE(status.ok());
- ASSERT_EQ(EINVAL, status.error());
-}
-
-TEST_F(BufferHubQueueTest, TestQueueInfo) {
- static const bool kIsAsync = true;
- ASSERT_TRUE(CreateQueues(config_builder_.SetIsAsync(kIsAsync)
- .SetDefaultWidth(kBufferWidth)
- .SetDefaultHeight(kBufferHeight)
- .SetDefaultFormat(kBufferFormat)
- .Build(),
- UsagePolicy{}));
-
- EXPECT_EQ(producer_queue_->default_width(), kBufferWidth);
- EXPECT_EQ(producer_queue_->default_height(), kBufferHeight);
- EXPECT_EQ(producer_queue_->default_format(), kBufferFormat);
- EXPECT_EQ(producer_queue_->is_async(), kIsAsync);
-
- EXPECT_EQ(consumer_queue_->default_width(), kBufferWidth);
- EXPECT_EQ(consumer_queue_->default_height(), kBufferHeight);
- EXPECT_EQ(consumer_queue_->default_format(), kBufferFormat);
- EXPECT_EQ(consumer_queue_->is_async(), kIsAsync);
-}
-
-TEST_F(BufferHubQueueTest, TestFreeAllBuffers) {
- constexpr size_t kBufferCount = 2;
-
-#define CHECK_NO_BUFFER_THEN_ALLOCATE(num_buffers) \
- EXPECT_EQ(consumer_queue_->count(), 0U); \
- EXPECT_EQ(consumer_queue_->capacity(), 0U); \
- EXPECT_EQ(producer_queue_->count(), 0U); \
- EXPECT_EQ(producer_queue_->capacity(), 0U); \
- for (size_t i = 0; i < num_buffers; i++) { \
- AllocateBuffer(); \
- } \
- EXPECT_EQ(producer_queue_->count(), num_buffers); \
- EXPECT_EQ(producer_queue_->capacity(), num_buffers);
-
- size_t slot;
- LocalHandle fence;
- pdx::Status<void> status;
- pdx::Status<std::shared_ptr<ConsumerBuffer>> consumer_status;
- pdx::Status<std::shared_ptr<ProducerBuffer>> producer_status;
- std::shared_ptr<ConsumerBuffer> consumer_buffer;
- std::shared_ptr<ProducerBuffer> producer_buffer;
- DvrNativeBufferMetadata mi, mo;
-
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- // Free all buffers when buffers are avaible for dequeue.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // Free all buffers when one buffer is dequeued.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // Free all buffers when all buffers are dequeued.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- for (size_t i = 0; i < kBufferCount; i++) {
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- }
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // Free all buffers when one buffer is posted.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- producer_buffer = producer_status.take();
- ASSERT_NE(nullptr, producer_buffer);
- ASSERT_EQ(0, producer_buffer->PostAsync(&mi, fence));
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // Free all buffers when all buffers are posted.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- for (size_t i = 0; i < kBufferCount; i++) {
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- producer_buffer = producer_status.take();
- ASSERT_NE(producer_buffer, nullptr);
- ASSERT_EQ(producer_buffer->PostAsync(&mi, fence), 0);
- }
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // Free all buffers when all buffers are acquired.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
- for (size_t i = 0; i < kBufferCount; i++) {
- producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(producer_status.ok());
- producer_buffer = producer_status.take();
- ASSERT_NE(producer_buffer, nullptr);
- ASSERT_EQ(producer_buffer->PostAsync(&mi, fence), 0);
- consumer_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence);
- ASSERT_TRUE(consumer_status.ok()) << consumer_status.GetErrorMessage();
- }
-
- status = producer_queue_->FreeAllBuffers();
- EXPECT_TRUE(status.ok());
-
- // In addition to FreeAllBuffers() from the queue, it is also required to
- // delete all references to the ProducerBuffer (i.e. the PDX client).
- producer_buffer = nullptr;
-
- // Crank consumer queue events to pickup EPOLLHUP events on the queue.
- consumer_queue_->HandleQueueEvents();
-
- // One last check.
- CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount);
-
-#undef CHECK_NO_BUFFER_THEN_ALLOCATE
-}
-
-TEST_F(BufferHubQueueTest, TestProducerToParcelableNotEmpty) {
- ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(),
- UsagePolicy{}));
-
- // Allocate only one buffer.
- AllocateBuffer();
-
- // Export should fail as the queue is not empty.
- auto status = producer_queue_->TakeAsParcelable();
- EXPECT_FALSE(status.ok());
-}
-
-TEST_F(BufferHubQueueTest, TestProducerExportToParcelable) {
- ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
-
- auto s1 = producer_queue_->TakeAsParcelable();
- EXPECT_TRUE(s1.ok());
-
- ProducerQueueParcelable output_parcelable = s1.take();
- EXPECT_TRUE(output_parcelable.IsValid());
-
- Parcel parcel;
- status_t res;
- res = output_parcelable.writeToParcel(&parcel);
- EXPECT_EQ(res, OK);
-
- // After written into parcelable, the output_parcelable is still valid has
- // keeps the producer channel alive.
- EXPECT_TRUE(output_parcelable.IsValid());
-
- // Creating producer buffer should fail.
- auto s2 = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
- kBufferLayerCount, kBufferFormat,
- kBufferUsage);
- ASSERT_FALSE(s2.ok());
-
- // Reset the data position so that we can read back from the same parcel
- // without doing actually Binder IPC.
- parcel.setDataPosition(0);
- producer_queue_ = nullptr;
-
- // Recreate the producer queue from the parcel.
- ProducerQueueParcelable input_parcelable;
- EXPECT_FALSE(input_parcelable.IsValid());
-
- res = input_parcelable.readFromParcel(&parcel);
- EXPECT_EQ(res, OK);
- EXPECT_TRUE(input_parcelable.IsValid());
-
- EXPECT_EQ(producer_queue_, nullptr);
- producer_queue_ = ProducerQueue::Import(input_parcelable.TakeChannelHandle());
- EXPECT_FALSE(input_parcelable.IsValid());
- ASSERT_NE(producer_queue_, nullptr);
-
- // Newly created queue from the parcel can allocate buffer, post buffer to
- // consumer.
- EXPECT_NO_FATAL_FAILURE(AllocateBuffer());
- EXPECT_EQ(producer_queue_->count(), 1U);
- EXPECT_EQ(producer_queue_->capacity(), 1U);
-
- size_t slot;
- DvrNativeBufferMetadata producer_meta;
- DvrNativeBufferMetadata consumer_meta;
- LocalHandle fence;
- auto s3 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence);
- EXPECT_TRUE(s3.ok());
-
- std::shared_ptr<ProducerBuffer> p1 = s3.take();
- ASSERT_NE(p1, nullptr);
-
- producer_meta.timestamp = 42;
- EXPECT_EQ(p1->PostAsync(&producer_meta, LocalHandle()), 0);
-
- // Make sure the buffer can be dequeued from consumer side.
- auto s4 = consumer_queue_->Dequeue(kTimeoutMs, &slot, &consumer_meta, &fence);
- EXPECT_TRUE(s4.ok()) << s4.GetErrorMessage();
- EXPECT_EQ(consumer_queue_->capacity(), 1U);
-
- auto consumer = s4.take();
- ASSERT_NE(consumer, nullptr);
- EXPECT_EQ(producer_meta.timestamp, consumer_meta.timestamp);
-}
-
-TEST_F(BufferHubQueueTest, TestCreateConsumerParcelable) {
- ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
-
- auto s1 = producer_queue_->CreateConsumerQueueParcelable();
- EXPECT_TRUE(s1.ok());
- ConsumerQueueParcelable output_parcelable = s1.take();
- EXPECT_TRUE(output_parcelable.IsValid());
-
- // Write to a Parcel new object.
- Parcel parcel;
- status_t res;
- res = output_parcelable.writeToParcel(&parcel);
-
- // Reset the data position so that we can read back from the same parcel
- // without doing actually Binder IPC.
- parcel.setDataPosition(0);
-
- // No consumer queue created yet.
- EXPECT_EQ(consumer_queue_, nullptr);
-
- // If the parcel contains a consumer queue, read into a
- // ProducerQueueParcelable should fail.
- ProducerQueueParcelable wrongly_typed_parcelable;
- EXPECT_FALSE(wrongly_typed_parcelable.IsValid());
- res = wrongly_typed_parcelable.readFromParcel(&parcel);
- EXPECT_EQ(res, -EINVAL);
- parcel.setDataPosition(0);
-
- // Create the consumer queue from the parcel.
- ConsumerQueueParcelable input_parcelable;
- EXPECT_FALSE(input_parcelable.IsValid());
-
- res = input_parcelable.readFromParcel(&parcel);
- EXPECT_EQ(res, OK);
- EXPECT_TRUE(input_parcelable.IsValid());
-
- consumer_queue_ = ConsumerQueue::Import(input_parcelable.TakeChannelHandle());
- EXPECT_FALSE(input_parcelable.IsValid());
- ASSERT_NE(consumer_queue_, nullptr);
-
- EXPECT_NO_FATAL_FAILURE(AllocateBuffer());
- EXPECT_EQ(producer_queue_->count(), 1U);
- EXPECT_EQ(producer_queue_->capacity(), 1U);
-
- size_t slot;
- DvrNativeBufferMetadata producer_meta;
- DvrNativeBufferMetadata consumer_meta;
- LocalHandle fence;
- auto s2 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence);
- EXPECT_TRUE(s2.ok());
-
- std::shared_ptr<ProducerBuffer> p1 = s2.take();
- ASSERT_NE(p1, nullptr);
-
- producer_meta.timestamp = 42;
- EXPECT_EQ(p1->PostAsync(&producer_meta, LocalHandle()), 0);
-
- // Make sure the buffer can be dequeued from consumer side.
- auto s3 = consumer_queue_->Dequeue(kTimeoutMs, &slot, &consumer_meta, &fence);
- EXPECT_TRUE(s3.ok()) << s3.GetErrorMessage();
- EXPECT_EQ(consumer_queue_->capacity(), 1U);
-
- auto consumer = s3.take();
- ASSERT_NE(consumer, nullptr);
- EXPECT_EQ(producer_meta.timestamp, consumer_meta.timestamp);
-}
-
-} // namespace
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
deleted file mode 100644
index b0ed950..0000000
--- a/libs/vr/libdisplay/Android.bp
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (C) 2015 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"],
-}
-
-sourceFiles = [
- "display_client.cpp",
- "display_manager_client.cpp",
- "display_protocol.cpp",
- "shared_buffer_helpers.cpp",
- "vsync_service.cpp",
-]
-
-localIncludeFiles = [
- "include",
-]
-
-sharedLibraries = [
- "libbase",
- "libbinder",
- "libbufferhubqueue",
- "libcutils",
- "liblog",
- "libutils",
- "libui",
- "libgui",
- "libhardware",
- "libsync",
- "libnativewindow",
- "libpdx_default_transport",
-]
-
-staticLibraries = [
- "libdvrcommon",
- "libbroadcastring",
-]
-
-headerLibraries = [
- "vulkan_headers",
- "libdvr_headers",
-]
-
-cc_library {
- srcs: sourceFiles,
- cflags: ["-DLOG_TAG=\"libdisplay\"",
- "-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- "-DGL_GLEXT_PROTOTYPES",
- "-DEGL_EGLEXT_PROTOTYPES",
- "-Wall",
- "-Werror",
- ], // + [ "-UNDEBUG", "-DDEBUG", "-O0", "-g" ],
- export_include_dirs: localIncludeFiles,
- shared_libs: sharedLibraries,
- static_libs: staticLibraries,
- header_libs: headerLibraries,
- export_header_lib_headers: headerLibraries,
-
- name: "libdisplay",
-}
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
deleted file mode 100644
index 62856df..0000000
--- a/libs/vr/libdisplay/display_client.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-#include "include/private/dvr/display_client.h"
-
-#include <cutils/native_handle.h>
-#include <log/log.h>
-#include <pdx/default_transport/client_channel.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/status.h>
-
-#include <mutex>
-
-#include <private/dvr/display_protocol.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::LocalHandle;
-using android::pdx::LocalChannelHandle;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::rpc::IfAnyOf;
-
-namespace android {
-namespace dvr {
-namespace display {
-
-Surface::Surface(LocalChannelHandle channel_handle, int* error)
- : BASE{pdx::default_transport::ClientChannel::Create(
- std::move(channel_handle))} {
- auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>();
- if (!status) {
- ALOGE("Surface::Surface: Failed to get surface info: %s",
- status.GetErrorMessage().c_str());
- Close(status.error());
- if (error)
- *error = status.error();
- }
-
- surface_id_ = status.get().surface_id;
- z_order_ = status.get().z_order;
- visible_ = status.get().visible;
-}
-
-Surface::Surface(const SurfaceAttributes& attributes, int* error)
- : BASE{pdx::default_transport::ClientChannelFactory::Create(
- DisplayProtocol::kClientPath),
- kInfiniteTimeout} {
- auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes);
- if (!status) {
- ALOGE("Surface::Surface: Failed to create display surface: %s",
- status.GetErrorMessage().c_str());
- Close(status.error());
- if (error)
- *error = status.error();
- }
-
- surface_id_ = status.get().surface_id;
- z_order_ = status.get().z_order;
- visible_ = status.get().visible;
-}
-
-Status<void> Surface::SetVisible(bool visible) {
- return SetAttributes(
- {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}});
-}
-
-Status<void> Surface::SetZOrder(int z_order) {
- return SetAttributes(
- {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}});
-}
-
-Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) {
- auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes);
- if (!status) {
- ALOGE(
- "Surface::SetAttributes: Failed to set display surface "
- "attributes: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- // Set the local cached copies of the attributes we care about from the full
- // set of attributes sent to the display service.
- for (const auto& attribute : attributes) {
- const auto& key = attribute.first;
- const auto* variant = &attribute.second;
- bool invalid_value = false;
- switch (key) {
- case SurfaceAttribute::Visible:
- invalid_value =
- !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_);
- break;
- case SurfaceAttribute::ZOrder:
- invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_);
- break;
- }
-
- if (invalid_value) {
- ALOGW(
- "Surface::SetAttributes: Failed to set display surface "
- "attribute %d because of incompatible type: %d",
- key, variant->index());
- }
- }
-
- return {};
-}
-
-Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
- uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) {
- ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue.");
- auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>(
- ProducerQueueConfigBuilder()
- .SetDefaultWidth(width)
- .SetDefaultHeight(height)
- .SetDefaultFormat(format)
- .SetMetadataSize(metadata_size)
- .Build());
- if (!status) {
- ALOGE("Surface::CreateQueue: Failed to create queue: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- auto producer_queue = ProducerQueue::Import(status.take());
- if (!producer_queue) {
- ALOGE("Surface::CreateQueue: Failed to import producer queue!");
- return ErrorStatus(ENOMEM);
- }
-
- return {std::move(producer_queue)};
-}
-
-Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
- uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t capacity, size_t metadata_size) {
- ALOGD_IF(TRACE,
- "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
- "usage=%" PRIx64 " capacity=%zu",
- width, height, layer_count, format, usage, capacity);
- auto status = CreateQueue(width, height, format, metadata_size);
- if (!status)
- return status.error_status();
-
- auto producer_queue = status.take();
-
- ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
- auto allocate_status = producer_queue->AllocateBuffers(
- width, height, layer_count, format, usage, capacity);
- if (!allocate_status) {
- ALOGE("Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
- producer_queue->id(), allocate_status.GetErrorMessage().c_str());
- return allocate_status.error_status();
- }
-
- return {std::move(producer_queue)};
-}
-
-DisplayClient::DisplayClient(int* error)
- : BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayProtocol::kClientPath),
- kInfiniteTimeout) {
- if (error)
- *error = Client::error();
-}
-
-Status<Metrics> DisplayClient::GetDisplayMetrics() {
- return InvokeRemoteMethod<DisplayProtocol::GetMetrics>();
-}
-
-Status<std::string> DisplayClient::GetConfigurationData(
- ConfigFileType config_type) {
- auto status =
- InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type);
- if (!status && status.error() != ENOENT) {
- ALOGE(
- "DisplayClient::GetConfigurationData: Unable to get"
- "configuration data. Error: %s",
- status.GetErrorMessage().c_str());
- }
- return status;
-}
-
-Status<uint8_t> DisplayClient::GetDisplayIdentificationPort() {
- return InvokeRemoteMethod<DisplayProtocol::GetDisplayIdentificationPort>();
-}
-
-Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface(
- const SurfaceAttributes& attributes) {
- int error;
- if (auto client = Surface::Create(attributes, &error))
- return {std::move(client)};
- else
- return ErrorStatus(error);
-}
-
-pdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer(
- DvrGlobalBufferKey key, size_t size, uint64_t usage) {
- auto status =
- InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage);
- if (!status) {
- ALOGE(
- "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer "
- "%s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- auto ion_buffer = std::make_unique<IonBuffer>();
- auto native_buffer_handle = status.take();
- const int ret = native_buffer_handle.Import(ion_buffer.get());
- if (ret < 0) {
- ALOGE(
- "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
- "key=%d; error=%s",
- key, strerror(-ret));
- return ErrorStatus(-ret);
- }
-
- return {std::move(ion_buffer)};
-}
-
-pdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) {
- auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key);
- if (!status) {
- ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s",
- status.GetErrorMessage().c_str());
- }
-
- return status;
-}
-
-Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer(
- DvrGlobalBufferKey key) {
- auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key);
- if (!status) {
- ALOGE(
- "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; "
- "error=%s",
- key, status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- auto ion_buffer = std::make_unique<IonBuffer>();
- auto native_buffer_handle = status.take();
- const int ret = native_buffer_handle.Import(ion_buffer.get());
- if (ret < 0) {
- ALOGE(
- "DisplayClient::GetGlobalBuffer: Failed to import global buffer: "
- "key=%d; error=%s",
- key, strerror(-ret));
- return ErrorStatus(-ret);
- }
-
- return {std::move(ion_buffer)};
-}
-
-Status<bool> DisplayClient::IsVrAppRunning() {
- return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>();
-}
-
-} // namespace display
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdisplay/display_manager_client.cpp
deleted file mode 100644
index fdeeb70..0000000
--- a/libs/vr/libdisplay/display_manager_client.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "include/private/dvr/display_manager_client.h"
-
-#include <pdx/default_transport/client_channel_factory.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/display_protocol.h>
-#include <utils/Log.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::Transaction;
-
-namespace android {
-namespace dvr {
-namespace display {
-
-DisplayManagerClient::DisplayManagerClient()
- : BASE(pdx::default_transport::ClientChannelFactory::Create(
- DisplayManagerProtocol::kClientPath)) {}
-
-DisplayManagerClient::~DisplayManagerClient() {}
-
-pdx::Status<std::vector<display::SurfaceState>>
-DisplayManagerClient::GetSurfaceState() {
- auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceState>();
- if (!status) {
- ALOGE(
- "DisplayManagerClient::GetSurfaceState: Failed to get surface info: %s",
- status.GetErrorMessage().c_str());
- }
-
- return status;
-}
-
-pdx::Status<std::unique_ptr<ConsumerQueue>>
-DisplayManagerClient::GetSurfaceQueue(int surface_id, int queue_id) {
- auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>(
- surface_id, queue_id);
- if (!status) {
- ALOGE(
- "DisplayManagerClient::GetSurfaceQueue: Failed to get queue for "
- "surface_id=%d queue_id=%d: %s",
- surface_id, queue_id, status.GetErrorMessage().c_str());
- return status.error_status();
- }
-
- return {ConsumerQueue::Import(status.take())};
-}
-
-} // namespace display
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdisplay/display_protocol.cpp b/libs/vr/libdisplay/display_protocol.cpp
deleted file mode 100644
index 773f9a5..0000000
--- a/libs/vr/libdisplay/display_protocol.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "include/private/dvr/display_protocol.h"
-
-namespace android {
-namespace dvr {
-namespace display {
-
-constexpr char DisplayProtocol::kClientPath[];
-constexpr char DisplayManagerProtocol::kClientPath[];
-constexpr char VSyncProtocol::kClientPath[];
-
-} // namespace display
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdisplay/include/CPPLINT.cfg b/libs/vr/libdisplay/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libdisplay/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
deleted file mode 100644
index 81546ac..0000000
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_CLIENT_H_
-#define ANDROID_DVR_DISPLAY_CLIENT_H_
-
-#include <dvr/dvr_api.h>
-#include <hardware/hwcomposer.h>
-#include <pdx/client.h>
-#include <pdx/file_handle.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/display_protocol.h>
-
-namespace android {
-namespace dvr {
-namespace display {
-
-class Surface : public pdx::ClientBase<Surface> {
- public:
- // Utility named constructor. This can be removed once ClientBase::Create is
- // refactored to return Status<T> types.
- static pdx::Status<std::unique_ptr<Surface>> CreateSurface(
- const SurfaceAttributes& attributes) {
- int error;
- pdx::Status<std::unique_ptr<Surface>> status;
- if (auto surface = Create(attributes, &error))
- status.SetValue(std::move(surface));
- else
- status.SetError(error);
- return status;
- }
-
- int surface_id() const { return surface_id_; }
- int z_order() const { return z_order_; }
- bool visible() const { return visible_; }
-
- pdx::Status<void> SetVisible(bool visible);
- pdx::Status<void> SetZOrder(int z_order);
- pdx::Status<void> SetAttributes(const SurfaceAttributes& attributes);
-
- // Creates an empty queue.
- pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width,
- uint32_t height,
- uint32_t format,
- size_t metadata_size);
-
- // Creates a queue and populates it with |capacity| buffers of the specified
- // parameters.
- pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width,
- uint32_t height,
- uint32_t layer_count,
- uint32_t format,
- uint64_t usage,
- size_t capacity,
- size_t metadata_size);
-
- private:
- friend BASE;
-
- int surface_id_ = -1;
- int z_order_ = 0;
- bool visible_ = false;
-
- // TODO(eieio,avakulenko): Remove error param once pdx::ClientBase::Create()
- // returns Status<T>.
- explicit Surface(const SurfaceAttributes& attributes, int* error = nullptr);
- explicit Surface(pdx::LocalChannelHandle channel_handle,
- int* error = nullptr);
-
- Surface(const Surface&) = delete;
- void operator=(const Surface&) = delete;
-};
-
-class DisplayClient : public pdx::ClientBase<DisplayClient> {
- public:
- pdx::Status<Metrics> GetDisplayMetrics();
- pdx::Status<std::string> GetConfigurationData(ConfigFileType config_type);
- pdx::Status<uint8_t> GetDisplayIdentificationPort();
- pdx::Status<std::unique_ptr<IonBuffer>> SetupGlobalBuffer(
- DvrGlobalBufferKey key, size_t size, uint64_t usage);
- pdx::Status<void> DeleteGlobalBuffer(DvrGlobalBufferKey key);
- pdx::Status<std::unique_ptr<IonBuffer>> GetGlobalBuffer(
- DvrGlobalBufferKey key);
- pdx::Status<std::unique_ptr<Surface>> CreateSurface(
- const SurfaceAttributes& attributes);
-
- // Temporary query for current VR status. Will be removed later.
- pdx::Status<bool> IsVrAppRunning();
-
- private:
- friend BASE;
-
- explicit DisplayClient(int* error = nullptr);
-
- DisplayClient(const DisplayClient&) = delete;
- void operator=(const DisplayClient&) = delete;
-};
-
-} // namespace display
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_DISPLAY_CLIENT_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
deleted file mode 100644
index 45aef51..0000000
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
+++ /dev/null
@@ -1,49 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
-#define ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
-
-#include <string>
-#include <vector>
-
-#include <pdx/client.h>
-#include <pdx/status.h>
-#include <private/dvr/display_protocol.h>
-
-namespace android {
-namespace dvr {
-
-class IonBuffer;
-class ConsumerQueue;
-
-namespace display {
-
-class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
- public:
- ~DisplayManagerClient() override;
-
- pdx::Status<std::vector<SurfaceState>> GetSurfaceState();
- pdx::Status<std::unique_ptr<ConsumerQueue>> GetSurfaceQueue(int surface_id,
- int queue_id);
-
- using Client::event_fd;
-
- pdx::Status<int> GetEventMask(int events) {
- if (auto* client_channel = GetChannel())
- return client_channel->GetEventMask(events);
- else
- return pdx::ErrorStatus(EINVAL);
- }
-
- private:
- friend BASE;
-
- DisplayManagerClient();
-
- DisplayManagerClient(const DisplayManagerClient&) = delete;
- void operator=(const DisplayManagerClient&) = delete;
-};
-
-} // namespace display
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/display_protocol.h b/libs/vr/libdisplay/include/private/dvr/display_protocol.h
deleted file mode 100644
index 9f4cc4a..0000000
--- a/libs/vr/libdisplay/include/private/dvr/display_protocol.h
+++ /dev/null
@@ -1,304 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_PROTOCOL_H_
-#define ANDROID_DVR_DISPLAY_PROTOCOL_H_
-
-#include <sys/types.h>
-
-#include <array>
-#include <map>
-
-#include <dvr/dvr_display_types.h>
-
-#include <dvr/dvr_api.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/variant.h>
-#include <private/dvr/bufferhub_rpc.h>
-
-// RPC protocol definitions for DVR display services (VrFlinger).
-
-namespace android {
-namespace dvr {
-namespace display {
-
-// Native display metrics.
-struct Metrics {
- // Basic display properties.
- uint32_t display_width;
- uint32_t display_height;
- uint32_t display_x_dpi;
- uint32_t display_y_dpi;
- uint32_t vsync_period_ns;
-
- // HMD metrics.
- // TODO(eieio): Determine how these fields should be populated. On phones
- // these values are determined at runtime by VrCore based on which headset the
- // phone is in. On dedicated hardware this needs to come from somewhere else.
- // Perhaps these should be moved to a separate structure that is returned by a
- // separate runtime call.
- uint32_t distorted_width;
- uint32_t distorted_height;
- uint32_t hmd_ipd_mm;
- float inter_lens_distance_m;
- std::array<float, 4> left_fov_lrbt;
- std::array<float, 4> right_fov_lrbt;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(Metrics, display_width, display_height,
- display_x_dpi, display_y_dpi, vsync_period_ns,
- distorted_width, distorted_height, hmd_ipd_mm,
- inter_lens_distance_m, left_fov_lrbt,
- right_fov_lrbt);
-};
-
-// Serializable base type for enum structs. Enum structs are easier to use than
-// enum classes, especially for bitmasks. This base type provides common
-// utilities for flags types.
-template <typename Integer>
-class Flags {
- public:
- using Base = Flags<Integer>;
- using Type = Integer;
-
- // NOLINTNEXTLINE(google-explicit-constructor)
- Flags(const Integer& value) : value_{value} {}
- Flags(const Flags&) = default;
- Flags& operator=(const Flags&) = default;
-
- Integer value() const { return value_; }
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator Integer() const { return value_; }
-
- bool IsSet(Integer bits) const { return (value_ & bits) == bits; }
- bool IsClear(Integer bits) const { return (value_ & bits) == 0; }
-
- void Set(Integer bits) { value_ |= bits; }
- void Clear(Integer bits) { value_ &= ~bits; }
-
- Integer operator|(Integer bits) const { return value_ | bits; }
- Integer operator&(Integer bits) const { return value_ & bits; }
-
- Flags& operator|=(Integer bits) {
- value_ |= bits;
- return *this;
- }
- Flags& operator&=(Integer bits) {
- value_ &= bits;
- return *this;
- }
-
- private:
- Integer value_;
-
- PDX_SERIALIZABLE_MEMBERS(Flags<Integer>, value_);
-};
-
-// Flags indicating what changed since last update.
-struct SurfaceUpdateFlags : public Flags<uint32_t> {
- enum : Type {
- None = DVR_SURFACE_UPDATE_FLAGS_NONE,
- NewSurface = DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE,
- BuffersChanged = DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED,
- VisibilityChanged = DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED,
- AttributesChanged = DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED,
- };
-
- SurfaceUpdateFlags() : Base{None} {}
- using Base::Base;
-};
-
-// Surface attribute key/value types.
-using SurfaceAttributeKey = int32_t;
-using SurfaceAttributeValue =
- pdx::rpc::Variant<int32_t, int64_t, bool, float, std::array<float, 2>,
- std::array<float, 3>, std::array<float, 4>,
- std::array<float, 8>, std::array<float, 16>>;
-
-// Defined surface attribute keys.
-struct SurfaceAttribute : public Flags<SurfaceAttributeKey> {
- enum : Type {
- // Keys in the negative integer space are interpreted by VrFlinger for
- // direct surfaces.
- Direct = DVR_SURFACE_ATTRIBUTE_DIRECT,
- ZOrder = DVR_SURFACE_ATTRIBUTE_Z_ORDER,
- Visible = DVR_SURFACE_ATTRIBUTE_VISIBLE,
-
- // Invalid key. May be used to terminate C style lists in public API code.
- Invalid = DVR_SURFACE_ATTRIBUTE_INVALID,
-
- // Positive keys are interpreted by the compositor only.
- FirstUserKey = DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY,
- };
-
- SurfaceAttribute() : Base{Invalid} {}
- using Base::Base;
-};
-
-// Collection of surface attribute key/value pairs.
-using SurfaceAttributes = std::map<SurfaceAttributeKey, SurfaceAttributeValue>;
-
-struct SurfaceState {
- int32_t surface_id;
- int32_t process_id;
- int32_t user_id;
-
- SurfaceAttributes surface_attributes;
- SurfaceUpdateFlags update_flags;
- std::vector<int32_t> queue_ids;
-
- // Convenience accessors.
- bool GetVisible() const {
- bool bool_value = false;
- GetAttribute(SurfaceAttribute::Visible, &bool_value,
- ValidTypes<int32_t, int64_t, bool, float>{});
- return bool_value;
- }
-
- int GetZOrder() const {
- int int_value = 0;
- GetAttribute(SurfaceAttribute::ZOrder, &int_value,
- ValidTypes<int32_t, int64_t, float>{});
- return int_value;
- }
-
- private:
- template <typename... Types>
- struct ValidTypes {};
-
- template <typename ReturnType, typename... Types>
- bool GetAttribute(SurfaceAttributeKey key, ReturnType* out_value,
- ValidTypes<Types...>) const {
- auto search = surface_attributes.find(key);
- if (search != surface_attributes.end())
- return pdx::rpc::IfAnyOf<Types...>::Get(&search->second, out_value);
- else
- return false;
- }
-
- PDX_SERIALIZABLE_MEMBERS(SurfaceState, surface_id, process_id,
- surface_attributes, update_flags, queue_ids);
-};
-
-struct SurfaceInfo {
- int surface_id;
- bool visible;
- int z_order;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(SurfaceInfo, surface_id, visible, z_order);
-};
-
-enum class ConfigFileType : uint32_t {
- kLensMetrics,
- kDeviceMetrics,
- kDeviceConfiguration,
- kDeviceEdid
-};
-
-struct DisplayProtocol {
- // Service path.
- static constexpr char kClientPath[] = "system/vr/display/client";
-
- // Op codes.
- enum {
- kOpGetMetrics = 0,
- kOpGetConfigurationData,
- kOpSetupGlobalBuffer,
- kOpDeleteGlobalBuffer,
- kOpGetGlobalBuffer,
- kOpIsVrAppRunning,
- kOpCreateSurface,
- kOpGetSurfaceInfo,
- kOpCreateQueue,
- kOpSetAttributes,
- kOpGetDisplayIdentificationPort,
- };
-
- // Aliases.
- using LocalChannelHandle = pdx::LocalChannelHandle;
- using Void = pdx::rpc::Void;
-
- // Methods.
- PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, Metrics(Void));
- PDX_REMOTE_METHOD(GetConfigurationData, kOpGetConfigurationData,
- std::string(ConfigFileType config_type));
- PDX_REMOTE_METHOD(GetDisplayIdentificationPort,
- kOpGetDisplayIdentificationPort, uint8_t(Void));
- PDX_REMOTE_METHOD(SetupGlobalBuffer, kOpSetupGlobalBuffer,
- LocalNativeBufferHandle(DvrGlobalBufferKey key, size_t size,
- uint64_t usage));
- PDX_REMOTE_METHOD(DeleteGlobalBuffer, kOpDeleteGlobalBuffer,
- void(DvrGlobalBufferKey key));
- PDX_REMOTE_METHOD(GetGlobalBuffer, kOpGetGlobalBuffer,
- LocalNativeBufferHandle(DvrGlobalBufferKey key));
- PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, bool(Void));
- PDX_REMOTE_METHOD(CreateSurface, kOpCreateSurface,
- SurfaceInfo(const SurfaceAttributes& attributes));
- PDX_REMOTE_METHOD(GetSurfaceInfo, kOpGetSurfaceInfo, SurfaceInfo(Void));
- PDX_REMOTE_METHOD(
- CreateQueue, kOpCreateQueue,
- LocalChannelHandle(const ProducerQueueConfig& producer_config));
- PDX_REMOTE_METHOD(SetAttributes, kOpSetAttributes,
- void(const SurfaceAttributes& attributes));
-};
-
-struct DisplayManagerProtocol {
- // Service path.
- static constexpr char kClientPath[] = "system/vr/display/manager";
-
- // Op codes.
- enum {
- kOpGetSurfaceState = 0,
- kOpGetSurfaceQueue,
- };
-
- // Aliases.
- using LocalChannelHandle = pdx::LocalChannelHandle;
- using Void = pdx::rpc::Void;
-
- // Methods.
- PDX_REMOTE_METHOD(GetSurfaceState, kOpGetSurfaceState,
- std::vector<SurfaceState>(Void));
- PDX_REMOTE_METHOD(GetSurfaceQueue, kOpGetSurfaceQueue,
- LocalChannelHandle(int surface_id, int queue_id));
-};
-
-struct VSyncSchedInfo {
- int64_t vsync_period_ns;
- int64_t timestamp_ns;
- uint32_t next_vsync_count;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(VSyncSchedInfo, vsync_period_ns, timestamp_ns,
- next_vsync_count);
-};
-
-struct VSyncProtocol {
- // Service path.
- static constexpr char kClientPath[] = "system/vr/display/vsync";
-
- // Op codes.
- enum {
- kOpWait = 0,
- kOpAck,
- kOpGetLastTimestamp,
- kOpGetSchedInfo,
- kOpAcknowledge,
- };
-
- // Aliases.
- using Void = pdx::rpc::Void;
- using Timestamp = int64_t;
-
- // Methods.
- PDX_REMOTE_METHOD(Wait, kOpWait, Timestamp(Void));
- PDX_REMOTE_METHOD(GetLastTimestamp, kOpGetLastTimestamp, Timestamp(Void));
- PDX_REMOTE_METHOD(GetSchedInfo, kOpGetSchedInfo, VSyncSchedInfo(Void));
- PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, void(Void));
-};
-
-} // namespace display
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_DISPLAY_PROTOCOL_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h b/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h
deleted file mode 100644
index 20541a6..0000000
--- a/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifndef ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
-#define ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
-
-#include <assert.h>
-#include <tuple>
-
-#include <libbroadcastring/broadcast_ring.h>
-#include <private/dvr/display_client.h>
-
-namespace android {
-namespace dvr {
-
-// The buffer usage type for mapped shared buffers.
-enum class CPUUsageMode { READ_OFTEN, READ_RARELY, WRITE_OFTEN, WRITE_RARELY };
-
-// Holds the memory for the mapped shared buffer. Unlocks and releases the
-// underlying IonBuffer in destructor.
-class CPUMappedBuffer {
- public:
- // This constructor will create a display client and get the buffer from it.
- CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode);
-
- // If you already have the IonBuffer, use this. It will take ownership.
- CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode);
-
- // Use this if you do not want to take ownership.
- CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode);
-
- ~CPUMappedBuffer();
-
- // Getters.
- size_t Size() const { return size_; }
- void* Address() const { return address_; }
- bool IsMapped() const { return Address() != nullptr; }
-
- // Attempt mapping this buffer to the CPU addressable space.
- // This will create a display client and see if the buffer exists.
- // If the buffer has not been setup yet, you will need to try again later.
- void TryMapping();
-
- protected:
- // The memory area if we managed to map it.
- size_t size_ = 0;
- void* address_ = nullptr;
-
- // If we are polling the display client, the buffer key here.
- DvrGlobalBufferKey buffer_key_;
-
- // If we just own the IonBuffer outright, it's here.
- std::unique_ptr<IonBuffer> owned_buffer_ = nullptr;
-
- // The last time we connected to the display service.
- int64_t last_display_service_connection_ns_ = 0;
-
- // If we do not own the IonBuffer, it's here
- IonBuffer* buffer_ = nullptr;
-
- // The usage mode.
- CPUUsageMode usage_mode_ = CPUUsageMode::READ_OFTEN;
-};
-
-// Represents a broadcast ring inside a mapped shared memory buffer.
-// If has the same set of constructors as CPUMappedBuffer.
-// The template argument is the concrete BroadcastRing class that this buffer
-// holds.
-template <class RingType>
-class CPUMappedBroadcastRing : public CPUMappedBuffer {
- public:
- CPUMappedBroadcastRing(DvrGlobalBufferKey key, CPUUsageMode mode)
- : CPUMappedBuffer(key, mode) {}
-
- CPUMappedBroadcastRing(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode)
- : CPUMappedBuffer(std::move(buffer), mode) {}
-
- CPUMappedBroadcastRing(IonBuffer* buffer, CPUUsageMode mode)
- : CPUMappedBuffer(buffer, mode) {}
-
- // Helper function for publishing records in the ring.
- void Publish(const typename RingType::Record& record) {
- assert((usage_mode_ == CPUUsageMode::WRITE_OFTEN) ||
- (usage_mode_ == CPUUsageMode::WRITE_RARELY));
-
- auto ring = Ring();
- if (ring) {
- ring->Put(record);
- }
- }
-
- // Helper function for getting records from the ring.
- // Returns true if we were able to retrieve the latest.
- bool GetNewest(typename RingType::Record* record) {
- assert((usage_mode_ == CPUUsageMode::READ_OFTEN) ||
- (usage_mode_ == CPUUsageMode::READ_RARELY));
-
- auto ring = Ring();
- if (ring) {
- return ring->GetNewest(&sequence_, record);
- }
-
- return false;
- }
-
- // Try obtaining the ring. If the named buffer has not been created yet, it
- // will return nullptr.
- RingType* Ring() {
- // No ring created yet?
- if (ring_ == nullptr) {
- // Not mapped the memory yet?
- if (IsMapped() == false) {
- TryMapping();
- }
-
- // If have the memory mapped, allocate the ring.
- if (IsMapped()) {
- switch (usage_mode_) {
- case CPUUsageMode::READ_OFTEN:
- case CPUUsageMode::READ_RARELY: {
- RingType ring;
- bool import_ok;
- std::tie(ring, import_ok) = RingType::Import(address_, size_);
- if (import_ok) {
- ring_ = std::make_unique<RingType>(ring);
- }
- } break;
- case CPUUsageMode::WRITE_OFTEN:
- case CPUUsageMode::WRITE_RARELY:
- ring_ =
- std::make_unique<RingType>(RingType::Create(address_, size_));
- break;
- }
- }
- }
-
- return ring_.get();
- }
-
- protected:
- std::unique_ptr<RingType> ring_ = nullptr;
-
- uint32_t sequence_ = 0;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/vsync_service.h b/libs/vr/libdisplay/include/private/dvr/vsync_service.h
deleted file mode 100644
index 152464a..0000000
--- a/libs/vr/libdisplay/include/private/dvr/vsync_service.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef ANDROID_DVR_VSYNC_SERVICE_H_
-#define ANDROID_DVR_VSYNC_SERVICE_H_
-
-#include <binder/IInterface.h>
-
-namespace android {
-namespace dvr {
-
-class IVsyncCallback : public IInterface {
- public:
- DECLARE_META_INTERFACE(VsyncCallback)
-
- enum {
- ON_VSYNC = IBinder::FIRST_CALL_TRANSACTION
- };
-
- virtual status_t onVsync(int64_t vsync_timestamp) = 0;
-};
-
-class BnVsyncCallback : public BnInterface<IVsyncCallback> {
- public:
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags = 0);
-};
-
-// Register a callback with IVsyncService to be notified of vsync events and
-// timestamps. There's also a shared memory vsync buffer defined in
-// dvr_shared_buffers.h. IVsyncService has advantages over the vsync shared
-// memory buffer that make it preferable in certain situations:
-//
-// 1. The shared memory buffer lifetime is controlled by VrCore. IVsyncService
-// is always available as long as surface flinger is running.
-//
-// 2. IVsyncService will make a binder callback when a vsync event occurs. This
-// allows the client to not write code to implement periodic "get the latest
-// vsync" calls, which is necessary with the vsync shared memory buffer.
-//
-// 3. The IVsyncService provides the real vsync timestamp reported by hardware
-// composer, whereas the vsync shared memory buffer only has predicted vsync
-// times.
-class IVsyncService : public IInterface {
-public:
- DECLARE_META_INTERFACE(VsyncService)
-
- static const char* GetServiceName() { return "vrflinger_vsync"; }
-
- enum {
- REGISTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION,
- UNREGISTER_CALLBACK
- };
-
- virtual status_t registerCallback(const sp<IVsyncCallback> callback) = 0;
- virtual status_t unregisterCallback(const sp<IVsyncCallback> callback) = 0;
-};
-
-class BnVsyncService : public BnInterface<IVsyncService> {
- public:
- virtual status_t onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags = 0);
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VSYNC_SERVICE_H_
diff --git a/libs/vr/libdisplay/shared_buffer_helpers.cpp b/libs/vr/libdisplay/shared_buffer_helpers.cpp
deleted file mode 100644
index 6ebf487..0000000
--- a/libs/vr/libdisplay/shared_buffer_helpers.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-#include <private/dvr/clock_ns.h>
-#include <private/dvr/shared_buffer_helpers.h>
-
-namespace android {
-namespace dvr {
-namespace {
-
-// We will not poll the display service for buffers more frequently than this.
-constexpr size_t kDisplayServiceTriesPerSecond = 2;
-} // namespace
-
-CPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode)
- : buffer_key_(key), usage_mode_(mode) {
- TryMapping();
-}
-
-CPUMappedBuffer::CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer,
- CPUUsageMode mode)
- : owned_buffer_(std::move(buffer)),
- buffer_(owned_buffer_.get()),
- usage_mode_(mode) {
- TryMapping();
-}
-
-CPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode)
- : buffer_(buffer), usage_mode_(mode) {
- TryMapping();
-}
-
-CPUMappedBuffer::~CPUMappedBuffer() {
- if (IsMapped()) {
- buffer_->Unlock();
- }
-}
-
-void CPUMappedBuffer::TryMapping() {
- // Do we have an IonBuffer for this shared memory object?
- if (buffer_ == nullptr) {
- // Has it been too long since we last connected to the display service?
- const auto current_time_ns = GetSystemClockNs();
- if ((current_time_ns - last_display_service_connection_ns_) <
- (1e9 / kDisplayServiceTriesPerSecond)) {
- // Early exit.
- return;
- }
- last_display_service_connection_ns_ = current_time_ns;
-
- // Create a display client and get the buffer.
- auto display_client = display::DisplayClient::Create();
- if (display_client) {
- auto get_result = display_client->GetGlobalBuffer(buffer_key_);
- if (get_result.ok()) {
- owned_buffer_ = get_result.take();
- buffer_ = owned_buffer_.get();
- } else {
- // The buffer has not been created yet. This is OK, we will keep
- // retrying.
- }
- } else {
- ALOGE("Unable to create display client for shared buffer access");
- }
- }
-
- if (buffer_) {
- auto usage = buffer_->usage() & ~GRALLOC_USAGE_SW_READ_MASK &
- ~GRALLOC_USAGE_SW_WRITE_MASK;
-
- // Figure out the usage bits.
- switch (usage_mode_) {
- case CPUUsageMode::READ_OFTEN:
- usage |= GRALLOC_USAGE_SW_READ_OFTEN;
- break;
- case CPUUsageMode::READ_RARELY:
- usage |= GRALLOC_USAGE_SW_READ_RARELY;
- break;
- case CPUUsageMode::WRITE_OFTEN:
- usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
- break;
- case CPUUsageMode::WRITE_RARELY:
- usage |= GRALLOC_USAGE_SW_WRITE_RARELY;
- break;
- }
-
- int width = static_cast<int>(buffer_->width());
- int height = 1;
- const auto ret = buffer_->Lock(usage, 0, 0, width, height, &address_);
-
- if (ret < 0 || !address_) {
- ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, address_);
- buffer_->Unlock();
- } else {
- size_ = width;
- }
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdisplay/system/CPPLINT.cfg b/libs/vr/libdisplay/system/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libdisplay/system/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libdisplay/vsync_service.cpp b/libs/vr/libdisplay/vsync_service.cpp
deleted file mode 100644
index 04d4f30..0000000
--- a/libs/vr/libdisplay/vsync_service.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-#include "include/private/dvr/vsync_service.h"
-
-#include <binder/Parcel.h>
-#include <log/log.h>
-
-namespace android {
-namespace dvr {
-
-status_t BnVsyncCallback::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- switch (code) {
- case ON_VSYNC: {
- CHECK_INTERFACE(IVsyncCallback, data, reply);
- int64_t vsync_timestamp = 0;
- status_t result = data.readInt64(&vsync_timestamp);
- if (result != OK) {
- ALOGE("onVsync failed to readInt64: %d", result);
- return result;
- }
- onVsync(vsync_timestamp);
- return OK;
- }
- default: {
- return BBinder::onTransact(code, data, reply, flags);
- }
- }
-}
-
-class BpVsyncCallback : public BpInterface<IVsyncCallback> {
-public:
- explicit BpVsyncCallback(const sp<IBinder>& impl)
- : BpInterface<IVsyncCallback>(impl) {}
- virtual ~BpVsyncCallback() {}
-
- virtual status_t onVsync(int64_t vsync_timestamp) {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(
- IVsyncCallback::getInterfaceDescriptor());
- if (result != OK) {
- ALOGE("onVsync failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeInt64(vsync_timestamp);
- if (result != OK) {
- ALOGE("onVsync failed to writeInt64: %d", result);
- return result;
- }
- result = remote()->transact(BnVsyncCallback::ON_VSYNC, data, &reply,
- IBinder::FLAG_ONEWAY);
- if (result != OK) {
- ALOGE("onVsync failed to transact: %d", result);
- return result;
- }
- return result;
- }
-};
-
-IMPLEMENT_META_INTERFACE(VsyncCallback, "android.dvr.IVsyncCallback");
-
-
-status_t BnVsyncService::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- switch (code) {
- case REGISTER_CALLBACK: {
- CHECK_INTERFACE(IVsyncService, data, reply);
- sp<IBinder> callback;
- status_t result = data.readStrongBinder(&callback);
- if (result != OK) {
- ALOGE("registerCallback failed to readStrongBinder: %d", result);
- return result;
- }
- registerCallback(interface_cast<IVsyncCallback>(callback));
- return OK;
- }
- case UNREGISTER_CALLBACK: {
- CHECK_INTERFACE(IVsyncService, data, reply);
- sp<IBinder> callback;
- status_t result = data.readStrongBinder(&callback);
- if (result != OK) {
- ALOGE("unregisterCallback failed to readStrongBinder: %d", result);
- return result;
- }
- unregisterCallback(interface_cast<IVsyncCallback>(callback));
- return OK;
- }
- default: {
- return BBinder::onTransact(code, data, reply, flags);
- }
- }
-}
-
-class BpVsyncService : public BpInterface<IVsyncService> {
-public:
- explicit BpVsyncService(const sp<IBinder>& impl)
- : BpInterface<IVsyncService>(impl) {}
- virtual ~BpVsyncService() {}
-
- virtual status_t registerCallback(const sp<IVsyncCallback> callback) {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(
- IVsyncService::getInterfaceDescriptor());
- if (result != OK) {
- ALOGE("registerCallback failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(IInterface::asBinder(callback));
- if (result != OK) {
- ALOGE("registerCallback failed to writeStrongBinder: %d", result);
- return result;
- }
- result = remote()->transact(
- BnVsyncService::REGISTER_CALLBACK, data, &reply);
- if (result != OK) {
- ALOGE("registerCallback failed to transact: %d", result);
- return result;
- }
- return result;
- }
-
- virtual status_t unregisterCallback(const sp<IVsyncCallback> callback) {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(
- IVsyncService::getInterfaceDescriptor());
- if (result != OK) {
- ALOGE("unregisterCallback failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(IInterface::asBinder(callback));
- if (result != OK) {
- ALOGE("unregisterCallback failed to writeStrongBinder: %d", result);
- return result;
- }
- result = remote()->transact(
- BnVsyncService::UNREGISTER_CALLBACK, data, &reply);
- if (result != OK) {
- ALOGE("unregisterCallback failed to transact: %d", result);
- return result;
- }
- return result;
- }
-};
-
-IMPLEMENT_META_INTERFACE(VsyncService, "android.dvr.IVsyncService");
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libvrsensor/Android.bp b/libs/vr/libvrsensor/Android.bp
deleted file mode 100644
index 40a5099..0000000
--- a/libs/vr/libvrsensor/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2015 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"],
-}
-
-sourceFiles = [
- "pose_client.cpp",
- "latency_model.cpp",
-]
-
-includeFiles = [
- "include",
-]
-
-staticLibraries = [
- "libdisplay",
- "libdvrcommon",
- "libbroadcastring",
-]
-
-sharedLibraries = [
- "libbase",
- "libbinder",
- "libbufferhubqueue",
- "libcutils",
- "libhardware",
- "liblog",
- "libutils",
- "libui",
- "libpdx_default_transport",
-]
-
-cc_library {
- srcs: sourceFiles,
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-macro-redefined",
- ],
- export_include_dirs: includeFiles,
- static_libs: staticLibraries,
- shared_libs: sharedLibraries,
- header_libs: ["libdvr_headers"],
- name: "libvrsensor",
-}
diff --git a/libs/vr/libvrsensor/include/CPPLINT.cfg b/libs/vr/libvrsensor/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libvrsensor/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libvrsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h
deleted file mode 100644
index b663a67..0000000
--- a/libs/vr/libvrsensor/include/dvr/pose_client.h
+++ /dev/null
@@ -1,176 +0,0 @@
-#ifndef ANDROID_DVR_POSE_CLIENT_H_
-#define ANDROID_DVR_POSE_CLIENT_H_
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__ ((__vector_size__ (16)));
-typedef struct float32x4x4_t { float32x4_t val[4]; } float32x4x4_t;
-#endif
-#endif
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <dvr/dvr_pose.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct DvrPoseClient DvrPoseClient;
-
-// Returned by the async pose ring buffer access API.
-typedef struct DvrPoseRingBufferInfo {
- // Read-only pointer to the pose ring buffer. The current pose is in this
- // buffer at element buffer[current_frame & (buffer_size - 1)]. The next
- // frame's forecasted pose is at element
- // ((current_frame + 1) & (buffer_size - 1)). And so on. The poses are
- // predicted for when 50% of the corresponding frame's pixel data is visible
- // to the user.
- // The last value returned by dvrPresent is the count for the next frame,
- // which is the earliest that the application could display something if they
- // were to render promptly. (TODO(jbates) move this comment to dvrPresent).
- volatile const DvrPoseAsync* buffer;
- // Minimum number of accurate forecasted poses including the current frame's
- // pose. This is the number of poses that are udpated by the pose service.
- // If the application reads past this count, they will get a stale prediction
- // from a previous frame. Guaranteed to be at least 2.
- uint32_t min_future_count;
- // Number of elements in buffer. At least 8 and greater than min_future_count.
- // Guaranteed to be a power of two. The total size of the buffer in bytes is:
- // total_count * sizeof(DvrPoseAsync)
- uint32_t total_count;
-} DvrPoseRingBufferInfo;
-
-typedef enum DvrPoseMode {
- DVR_POSE_MODE_6DOF = 0,
- DVR_POSE_MODE_3DOF,
- DVR_POSE_MODE_MOCK_FROZEN,
- DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW,
- DVR_POSE_MODE_MOCK_HEAD_TURN_FAST,
- DVR_POSE_MODE_MOCK_ROTATE_SLOW,
- DVR_POSE_MODE_MOCK_ROTATE_MEDIUM,
- DVR_POSE_MODE_MOCK_ROTATE_FAST,
- DVR_POSE_MODE_MOCK_CIRCLE_STRAFE,
- DVR_POSE_MODE_FLOAT,
- DVR_POSE_MODE_MOCK_MOTION_SICKNESS,
-
- // Always last.
- DVR_POSE_MODE_COUNT,
-} DvrPoseMode;
-
-typedef enum DvrControllerId {
- DVR_CONTROLLER_0 = 0,
- DVR_CONTROLLER_1 = 1,
-} DvrControllerId;
-
-// Creates a new pose client.
-//
-// @return Pointer to the created pose client, nullptr on failure.
-DvrPoseClient* dvrPoseClientCreate();
-
-// Destroys a pose client.
-//
-// @param client Pointer to the pose client to be destroyed.
-void dvrPoseClientDestroy(DvrPoseClient* client);
-
-// Gets the pose for the given vsync count.
-//
-// @param client Pointer to the pose client.
-// @param vsync_count Vsync that this pose should be forward-predicted to.
-// Typically this is the count returned by dvrGetNextVsyncCount.
-// @param out_pose Struct to store pose state.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count,
- DvrPoseAsync* out_pose);
-
-// Gets the current vsync count.
-uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client);
-
-// Gets the pose for the given controller at the given vsync count.
-//
-// @param client Pointer to the pose client.
-// @param controller_id The controller id.
-// @param vsync_count Vsync that this pose should be forward-predicted to.
-// Typically this is the count returned by dvrGetNextVsyncCount.
-// @param out_pose Struct to store pose state.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientGetController(DvrPoseClient* client, int32_t controller_id,
- uint32_t vsync_count, DvrPoseAsync* out_pose);
-
-// Enables/disables logging for the controller fusion.
-//
-// @param client Pointer to the pose client.
-// @param enable True starts logging, False stops.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientLogController(DvrPoseClient* client, bool enable);
-
-// DEPRECATED
-// Polls current pose state.
-//
-// @param client Pointer to the pose client.
-// @param state Struct to store polled state.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientPoll(DvrPoseClient* client, DvrPose* state);
-
-// Freezes the pose to the provided state.
-//
-// Future poll operations will return this state until a different state is
-// frozen or dvrPoseClientModeSet() is called with a different mode. The timestamp is
-// not frozen.
-//
-// @param client Pointer to the pose client.
-// @param frozen_state State pose to be frozen to.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientFreeze(DvrPoseClient* client, const DvrPose* frozen_state);
-
-// Sets the pose service mode.
-//
-// @param mode The requested pose mode.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientModeSet(DvrPoseClient* client, DvrPoseMode mode);
-
-// Gets the pose service mode.
-//
-// @param mode Return value for the current pose mode.
-// @return Zero on success, negative error code on failure.
-int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode);
-
-// Get access to the shared memory pose ring buffer.
-// A future pose at vsync <current> + <offset> is accessed at index:
-// index = (<current> + <offset>) % out_buffer_size
-// Where <current> was the last value returned by dvrPresent and
-// <offset> is less than or equal to |out_min_future_count|.
-// |out_buffer| will be set to a pointer to the buffer.
-// |out_fd| will be set to the gralloc buffer file descriptor, which is
-// required for binding this buffer for GPU use.
-// Returns 0 on success.
-int dvrPoseClientGetRingBuffer(DvrPoseClient* client,
- DvrPoseRingBufferInfo* out_info);
-
-// Sets enabled state for sensors pose processing.
-//
-// @param enabled Whether sensors are enabled or disabled.
-// @return Zero on success
-int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled);
-
-// Requests a burst of data samples from pose service. The data samples are
-// passed through a shared memory buffer obtained by calling
-// dvrPoseClientGetDataReader().
-//
-// @param DvrPoseDataCaptureRequest Parameters on how to capture data.
-// @return Zero on success.
-int dvrPoseClientDataCapture(DvrPoseClient* client,
- const DvrPoseDataCaptureRequest* request);
-
-// Destroys the write buffer queue for the given |data_type|.
-int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, uint64_t data_type);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_POSE_CLIENT_H_
diff --git a/libs/vr/libvrsensor/include/private/dvr/latency_model.h b/libs/vr/libvrsensor/include/private/dvr/latency_model.h
deleted file mode 100644
index bf0e687..0000000
--- a/libs/vr/libvrsensor/include/private/dvr/latency_model.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef ANDROID_DVR_LATENCY_MODEL_H_
-#define ANDROID_DVR_LATENCY_MODEL_H_
-
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-// This class models the latency from sensors. It will look at the first
-// window_size measurements and return their average after that.
-class LatencyModel {
- public:
- explicit LatencyModel(size_t window_size);
- ~LatencyModel() = default;
-
- void AddLatency(int64_t latency_ns);
- int64_t CurrentLatencyEstimate() const { return latency_; }
-
- private:
- size_t window_size_;
- int64_t latency_sum_ = 0;
- size_t num_summed_ = 0;
- int64_t latency_ = 0;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_LATENCY_MODEL_H_
diff --git a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
deleted file mode 100644
index 7bf1cd4..0000000
--- a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef ANDROID_DVR_POSE_IPC_H_
-#define ANDROID_DVR_POSE_IPC_H_
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define DVR_POSE_SERVICE_BASE "system/vr/pose"
-#define DVR_POSE_SERVICE_CLIENT (DVR_POSE_SERVICE_BASE "/client")
-
-enum {
- DVR_POSE_FREEZE = 0,
- DVR_POSE_SET_MODE,
- DVR_POSE_GET_MODE,
- DVR_POSE_GET_CONTROLLER_RING_BUFFER,
- DVR_POSE_LOG_CONTROLLER,
- DVR_POSE_SENSORS_ENABLE,
- DVR_POSE_GET_TANGO_READER,
- DVR_POSE_DATA_CAPTURE,
- DVR_POSE_TANGO_READER_DESTROY,
-};
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_POSE_IPC_H_
diff --git a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h b/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
deleted file mode 100644
index 39592bb..0000000
--- a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
-#define ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
-
-#include <private/dvr/buffer_hub_queue_client.h>
-
-using android::dvr::ConsumerQueue;
-
-typedef struct DvrPoseClient DvrPoseClient;
-
-namespace android {
-namespace dvr {
-
-int dvrPoseClientGetDataReaderHandle(DvrPoseClient *client, uint64_t data_type,
- ConsumerQueue **queue_out);
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
diff --git a/libs/vr/libvrsensor/latency_model.cpp b/libs/vr/libvrsensor/latency_model.cpp
deleted file mode 100644
index d3a4521..0000000
--- a/libs/vr/libvrsensor/latency_model.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <private/dvr/latency_model.h>
-
-#include <cmath>
-
-namespace android {
-namespace dvr {
-
-LatencyModel::LatencyModel(size_t window_size) : window_size_(window_size) {}
-
-void LatencyModel::AddLatency(int64_t latency_ns) {
- // Not enough samples yet?
- if (num_summed_ < window_size_) {
- // Accumulate.
- latency_sum_ += latency_ns;
-
- // Have enough samples for latency estimate?
- if (++num_summed_ == window_size_) {
- latency_ = latency_sum_ / window_size_;
- }
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libvrsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp
deleted file mode 100644
index 4ff6a09..0000000
--- a/libs/vr/libvrsensor/pose_client.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-#define LOG_TAG "PoseClient"
-#include <dvr/dvr_shared_buffers.h>
-#include <dvr/pose_client.h>
-
-#include <stdint.h>
-
-#include <log/log.h>
-#include <pdx/client.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/file_handle.h>
-#include <private/dvr/buffer_hub_queue_client.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/display_client.h>
-#include <private/dvr/pose-ipc.h>
-#include <private/dvr/shared_buffer_helpers.h>
-
-using android::dvr::ConsumerQueue;
-using android::pdx::LocalHandle;
-using android::pdx::LocalChannelHandle;
-using android::pdx::Status;
-using android::pdx::Transaction;
-
-namespace android {
-namespace dvr {
-namespace {
-
-typedef CPUMappedBroadcastRing<DvrPoseRing> SensorPoseRing;
-
-constexpr static int32_t MAX_CONTROLLERS = 2;
-} // namespace
-
-// PoseClient is a remote interface to the pose service in sensord.
-class PoseClient : public pdx::ClientBase<PoseClient> {
- public:
- ~PoseClient() override {}
-
- // Casts C handle into an instance of this class.
- static PoseClient* FromC(DvrPoseClient* client) {
- return reinterpret_cast<PoseClient*>(client);
- }
-
- // Polls the pose service for the current state and stores it in *state.
- // Returns zero on success, a negative error code otherwise.
- int Poll(DvrPose* state) {
- // Allocate the helper class to access the sensor pose buffer.
- if (sensor_pose_buffer_ == nullptr) {
- sensor_pose_buffer_ = std::make_unique<SensorPoseRing>(
- DvrGlobalBuffers::kSensorPoseBuffer, CPUUsageMode::READ_RARELY);
- }
-
- if (state) {
- if (sensor_pose_buffer_->GetNewest(state)) {
- return 0;
- } else {
- return -EAGAIN;
- }
- }
-
- return -EINVAL;
- }
-
- int GetPose(uint32_t vsync_count, DvrPoseAsync* out_pose) {
- const auto vsync_buffer = GetVsyncBuffer();
- if (vsync_buffer) {
- *out_pose =
- vsync_buffer
- ->vsync_poses[vsync_count & DvrVsyncPoseBuffer::kIndexMask];
- return 0;
- } else {
- return -EAGAIN;
- }
- }
-
- uint32_t GetVsyncCount() {
- const auto vsync_buffer = GetVsyncBuffer();
- if (vsync_buffer) {
- return vsync_buffer->vsync_count;
- }
-
- return 0;
- }
-
- int GetControllerPose(int32_t controller_id, uint32_t vsync_count,
- DvrPoseAsync* out_pose) {
- if (controller_id < 0 || controller_id >= MAX_CONTROLLERS) {
- return -EINVAL;
- }
- if (!controllers_[controller_id].mapped_pose_buffer) {
- int ret = GetControllerRingBuffer(controller_id);
- if (ret < 0)
- return ret;
- }
- *out_pose =
- controllers_[controller_id]
- .mapped_pose_buffer[vsync_count & DvrVsyncPoseBuffer::kIndexMask];
- return 0;
- }
-
- int LogController(bool enable) {
- Transaction trans{*this};
- Status<int> status = trans.Send<int>(DVR_POSE_LOG_CONTROLLER, &enable,
- sizeof(enable), nullptr, 0);
- ALOGE_IF(!status, "Pose LogController() failed because: %s",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- // Freezes the pose to the provided state. Future poll operations will return
- // this state until a different state is frozen or SetMode() is called with a
- // different mode.
- // Returns zero on success, a negative error code otherwise.
- int Freeze(const DvrPose& frozen_state) {
- Transaction trans{*this};
- Status<int> status = trans.Send<int>(DVR_POSE_FREEZE, &frozen_state,
- sizeof(frozen_state), nullptr, 0);
- ALOGE_IF(!status, "Pose Freeze() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- // Sets the data mode for the pose service.
- int SetMode(DvrPoseMode mode) {
- Transaction trans{*this};
- Status<int> status =
- trans.Send<int>(DVR_POSE_SET_MODE, &mode, sizeof(mode), nullptr, 0);
- ALOGE_IF(!status, "Pose SetPoseMode() failed because: %s",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- // Gets the data mode for the pose service.
- int GetMode(DvrPoseMode* out_mode) {
- int mode;
- Transaction trans{*this};
- Status<int> status =
- trans.Send<int>(DVR_POSE_GET_MODE, nullptr, 0, &mode, sizeof(mode));
- ALOGE_IF(!status, "Pose GetPoseMode() failed because: %s",
- status.GetErrorMessage().c_str());
- if (status)
- *out_mode = DvrPoseMode(mode);
- return ReturnStatusOrError(status);
- }
-
- int GetTangoReaderHandle(uint64_t data_type, ConsumerQueue** queue_out) {
- // Get buffer.
- Transaction trans{*this};
- Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>(
- DVR_POSE_GET_TANGO_READER, &data_type, sizeof(data_type), nullptr, 0);
-
- if (!status) {
- ALOGE("PoseClient GetTangoReaderHandle() failed because: %s",
- status.GetErrorMessage().c_str());
- *queue_out = nullptr;
- return -status.error();
- }
-
- std::unique_ptr<ConsumerQueue> consumer_queue =
- ConsumerQueue::Import(status.take());
- *queue_out = consumer_queue.release();
- return 0;
- }
-
- int DataCapture(const DvrPoseDataCaptureRequest* request) {
- Transaction trans{*this};
- Status<int> status = trans.Send<int>(DVR_POSE_DATA_CAPTURE, request,
- sizeof(*request), nullptr, 0);
- ALOGE_IF(!status, "PoseClient DataCapture() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- int DataReaderDestroy(uint64_t data_type) {
- Transaction trans{*this};
- Status<int> status = trans.Send<int>(DVR_POSE_TANGO_READER_DESTROY,
- &data_type, sizeof(data_type), nullptr,
- 0);
- ALOGE_IF(!status, "PoseClient DataReaderDestroy() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- // Enables or disables all pose processing from sensors
- int EnableSensors(bool enabled) {
- Transaction trans{*this};
- Status<int> status = trans.Send<int>(DVR_POSE_SENSORS_ENABLE, &enabled,
- sizeof(enabled), nullptr, 0);
- ALOGE_IF(!status, "Pose EnableSensors() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- int GetRingBuffer(DvrPoseRingBufferInfo* out_info) {
- // First time mapping the buffer?
- const auto vsync_buffer = GetVsyncBuffer();
- if (vsync_buffer) {
- if (out_info) {
- out_info->min_future_count = DvrVsyncPoseBuffer::kMinFutureCount;
- out_info->total_count = DvrVsyncPoseBuffer::kSize;
- out_info->buffer = vsync_buffer->vsync_poses;
- }
- return -EINVAL;
- }
-
- return -EAGAIN;
- }
-
- int GetControllerRingBuffer(int32_t controller_id) {
- if (controller_id < 0 || controller_id >= MAX_CONTROLLERS) {
- return -EINVAL;
- }
- ControllerClientState& client_state = controllers_[controller_id];
- if (client_state.pose_buffer.get()) {
- return 0;
- }
-
- Transaction trans{*this};
- Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>(
- DVR_POSE_GET_CONTROLLER_RING_BUFFER, &controller_id,
- sizeof(controller_id), nullptr, 0);
- if (!status) {
- return -status.error();
- }
-
- auto buffer = ConsumerBuffer::Import(status.take());
- if (!buffer) {
- ALOGE("Pose failed to import ring buffer");
- return -EIO;
- }
- constexpr size_t size = DvrVsyncPoseBuffer::kSize * sizeof(DvrPoseAsync);
- void* addr = nullptr;
- int ret = buffer->GetBlobReadWritePointer(size, &addr);
- if (ret < 0 || !addr) {
- ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, addr);
- return -EIO;
- }
- client_state.pose_buffer.swap(buffer);
- client_state.mapped_pose_buffer = static_cast<const DvrPoseAsync*>(addr);
- ALOGI(
- "Mapped controller %d pose data translation %f,%f,%f quat %f,%f,%f,%f",
- controller_id, client_state.mapped_pose_buffer[0].position[0],
- client_state.mapped_pose_buffer[0].position[1],
- client_state.mapped_pose_buffer[0].position[2],
- client_state.mapped_pose_buffer[0].orientation[0],
- client_state.mapped_pose_buffer[0].orientation[1],
- client_state.mapped_pose_buffer[0].orientation[2],
- client_state.mapped_pose_buffer[0].orientation[3]);
- return 0;
- }
-
- private:
- friend BASE;
-
- // Set up a channel to the pose service.
- PoseClient()
- : BASE(pdx::default_transport::ClientChannelFactory::Create(
- DVR_POSE_SERVICE_CLIENT)) {
- // TODO(eieio): Cache the pose and make timeout 0 so that the API doesn't
- // block while waiting for the pose service to come back up.
- EnableAutoReconnect(kInfiniteTimeout);
- }
-
- PoseClient(const PoseClient&) = delete;
- PoseClient& operator=(const PoseClient&) = delete;
-
- const DvrVsyncPoseBuffer* GetVsyncBuffer() {
- if (mapped_vsync_pose_buffer_ == nullptr) {
- if (vsync_pose_buffer_ == nullptr) {
- // The constructor tries mapping it so we do not need TryMapping after.
- vsync_pose_buffer_ = std::make_unique<CPUMappedBuffer>(
- DvrGlobalBuffers::kVsyncPoseBuffer, CPUUsageMode::READ_OFTEN);
- } else if (vsync_pose_buffer_->IsMapped() == false) {
- vsync_pose_buffer_->TryMapping();
- }
-
- if (vsync_pose_buffer_->IsMapped()) {
- mapped_vsync_pose_buffer_ =
- static_cast<DvrVsyncPoseBuffer*>(vsync_pose_buffer_->Address());
- }
- }
-
- return mapped_vsync_pose_buffer_;
- }
-
- // The vsync pose buffer if already mapped.
- std::unique_ptr<CPUMappedBuffer> vsync_pose_buffer_;
-
- // The direct sensor pose buffer.
- std::unique_ptr<SensorPoseRing> sensor_pose_buffer_;
-
- const DvrVsyncPoseBuffer* mapped_vsync_pose_buffer_ = nullptr;
-
- struct ControllerClientState {
- std::unique_ptr<ConsumerBuffer> pose_buffer;
- const DvrPoseAsync* mapped_pose_buffer = nullptr;
- };
- ControllerClientState controllers_[MAX_CONTROLLERS];
-};
-
-int dvrPoseClientGetDataReaderHandle(DvrPoseClient* client, uint64_t type,
- ConsumerQueue** queue_out) {
- return PoseClient::FromC(client)->GetTangoReaderHandle(type, queue_out);
-}
-
-} // namespace dvr
-} // namespace android
-
-using android::dvr::PoseClient;
-
-extern "C" {
-
-DvrPoseClient* dvrPoseClientCreate() {
- auto* client = PoseClient::Create().release();
- return reinterpret_cast<DvrPoseClient*>(client);
-}
-
-void dvrPoseClientDestroy(DvrPoseClient* client) {
- delete PoseClient::FromC(client);
-}
-
-int dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count,
- DvrPoseAsync* out_pose) {
- return PoseClient::FromC(client)->GetPose(vsync_count, out_pose);
-}
-
-uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client) {
- return PoseClient::FromC(client)->GetVsyncCount();
-}
-
-int dvrPoseClientGetController(DvrPoseClient* client, int32_t controller_id,
- uint32_t vsync_count, DvrPoseAsync* out_pose) {
- return PoseClient::FromC(client)->GetControllerPose(controller_id,
- vsync_count, out_pose);
-}
-
-int dvrPoseClientLogController(DvrPoseClient* client, bool enable) {
- return PoseClient::FromC(client)->LogController(enable);
-}
-
-int dvrPoseClientPoll(DvrPoseClient* client, DvrPose* state) {
- return PoseClient::FromC(client)->Poll(state);
-}
-
-int dvrPoseClientFreeze(DvrPoseClient* client, const DvrPose* frozen_state) {
- return PoseClient::FromC(client)->Freeze(*frozen_state);
-}
-
-int dvrPoseClientModeSet(DvrPoseClient* client, DvrPoseMode mode) {
- return PoseClient::FromC(client)->SetMode(mode);
-}
-
-int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode) {
- return PoseClient::FromC(client)->GetMode(mode);
-}
-
-int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled) {
- return PoseClient::FromC(client)->EnableSensors(enabled);
-}
-
-int dvrPoseClientDataCapture(DvrPoseClient* client,
- const DvrPoseDataCaptureRequest* request) {
- return PoseClient::FromC(client)->DataCapture(request);
-}
-
-int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, uint64_t data_type) {
- return PoseClient::FromC(client)->DataReaderDestroy(data_type);
-}
-
-} // extern "C"
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index b4b617e..8d5d883 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -15,6 +15,9 @@
"name": "inputflinger_tests"
},
{
+ "name": "libchrome-gestures_test"
+ },
+ {
"name": "libpalmrejection_test"
},
{
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 564acc0..f634ce7 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -4721,10 +4721,13 @@
updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
- if (mLastHoverWindowHandle &&
- std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
- windowHandles.end()) {
- mLastHoverWindowHandle = nullptr;
+ if (mLastHoverWindowHandle) {
+ const WindowInfo* lastHoverWindowInfo = mLastHoverWindowHandle->getInfo();
+ if (lastHoverWindowInfo->displayId == displayId &&
+ std::find(windowHandles.begin(), windowHandles.end(), mLastHoverWindowHandle) ==
+ windowHandles.end()) {
+ mLastHoverWindowHandle = nullptr;
+ }
}
std::optional<FocusResolver::FocusChanges> changes =
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.cpp b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
index 76a87bb..40e9a3c 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.cpp
@@ -80,7 +80,7 @@
void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- if (mParameters.mode == Parameters::MODE_POINTER) {
+ if (mParameters.mode == Parameters::Mode::POINTER) {
float minX, minY, maxX, maxY;
if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
@@ -135,12 +135,12 @@
// Configure device mode.
switch (mParameters.mode) {
- case Parameters::MODE_POINTER_RELATIVE:
+ case Parameters::Mode::POINTER_RELATIVE:
// Should not happen during first time configuration.
ALOGE("Cannot start a device in MODE_POINTER_RELATIVE, starting in MODE_POINTER");
- mParameters.mode = Parameters::MODE_POINTER;
+ mParameters.mode = Parameters::Mode::POINTER;
[[fallthrough]];
- case Parameters::MODE_POINTER:
+ case Parameters::Mode::POINTER:
mSource = AINPUT_SOURCE_MOUSE;
mXPrecision = 1.0f;
mYPrecision = 1.0f;
@@ -148,7 +148,7 @@
mYScale = 1.0f;
mPointerController = getContext()->getPointerController(getDeviceId());
break;
- case Parameters::MODE_NAVIGATION:
+ case Parameters::Mode::NAVIGATION:
mSource = AINPUT_SOURCE_TRACKBALL;
mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
@@ -161,12 +161,13 @@
mHWheelScale = 1.0f;
}
- const bool configurePointerCapture = (!changes && config->pointerCaptureRequest.enable) ||
- (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ const bool configurePointerCapture = mParameters.mode != Parameters::Mode::NAVIGATION &&
+ ((!changes && config->pointerCaptureRequest.enable) ||
+ (changes & InputReaderConfiguration::CHANGE_POINTER_CAPTURE));
if (configurePointerCapture) {
if (config->pointerCaptureRequest.enable) {
- if (mParameters.mode == Parameters::MODE_POINTER) {
- mParameters.mode = Parameters::MODE_POINTER_RELATIVE;
+ if (mParameters.mode == Parameters::Mode::POINTER) {
+ mParameters.mode = Parameters::Mode::POINTER_RELATIVE;
mSource = AINPUT_SOURCE_MOUSE_RELATIVE;
// Keep PointerController around in order to preserve the pointer position.
mPointerController->fade(PointerControllerInterface::Transition::IMMEDIATE);
@@ -174,8 +175,8 @@
ALOGE("Cannot request pointer capture, device is not in MODE_POINTER");
}
} else {
- if (mParameters.mode == Parameters::MODE_POINTER_RELATIVE) {
- mParameters.mode = Parameters::MODE_POINTER;
+ if (mParameters.mode == Parameters::Mode::POINTER_RELATIVE) {
+ mParameters.mode = Parameters::Mode::POINTER;
mSource = AINPUT_SOURCE_MOUSE;
} else {
ALOGE("Cannot release pointer capture, device is not in MODE_POINTER_RELATIVE");
@@ -190,8 +191,8 @@
if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED) ||
configurePointerCapture) {
- if (config->pointerCaptureRequest.enable) {
- // Disable any acceleration or scaling when Pointer Capture is enabled.
+ if (mParameters.mode == Parameters::Mode::POINTER_RELATIVE) {
+ // Disable any acceleration or scaling for the pointer when Pointer Capture is enabled.
mPointerVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
mWheelXVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
mWheelYVelocityControl.setParameters(FLAT_VELOCITY_CONTROL_PARAMS);
@@ -202,7 +203,8 @@
}
}
- if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO) ||
+ configurePointerCapture) {
mOrientation = DISPLAY_ORIENTATION_0;
const bool isOrientedDevice =
(mParameters.orientationAware && mParameters.hasAssociatedDisplay);
@@ -211,8 +213,9 @@
// anything if the device is already orientation-aware. If the device is not
// orientation-aware, then we need to apply the inverse rotation of the display so that
// when the display rotation is applied later as a part of the per-window transform, we
- // get the expected screen coordinates.
- if (!isOrientedDevice) {
+ // get the expected screen coordinates. When pointer capture is enabled, we do not apply any
+ // rotations and report values directly from the input device.
+ if (!isOrientedDevice && mParameters.mode != Parameters::Mode::POINTER_RELATIVE) {
std::optional<DisplayViewport> internalViewport =
config->getDisplayViewportByType(ViewportType::INTERNAL);
if (internalViewport) {
@@ -225,12 +228,12 @@
}
void CursorInputMapper::configureParameters() {
- mParameters.mode = Parameters::MODE_POINTER;
+ mParameters.mode = Parameters::Mode::POINTER;
String8 cursorModeString;
if (getDeviceContext().getConfiguration().tryGetProperty(String8("cursor.mode"),
cursorModeString)) {
if (cursorModeString == "navigation") {
- mParameters.mode = Parameters::MODE_NAVIGATION;
+ mParameters.mode = Parameters::Mode::NAVIGATION;
} else if (cursorModeString != "pointer" && cursorModeString != "default") {
ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
}
@@ -241,7 +244,7 @@
mParameters.orientationAware);
mParameters.hasAssociatedDisplay = false;
- if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
+ if (mParameters.mode == Parameters::Mode::POINTER || mParameters.orientationAware) {
mParameters.hasAssociatedDisplay = true;
}
}
@@ -250,21 +253,7 @@
dump += INDENT3 "Parameters:\n";
dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
toString(mParameters.hasAssociatedDisplay));
-
- switch (mParameters.mode) {
- case Parameters::MODE_POINTER:
- dump += INDENT4 "Mode: pointer\n";
- break;
- case Parameters::MODE_POINTER_RELATIVE:
- dump += INDENT4 "Mode: relative pointer\n";
- break;
- case Parameters::MODE_NAVIGATION:
- dump += INDENT4 "Mode: navigation\n";
- break;
- default:
- ALOG_ASSERT(false);
- }
-
+ dump += StringPrintf(INDENT4 "Mode: %s\n", ftl::enum_string(mParameters.mode).c_str());
dump += StringPrintf(INDENT4 "OrientationAware: %s\n", toString(mParameters.orientationAware));
}
@@ -490,7 +479,7 @@
std::optional<int32_t> CursorInputMapper::getAssociatedDisplayId() {
if (mParameters.hasAssociatedDisplay) {
- if (mParameters.mode == Parameters::MODE_POINTER) {
+ if (mParameters.mode == Parameters::Mode::POINTER) {
return std::make_optional(mPointerController->getDisplayId());
} else {
// If the device is orientationAware and not a mouse,
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index c84c6c4..75aeffb 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -74,10 +74,17 @@
// Immutable configuration parameters.
struct Parameters {
- enum Mode {
- MODE_POINTER,
- MODE_POINTER_RELATIVE,
- MODE_NAVIGATION,
+ enum class Mode {
+ // In POINTER mode, the device is a mouse that controls the mouse cursor on the screen,
+ // reporting absolute screen locations using SOURCE_MOUSE.
+ POINTER,
+ // A mouse device in POINTER mode switches to the POINTER_RELATIVE mode when Pointer
+ // Capture is enabled, and reports relative values only using SOURCE_MOUSE_RELATIVE.
+ POINTER_RELATIVE,
+ // A device in NAVIGATION mode emits relative values using SOURCE_TRACKBALL.
+ NAVIGATION,
+
+ ftl_last = NAVIGATION,
};
Mode mode;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index df43071..bb8e566 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -2131,6 +2131,59 @@
ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
}
+TEST_F(InputDispatcherTest, HoverEnterMoveRemoveWindowsInSecondDisplay) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> windowDefaultDisplay =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "DefaultDisplay",
+ ADISPLAY_ID_DEFAULT);
+ windowDefaultDisplay->setFrame(Rect(0, 0, 600, 800));
+ sp<FakeWindowHandle> windowSecondDisplay =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "SecondDisplay",
+ SECOND_DISPLAY_ID);
+ windowSecondDisplay->setFrame(Rect(0, 0, 600, 800));
+
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowDefaultDisplay}},
+ {SECOND_DISPLAY_ID, {windowSecondDisplay}}});
+
+ // Set cursor position in window in default display and check that hover enter and move
+ // events are generated.
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+ AINPUT_SOURCE_MOUSE)
+ .displayId(ADISPLAY_ID_DEFAULT)
+ .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(300)
+ .y(600))
+ .build()));
+ windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_ENTER,
+ ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
+ windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
+ ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
+
+ // Remove all windows in secondary display and check that no event happens on window in
+ // primary display.
+ mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
+ windowDefaultDisplay->assertNoEvents();
+
+ // Move cursor position in window in default display and check that only hover move
+ // event is generated and not hover enter event.
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowDefaultDisplay}},
+ {SECOND_DISPLAY_ID, {windowSecondDisplay}}});
+ ASSERT_EQ(InputEventInjectionResult::SUCCEEDED,
+ injectMotionEvent(mDispatcher,
+ MotionEventBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+ AINPUT_SOURCE_MOUSE)
+ .displayId(ADISPLAY_ID_DEFAULT)
+ .pointer(PointerBuilder(0, AMOTION_EVENT_TOOL_TYPE_MOUSE)
+ .x(400)
+ .y(700))
+ .build()));
+ windowDefaultDisplay->consumeEvent(AINPUT_EVENT_TYPE_MOTION, AMOTION_EVENT_ACTION_HOVER_MOVE,
+ ADISPLAY_ID_DEFAULT, 0 /* expectedFlag */);
+ windowDefaultDisplay->assertNoEvents();
+}
+
TEST_F(InputDispatcherTest, DispatchMouseEventsUnderCursor) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index db46699..5d6ec74 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -4974,6 +4974,48 @@
ASSERT_EQ(20, args.pointerCoords[0].getY());
}
+TEST_F(CursorInputMapperTest, PointerCaptureDisablesOrientationChanges) {
+ addConfigurationProperty("cursor.mode", "pointer");
+ CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
+
+ NotifyDeviceResetArgs resetArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
+ ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
+ ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
+
+ // Ensure the display is rotated.
+ prepareDisplay(DISPLAY_ORIENTATION_90);
+
+ NotifyMotionArgs args;
+
+ // Verify that the coordinates are rotated.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
+ ASSERT_EQ(-20, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X));
+ ASSERT_EQ(10, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y));
+
+ // Enable Pointer Capture.
+ mFakePolicy->setPointerCapture(true);
+ configureDevice(InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
+ NotifyPointerCaptureChangedArgs captureArgs;
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyCaptureWasCalled(&captureArgs));
+ ASSERT_TRUE(captureArgs.request.enable);
+
+ // Move and verify rotation is not applied.
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_X, 10);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_REL, REL_Y, 20);
+ process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
+ ASSERT_EQ(AINPUT_SOURCE_MOUSE_RELATIVE, args.source);
+ ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+ ASSERT_EQ(10, args.pointerCoords[0].getX());
+ ASSERT_EQ(20, args.pointerCoords[0].getY());
+}
+
TEST_F(CursorInputMapperTest, Process_ShouldHandleDisplayId) {
CursorInputMapper& mapper = addMapperAndConfigure<CursorInputMapper>();
diff --git a/services/sensorservice/aidl/Android.bp b/services/sensorservice/aidl/Android.bp
index bbf49da..34d1de7 100644
--- a/services/sensorservice/aidl/Android.bp
+++ b/services/sensorservice/aidl/Android.bp
@@ -7,7 +7,7 @@
default_applicable_licenses: ["frameworks_native_license"],
}
-cc_library_shared {
+cc_library {
name: "libsensorserviceaidl",
srcs: [
"EventQueue.cpp",
@@ -15,6 +15,7 @@
"SensorManager.cpp",
"utils.cpp",
],
+ host_supported: true,
cflags: [
"-Wall",
"-Werror",
diff --git a/services/sensorservice/aidl/EventQueue.cpp b/services/sensorservice/aidl/EventQueue.cpp
index d4e8906..c394709 100644
--- a/services/sensorservice/aidl/EventQueue.cpp
+++ b/services/sensorservice/aidl/EventQueue.cpp
@@ -34,7 +34,7 @@
std::shared_ptr<IEventQueueCallback> callback)
: mQueue(queue), mCallback(callback) {}
- int handleEvent(__unused int fd, __unused int events, __unused void* data) {
+ int handleEvent(int /* fd */, int /* events */, void* /* data */) {
ASensorEvent event;
ssize_t actual;
@@ -66,7 +66,6 @@
new EventQueueLooperCallback(internalQueue, callback), nullptr);
}
-// FIXME why was this on onLastStrongRef instead of dtor?
EventQueue::~EventQueue() {
mLooper->removeFd(mInternalQueue->getFd());
}
diff --git a/services/sensorservice/aidl/SensorManager.cpp b/services/sensorservice/aidl/SensorManager.cpp
index 6d8d574..9b03344 100644
--- a/services/sensorservice/aidl/SensorManager.cpp
+++ b/services/sensorservice/aidl/SensorManager.cpp
@@ -201,7 +201,7 @@
// if thread not initialized, start thread
mStopThread = false;
std::thread pollThread{[&stopThread = mStopThread, looper = mLooper, javaVm = mJavaVm] {
- struct sched_param p = {0};
+ struct sched_param p = {};
p.sched_priority = 10;
if (sched_setscheduler(0 /* current thread*/, SCHED_FIFO, &p) != 0) {
LOG(ERROR) << "Could not use SCHED_FIFO for looper thread: " << strerror(errno);
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
new file mode 100644
index 0000000..0d6e476
--- /dev/null
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -0,0 +1,52 @@
+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_fuzz {
+ name: "libsensorserviceaidl_fuzzer",
+ defaults: [
+ "service_fuzzer_defaults",
+ ],
+ host_supported: true,
+ static_libs: [
+ "libsensorserviceaidl",
+ "libpermission",
+ "android.frameworks.sensorservice-V1-ndk",
+ "android.hardware.sensors-V1-convert",
+ "android.hardware.sensors-V1-ndk",
+ "android.hardware.common-V2-ndk",
+ "libsensor",
+ "libfakeservicemanager",
+ "libcutils",
+ "liblog",
+ ],
+ srcs: [
+ "fuzzer.cpp",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-sensors@google.com",
+ "devinmoore@google.com",
+ ],
+ },
+ sanitize: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ ],
+ diag: {
+ misc_undefined: [
+ "signed-integer-overflow",
+ "unsigned-integer-overflow",
+ ],
+ },
+ address: true,
+ integer_overflow: true,
+ },
+
+}
diff --git a/services/sensorservice/aidl/fuzzer/fuzzer.cpp b/services/sensorservice/aidl/fuzzer/fuzzer.cpp
new file mode 100644
index 0000000..1b63d76
--- /dev/null
+++ b/services/sensorservice/aidl/fuzzer/fuzzer.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2022 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 <fuzzbinder/libbinder_ndk_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <ServiceManager.h>
+#include <android-base/logging.h>
+#include <android/binder_interface_utils.h>
+#include <fuzzbinder/random_binder.h>
+#include <sensorserviceaidl/SensorManagerAidl.h>
+
+using android::fuzzService;
+using android::frameworks::sensorservice::implementation::SensorManagerAidl;
+using ndk::SharedRefBase;
+
+[[clang::no_destroy]] static std::once_flag gSmOnce;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ static android::sp<android::ServiceManager> fakeServiceManager = new android::ServiceManager();
+ std::call_once(gSmOnce, [&] { setDefaultServiceManager(fakeServiceManager); });
+ fakeServiceManager->clear();
+
+ FuzzedDataProvider fdp(data, size);
+ android::sp<android::IBinder> binder = android::getRandomBinder(&fdp);
+ if (binder == nullptr) {
+ // Nothing to do if we get a null binder. It will cause SensorManager to
+ // hang while trying to get sensorservice.
+ return 0;
+ }
+
+ CHECK(android::NO_ERROR == fakeServiceManager->addService(android::String16("sensorservice"),
+ binder));
+
+ std::shared_ptr<SensorManagerAidl> sensorService =
+ ndk::SharedRefBase::make<SensorManagerAidl>(nullptr);
+
+ fuzzService(sensorService->asBinder().get(), std::move(fdp));
+
+ return 0;
+}
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
deleted file mode 100644
index 80e9a3c..0000000
--- a/services/vr/hardware_composer/Android.bp
+++ /dev/null
@@ -1,134 +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_library_shared {
- name: "libvr_hwc-hal",
-
- system_ext_specific: true,
-
- srcs: [
- "impl/vr_hwc.cpp",
- "impl/vr_composer_client.cpp",
- ],
-
- static_libs: [
- "libbroadcastring",
- "libdisplay",
- ],
-
- shared_libs: [
- "android.frameworks.vr.composer@2.0",
- "android.hardware.graphics.composer@2.1",
- "android.hardware.graphics.composer@2.2",
- "android.hardware.graphics.composer@2.3",
- "android.hardware.graphics.composer@2.1-resources",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@4.0",
- "libbase",
- "libbufferhubqueue",
- "libbinder",
- "libcutils",
- "libfmq",
- "libhardware",
- "libhidlbase",
- "liblog",
- "libsync",
- "libui",
- "libutils",
- "libpdx_default_transport",
- ],
-
- header_libs: [
- "android.hardware.graphics.composer@2.1-command-buffer",
- "android.hardware.graphics.composer@2.3-hal",
- ],
-
- export_header_lib_headers: [
- "android.hardware.graphics.composer@2.3-hal",
- ],
-
- export_static_lib_headers: [
- "libdisplay",
- ],
-
- export_shared_lib_headers: [
- "android.frameworks.vr.composer@2.0",
- "android.hardware.graphics.composer@2.1",
- "android.hardware.graphics.composer@2.2",
- "android.hardware.graphics.composer@2.3",
- ],
-
- export_include_dirs: ["."],
-
- cflags: [
- "-DLOG_TAG=\"vr_hwc\"",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- "-Wall",
- "-Werror",
- "-Wno-error=unused-private-field",
- // Warnings in vr_hwc.cpp to be fixed after sync of goog/master.
- "-Wno-sign-compare",
- "-Wno-unused-parameter",
- ],
-
-}
-
-cc_library_static {
- name: "libvr_hwc-impl",
- srcs: [
- "vr_composer.cpp",
- ],
- static_libs: [
- "libvr_hwc-binder",
- ],
- shared_libs: [
- "libbase",
- "libbinder",
- "liblog",
- "libui",
- "libutils",
- "libvr_hwc-hal",
- ],
- export_shared_lib_headers: [
- "libvr_hwc-hal",
- ],
- cflags: [
- "-DLOG_TAG=\"vr_hwc\"",
- "-Wall",
- "-Werror",
- ],
-}
-
-cc_test {
- name: "vr_hwc_test",
- gtest: true,
- srcs: ["tests/vr_composer_test.cpp"],
- static_libs: [
- "libgtest",
- "libvr_hwc-impl",
- // NOTE: This needs to be included after the *-impl lib otherwise the
- // symbols in the *-binder library get optimized out.
- "libvr_hwc-binder",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- // warnings in vr_composer_test.cpp to be fixed after merge of goog/master
- "-Wno-sign-compare",
- "-Wno-unused-parameter",
- ],
- shared_libs: [
- "libbase",
- "libbinder",
- "liblog",
- "libui",
- "libutils",
- ],
-}
diff --git a/services/vr/hardware_composer/aidl/Android.bp b/services/vr/hardware_composer/aidl/Android.bp
deleted file mode 100644
index fa71ed7..0000000
--- a/services/vr/hardware_composer/aidl/Android.bp
+++ /dev/null
@@ -1,36 +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_library_static {
- name: "libvr_hwc-binder",
- srcs: [
- "android/dvr/IVrComposer.aidl",
- "android/dvr/IVrComposerCallback.aidl",
- "android/dvr/parcelable_composer_frame.cpp",
- "android/dvr/parcelable_composer_layer.cpp",
- "android/dvr/parcelable_unique_fd.cpp",
- ],
- aidl: {
- local_include_dirs: ["."],
- export_aidl_headers: true,
- },
- export_include_dirs: ["."],
-
- cflags: [
- "-Wall",
- "-Werror",
- ],
-
- shared_libs: [
- "libbinder",
- "libui",
- "libutils",
- "libvr_hwc-hal",
- ],
-}
diff --git a/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl b/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl
deleted file mode 100644
index be1ec5b..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-package android.dvr;
-
-import android.dvr.IVrComposerCallback;
-
-/**
- * Service interface exposed by VR HWC exposed to system apps which allows one
- * system app to connect to get SurfaceFlinger's outputs (all displays). This
- * is active when SurfaceFlinger is in VR mode, where all 2D output is
- * redirected to VR HWC.
- *
- * @hide */
-interface IVrComposer
-{
- const String SERVICE_NAME = "vr_hwc";
-
- /**
- * Registers a callback used to receive frame notifications.
- */
- void registerObserver(in IVrComposerCallback callback);
-
- /**
- * Clears a previously registered frame notification callback.
- */
- void clearObserver();
-}
diff --git a/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl b/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl
deleted file mode 100644
index aa70de1..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-package android.dvr;
-
-import android.dvr.ParcelableComposerFrame;
-import android.dvr.ParcelableUniqueFd;
-
-/**
- * A system app will implement and register this callback with VRComposer
- * to receive the layers SurfaceFlinger presented when in VR mode.
- *
- * @hide */
-interface IVrComposerCallback {
- /**
- * Called by the VR HWC service when a new frame is ready to be presented.
- *
- * @param frame The new frame VR HWC wants to present.
- * @return A fence FD used to signal when the previous frame is no longer
- * used by the client. This may be an invalid fence (-1) if the client is not
- * using the previous frame, in which case the previous frame may be re-used
- * at any point in time.
- */
- ParcelableUniqueFd onNewFrame(in ParcelableComposerFrame frame);
-}
diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl
deleted file mode 100644
index 84abc19..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.dvr;
-
-parcelable ParcelableComposerFrame cpp_header "android/dvr/parcelable_composer_frame.h";
diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl
deleted file mode 100644
index a200345..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.dvr;
-
-parcelable ParcelableComposerLayer cpp_header "android/dvr/parcelable_composer_layer.h";
diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl
deleted file mode 100644
index eee9d13..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl
+++ /dev/null
@@ -1,3 +0,0 @@
-package android.dvr;
-
-parcelable ParcelableUniqueFd cpp_header "android/dvr/parcelable_unique_fd.h";
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp
deleted file mode 100644
index db7d5dc..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-#include "aidl/android/dvr/parcelable_composer_frame.h"
-
-#include <binder/Parcel.h>
-
-#include "aidl/android/dvr/parcelable_composer_layer.h"
-
-namespace android {
-namespace dvr {
-
-ParcelableComposerFrame::ParcelableComposerFrame() {}
-
-ParcelableComposerFrame::ParcelableComposerFrame(
- const ComposerView::Frame& frame)
- : frame_(frame) {}
-
-ParcelableComposerFrame::~ParcelableComposerFrame() {}
-
-status_t ParcelableComposerFrame::writeToParcel(Parcel* parcel) const {
- status_t ret = parcel->writeUint64(frame_.display_id);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(frame_.display_width);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(frame_.display_height);
- if (ret != OK) return ret;
-
- ret = parcel->writeBool(frame_.removed);
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(static_cast<uint32_t>(frame_.active_config));
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(static_cast<uint32_t>(frame_.color_mode));
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(static_cast<uint32_t>(frame_.power_mode));
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(static_cast<uint32_t>(frame_.vsync_enabled));
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(frame_.color_transform_hint);
- if (ret != OK) return ret;
-
- for(size_t i = 0; i < 16; i++) {
- ret = parcel->writeFloat(frame_.color_transform[i]);
- if (ret != OK) return ret;
- }
-
- std::vector<ParcelableComposerLayer> layers;
- for (size_t i = 0; i < frame_.layers.size(); ++i)
- layers.push_back(ParcelableComposerLayer(frame_.layers[i]));
-
- ret = parcel->writeParcelableVector(layers);
-
- return ret;
-}
-
-status_t ParcelableComposerFrame::readFromParcel(const Parcel* parcel) {
- status_t ret = parcel->readUint64(&frame_.display_id);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&frame_.display_width);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&frame_.display_height);
- if (ret != OK) return ret;
-
- ret = parcel->readBool(&frame_.removed);
- if (ret != OK) return ret;
-
- uint32_t value;
- ret = parcel->readUint32(&value);
- if (ret != OK) return ret;
- frame_.active_config = static_cast<Config>(value);
-
- ret = parcel->readUint32(&value);
- if (ret != OK) return ret;
- frame_.color_mode = static_cast<ColorMode>(value);
-
- ret = parcel->readUint32(&value);
- if (ret != OK) return ret;
- frame_.power_mode = static_cast<IComposerClient::PowerMode>(value);
-
- ret = parcel->readUint32(&value);
- if (ret != OK) return ret;
- frame_.vsync_enabled = static_cast<IComposerClient::Vsync>(value);
-
- ret = parcel->readInt32(&frame_.color_transform_hint);
- if (ret != OK) return ret;
-
- for(size_t i = 0; i < 16; i++) {
- ret = parcel->readFloat(&frame_.color_transform[i]);
- if (ret != OK) return ret;
- }
-
- std::vector<ParcelableComposerLayer> layers;
- ret = parcel->readParcelableVector(&layers);
- if (ret != OK) return ret;
-
- frame_.layers.clear();
- for (size_t i = 0; i < layers.size(); ++i)
- frame_.layers.push_back(layers[i].layer());
-
- return ret;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
deleted file mode 100644
index a82df7f..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H
-
-#include <binder/Parcelable.h>
-#include <impl/vr_hwc.h>
-
-namespace android {
-namespace dvr {
-
-class ParcelableComposerFrame : public Parcelable {
- public:
- ParcelableComposerFrame();
- explicit ParcelableComposerFrame(const ComposerView::Frame& frame);
- ~ParcelableComposerFrame() override;
-
- ComposerView::Frame frame() const { return frame_; }
-
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
-
- private:
- ComposerView::Frame frame_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
deleted file mode 100644
index c3621eb..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-#include "aidl/android/dvr/parcelable_composer_layer.h"
-
-#include <binder/Parcel.h>
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-
-namespace android {
-namespace dvr {
-
-ParcelableComposerLayer::ParcelableComposerLayer() {}
-
-ParcelableComposerLayer::ParcelableComposerLayer(
- const ComposerView::ComposerLayer& layer) : layer_(layer) {}
-
-ParcelableComposerLayer::~ParcelableComposerLayer() {}
-
-status_t ParcelableComposerLayer::writeToParcel(Parcel* parcel) const {
- status_t ret = parcel->writeUint64(layer_.id);
- if (ret != OK) return ret;
-
- ret = parcel->write(*layer_.buffer);
- if (ret != OK) return ret;
-
- ret = parcel->writeBool(layer_.fence->isValid());
- if (ret != OK) return ret;
-
- if (layer_.fence->isValid()) {
- ret = parcel->writeFileDescriptor(layer_.fence->dup(), true);
- if (ret != OK) return ret;
- }
-
- ret = parcel->writeInt32(layer_.display_frame.left);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.display_frame.top);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.display_frame.right);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.display_frame.bottom);
- if (ret != OK) return ret;
-
- ret = parcel->writeFloat(layer_.crop.left);
- if (ret != OK) return ret;
-
- ret = parcel->writeFloat(layer_.crop.top);
- if (ret != OK) return ret;
-
- ret = parcel->writeFloat(layer_.crop.right);
- if (ret != OK) return ret;
-
- ret = parcel->writeFloat(layer_.crop.bottom);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(static_cast<int32_t>(layer_.blend_mode));
- if (ret != OK) return ret;
-
- ret = parcel->writeFloat(layer_.alpha);
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(layer_.type);
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(layer_.app_id);
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(layer_.z_order);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.cursor_x);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.cursor_y);
- if (ret != OK) return ret;
-
- uint32_t color = layer_.color.r |
- (static_cast<uint32_t>(layer_.color.g) << 8) |
- (static_cast<uint32_t>(layer_.color.b) << 16) |
- (static_cast<uint32_t>(layer_.color.a) << 24);
- ret = parcel->writeUint32(color);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.dataspace);
- if (ret != OK) return ret;
-
- ret = parcel->writeInt32(layer_.transform);
- if (ret != OK) return ret;
-
- ret = parcel->writeUint32(static_cast<uint32_t>(layer_.visible_regions.size()));
- if (ret != OK) return ret;
-
- for (auto& rect: layer_.visible_regions) {
- ret = parcel->writeInt32(rect.left);
- ret = parcel->writeInt32(rect.top);
- ret = parcel->writeInt32(rect.right);
- ret = parcel->writeInt32(rect.bottom);
- if (ret != OK) return ret;
- }
-
- ret = parcel->writeUint32(static_cast<uint32_t>(layer_.damaged_regions.size()));
- if (ret != OK) return ret;
-
- for (auto& rect: layer_.damaged_regions) {
- ret = parcel->writeInt32(rect.left);
- ret = parcel->writeInt32(rect.top);
- ret = parcel->writeInt32(rect.right);
- ret = parcel->writeInt32(rect.bottom);
- if (ret != OK) return ret;
- }
-
- return OK;
-}
-
-status_t ParcelableComposerLayer::readFromParcel(const Parcel* parcel) {
- status_t ret = parcel->readUint64(&layer_.id);
- if (ret != OK) return ret;
-
- layer_.buffer = new GraphicBuffer();
- ret = parcel->read(*layer_.buffer);
- if (ret != OK) {
- layer_.buffer.clear();
- return ret;
- }
-
- bool has_fence = 0;
- ret = parcel->readBool(&has_fence);
- if (ret != OK) return ret;
-
- if (has_fence)
- layer_.fence = new Fence(dup(parcel->readFileDescriptor()));
- else
- layer_.fence = new Fence();
-
- ret = parcel->readInt32(&layer_.display_frame.left);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.display_frame.top);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.display_frame.right);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.display_frame.bottom);
- if (ret != OK) return ret;
-
- ret = parcel->readFloat(&layer_.crop.left);
- if (ret != OK) return ret;
-
- ret = parcel->readFloat(&layer_.crop.top);
- if (ret != OK) return ret;
-
- ret = parcel->readFloat(&layer_.crop.right);
- if (ret != OK) return ret;
-
- ret = parcel->readFloat(&layer_.crop.bottom);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(reinterpret_cast<int32_t*>(&layer_.blend_mode));
- if (ret != OK) return ret;
-
- ret = parcel->readFloat(&layer_.alpha);
- if (ret != OK) return ret;
-
- ret = parcel->readUint32(&layer_.type);
- if (ret != OK) return ret;
-
- ret = parcel->readUint32(&layer_.app_id);
- if (ret != OK) return ret;
-
- ret = parcel->readUint32(&layer_.z_order);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.cursor_x);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.cursor_y);
- if (ret != OK) return ret;
-
- uint32_t color;
- ret = parcel->readUint32(&color);
- if (ret != OK) return ret;
- layer_.color.r = color & 0xFF;
- layer_.color.g = (color >> 8) & 0xFF;
- layer_.color.b = (color >> 16) & 0xFF;
- layer_.color.a = (color >> 24) & 0xFF;
-
- ret = parcel->readInt32(&layer_.dataspace);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&layer_.transform);
- if (ret != OK) return ret;
-
- uint32_t size;
- ret = parcel->readUint32(&size);
- if (ret != OK) return ret;
-
- for(size_t i = 0; i < size; i++) {
- hwc_rect_t rect;
- ret = parcel->readInt32(&rect.left);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.top);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.right);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.bottom);
- if (ret != OK) return ret;
-
- layer_.visible_regions.push_back(rect);
- }
-
- ret = parcel->readUint32(&size);
- if (ret != OK) return ret;
-
- for(size_t i = 0; i < size; i++) {
- hwc_rect_t rect;
- ret = parcel->readInt32(&rect.left);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.top);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.right);
- if (ret != OK) return ret;
-
- ret = parcel->readInt32(&rect.bottom);
- if (ret != OK) return ret;
-
- layer_.damaged_regions.push_back(rect);
- }
-
- return OK;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
deleted file mode 100644
index 6d2ac09..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H
-
-#include <binder/Parcelable.h>
-#include <impl/vr_hwc.h>
-
-#include <memory>
-
-namespace android {
-namespace dvr {
-
-class ParcelableComposerLayer : public Parcelable {
- public:
- ParcelableComposerLayer();
- explicit ParcelableComposerLayer(const ComposerView::ComposerLayer& layer);
- ~ParcelableComposerLayer() override;
-
- ComposerView::ComposerLayer layer() const { return layer_; }
-
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
-
- private:
- ComposerView::ComposerLayer layer_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp
deleted file mode 100644
index 9486f3c..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "android/dvr/parcelable_unique_fd.h"
-
-#include <binder/Parcel.h>
-
-namespace android {
-namespace dvr {
-
-ParcelableUniqueFd::ParcelableUniqueFd() {}
-
-ParcelableUniqueFd::ParcelableUniqueFd(const base::unique_fd& fence)
- : fence_(dup(fence.get())) {}
-
-ParcelableUniqueFd::~ParcelableUniqueFd() {}
-
-status_t ParcelableUniqueFd::writeToParcel(Parcel* parcel) const {
- status_t ret = parcel->writeBool(fence_.get() >= 0);
- if (ret != OK) return ret;
-
- if (fence_.get() >= 0)
- ret = parcel->writeUniqueFileDescriptor(fence_);
-
- return ret;
-}
-
-status_t ParcelableUniqueFd::readFromParcel(const Parcel* parcel) {
- bool has_fence = 0;
- status_t ret = parcel->readBool(&has_fence);
- if (ret != OK) return ret;
-
- if (has_fence)
- ret = parcel->readUniqueFileDescriptor(&fence_);
-
- return ret;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
deleted file mode 100644
index c4216f6..0000000
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H
-
-#include <android-base/unique_fd.h>
-#include <binder/Parcelable.h>
-
-namespace android {
-namespace dvr {
-
-// Provide a wrapper to serialized base::unique_fd. The wrapper also handles the
-// case where the FD is invalid (-1), unlike FileDescriptor which expects a
-// valid FD.
-class ParcelableUniqueFd : public Parcelable {
- public:
- ParcelableUniqueFd();
- explicit ParcelableUniqueFd(const base::unique_fd& fence);
- ~ParcelableUniqueFd() override;
-
- void set_fence(const base::unique_fd& fence) {
- fence_.reset(dup(fence.get()));
- }
- base::unique_fd fence() const { return base::unique_fd(dup(fence_.get())); }
-
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
-
- private:
- base::unique_fd fence_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H
diff --git a/services/vr/hardware_composer/impl/vr_composer_client.cpp b/services/vr/hardware_composer/impl/vr_composer_client.cpp
deleted file mode 100644
index dd1603d..0000000
--- a/services/vr/hardware_composer/impl/vr_composer_client.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright 2016 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 <android/frameworks/vr/composer/2.0/IVrComposerClient.h>
-#include <hardware/gralloc.h>
-#include <hardware/gralloc1.h>
-#include <log/log.h>
-
-#include <memory>
-
-#include "impl/vr_hwc.h"
-#include "impl/vr_composer_client.h"
-
-namespace android {
-namespace dvr {
-
-using android::frameworks::vr::composer::V2_0::IVrComposerClient;
-
-VrComposerClient::VrComposerClient(dvr::VrHwc& hal)
- : ComposerClient(&hal), mVrHal(hal) {
- if (!init()) {
- LOG_ALWAYS_FATAL("failed to initialize VrComposerClient");
- }
-}
-
-VrComposerClient::~VrComposerClient() {}
-
-std::unique_ptr<ComposerCommandEngine>
-VrComposerClient::createCommandEngine() {
- return std::make_unique<VrCommandEngine>(*this);
-}
-
-VrComposerClient::VrCommandEngine::VrCommandEngine(VrComposerClient& client)
- : ComposerCommandEngine(client.mHal, client.mResources.get()),
- mVrHal(client.mVrHal) {}
-
-VrComposerClient::VrCommandEngine::~VrCommandEngine() {}
-
-bool VrComposerClient::VrCommandEngine::executeCommand(
- hardware::graphics::composer::V2_1::IComposerClient::Command command,
- uint16_t length) {
- IVrComposerClient::VrCommand vrCommand =
- static_cast<IVrComposerClient::VrCommand>(command);
- switch (vrCommand) {
- case IVrComposerClient::VrCommand::SET_LAYER_INFO:
- return executeSetLayerInfo(length);
- case IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA:
- return executeSetClientTargetMetadata(length);
- case IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA:
- return executeSetLayerBufferMetadata(length);
- default:
- return ComposerCommandEngine::executeCommand(command, length);
- }
-}
-
-bool VrComposerClient::VrCommandEngine::executeSetLayerInfo(uint16_t length) {
- if (length != 2) {
- return false;
- }
-
- auto err = mVrHal.setLayerInfo(mCurrentDisplay, mCurrentLayer, read(), read());
- if (err != Error::NONE) {
- mWriter->setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool VrComposerClient::VrCommandEngine::executeSetClientTargetMetadata(
- uint16_t length) {
- if (length != 7)
- return false;
-
- auto err = mVrHal.setClientTargetMetadata(mCurrentDisplay, readBufferMetadata());
- if (err != Error::NONE)
- mWriter->setError(getCommandLoc(), err);
-
- return true;
-}
-
-bool VrComposerClient::VrCommandEngine::executeSetLayerBufferMetadata(
- uint16_t length) {
- if (length != 7)
- return false;
-
- auto err = mVrHal.setLayerBufferMetadata(mCurrentDisplay, mCurrentLayer,
- readBufferMetadata());
- if (err != Error::NONE)
- mWriter->setError(getCommandLoc(), err);
-
- return true;
-}
-
-IVrComposerClient::BufferMetadata
-VrComposerClient::VrCommandEngine::readBufferMetadata() {
- IVrComposerClient::BufferMetadata metadata = {
- .width = read(),
- .height = read(),
- .stride = read(),
- .layerCount = read(),
- .format =
- static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(
- readSigned()),
- .usage = read64(),
- };
- return metadata;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/impl/vr_composer_client.h b/services/vr/hardware_composer/impl/vr_composer_client.h
deleted file mode 100644
index 1b2b5f4..0000000
--- a/services/vr/hardware_composer/impl/vr_composer_client.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
-
-#include <android/frameworks/vr/composer/2.0/IVrComposerClient.h>
-#include <composer-command-buffer/2.3/ComposerCommandBuffer.h>
-#include <composer-hal/2.1/ComposerClient.h>
-#include <composer-hal/2.1/ComposerCommandEngine.h>
-#include <composer-hal/2.2/ComposerClient.h>
-#include <composer-hal/2.3/ComposerClient.h>
-
-namespace android {
-namespace dvr {
-
-class VrHwc;
-
-using hardware::graphics::composer::V2_1::hal::ComposerCommandEngine;
-using hardware::graphics::composer::V2_3::hal::ComposerHal;
-using hardware::graphics::composer::V2_3::hal::detail::ComposerClientImpl;
-
-using ComposerClient = ComposerClientImpl<IVrComposerClient, ComposerHal>;
-
-class VrComposerClient : public ComposerClient {
- public:
- explicit VrComposerClient(android::dvr::VrHwc& hal);
- virtual ~VrComposerClient();
-
- private:
- class VrCommandEngine : public ComposerCommandEngine {
- public:
- explicit VrCommandEngine(VrComposerClient& client);
- ~VrCommandEngine() override;
-
- bool executeCommand(
- hardware::graphics::composer::V2_1::IComposerClient::Command command,
- uint16_t length) override;
-
- private:
- bool executeSetLayerInfo(uint16_t length);
- bool executeSetClientTargetMetadata(uint16_t length);
- bool executeSetLayerBufferMetadata(uint16_t length);
-
- IVrComposerClient::BufferMetadata readBufferMetadata();
-
- android::dvr::VrHwc& mVrHal;
-
- VrCommandEngine(const VrCommandEngine&) = delete;
- void operator=(const VrCommandEngine&) = delete;
- };
-
- VrComposerClient(const VrComposerClient&) = delete;
- void operator=(const VrComposerClient&) = delete;
-
- std::unique_ptr<ComposerCommandEngine> createCommandEngine() override;
- dvr::VrHwc& mVrHal;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
deleted file mode 100644
index e530b16..0000000
--- a/services/vr/hardware_composer/impl/vr_hwc.cpp
+++ /dev/null
@@ -1,1178 +0,0 @@
-/*
- * Copyright 2016 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 "impl/vr_hwc.h"
-
-#include "android-base/stringprintf.h"
-#include <binder/IServiceManager.h>
-#include <cutils/properties.h>
-#include <private/dvr/display_client.h>
-#include <ui/Fence.h>
-#include <utils/Trace.h>
-
-#include <mutex>
-
-#include "vr_composer_client.h"
-
-using namespace android::hardware::graphics::common::V1_0;
-using namespace android::hardware::graphics::composer::V2_3;
-
-using android::base::StringPrintf;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_string;
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::Void;
-
-namespace types = android::hardware::graphics::common;
-
-namespace android {
-namespace dvr {
-namespace {
-
-const Display kDefaultDisplayId = 1;
-const Config kDefaultConfigId = 1;
-
-sp<GraphicBuffer> CreateGraphicBuffer(
- const native_handle_t* handle,
- const IVrComposerClient::BufferMetadata& metadata) {
- sp<GraphicBuffer> buffer = new GraphicBuffer(
- handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height,
- static_cast<int32_t>(metadata.format), metadata.layerCount,
- metadata.usage, metadata.stride);
- if (buffer->initCheck() != OK) {
- ALOGE("Failed to create graphic buffer");
- return nullptr;
- }
-
- return buffer;
-}
-
-void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
- *width = 1080;
- *height = 1920;
-
- int error = 0;
- auto display_client = display::DisplayClient::Create(&error);
- if (!display_client) {
- ALOGE("Could not connect to display service : %s(%d)", strerror(error),
- error);
- return;
- }
-
- auto status = display_client->GetDisplayMetrics();
- if (!status) {
- ALOGE("Could not get display metrics from display service : %s(%d)",
- status.GetErrorMessage().c_str(), status.error());
- return;
- }
-
- *width = status.get().display_width;
- *height = status.get().display_height;
-}
-
-} // namespace
-
-HwcDisplay::HwcDisplay(int32_t width, int32_t height)
- : width_(width), height_(height) {}
-
-HwcDisplay::~HwcDisplay() {}
-
-bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
- base::unique_fd fence) {
- if (handle)
- buffer_ = CreateGraphicBuffer(handle, buffer_metadata_);
-
- fence_ = new Fence(fence.release());
- return true;
-}
-
-void HwcDisplay::SetClientTargetMetadata(
- const IVrComposerClient::BufferMetadata& metadata) {
- buffer_metadata_ = metadata;
-}
-
-HwcLayer* HwcDisplay::CreateLayer() {
- uint64_t layer_id = layer_ids_++;
- layers_.push_back(HwcLayer(layer_id));
- return &layers_.back();
-}
-
-HwcLayer* HwcDisplay::GetLayer(Layer id) {
- for (size_t i = 0; i < layers_.size(); ++i)
- if (layers_[i].info.id == id)
- return &layers_[i];
-
- return nullptr;
-}
-
-bool HwcDisplay::DestroyLayer(Layer id) {
- for (auto it = layers_.begin(); it != layers_.end(); ++it) {
- if (it->info.id == id) {
- layers_.erase(it);
- return true;
- }
- }
-
- return false;
-}
-
-void HwcDisplay::GetChangedCompositionTypes(
- std::vector<Layer>* layer_ids,
- std::vector<IComposerClient::Composition>* types) {
- std::sort(layers_.begin(), layers_.end(),
- [](const auto& lhs, const auto& rhs) {
- return lhs.info.z_order < rhs.info.z_order;
- });
-
- const size_t no_layer = std::numeric_limits<size_t>::max();
- size_t first_client_layer = no_layer, last_client_layer = no_layer;
- for (size_t i = 0; i < layers_.size(); ++i) {
- switch (layers_[i].composition_type) {
- case IComposerClient::Composition::SOLID_COLOR:
- case IComposerClient::Composition::CURSOR:
- case IComposerClient::Composition::SIDEBAND:
- if (first_client_layer == no_layer)
- first_client_layer = i;
-
- last_client_layer = i;
- break;
- default:
- break;
- }
- }
-
- for (size_t i = 0; i < layers_.size(); ++i) {
- if (i >= first_client_layer && i <= last_client_layer) {
- if (layers_[i].composition_type != IComposerClient::Composition::CLIENT) {
- layer_ids->push_back(layers_[i].info.id);
- types->push_back(IComposerClient::Composition::CLIENT);
- layers_[i].composition_type = IComposerClient::Composition::CLIENT;
- }
-
- continue;
- }
-
- if (layers_[i].composition_type != IComposerClient::Composition::DEVICE) {
- layer_ids->push_back(layers_[i].info.id);
- types->push_back(IComposerClient::Composition::DEVICE);
- layers_[i].composition_type = IComposerClient::Composition::DEVICE;
- }
- }
-}
-
-Error HwcDisplay::GetFrame(
- std::vector<ComposerView::ComposerLayer>* out_frames) {
- bool queued_client_target = false;
- std::vector<ComposerView::ComposerLayer> frame;
- for (const auto& layer : layers_) {
- if (layer.composition_type == IComposerClient::Composition::CLIENT) {
- if (queued_client_target)
- continue;
-
- if (!buffer_.get()) {
- ALOGE("Client composition requested but no client target buffer");
- return Error::BAD_LAYER;
- }
-
- ComposerView::ComposerLayer client_target_layer = {
- .buffer = buffer_,
- .fence = fence_.get() ? fence_ : new Fence(-1),
- .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
- static_cast<int32_t>(buffer_->getHeight())},
- .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
- static_cast<float>(buffer_->getHeight())},
- .blend_mode = IComposerClient::BlendMode::NONE,
- };
-
- frame.push_back(client_target_layer);
- queued_client_target = true;
- } else {
- if (!layer.info.buffer.get() || !layer.info.fence.get()) {
- ALOGV("Layer requested without valid buffer");
- continue;
- }
-
- frame.push_back(layer.info);
- }
- }
-
- out_frames->swap(frame);
- return Error::NONE;
-}
-
-std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
- std::vector<Layer> last_frame_layers;
- last_frame_layers.swap(last_frame_layers_ids_);
-
- for (const auto& layer : layers_)
- last_frame_layers_ids_.push_back(layer.info.id);
-
- return last_frame_layers;
-}
-
-void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) {
- color_transform_hint_ = hint;
- if (matrix)
- memcpy(color_transform_, matrix, sizeof(color_transform_));
-}
-
-void HwcDisplay::dumpDebugInfo(std::string* result) const {
- if (!result) {
- return;
- }
- *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\
- , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_);
- *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\
- layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height,
- buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format);
- for (const auto& layer : layers_) {
- layer.dumpDebugInfo(result);
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// VrHwcClient
-
-VrHwc::VrHwc() {
- vsync_callback_ = new VsyncCallback;
-}
-
-VrHwc::~VrHwc() {
- vsync_callback_->SetEventCallback(nullptr);
-}
-
-bool VrHwc::hasCapability(hwc2_capability_t /* capability */) { return false; }
-
-void VrHwc::registerEventCallback(EventCallback* callback) {
- std::unique_lock<std::mutex> lock(mutex_);
- event_callback_ = callback;
- int32_t width, height;
- GetPrimaryDisplaySize(&width, &height);
- // Create the primary display late to avoid initialization issues between
- // VR HWC and SurfaceFlinger.
- displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height));
-
- // Surface flinger will make calls back into vr_hwc when it receives the
- // onHotplug() call, so it's important to release mutex_ here.
- lock.unlock();
- event_callback_->onHotplug(kDefaultDisplayId,
- hardware::graphics::composer::V2_1::
- IComposerCallback::Connection::CONNECTED);
- lock.lock();
- UpdateVsyncCallbackEnabledLocked();
-}
-
-void VrHwc::unregisterEventCallback() {
- std::lock_guard<std::mutex> guard(mutex_);
- event_callback_ = nullptr;
- UpdateVsyncCallbackEnabledLocked();
-}
-
-uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; }
-
-Error VrHwc::destroyVirtualDisplay(Display display) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (display == kDefaultDisplayId || displays_.erase(display) == 0)
- return Error::BAD_DISPLAY;
- ComposerView::Frame frame;
- frame.display_id = display;
- frame.removed = true;
- if (observer_)
- observer_->OnNewFrame(frame);
- return Error::NONE;
-}
-
-Error VrHwc::createLayer(Display display, Layer* outLayer) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* layer = display_ptr->CreateLayer();
- *outLayer = layer->info.id;
- return Error::NONE;
-}
-
-Error VrHwc::destroyLayer(Display display, Layer layer) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr) {
- return Error::BAD_DISPLAY;
- }
-
- return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
-}
-
-Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (!FindDisplay(display))
- return Error::BAD_DISPLAY;
- *outConfig = kDefaultConfigId;
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayAttribute(Display display, Config config,
- IComposerClient::Attribute attribute,
- int32_t* outValue) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr) {
- return Error::BAD_DISPLAY;
- }
- if (config != kDefaultConfigId) {
- return Error::BAD_CONFIG;
- }
-
- switch (attribute) {
- case IComposerClient::Attribute::WIDTH:
- *outValue = display_ptr->width();
- break;
- case IComposerClient::Attribute::HEIGHT:
- *outValue = display_ptr->height();
- break;
- case IComposerClient::Attribute::VSYNC_PERIOD:
- {
- int error = 0;
- auto display_client = display::DisplayClient::Create(&error);
- if (!display_client) {
- ALOGE("Could not connect to display service : %s(%d)",
- strerror(error), error);
- // Return a default value of 30 fps
- *outValue = 1000 * 1000 * 1000 / 30;
- } else {
- auto metrics = display_client->GetDisplayMetrics();
- *outValue = metrics.get().vsync_period_ns;
- }
- }
- break;
- case IComposerClient::Attribute::DPI_X:
- case IComposerClient::Attribute::DPI_Y:
- {
- constexpr int32_t kDefaultDPI = 300;
- int32_t dpi = property_get_int32("ro.vr.hwc.dpi", kDefaultDPI);
- if (dpi <= 0) {
- dpi = kDefaultDPI;
- }
- *outValue = 1000 * dpi;
- }
- break;
- default:
- return Error::BAD_PARAMETER;
- }
-
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (!FindDisplay(display))
- return Error::BAD_DISPLAY;
- std::vector<Config> configs(1, kDefaultConfigId);
- *outConfigs = hidl_vec<Config>(configs);
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayName(Display /* display */, hidl_string* outName) {
- *outName = hidl_string();
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayType(Display display,
- IComposerClient::DisplayType* outType) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr) {
- *outType = IComposerClient::DisplayType::INVALID;
- return Error::BAD_DISPLAY;
- }
-
- if (display == kDefaultDisplayId)
- *outType = IComposerClient::DisplayType::PHYSICAL;
- else
- *outType = IComposerClient::DisplayType::VIRTUAL;
-
- return Error::NONE;
-}
-
-Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
- *outSupport = false;
- std::lock_guard<std::mutex> guard(mutex_);
- if (!FindDisplay(display))
- return Error::BAD_DISPLAY;
- return Error::NONE;
-}
-
-Error VrHwc::setActiveConfig(Display display, Config config) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
- if (config != kDefaultConfigId)
- return Error::BAD_CONFIG;
-
- display_ptr->set_active_config(config);
- return Error::NONE;
-}
-
-Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- if (enabled != IComposerClient::Vsync::ENABLE &&
- enabled != IComposerClient::Vsync::DISABLE) {
- return Error::BAD_PARAMETER;
- }
-
- Error set_vsync_result = Error::NONE;
- if (display == kDefaultDisplayId) {
- sp<IVsyncService> vsync_service = interface_cast<IVsyncService>(
- defaultServiceManager()->getService(
- String16(IVsyncService::GetServiceName())));
- if (vsync_service == nullptr) {
- ALOGE("Failed to get vsync service");
- return Error::NO_RESOURCES;
- }
-
- if (enabled == IComposerClient::Vsync::ENABLE) {
- ALOGI("Enable vsync");
- display_ptr->set_vsync_enabled(true);
- status_t result = vsync_service->registerCallback(vsync_callback_);
- if (result != OK) {
- ALOGE("%s service registerCallback() failed: %s (%d)",
- IVsyncService::GetServiceName(), strerror(-result), result);
- set_vsync_result = Error::NO_RESOURCES;
- }
- } else if (enabled == IComposerClient::Vsync::DISABLE) {
- ALOGI("Disable vsync");
- display_ptr->set_vsync_enabled(false);
- status_t result = vsync_service->unregisterCallback(vsync_callback_);
- if (result != OK) {
- ALOGE("%s service unregisterCallback() failed: %s (%d)",
- IVsyncService::GetServiceName(), strerror(-result), result);
- set_vsync_result = Error::NO_RESOURCES;
- }
- }
-
- UpdateVsyncCallbackEnabledLocked();
- }
-
- return set_vsync_result;
-}
-
-Error VrHwc::setColorTransform(Display display, const float* matrix,
- int32_t hint) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- display_ptr->SetColorTransform(matrix, hint);
- return Error::NONE;
-}
-
-Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
- int32_t acquireFence, int32_t /* dataspace */,
- const std::vector<hwc_rect_t>& /* damage */) {
- base::unique_fd fence(acquireFence);
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- if (target == nullptr)
- return Error::NONE;
-
- if (!display_ptr->SetClientTarget(target, std::move(fence)))
- return Error::BAD_PARAMETER;
-
- return Error::NONE;
-}
-
-Error VrHwc::setOutputBuffer(Display display, buffer_handle_t /* buffer */,
- int32_t releaseFence) {
- base::unique_fd fence(releaseFence);
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- // TODO(dnicoara): Is it necessary to do anything here?
- return Error::NONE;
-}
-
-Error VrHwc::validateDisplay(
- Display display, std::vector<Layer>* outChangedLayers,
- std::vector<IComposerClient::Composition>* outCompositionTypes,
- uint32_t* /* outDisplayRequestMask */,
- std::vector<Layer>* /* outRequestedLayers */,
- std::vector<uint32_t>* /* outRequestMasks */) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- display_ptr->GetChangedCompositionTypes(outChangedLayers,
- outCompositionTypes);
- return Error::NONE;
-}
-
-Error VrHwc::acceptDisplayChanges(Display /* display */) { return Error::NONE; }
-
-Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
- std::vector<Layer>* outLayers,
- std::vector<int32_t>* outReleaseFences) {
- *outPresentFence = -1;
- outLayers->clear();
- outReleaseFences->clear();
-
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
-
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- ComposerView::Frame frame;
- std::vector<Layer> last_frame_layers;
- Error status = display_ptr->GetFrame(&frame.layers);
- frame.display_id = display;
- frame.display_width = display_ptr->width();
- frame.display_height = display_ptr->height();
- frame.active_config = display_ptr->active_config();
- frame.power_mode = display_ptr->power_mode();
- frame.vsync_enabled = display_ptr->vsync_enabled() ?
- IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE;
- frame.color_transform_hint = display_ptr->color_transform_hint();
- frame.color_mode = display_ptr->color_mode();
- memcpy(frame.color_transform, display_ptr->color_transform(),
- sizeof(frame.color_transform));
- if (status != Error::NONE)
- return status;
-
- last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers();
-
- base::unique_fd fence;
- if (observer_)
- fence = observer_->OnNewFrame(frame);
-
- if (fence.get() < 0)
- return Error::NONE;
-
- *outPresentFence = dup(fence.get());
- outLayers->swap(last_frame_layers);
- for (size_t i = 0; i < outLayers->size(); ++i)
- outReleaseFences->push_back(dup(fence.get()));
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
- int32_t y) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.cursor_x = x;
- hwc_layer->info.cursor_y = y;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerBuffer(Display display, Layer layer,
- buffer_handle_t buffer, int32_t acquireFence) {
- base::unique_fd fence(acquireFence);
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.buffer = CreateGraphicBuffer(
- buffer, hwc_layer->buffer_metadata);
- hwc_layer->info.fence = new Fence(fence.release());
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
- const std::vector<hwc_rect_t>& damage) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.damaged_regions = damage;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.blend_mode =
- static_cast<ComposerView::ComposerLayer::BlendMode>(mode);
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerColor(Display display, Layer layer,
- IComposerClient::Color color) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.color = color;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerCompositionType(Display display, Layer layer,
- int32_t type) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->composition_type = static_cast<HwcLayer::Composition>(type);
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerDataspace(Display display, Layer layer,
- int32_t dataspace) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.dataspace = dataspace;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
- const hwc_rect_t& frame) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.display_frame =
- {frame.left, frame.top, frame.right, frame.bottom};
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.alpha = alpha;
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerSidebandStream(Display display, Layer /* layer */,
- buffer_handle_t /* stream */) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (!FindDisplay(display))
- return Error::BAD_DISPLAY;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
- const hwc_frect_t& crop) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.crop = {crop.left, crop.top, crop.right, crop.bottom};
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerTransform(Display display, Layer layer,
- int32_t transform) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.transform = transform;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
- const std::vector<hwc_rect_t>& visible) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.visible_regions = visible;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.z_order = z;
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
- uint32_t appId) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->info.type = type;
- hwc_layer->info.app_id = appId;
-
- return Error::NONE;
-}
-
-Error VrHwc::setClientTargetMetadata(
- Display display, const IVrComposerClient::BufferMetadata& metadata) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- display_ptr->SetClientTargetMetadata(metadata);
-
- return Error::NONE;
-}
-
-Error VrHwc::setLayerBufferMetadata(
- Display display, Layer layer,
- const IVrComposerClient::BufferMetadata& metadata) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
- if (!hwc_layer)
- return Error::BAD_LAYER;
-
- hwc_layer->buffer_metadata = metadata;
-
- return Error::NONE;
-}
-
-Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
- hidl_cb(hidl_vec<Capability>());
- return Void();
-}
-
-Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
- std::string result;
-
- {
- std::lock_guard<std::mutex> guard(mutex_);
- result = "\nVrHwc states:\n";
- for (const auto& pair : displays_) {
- result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first);
- pair.second->dumpDebugInfo(&result);
- }
- result += "\n";
- }
-
- hidl_cb(hidl_string(result));
- return Void();
-}
-
-Return<void> VrHwc::createClient(createClient_cb hidl_cb) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- Error status = Error::NONE;
- sp<VrComposerClient> client;
- if (!client_.promote().get()) {
- client = new VrComposerClient(*this);
- } else {
- ALOGE("Already have a client");
- status = Error::NO_RESOURCES;
- }
-
- client_ = client;
- hidl_cb(status, client);
- return Void();
-}
-
-Return<void> VrHwc::createClient_2_3(IComposer::createClient_2_3_cb hidl_cb) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- Error status = Error::NONE;
- sp<VrComposerClient> client;
- if (!client_.promote().get()) {
- client = new VrComposerClient(*this);
- } else {
- ALOGE("Already have a client");
- status = Error::NO_RESOURCES;
- }
-
- client_ = client;
- hidl_cb(status, client);
- return Void();
-}
-
-void VrHwc::ForceDisplaysRefresh() {
- std::lock_guard<std::mutex> guard(mutex_);
- if (event_callback_ != nullptr) {
- for (const auto& pair : displays_)
- event_callback_->onRefresh(pair.first);
- }
-}
-
-void VrHwc::RegisterObserver(Observer* observer) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (observer_)
- ALOGE("Overwriting observer");
- else
- observer_ = observer;
-}
-
-void VrHwc::UnregisterObserver(Observer* observer) {
- std::lock_guard<std::mutex> guard(mutex_);
- if (observer != observer_)
- ALOGE("Trying to unregister unknown observer");
- else
- observer_ = nullptr;
-}
-
-HwcDisplay* VrHwc::FindDisplay(Display display) {
- auto iter = displays_.find(display);
- return iter == displays_.end() ? nullptr : iter->second.get();
-}
-
-void VrHwc::UpdateVsyncCallbackEnabledLocked() {
- auto primary_display = FindDisplay(kDefaultDisplayId);
- LOG_ALWAYS_FATAL_IF(event_callback_ != nullptr && primary_display == nullptr,
- "Should have created the primary display by now");
- bool send_vsync =
- event_callback_ != nullptr && primary_display->vsync_enabled();
- vsync_callback_->SetEventCallback(send_vsync ? event_callback_ : nullptr);
-}
-
-Return<void> VrHwc::debug(const hidl_handle& fd,
- const hidl_vec<hidl_string>& args) {
- std::string result;
-
- {
- std::lock_guard<std::mutex> guard(mutex_);
- for (const auto& pair : displays_) {
- result += StringPrintf("Display id: %d\n", static_cast<int>(pair.first));
- pair.second->dumpDebugInfo(&result);
- }
- result += "\n";
- }
-
- FILE* out = fdopen(dup(fd->data[0]), "w");
- fprintf(out, "%s", result.c_str());
- fclose(out);
-
- return Void();
-}
-
-void HwcLayer::dumpDebugInfo(std::string* result) const {
- if (!result) {
- return;
- }
- *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\
- cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\
- display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n",
- composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y,
- info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform,
- info.display_frame.left, info.display_frame.top, info.display_frame.right,
- info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right,
- info.crop.bottom, info.blend_mode);
- *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\
- , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride,
- buffer_metadata.layerCount, buffer_metadata.format);
-}
-
-status_t VrHwc::VsyncCallback::onVsync(int64_t vsync_timestamp) {
- ATRACE_NAME("vr_hwc onVsync");
- std::lock_guard<std::mutex> guard(mutex_);
- if (callback_ != nullptr)
- callback_->onVsync(kDefaultDisplayId, vsync_timestamp);
- return OK;
-}
-
-void VrHwc::VsyncCallback::SetEventCallback(EventCallback* callback) {
- std::lock_guard<std::mutex> guard(mutex_);
- callback_ = callback;
-}
-
-// composer::V2_2::ComposerHal
-Error VrHwc::setReadbackBuffer(Display display,
- const native_handle_t* bufferHandle,
- android::base::unique_fd fenceFd) {
- return Error::NONE;
-}
-
-Error VrHwc::getReadbackBufferFence(Display display,
- android::base::unique_fd* outFenceFd) {
- return Error::NONE;
-}
-
-Error VrHwc::createVirtualDisplay_2_2(uint32_t width, uint32_t height,
- types::V1_1::PixelFormat* format,
- Display* outDisplay) {
- *format = types::V1_1::PixelFormat::RGBA_8888;
- *outDisplay = display_count_;
- displays_[display_count_].reset(new HwcDisplay(width, height));
- display_count_++;
- return Error::NONE;
-}
-
-Error VrHwc::setPowerMode_2_2(Display display,
- IComposerClient::PowerMode mode) {
- bool dozeSupported = false;
-
- Error dozeSupportError = getDozeSupport(display, &dozeSupported);
-
- if (dozeSupportError != Error::NONE)
- return dozeSupportError;
-
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- if (mode < IComposerClient::PowerMode::OFF ||
- mode > IComposerClient::PowerMode::DOZE_SUSPEND) {
- return Error::BAD_PARAMETER;
- }
-
- if (!dozeSupported && (mode == IComposerClient::PowerMode::DOZE ||
- mode == IComposerClient::PowerMode::DOZE_SUSPEND)) {
- return Error::UNSUPPORTED;
- }
-
- display_ptr->set_power_mode(mode);
- return Error::NONE;
-}
-
-Error VrHwc::setLayerFloatColor(Display display, Layer layer,
- IComposerClient::FloatColor color) {
- return Error::NONE;
-}
-
-Error VrHwc::getRenderIntents(Display display, types::V1_1::ColorMode mode,
- std::vector<RenderIntent>* outIntents) {
- return Error::NONE;
-}
-
-std::array<float, 16> VrHwc::getDataspaceSaturationMatrix(
- types::V1_1::Dataspace dataspace) {
- return {};
-}
-
-// composer::V2_3::ComposerHal
-Error VrHwc::getHdrCapabilities_2_3(Display /*display*/,
- hidl_vec<Hdr>* /*outTypes*/,
- float* outMaxLuminance,
- float* outMaxAverageLuminance,
- float* outMinLuminance) {
- *outMaxLuminance = 0;
- *outMaxAverageLuminance = 0;
- *outMinLuminance = 0;
- return Error::NONE;
-}
-
-Error VrHwc::setLayerPerFrameMetadata_2_3(
- Display display, Layer layer,
- const std::vector<IComposerClient::PerFrameMetadata>& metadata) {
- return Error::NONE;
-}
-
-Error VrHwc::getPerFrameMetadataKeys_2_3(
- Display display,
- std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) {
- return Error::NONE;
-}
-
-Error VrHwc::setColorMode_2_3(Display display, ColorMode mode,
- RenderIntent intent) {
- std::lock_guard<std::mutex> guard(mutex_);
- auto display_ptr = FindDisplay(display);
- if (!display_ptr)
- return Error::BAD_DISPLAY;
-
- if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3)
- return Error::BAD_PARAMETER;
-
- display_ptr->set_color_mode(mode);
- return Error::NONE;
-}
-
-Error VrHwc::getRenderIntents_2_3(Display display, ColorMode mode,
- std::vector<RenderIntent>* outIntents) {
- return Error::NONE;
-}
-
-Error VrHwc::getColorModes_2_3(Display display, hidl_vec<ColorMode>* outModes) {
- return Error::NONE;
-}
-
-Error VrHwc::getClientTargetSupport_2_3(Display display, uint32_t width,
- uint32_t height, PixelFormat format,
- Dataspace dataspace) {
- return Error::NONE;
-}
-
-Error VrHwc::getReadbackBufferAttributes_2_3(Display display,
- PixelFormat* outFormat,
- Dataspace* outDataspace) {
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayIdentificationData(Display display, uint8_t* outPort,
- std::vector<uint8_t>* outData) {
- int error = 0;
- auto display_client = display::DisplayClient::Create(&error);
- if (!display_client) {
- ALOGE("Could not connect to display service : %s(%d)", strerror(error),
- error);
- return Error::BAD_CONFIG;
- }
- auto edid_data = display_client->GetConfigurationData(
- display::ConfigFileType::kDeviceEdid);
- auto display_identification_port =
- display_client->GetDisplayIdentificationPort();
- *outPort = display_identification_port.get();
-
- std::copy(edid_data.get().begin(), edid_data.get().end(),
- std::back_inserter(*outData));
- return Error::NONE;
-}
-
-Error VrHwc::setLayerColorTransform(Display display, Layer layer,
- const float* matrix) {
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayedContentSamplingAttributes(
- Display display, PixelFormat& format, Dataspace& dataspace,
- hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) {
- return Error::NONE;
-}
-
-Error VrHwc::setDisplayedContentSamplingEnabled(
- Display display, IComposerClient::DisplayedContentSampling enable,
- hidl_bitfield<IComposerClient::FormatColorComponent> componentMask,
- uint64_t maxFrames) {
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayedContentSample(Display display, uint64_t maxFrames,
- uint64_t timestamp, uint64_t& frameCount,
- hidl_vec<uint64_t>& sampleComponent0,
- hidl_vec<uint64_t>& sampleComponent1,
- hidl_vec<uint64_t>& sampleComponent2,
- hidl_vec<uint64_t>& sampleComponent3) {
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayCapabilities(
- Display display,
- std::vector<IComposerClient::DisplayCapability>* outCapabilities) {
- return Error::NONE;
-}
-
-Error VrHwc::setLayerPerFrameMetadataBlobs(
- Display display, Layer layer,
- std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) {
- return Error::NONE;
-}
-
-Error VrHwc::getDisplayBrightnessSupport(Display display, bool* outSupport) {
- return Error::NONE;
-}
-
-Error VrHwc::setDisplayBrightness(Display display, float brightness) {
- return Error::NONE;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
deleted file mode 100644
index 3e3a630..0000000
--- a/services/vr/hardware_composer/impl/vr_hwc.h
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright 2016 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_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
-
-#include <android-base/unique_fd.h>
-#include <android/frameworks/vr/composer/2.0/IVrComposerClient.h>
-#include <android/hardware/graphics/composer/2.3/IComposer.h>
-#include <composer-hal/2.3/ComposerHal.h>
-#include <private/dvr/vsync_service.h>
-#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-#include <utils/StrongPointer.h>
-
-#include <mutex>
-#include <unordered_map>
-
-using namespace android::frameworks::vr::composer::V2_0;
-using namespace android::hardware::graphics::common::V1_0;
-using namespace android::hardware::graphics::composer::V2_3;
-
-using android::hardware::hidl_bitfield;
-using android::hardware::hidl_handle;
-using android::hardware::hidl_string;
-using android::hardware::hidl_vec;
-using android::hardware::Return;
-using android::hardware::Void;
-using android::hardware::graphics::composer::V2_1::Config;
-using android::hardware::graphics::composer::V2_1::Display;
-using android::hardware::graphics::composer::V2_1::Error;
-using android::hardware::graphics::composer::V2_1::Layer;
-using android::hardware::graphics::composer::V2_3::IComposerClient;
-
-namespace android {
-
-class Fence;
-
-namespace dvr {
-
-class VrComposerClient;
-
-using android::hardware::graphics::composer::V2_3::hal::ComposerHal;
-
-namespace types = android::hardware::graphics::common;
-
-using types::V1_1::RenderIntent;
-using types::V1_2::ColorMode;
-using types::V1_2::Dataspace;
-using types::V1_2::Hdr;
-using types::V1_2::PixelFormat;
-
-class ComposerView {
- public:
- struct ComposerLayer {
- using Recti = hardware::graphics::composer::V2_3::IComposerClient::Rect;
- using Rectf = hardware::graphics::composer::V2_3::IComposerClient::FRect;
- using BlendMode =
- hardware::graphics::composer::V2_3::IComposerClient::BlendMode;
-
- Layer id;
- sp<GraphicBuffer> buffer;
- sp<Fence> fence;
- Recti display_frame;
- Rectf crop;
- BlendMode blend_mode;
- float alpha;
- uint32_t type;
- uint32_t app_id;
- uint32_t z_order;
- int32_t cursor_x;
- int32_t cursor_y;
- IComposerClient::Color color;
- int32_t dataspace;
- int32_t transform;
- std::vector<hwc_rect_t> visible_regions;
- std::vector<hwc_rect_t> damaged_regions;
- };
-
- struct Frame {
- Display display_id;
- // This is set to true to notify the upper layer that the display is
- // being removed, or left false in the case of a normal frame. The upper
- // layer tracks display IDs and will handle new ones showing up.
- bool removed = false;
- int32_t display_width;
- int32_t display_height;
- Config active_config;
- ColorMode color_mode;
- IComposerClient::PowerMode power_mode;
- IComposerClient::Vsync vsync_enabled;
- float color_transform[16];
- int32_t color_transform_hint;
- std::vector<ComposerLayer> layers;
- };
-
- class Observer {
- public:
- virtual ~Observer() {}
-
- // Returns a list of layers that need to be shown together. Layers are
- // returned in z-order, with the lowest layer first.
- virtual base::unique_fd OnNewFrame(const Frame& frame) = 0;
- };
-
- virtual ~ComposerView() {}
-
- virtual void ForceDisplaysRefresh() = 0;
- virtual void RegisterObserver(Observer* observer) = 0;
- virtual void UnregisterObserver(Observer* observer) = 0;
-};
-
-struct HwcLayer {
- using Composition =
- hardware::graphics::composer::V2_3::IComposerClient::Composition;
-
- explicit HwcLayer(Layer new_id) { info.id = new_id; }
-
- void dumpDebugInfo(std::string* result) const;
-
- Composition composition_type;
- ComposerView::ComposerLayer info;
- IVrComposerClient::BufferMetadata buffer_metadata;
-};
-
-class HwcDisplay {
- public:
- HwcDisplay(int32_t width, int32_t height);
- ~HwcDisplay();
-
- int32_t width() const { return width_; }
- int32_t height() const { return height_; }
-
- HwcLayer* CreateLayer();
- bool DestroyLayer(Layer id);
- HwcLayer* GetLayer(Layer id);
-
- bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence);
- void SetClientTargetMetadata(
- const IVrComposerClient::BufferMetadata& metadata);
-
- void GetChangedCompositionTypes(
- std::vector<Layer>* layer_ids,
- std::vector<IComposerClient::Composition>* composition);
-
- Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame);
-
- std::vector<Layer> UpdateLastFrameAndGetLastFrameLayers();
-
- Config active_config() const { return active_config_; }
- void set_active_config(Config config) { active_config_ = config; }
-
- ColorMode color_mode() const { return color_mode_; }
- void set_color_mode(ColorMode mode) { color_mode_ = mode; }
-
- IComposerClient::PowerMode power_mode() const { return power_mode_; }
- void set_power_mode(IComposerClient::PowerMode mode) { power_mode_ = mode; }
-
- bool vsync_enabled() const { return vsync_enabled_; }
- void set_vsync_enabled(bool vsync) {vsync_enabled_ = vsync;}
-
- const float* color_transform() const { return color_transform_; }
- int32_t color_transform_hint() const { return color_transform_hint_; }
- void SetColorTransform(const float* matrix, int32_t hint);
-
- void dumpDebugInfo(std::string* result) const;
-
- private:
- // The client target buffer and the associated fence.
- sp<GraphicBuffer> buffer_;
- IVrComposerClient::BufferMetadata buffer_metadata_;
- sp<Fence> fence_;
-
- // List of currently active layers.
- std::vector<HwcLayer> layers_;
-
- std::vector<Layer> last_frame_layers_ids_;
-
- // Layer ID generator.
- uint64_t layer_ids_ = 1;
-
- int32_t width_;
- int32_t height_;
-
- Config active_config_;
- ColorMode color_mode_;
- IComposerClient::PowerMode power_mode_;
- bool vsync_enabled_ = false;
- float color_transform_[16];
- int32_t color_transform_hint_;
-
- HwcDisplay(const HwcDisplay&) = delete;
- void operator=(const HwcDisplay&) = delete;
-};
-
-class VrHwc : public IComposer, public ComposerHal, public ComposerView {
- public:
- VrHwc();
- ~VrHwc() override;
-
- Error setLayerInfo(Display display, Layer layer, uint32_t type,
- uint32_t appId);
- Error setClientTargetMetadata(
- Display display, const IVrComposerClient::BufferMetadata& metadata);
- Error setLayerBufferMetadata(
- Display display, Layer layer,
- const IVrComposerClient::BufferMetadata& metadata);
-
- // composer::V2_1::ComposerHal
- bool hasCapability(hwc2_capability_t capability) override;
-
- std::string dumpDebugInfo() override { return {}; }
-
- void registerEventCallback(ComposerHal::EventCallback* callback) override;
- void unregisterEventCallback() override;
-
- uint32_t getMaxVirtualDisplayCount() override;
- Error destroyVirtualDisplay(Display display) override;
-
- Error createLayer(Display display, Layer* outLayer) override;
- Error destroyLayer(Display display, Layer layer) override;
-
- Error getActiveConfig(Display display, Config* outConfig) override;
- Error getDisplayAttribute(Display display, Config config,
- IComposerClient::Attribute attribute,
- int32_t* outValue) override;
- Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override;
- Error getDisplayName(Display display, hidl_string* outName) override;
- Error getDisplayType(Display display,
- IComposerClient::DisplayType* outType) override;
- Error getDozeSupport(Display display, bool* outSupport) override;
-
- Error setActiveConfig(Display display, Config config) override;
- Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override;
-
- Error setColorTransform(Display display, const float* matrix,
- int32_t hint) override;
- Error setClientTarget(Display display, buffer_handle_t target,
- int32_t acquireFence, int32_t dataspace,
- const std::vector<hwc_rect_t>& damage) override;
- Error setOutputBuffer(Display display, buffer_handle_t buffer,
- int32_t releaseFence) override;
- Error validateDisplay(
- Display display, std::vector<Layer>* outChangedLayers,
- std::vector<IComposerClient::Composition>* outCompositionTypes,
- uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
- std::vector<uint32_t>* outRequestMasks) override;
- Error acceptDisplayChanges(Display display) override;
- Error presentDisplay(Display display, int32_t* outPresentFence,
- std::vector<Layer>* outLayers,
- std::vector<int32_t>* outReleaseFences) override;
-
- Error setLayerCursorPosition(Display display, Layer layer, int32_t x,
- int32_t y) override;
- Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer,
- int32_t acquireFence) override;
- Error setLayerSurfaceDamage(Display display, Layer layer,
- const std::vector<hwc_rect_t>& damage) override;
- Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override;
- Error setLayerColor(Display display, Layer layer,
- IComposerClient::Color color) override;
- Error setLayerCompositionType(Display display, Layer layer,
- int32_t type) override;
- Error setLayerDataspace(Display display, Layer layer,
- int32_t dataspace) override;
- Error setLayerDisplayFrame(Display display, Layer layer,
- const hwc_rect_t& frame) override;
- Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
- Error setLayerSidebandStream(Display display, Layer layer,
- buffer_handle_t stream) override;
- Error setLayerSourceCrop(Display display, Layer layer,
- const hwc_frect_t& crop) override;
- Error setLayerTransform(Display display, Layer layer,
- int32_t transform) override;
- Error setLayerVisibleRegion(Display display, Layer layer,
- const std::vector<hwc_rect_t>& visible) override;
- Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
-
- // composer::V2_2::ComposerHal
- Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle,
- android::base::unique_fd fenceFd) override;
- Error getReadbackBufferFence(Display display,
- android::base::unique_fd* outFenceFd) override;
- Error createVirtualDisplay_2_2(uint32_t width, uint32_t height,
- types::V1_1::PixelFormat* format,
- Display* outDisplay) override;
- Error setPowerMode_2_2(Display display,
- IComposerClient::PowerMode mode) override;
- Error setLayerFloatColor(Display display, Layer layer,
- IComposerClient::FloatColor color) override;
- Error getRenderIntents(Display display, types::V1_1::ColorMode mode,
- std::vector<RenderIntent>* outIntents) override;
- std::array<float, 16> getDataspaceSaturationMatrix(
- types::V1_1::Dataspace dataspace) override;
-
- // composer::V2_3::ComposerHal
- Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes,
- float* outMaxLuminance,
- float* outMaxAverageLuminance,
- float* outMinLuminance) override;
- Error setLayerPerFrameMetadata_2_3(
- Display display, Layer layer,
- const std::vector<IComposerClient::PerFrameMetadata>& metadata) override;
- Error getPerFrameMetadataKeys_2_3(
- Display display,
- std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override;
- Error setColorMode_2_3(Display display, ColorMode mode,
- RenderIntent intent) override;
- Error getRenderIntents_2_3(Display display, ColorMode mode,
- std::vector<RenderIntent>* outIntents) override;
- Error getColorModes_2_3(Display display,
- hidl_vec<ColorMode>* outModes) override;
- Error getClientTargetSupport_2_3(Display display, uint32_t width,
- uint32_t height, PixelFormat format,
- Dataspace dataspace) override;
- Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat,
- Dataspace* outDataspace) override;
- Error getDisplayIdentificationData(Display display, uint8_t* outPort,
- std::vector<uint8_t>* outData) override;
- Error setLayerColorTransform(Display display, Layer layer,
- const float* matrix) override;
- Error getDisplayedContentSamplingAttributes(
- Display display, PixelFormat& format, Dataspace& dataspace,
- hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask)
- override;
- Error setDisplayedContentSamplingEnabled(
- Display display, IComposerClient::DisplayedContentSampling enable,
- hidl_bitfield<IComposerClient::FormatColorComponent> componentMask,
- uint64_t maxFrames) override;
- Error getDisplayedContentSample(
- Display display, uint64_t maxFrames, uint64_t timestamp,
- uint64_t& frameCount, hidl_vec<uint64_t>& sampleComponent0,
- hidl_vec<uint64_t>& sampleComponent1,
- hidl_vec<uint64_t>& sampleComponent2,
- hidl_vec<uint64_t>& sampleComponent3) override;
- Error getDisplayCapabilities(Display display,
- std::vector<IComposerClient::DisplayCapability>*
- outCapabilities) override;
- Error setLayerPerFrameMetadataBlobs(
- Display display, Layer layer,
- std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) override;
- Error getDisplayBrightnessSupport(Display display, bool* outSupport) override;
- Error setDisplayBrightness(Display display, float brightness) override;
-
- // IComposer:
- Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
- Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
- Return<void> createClient(createClient_cb hidl_cb) override;
- Return<void> createClient_2_3(
- IComposer::createClient_2_3_cb hidl_cb) override;
-
- // ComposerView:
- void ForceDisplaysRefresh() override;
- void RegisterObserver(Observer* observer) override;
- void UnregisterObserver(Observer* observer) override;
-
- Return<void> debug(const hidl_handle& fd,
- const hidl_vec<hidl_string>& args) override;
-
- private:
- class VsyncCallback : public BnVsyncCallback {
- public:
- status_t onVsync(int64_t vsync_timestamp) override;
- void SetEventCallback(EventCallback* callback);
- private:
- std::mutex mutex_;
- EventCallback* callback_;
- };
-
- HwcDisplay* FindDisplay(Display display);
-
- // Re-evaluate whether or not we should start making onVsync() callbacks to
- // the client. We need enableCallback(true) to have been called, and
- // setVsyncEnabled() to have been called for the primary display. The caller
- // must have mutex_ locked already.
- void UpdateVsyncCallbackEnabledLocked();
-
- wp<VrComposerClient> client_;
-
- // Guard access to internal state from binder threads.
- std::mutex mutex_;
-
- std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_;
- Display display_count_ = 2;
-
- EventCallback* event_callback_ = nullptr;
- Observer* observer_ = nullptr;
-
- sp<VsyncCallback> vsync_callback_;
-
- VrHwc(const VrHwc&) = delete;
- void operator=(const VrHwc&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
diff --git a/services/vr/hardware_composer/tests/vr_composer_test.cpp b/services/vr/hardware_composer/tests/vr_composer_test.cpp
deleted file mode 100644
index 2e70928..0000000
--- a/services/vr/hardware_composer/tests/vr_composer_test.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include <android/dvr/BnVrComposerCallback.h>
-#include <binder/IServiceManager.h>
-#include <gtest/gtest.h>
-#include <sys/eventfd.h>
-#include <vr_composer.h>
-
-namespace android {
-namespace dvr {
-namespace {
-
-const char kVrDisplayName[] = "VrDisplay_Test";
-
-class TestComposerView : public ComposerView {
- public:
- TestComposerView() {}
- ~TestComposerView() override = default;
-
- size_t display_refresh_count() const { return display_refresh_count_; }
-
- void ForceDisplaysRefresh() override { display_refresh_count_++; }
- void RegisterObserver(Observer* observer) override {}
- void UnregisterObserver(Observer* observer) override {}
-
- TestComposerView(const TestComposerView&) = delete;
- void operator=(const TestComposerView&) = delete;
-
- private:
- size_t display_refresh_count_ = 0;
-};
-
-class TestComposerCallback : public BnVrComposerCallback {
- public:
- TestComposerCallback() {}
- ~TestComposerCallback() override = default;
-
- ComposerView::Frame last_frame() const { return last_frame_; }
-
- binder::Status onNewFrame(
- const ParcelableComposerFrame& frame,
- ParcelableUniqueFd* /* fence */) override {
- last_frame_ = frame.frame();
- return binder::Status::ok();
- }
-
- private:
- ComposerView::Frame last_frame_;
-
- TestComposerCallback(const TestComposerCallback&) = delete;
- void operator=(const TestComposerCallback&) = delete;
-};
-
-class TestComposerCallbackWithFence : public TestComposerCallback {
- public:
- ~TestComposerCallbackWithFence() override = default;
-
- binder::Status onNewFrame(
- const ParcelableComposerFrame& frame,
- ParcelableUniqueFd* fence) override {
- binder::Status status = TestComposerCallback::onNewFrame(frame, fence);
-
- base::unique_fd fd(eventfd(0, 0));
- EXPECT_LE(0, fd.get());
- fence->set_fence(fd);
-
- return status;
- }
-};
-
-sp<GraphicBuffer> CreateBuffer() {
- return new GraphicBuffer(600, 400, PIXEL_FORMAT_RGBA_8888,
- GraphicBuffer::USAGE_HW_TEXTURE);
-}
-
-} // namespace
-
-class VrComposerTest : public testing::Test {
- public:
- VrComposerTest() : composer_(new VrComposer(&composer_view_)) {}
- ~VrComposerTest() override = default;
-
- sp<IVrComposer> GetComposerProxy() const {
- sp<IServiceManager> sm(defaultServiceManager());
- return interface_cast<IVrComposer>(sm->getService(String16(kVrDisplayName)));
- }
-
- void SetUp() override {
- sp<IServiceManager> sm(defaultServiceManager());
- EXPECT_EQ(OK,
- sm->addService(String16(kVrDisplayName), composer_, false));
- }
-
- protected:
- TestComposerView composer_view_;
- sp<VrComposer> composer_;
-
- VrComposerTest(const VrComposerTest&) = delete;
- void operator=(const VrComposerTest&) = delete;
-};
-
-TEST_F(VrComposerTest, TestWithoutObserver) {
- sp<IVrComposer> composer = GetComposerProxy();
- ComposerView::Frame frame;
-
- base::unique_fd fence = composer_->OnNewFrame(frame);
- ASSERT_EQ(-1, fence.get());
-}
-
-TEST_F(VrComposerTest, TestWithObserver) {
- sp<IVrComposer> composer = GetComposerProxy();
- sp<TestComposerCallback> callback = new TestComposerCallback();
- ASSERT_EQ(0, composer_view_.display_refresh_count());
- ASSERT_TRUE(composer->registerObserver(callback).isOk());
- ASSERT_EQ(1, composer_view_.display_refresh_count());
-
- ComposerView::Frame frame;
- base::unique_fd fence = composer_->OnNewFrame(frame);
- ASSERT_EQ(-1, fence.get());
-}
-
-TEST_F(VrComposerTest, TestWithOneLayer) {
- sp<IVrComposer> composer = GetComposerProxy();
- sp<TestComposerCallback> callback = new TestComposerCallbackWithFence();
- ASSERT_TRUE(composer->registerObserver(callback).isOk());
-
- ComposerView::Frame frame;
- frame.display_id = 1;
- frame.removed = false;
- frame.display_width = 600;
- frame.display_height = 400;
- frame.layers.push_back(ComposerView::ComposerLayer{
- .id = 1,
- .buffer = CreateBuffer(),
- .fence = new Fence(eventfd(0, 0)),
- .display_frame = {0, 0, 600, 400},
- .crop = {0.0f, 0.0f, 600.0f, 400.0f},
- .blend_mode = IComposerClient::BlendMode::NONE,
- .alpha = 1.0f,
- .type = 1,
- .app_id = 1,
- });
- base::unique_fd fence = composer_->OnNewFrame(frame);
- ASSERT_LE(0, fence.get());
-
- ComposerView::Frame received_frame = callback->last_frame();
- ASSERT_EQ(frame.display_id, received_frame.display_id);
- ASSERT_EQ(frame.display_width, received_frame.display_width);
- ASSERT_EQ(frame.display_height, received_frame.display_height);
- ASSERT_EQ(frame.removed, received_frame.removed);
- ASSERT_EQ(1u, received_frame.layers.size());
- ASSERT_EQ(frame.layers[0].id, received_frame.layers[0].id);
- ASSERT_NE(nullptr, received_frame.layers[0].buffer.get());
- ASSERT_TRUE(received_frame.layers[0].fence->isValid());
- ASSERT_EQ(frame.layers[0].display_frame.left,
- received_frame.layers[0].display_frame.left);
- ASSERT_EQ(frame.layers[0].display_frame.top,
- received_frame.layers[0].display_frame.top);
- ASSERT_EQ(frame.layers[0].display_frame.right,
- received_frame.layers[0].display_frame.right);
- ASSERT_EQ(frame.layers[0].display_frame.bottom,
- received_frame.layers[0].display_frame.bottom);
- ASSERT_EQ(frame.layers[0].crop.left, received_frame.layers[0].crop.left);
- ASSERT_EQ(frame.layers[0].crop.top, received_frame.layers[0].crop.top);
- ASSERT_EQ(frame.layers[0].crop.right, received_frame.layers[0].crop.right);
- ASSERT_EQ(frame.layers[0].crop.bottom, received_frame.layers[0].crop.bottom);
- ASSERT_EQ(frame.layers[0].blend_mode, received_frame.layers[0].blend_mode);
- ASSERT_EQ(frame.layers[0].alpha, received_frame.layers[0].alpha);
- ASSERT_EQ(frame.layers[0].type, received_frame.layers[0].type);
- ASSERT_EQ(frame.layers[0].app_id, received_frame.layers[0].app_id);
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/vr_composer.cpp b/services/vr/hardware_composer/vr_composer.cpp
deleted file mode 100644
index d93f370..0000000
--- a/services/vr/hardware_composer/vr_composer.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "vr_composer.h"
-
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionCache.h>
-
-namespace android {
-namespace dvr {
-namespace {
-
-bool CheckPermission() {
- const android::IPCThreadState* ipc = android::IPCThreadState::self();
- const pid_t pid = ipc->getCallingPid();
- const uid_t uid = ipc->getCallingUid();
- const bool permission = PermissionCache::checkPermission(
- String16("android.permission.RESTRICTED_VR_ACCESS"), pid, uid);
- if (!permission)
- ALOGE("permission denied to pid=%d uid=%u", pid, uid);
-
- return permission;
-}
-
-} // namespace
-
-VrComposer::VrComposer(ComposerView* composer_view)
- : composer_view_(composer_view) {
- composer_view_->RegisterObserver(this);
-}
-
-VrComposer::~VrComposer() {
- composer_view_->UnregisterObserver(this);
-}
-
-binder::Status VrComposer::registerObserver(
- const sp<IVrComposerCallback>& callback) {
- {
- std::lock_guard<std::mutex> guard(mutex_);
-
- if (!CheckPermission())
- return binder::Status::fromStatusT(PERMISSION_DENIED);
-
- if (callback_.get()) {
- ALOGE("Failed to register callback, already registered");
- return binder::Status::fromStatusT(ALREADY_EXISTS);
- }
-
- callback_ = callback;
- IInterface::asBinder(callback_)->linkToDeath(this);
- }
-
- // Don't take the lock to force display refresh otherwise it could end in a
- // deadlock since HWC calls this with new frames and it has a lock of its own
- // to serialize access to the display information.
- composer_view_->ForceDisplaysRefresh();
- return binder::Status::ok();
-}
-
-binder::Status VrComposer::clearObserver() {
- std::lock_guard<std::mutex> guard(mutex_);
- callback_ = nullptr;
- return binder::Status::ok();
-}
-
-base::unique_fd VrComposer::OnNewFrame(const ComposerView::Frame& frame) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- if (!callback_.get())
- return base::unique_fd();
-
- ParcelableComposerFrame parcelable_frame(frame);
- ParcelableUniqueFd fence;
- binder::Status ret = callback_->onNewFrame(parcelable_frame, &fence);
- if (!ret.isOk())
- ALOGE("Failed to send new frame: %s", ret.toString8().string());
-
- return fence.fence();
-}
-
-void VrComposer::binderDied(const wp<IBinder>& /* who */) {
- std::lock_guard<std::mutex> guard(mutex_);
-
- callback_ = nullptr;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/hardware_composer/vr_composer.h b/services/vr/hardware_composer/vr_composer.h
deleted file mode 100644
index 1273352..0000000
--- a/services/vr/hardware_composer/vr_composer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H
-
-#include <android/dvr/BnVrComposer.h>
-#include <impl/vr_hwc.h>
-
-namespace android {
-namespace dvr {
-
-class VrComposerCallback;
-
-// Implementation of the IVrComposer service used to notify VR Window Manager
-// when SurfaceFlinger presents 2D UI changes.
-//
-// VR HWC updates the presented frame via the ComposerView::Observer interface.
-// On notification |callback_| is called to update VR Window Manager.
-// NOTE: If VR Window Manager isn't connected, the notification is a no-op.
-class VrComposer
- : public BnVrComposer,
- public ComposerView::Observer,
- public IBinder::DeathRecipient {
- public:
- explicit VrComposer(ComposerView* composer_view);
- ~VrComposer() override;
-
- // BnVrComposer:
- binder::Status registerObserver(
- const sp<IVrComposerCallback>& callback) override;
-
- binder::Status clearObserver() override;
-
- // ComposerView::Observer:
- base::unique_fd OnNewFrame(const ComposerView::Frame& frame) override;
-
- private:
- // IBinder::DeathRecipient:
- void binderDied(const wp<IBinder>& who) override;
-
- std::mutex mutex_;
-
- sp<IVrComposerCallback> callback_;
-
- ComposerView* composer_view_; // Not owned.
-
- VrComposer(const VrComposer&) = delete;
- void operator=(const VrComposer&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 4927150..a99355f 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -1027,8 +1027,11 @@
}
}
-bool GetAndroidNativeBufferSpecVersion9Support(
- VkPhysicalDevice physicalDevice) {
+VkResult GetAndroidNativeBufferSpecVersion9Support(
+ VkPhysicalDevice physicalDevice,
+ bool& support) {
+ support = false;
+
const InstanceData& data = GetData(physicalDevice);
// Call to get propertyCount
@@ -1038,6 +1041,10 @@
physicalDevice, nullptr, &propertyCount, nullptr);
ATRACE_END();
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ return result;
+ }
+
// Call to enumerate properties
std::vector<VkExtensionProperties> properties(propertyCount);
ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
@@ -1045,6 +1052,10 @@
physicalDevice, nullptr, &propertyCount, properties.data());
ATRACE_END();
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ return result;
+ }
+
for (uint32_t i = 0; i < propertyCount; i++) {
auto& prop = properties[i];
@@ -1053,11 +1064,12 @@
continue;
if (prop.specVersion >= 9) {
- return true;
+ support = true;
+ return result;
}
}
- return false;
+ return result;
}
VkResult EnumerateDeviceExtensionProperties(
@@ -1101,18 +1113,30 @@
swapchainCompFeats.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT;
swapchainCompFeats.pNext = nullptr;
+ swapchainCompFeats.imageCompressionControlSwapchain = false;
VkPhysicalDeviceImageCompressionControlFeaturesEXT imageCompFeats = {};
imageCompFeats.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
imageCompFeats.pNext = &swapchainCompFeats;
+ imageCompFeats.imageCompressionControl = false;
VkPhysicalDeviceFeatures2 feats2 = {};
feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
feats2.pNext = &imageCompFeats;
- GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
+ const auto& driver = GetData(physicalDevice).driver;
+ if (driver.GetPhysicalDeviceFeatures2 ||
+ driver.GetPhysicalDeviceFeatures2KHR) {
+ GetPhysicalDeviceFeatures2(physicalDevice, &feats2);
+ }
- bool anb9 = GetAndroidNativeBufferSpecVersion9Support(physicalDevice);
+ bool anb9 = false;
+ VkResult result =
+ GetAndroidNativeBufferSpecVersion9Support(physicalDevice, anb9);
+
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ return result;
+ }
if (anb9 && imageCompFeats.imageCompressionControl) {
loader_extensions.push_back(
@@ -1142,7 +1166,7 @@
}
ATRACE_BEGIN("driver.EnumerateDeviceExtensionProperties");
- VkResult result = data.driver.EnumerateDeviceExtensionProperties(
+ result = data.driver.EnumerateDeviceExtensionProperties(
physicalDevice, pLayerName, pPropertyCount, pProperties);
ATRACE_END();
@@ -1532,6 +1556,11 @@
} break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT: {
+ VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*
+ compressionFeat = reinterpret_cast<
+ VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT*>(
+ pFeats);
+ compressionFeat->imageCompressionControlSwapchain = false;
imageCompressionControlSwapchainInChain = true;
} break;
@@ -1551,6 +1580,7 @@
imageCompFeats.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT;
imageCompFeats.pNext = nullptr;
+ imageCompFeats.imageCompressionControl = false;
VkPhysicalDeviceFeatures2 feats2 = {};
feats2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 48a75c5..2e22c36 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -950,27 +950,36 @@
return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice,
pSurfaceInfo->surface,
pSurfaceFormatCount, nullptr);
- } else {
- // temp vector for forwarding; we'll marshal it into the pSurfaceFormats
- // after the call.
- std::vector<VkSurfaceFormatKHR> surface_formats(*pSurfaceFormatCount);
- VkResult result = GetPhysicalDeviceSurfaceFormatsKHR(
- physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount,
- surface_formats.data());
+ }
- if (result == VK_SUCCESS || result == VK_INCOMPLETE) {
- const auto& driver = GetData(physicalDevice).driver;
+ // temp vector for forwarding; we'll marshal it into the pSurfaceFormats
+ // after the call.
+ std::vector<VkSurfaceFormatKHR> surface_formats(*pSurfaceFormatCount);
+ VkResult result = GetPhysicalDeviceSurfaceFormatsKHR(
+ physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount,
+ surface_formats.data());
- // marshal results individually due to stride difference.
- uint32_t formats_to_marshal = *pSurfaceFormatCount;
- for (uint32_t i = 0u; i < formats_to_marshal; i++) {
- pSurfaceFormats[i].surfaceFormat = surface_formats[i];
+ if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
+ return result;
+ }
- // Query the compression properties for the surface format
- if (pSurfaceFormats[i].pNext) {
+ const auto& driver = GetData(physicalDevice).driver;
+
+ // marshal results individually due to stride difference.
+ uint32_t formats_to_marshal = *pSurfaceFormatCount;
+ for (uint32_t i = 0u; i < formats_to_marshal; i++) {
+ pSurfaceFormats[i].surfaceFormat = surface_formats[i];
+
+ // Query the compression properties for the surface format
+ VkSurfaceFormat2KHR* pSurfaceFormat = &pSurfaceFormats[i];
+ while (pSurfaceFormat->pNext) {
+ pSurfaceFormat =
+ reinterpret_cast<VkSurfaceFormat2KHR*>(pSurfaceFormat->pNext);
+ switch (pSurfaceFormat->sType) {
+ case VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT: {
VkImageCompressionPropertiesEXT* surfaceCompressionProps =
reinterpret_cast<VkImageCompressionPropertiesEXT*>(
- pSurfaceFormats[i].pNext);
+ pSurfaceFormat);
if (surfaceCompressionProps &&
driver.GetPhysicalDeviceImageFormatProperties2KHR) {
@@ -1012,12 +1021,16 @@
return compressionRes;
}
}
- }
+ } break;
+
+ default:
+ // Ignore all other extension structs
+ break;
}
}
-
- return result;
}
+
+ return result;
}
VKAPI_ATTR