Merge "Reject usage == 0 in AHardwareBuffer_lock* functions" into main
diff --git a/Android.bp b/Android.bp
index 2520a71..4befb1b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -39,6 +39,11 @@
cc_library_headers {
name: "native_headers",
host_supported: true,
+ target: {
+ windows: {
+ enabled: true,
+ },
+ },
export_include_dirs: [
"include/",
],
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 1c4e63e..bc69b35 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -33,7 +33,6 @@
"libcutils",
"libz",
"libbase",
- "libpdx_default_transport",
"android.hardware.atrace@1.0",
],
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 4160a72..888dc4e 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -41,7 +41,6 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
-#include <pdx/default_transport/service_utility.h>
#include <utils/String8.h>
#include <utils/Timers.h>
#include <utils/Tokenizer.h>
@@ -53,7 +52,6 @@
#include <android-base/stringprintf.h>
using namespace android;
-using pdx::default_transport::ServiceUtility;
using hardware::hidl_vec;
using hardware::hidl_string;
using hardware::Return;
@@ -72,7 +70,6 @@
const char* k_traceAppsNumberProperty = "debug.atrace.app_number";
const char* k_traceAppsPropertyTemplate = "debug.atrace.app_%d";
const char* k_coreServiceCategory = "core_services";
-const char* k_pdxServiceCategory = "pdx";
const char* k_coreServicesProp = "ro.atrace.core.services";
const char* kVendorCategoriesPath = "/vendor/etc/atrace/atrace_categories.txt";
@@ -131,7 +128,6 @@
{ "nnapi", "NNAPI", ATRACE_TAG_NNAPI, { } },
{ "rro", "Runtime Resource Overlay", ATRACE_TAG_RRO, { } },
{ k_coreServiceCategory, "Core services", 0, { } },
- { k_pdxServiceCategory, "PDX services", 0, { } },
{ "sched", "CPU Scheduling", 0, {
{ REQ, "events/sched/sched_switch/enable" },
{ REQ, "events/sched/sched_wakeup/enable" },
@@ -299,7 +295,6 @@
static const char* g_outputFile = nullptr;
/* Global state */
-static bool g_tracePdx = false;
static bool g_traceAborted = false;
static bool g_categoryEnables[arraysize(k_categories)] = {};
static std::string g_traceFolder;
@@ -456,10 +451,6 @@
return !android::base::GetProperty(k_coreServicesProp, "").empty();
}
- if (strcmp(category.name, k_pdxServiceCategory) == 0) {
- return true;
- }
-
bool ok = category.tags != 0;
for (int i = 0; i < MAX_SYS_FILES; i++) {
const char* path = category.sysfiles[i].path;
@@ -818,11 +809,6 @@
if (strcmp(k_categories[i].name, k_coreServiceCategory) == 0) {
coreServicesTagEnabled = g_categoryEnables[i];
}
-
- // Set whether to poke PDX services in this session.
- if (strcmp(k_categories[i].name, k_pdxServiceCategory) == 0) {
- g_tracePdx = g_categoryEnables[i];
- }
}
std::string packageList(g_debugAppCmdLine);
@@ -834,9 +820,6 @@
}
ok &= setAppCmdlineProperty(&packageList[0]);
ok &= setTagsProperty(tags);
- if (g_tracePdx) {
- ok &= ServiceUtility::PokeServices();
- }
return ok;
}
@@ -845,10 +828,6 @@
{
setTagsProperty(0);
clearAppProperties();
-
- if (g_tracePdx) {
- ServiceUtility::PokeServices();
- }
}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6576ffd..220fef6 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1559,6 +1559,13 @@
CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
printf("========================================================\n");
+ printf("== Networking Policy\n");
+ printf("========================================================\n");
+
+ RunDumpsys("DUMPSYS NETWORK POLICY", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
+
+ printf("========================================================\n");
printf("== Dropbox crashes\n");
printf("========================================================\n");
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index c18d3f5..50c2cd8 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -24,7 +24,7 @@
cc_defaults {
name: "idlcli-defaults",
shared_libs: [
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/cmds/idlcli/vibrator.h b/cmds/idlcli/vibrator.h
index e100eac..b943495 100644
--- a/cmds/idlcli/vibrator.h
+++ b/cmds/idlcli/vibrator.h
@@ -49,7 +49,7 @@
template <typename I>
inline auto getService(std::string name) {
const auto instance = std::string() + I::descriptor + "/" + name;
- auto vibBinder = ndk::SpAIBinder(AServiceManager_getService(instance.c_str()));
+ auto vibBinder = ndk::SpAIBinder(AServiceManager_checkService(instance.c_str()));
return I::fromBinder(vibBinder);
}
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 9384926..28bd793 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -50,37 +50,6 @@
exit 1
fi
-# A source that infinitely emits arbitrary lines.
-# When connected to STDIN of another process, this source keeps STDIN open until
-# the consumer process closes STDIN or this script dies.
-function infinite_source {
- while echo .; do
- sleep 1
- done
-}
-
-PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
-if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 2 )); then
- # Delegate to Pre-reboot Dexopt, a feature of ART Service.
- # ART Service decides what to do with this request:
- # - If Pre-reboot Dexopt is disabled or unsupported, the command returns
- # non-zero. This is always the case if the current system is Android 14 or
- # earlier.
- # - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
- # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
- # not. This is the default behavior if the current system is Android 15.
- # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
- # an asynchronous job and returns 0 immediately. The job will then run by the
- # job scheduler when the device is idle and charging.
- if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
- # Handled by Pre-reboot Dexopt.
- exit 0
- fi
- echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."
-else
- echo "Pre-reboot Dexopt is too old. Fall back to otapreopt."
-fi
-
if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
# We require an updated chroot wrapper that reads dexopt commands from stdin.
# Even if we kept compat with the old binary, the OTA preopt wouldn't work due
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 1333599..ef2fa4d 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -29,6 +29,7 @@
#include <thread>
#if !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
+#include "perfetto/public/protos/trace/android/android_track_event.pzc.h"
#include "perfetto/public/te_category_macros.h"
#include "perfetto/public/te_macros.h"
#endif // !defined(VENDORSERVICEMANAGER) && !defined(__ANDROID_RECOVERY__)
@@ -57,6 +58,12 @@
#define SM_PERFETTO_TRACE_FUNC(...) \
PERFETTO_TE_SCOPED(servicemanager, PERFETTO_TE_SLICE_BEGIN(__func__) __VA_OPT__(, ) __VA_ARGS__)
+constexpr uint32_t kProtoServiceName =
+ perfetto_protos_AndroidTrackEvent_binder_service_name_field_number;
+constexpr uint32_t kProtoInterfaceName =
+ perfetto_protos_AndroidTrackEvent_binder_interface_name_field_number;
+constexpr uint32_t kProtoApexName = perfetto_protos_AndroidTrackEvent_apex_name_field_number;
+
#endif // !(defined(VENDORSERVICEMANAGER) || defined(__ANDROID_RECOVERY__))
bool is_multiuser_uid_isolated(uid_t uid) {
@@ -112,13 +119,15 @@
std::string iface;
std::string instance;
- static bool fill(const std::string& name, AidlName* aname) {
+ static bool fill(const std::string& name, AidlName* aname, bool logError) {
size_t firstSlash = name.find('/');
size_t lastDot = name.rfind('.', firstSlash);
if (firstSlash == std::string::npos || lastDot == std::string::npos) {
- ALOGE("VINTF HALs require names in the format type/instance (e.g. "
- "some.package.foo.IFoo/default) but got: %s",
- name.c_str());
+ if (logError) {
+ ALOGE("VINTF HALs require names in the format type/instance (e.g. "
+ "some.package.foo.IFoo/default) but got: %s",
+ name.c_str());
+ }
return false;
}
aname->package = name.substr(0, lastDot);
@@ -151,7 +160,7 @@
}
AidlName aname;
- if (!AidlName::fill(name, &aname)) return false;
+ if (!AidlName::fill(name, &aname, true)) return false;
bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
@@ -209,7 +218,7 @@
}
AidlName aname;
- if (!AidlName::fill(name, &aname)) return std::nullopt;
+ if (!AidlName::fill(name, &aname, true)) return std::nullopt;
std::optional<std::string> updatableViaApex;
@@ -249,9 +258,28 @@
return names;
}
+static std::optional<std::string> getVintfAccessorName(const std::string& name) {
+ AidlName aname;
+ if (!AidlName::fill(name, &aname, false)) return std::nullopt;
+
+ std::optional<std::string> accessor;
+ forEachManifest([&](const ManifestWithDescription& mwd) {
+ mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
+ if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
+ if (manifestInstance.package() != aname.package) return true;
+ if (manifestInstance.interface() != aname.iface) return true;
+ if (manifestInstance.instance() != aname.instance) return true;
+ accessor = manifestInstance.accessor();
+ return false; // break (libvintf uses opposite convention)
+ });
+ return false; // continue
+ });
+ return accessor;
+}
+
static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
AidlName aname;
- if (!AidlName::fill(name, &aname)) return std::nullopt;
+ if (!AidlName::fill(name, &aname, true)) return std::nullopt;
std::optional<std::string> ip;
std::optional<uint64_t> port;
@@ -365,23 +393,52 @@
}
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
- *outBinder = tryGetService(name, true);
+ *outBinder = tryGetBinder(name, true);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
-Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+Status ServiceManager::getService2(const std::string& name, os::Service* outService) {
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
- *outBinder = tryGetService(name, false);
+ *outService = tryGetService(name, true);
// returns ok regardless of result for legacy reasons
return Status::ok();
}
-sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+Status ServiceManager::checkService(const std::string& name, os::Service* outService) {
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
+
+ *outService = tryGetService(name, false);
+ // returns ok regardless of result for legacy reasons
+ return Status::ok();
+}
+
+os::Service ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
+ std::optional<std::string> accessorName;
+#ifndef VENDORSERVICEMANAGER
+ accessorName = getVintfAccessorName(name);
+#endif
+ if (accessorName.has_value()) {
+ auto ctx = mAccess->getCallingContext();
+ if (!mAccess->canFind(ctx, name)) {
+ return os::Service::make<os::Service::Tag::accessor>(nullptr);
+ }
+ return os::Service::make<os::Service::Tag::accessor>(
+ tryGetBinder(*accessorName, startIfNotFound));
+ } else {
+ return os::Service::make<os::Service::Tag::binder>(tryGetBinder(name, startIfNotFound));
+ }
+}
+
+sp<IBinder> ServiceManager::tryGetBinder(const std::string& name, bool startIfNotFound) {
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
@@ -421,7 +478,8 @@
}
bool isValidServiceName(const std::string& name) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
if (name.size() == 0) return false;
if (name.size() > 127) return false;
@@ -438,7 +496,8 @@
}
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
@@ -561,12 +620,16 @@
Status ServiceManager::registerForNotifications(
const std::string& name, const sp<IServiceCallback>& callback) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux");
+ // TODO(b/338541373): Implement the notification mechanism for services accessed via
+ // IAccessor.
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
// note - we could allow isolated apps to get notifications if we
@@ -609,12 +672,14 @@
}
Status ServiceManager::unregisterForNotifications(
const std::string& name, const sp<IServiceCallback>& callback) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
bool found = false;
@@ -634,12 +699,14 @@
}
Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> accessorName;
+ if (auto status = canFindService(ctx, name, &accessorName); !status.isOk()) {
+ return status;
}
*outReturn = false;
@@ -651,7 +718,8 @@
}
binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("interface", interface.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoInterfaceName, interface.c_str())));
auto ctx = mAccess->getCallingContext();
@@ -662,8 +730,10 @@
outReturn->clear();
+ std::optional<std::string> _accessorName;
for (const std::string& instance : allInstances) {
- if (mAccess->canFind(ctx, interface + "/" + instance)) {
+ if (auto status = canFindService(ctx, interface + "/" + instance, &_accessorName);
+ status.isOk()) {
outReturn->push_back(instance);
}
}
@@ -677,12 +747,14 @@
Status ServiceManager::updatableViaApex(const std::string& name,
std::optional<std::string>* outReturn) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> _accessorName;
+ if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+ return status;
}
*outReturn = std::nullopt;
@@ -695,7 +767,8 @@
Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
std::vector<std::string>* outReturn) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("apexName", apexName.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoApexName, apexName.c_str())));
auto ctx = mAccess->getCallingContext();
@@ -706,8 +779,9 @@
outReturn->clear();
+ std::optional<std::string> _accessorName;
for (const std::string& name : apexUpdatableNames) {
- if (mAccess->canFind(ctx, name)) {
+ if (auto status = canFindService(ctx, name, &_accessorName); status.isOk()) {
outReturn->push_back(name);
}
}
@@ -720,12 +794,14 @@
Status ServiceManager::getConnectionInfo(const std::string& name,
std::optional<ConnectionInfo>* outReturn) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
auto ctx = mAccess->getCallingContext();
- if (!mAccess->canFind(ctx, name)) {
- return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied.");
+ std::optional<std::string> _accessorName;
+ if (auto status = canFindService(ctx, name, &_accessorName); !status.isOk()) {
+ return status;
}
*outReturn = std::nullopt;
@@ -804,7 +880,8 @@
Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
const sp<IClientCallback>& cb) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
if (cb == nullptr) {
return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Callback null.");
@@ -966,7 +1043,8 @@
}
Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
- SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_ARG_STRING("name", name.c_str()));
+ SM_PERFETTO_TRACE_FUNC(PERFETTO_TE_PROTO_FIELDS(
+ PERFETTO_TE_PROTO_FIELD_CSTR(kProtoServiceName, name.c_str())));
if (binder == nullptr) {
return Status::fromExceptionCode(Status::EX_NULL_POINTER, "Null service.");
@@ -1032,6 +1110,23 @@
return Status::ok();
}
+Status ServiceManager::canFindService(const Access::CallingContext& ctx, const std::string& name,
+ std::optional<std::string>* accessor) {
+ if (!mAccess->canFind(ctx, name)) {
+ return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denied for service.");
+ }
+#ifndef VENDORSERVICEMANAGER
+ *accessor = getVintfAccessorName(name);
+#endif
+ if (accessor->has_value()) {
+ if (!mAccess->canFind(ctx, accessor->value())) {
+ return Status::fromExceptionCode(Status::EX_SECURITY,
+ "SELinux denied for the accessor of the service.");
+ }
+ }
+ return Status::ok();
+}
+
Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
SM_PERFETTO_TRACE_FUNC();
if (!mAccess->canList(mAccess->getCallingContext())) {
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 1536014..0d666c6 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -45,7 +45,8 @@
// getService will try to start any services it cannot find
binder::Status getService(const std::string& name, sp<IBinder>* outBinder) override;
- binder::Status checkService(const std::string& name, sp<IBinder>* outBinder) override;
+ binder::Status getService2(const std::string& name, os::Service* outService) override;
+ binder::Status checkService(const std::string& name, os::Service* outService) override;
binder::Status addService(const std::string& name, const sp<IBinder>& binder,
bool allowIsolated, int32_t dumpPriority) override;
binder::Status listServices(int32_t dumpPriority, std::vector<std::string>* outList) override;
@@ -112,7 +113,10 @@
// this updates the iterator to the next location
void removeClientCallback(const wp<IBinder>& who, ClientCallbackMap::iterator* it);
- sp<IBinder> tryGetService(const std::string& name, bool startIfNotFound);
+ os::Service tryGetService(const std::string& name, bool startIfNotFound);
+ sp<IBinder> tryGetBinder(const std::string& name, bool startIfNotFound);
+ binder::Status canFindService(const Access::CallingContext& ctx, const std::string& name,
+ std::optional<std::string>* accessor);
ServiceMap mNameToService;
ServiceCallbackMap mNameToRegistrationCallback;
diff --git a/cmds/servicemanager/test_sm.cpp b/cmds/servicemanager/test_sm.cpp
index b575053..95f459f 100644
--- a/cmds/servicemanager/test_sm.cpp
+++ b/cmds/servicemanager/test_sm.cpp
@@ -38,6 +38,7 @@
using android::binder::Status;
using android::os::BnServiceCallback;
using android::os::IServiceManager;
+using android::os::Service;
using testing::_;
using testing::ElementsAre;
using testing::NiceMock;
@@ -153,18 +154,24 @@
EXPECT_TRUE(sm->addService("foo", serviceA, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> outA;
- EXPECT_TRUE(sm->getService("foo", &outA).isOk());
- EXPECT_EQ(serviceA, outA);
+ Service outA;
+ EXPECT_TRUE(sm->getService2("foo", &outA).isOk());
+ EXPECT_EQ(serviceA, outA.get<Service::Tag::binder>());
+ sp<IBinder> outBinderA;
+ EXPECT_TRUE(sm->getService("foo", &outBinderA).isOk());
+ EXPECT_EQ(serviceA, outBinderA);
// serviceA should be overwritten by serviceB
sp<IBinder> serviceB = getBinder();
EXPECT_TRUE(sm->addService("foo", serviceB, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> outB;
- EXPECT_TRUE(sm->getService("foo", &outB).isOk());
- EXPECT_EQ(serviceB, outB);
+ Service outB;
+ EXPECT_TRUE(sm->getService2("foo", &outB).isOk());
+ EXPECT_EQ(serviceB, outB.get<Service::Tag::binder>());
+ sp<IBinder> outBinderB;
+ EXPECT_TRUE(sm->getService("foo", &outBinderB).isOk());
+ EXPECT_EQ(serviceB, outBinderB);
}
TEST(AddService, NoPermissions) {
@@ -186,17 +193,23 @@
EXPECT_TRUE(sm->addService("foo", service, false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
- EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(service, out);
+ Service out;
+ EXPECT_TRUE(sm->getService2("foo", &out).isOk());
+ EXPECT_EQ(service, out.get<Service::Tag::binder>());
+ sp<IBinder> outBinder;
+ EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
+ EXPECT_EQ(service, outBinder);
}
TEST(GetService, NonExistant) {
auto sm = getPermissiveServiceManager();
- sp<IBinder> out;
- EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ Service out;
+ EXPECT_TRUE(sm->getService2("foo", &out).isOk());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ sp<IBinder> outBinder;
+ EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
+ EXPECT_EQ(nullptr, outBinder);
}
TEST(GetService, NoPermissionsForGettingService) {
@@ -204,31 +217,37 @@
EXPECT_CALL(*access, getCallingContext()).WillRepeatedly(Return(Access::CallingContext{}));
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
- EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(false));
+ EXPECT_CALL(*access, canFind(_, _)).WillRepeatedly(Return(false));
sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
// returns nullptr but has OK status for legacy compatibility
- EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ EXPECT_TRUE(sm->getService2("foo", &out).isOk());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ sp<IBinder> outBinder;
+ EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
+ EXPECT_EQ(nullptr, outBinder);
}
TEST(GetService, AllowedFromIsolated) {
std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>();
EXPECT_CALL(*access, getCallingContext())
- // something adds it
- .WillOnce(Return(Access::CallingContext{}))
- // next call is from isolated app
- .WillOnce(Return(Access::CallingContext{
- .uid = AID_ISOLATED_START,
- }));
+ // something adds it
+ .WillOnce(Return(Access::CallingContext{}))
+ // next calls is from isolated app
+ .WillOnce(Return(Access::CallingContext{
+ .uid = AID_ISOLATED_START,
+ }))
+ .WillOnce(Return(Access::CallingContext{
+ .uid = AID_ISOLATED_START,
+ }));
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
- EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true));
+ EXPECT_CALL(*access, canFind(_, _)).WillRepeatedly(Return(true));
sp<ServiceManager> sm = sp<NiceMock<MockServiceManager>>::make(std::move(access));
@@ -236,21 +255,27 @@
EXPECT_TRUE(sm->addService("foo", service, true /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
- EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(service, out.get());
+ Service out;
+ EXPECT_TRUE(sm->getService2("foo", &out).isOk());
+ EXPECT_EQ(service, out.get<Service::Tag::binder>());
+ sp<IBinder> outBinder;
+ EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
+ EXPECT_EQ(service, outBinder);
}
TEST(GetService, NotAllowedFromIsolated) {
std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>();
EXPECT_CALL(*access, getCallingContext())
- // something adds it
- .WillOnce(Return(Access::CallingContext{}))
- // next call is from isolated app
- .WillOnce(Return(Access::CallingContext{
- .uid = AID_ISOLATED_START,
- }));
+ // something adds it
+ .WillOnce(Return(Access::CallingContext{}))
+ // next calls is from isolated app
+ .WillOnce(Return(Access::CallingContext{
+ .uid = AID_ISOLATED_START,
+ }))
+ .WillOnce(Return(Access::CallingContext{
+ .uid = AID_ISOLATED_START,
+ }));
EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true));
// TODO(b/136023468): when security check is first, this should be called first
@@ -261,10 +286,13 @@
EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/,
IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk());
- sp<IBinder> out;
+ Service out;
// returns nullptr but has OK status for legacy compatibility
- EXPECT_TRUE(sm->getService("foo", &out).isOk());
- EXPECT_EQ(nullptr, out.get());
+ EXPECT_TRUE(sm->getService2("foo", &out).isOk());
+ EXPECT_EQ(nullptr, out.get<Service::Tag::binder>());
+ sp<IBinder> outBinder;
+ EXPECT_TRUE(sm->getService("foo", &outBinder).isOk());
+ EXPECT_EQ(nullptr, outBinder);
}
TEST(ListServices, NoPermissions) {
diff --git a/data/etc/input/motion_predictor_config.xml b/data/etc/input/motion_predictor_config.xml
index c3f2fed..14540ec 100644
--- a/data/etc/input/motion_predictor_config.xml
+++ b/data/etc/input/motion_predictor_config.xml
@@ -35,7 +35,10 @@
The jerk thresholds are based on normalized dt = 1 calculations.
-->
- <low-jerk>1.0</low-jerk>
- <high-jerk>1.1</high-jerk>
+ <low-jerk>1.5</low-jerk>
+ <high-jerk>2.0</high-jerk>
+
+ <!-- The forget factor in the first-order IIR filter for jerk smoothing -->
+ <jerk-forget-factor>0.25</jerk-forget-factor>
</motion-predictor>
diff --git a/include/ftl/fake_guard.h b/include/ftl/fake_guard.h
index e601251..0bf2870 100644
--- a/include/ftl/fake_guard.h
+++ b/include/ftl/fake_guard.h
@@ -76,12 +76,8 @@
FTL_ATTRIBUTE(release_capability(mutex))
#endif
-// The parentheses around `expr` are needed to deduce an lvalue or rvalue reference.
-#define FTL_FAKE_GUARD2(mutex, expr) \
- [&]() -> decltype(auto) { \
- const android::ftl::FakeGuard guard(mutex); \
- return (expr); \
- }()
+#define FTL_FAKE_GUARD2(mutex, expr) \
+ (android::ftl::FakeGuard(mutex), expr)
#define FTL_MAKE_FAKE_GUARD(arg1, arg2, guard, ...) guard
diff --git a/include/input/Input.h b/include/input/Input.h
index 77d7448..1a3cb6a 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -900,9 +900,7 @@
void splitFrom(const MotionEvent& other, std::bitset<MAX_POINTER_ID + 1> splitPointerIds,
int32_t newEventId);
- void addSample(
- nsecs_t eventTime,
- const PointerCoords* pointerCoords);
+ void addSample(nsecs_t eventTime, const PointerCoords* pointerCoords, int32_t eventId);
void offsetLocation(float xOffset, float yOffset);
diff --git a/include/input/InputConsumerNoResampling.h b/include/input/InputConsumerNoResampling.h
index c7b1970..ae8de5f 100644
--- a/include/input/InputConsumerNoResampling.h
+++ b/include/input/InputConsumerNoResampling.h
@@ -16,8 +16,8 @@
#pragma once
+#include <input/InputTransport.h>
#include <utils/Looper.h>
-#include "InputTransport.h"
namespace android {
@@ -182,6 +182,16 @@
*/
std::map<DeviceId, std::queue<InputMessage>> mBatches;
/**
+ * Creates a MotionEvent by consuming samples from the provided queue. If one message has
+ * eventTime > frameTime, all subsequent messages in the queue will be skipped. It is assumed
+ * that messages are queued in chronological order. In other words, only events that occurred
+ * prior to the requested frameTime will be consumed.
+ * @param frameTime the time up to which to consume events
+ * @param messages the queue of messages to consume from
+ */
+ std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>> createBatchedMotionEvent(
+ const nsecs_t frameTime, std::queue<InputMessage>& messages);
+ /**
* A map from a single sequence number to several sequence numbers. This is needed because of
* batching. When batching is enabled, a single MotionEvent will contain several samples. Each
* sample came from an individual InputMessage of Type::Motion, and therefore will have to be
diff --git a/include/input/MotionPredictor.h b/include/input/MotionPredictor.h
index f715039..2f1ef86 100644
--- a/include/input/MotionPredictor.h
+++ b/include/input/MotionPredictor.h
@@ -56,12 +56,20 @@
// acceleration) and has the units of d^3p/dt^3.
std::optional<float> jerkMagnitude() const;
+ // forgetFactor is the coefficient of the first-order IIR filter for jerk. A factor of 1 results
+ // in no smoothing.
+ void setForgetFactor(float forgetFactor);
+ float getForgetFactor() const;
+
private:
const bool mNormalizedDt;
+ // Coefficient of first-order IIR filter to smooth jerk calculation.
+ float mForgetFactor = 1;
RingBuffer<int64_t> mTimestamps{4};
std::array<float, 4> mXDerivatives{}; // [x, x', x'', x''']
std::array<float, 4> mYDerivatives{}; // [y, y', y'', y''']
+ float mJerkMagnitude;
};
/**
@@ -116,6 +124,11 @@
bool isPredictionAvailable(int32_t deviceId, int32_t source);
+ /**
+ * Currently used to expose config constants in testing.
+ */
+ const TfLiteMotionPredictorModel::Config& getModelConfig();
+
private:
const nsecs_t mPredictionTimestampOffsetNanos;
const std::function<bool()> mCheckMotionPredictionEnabled;
diff --git a/include/input/TfLiteMotionPredictor.h b/include/input/TfLiteMotionPredictor.h
index 728a8e1..08a4330 100644
--- a/include/input/TfLiteMotionPredictor.h
+++ b/include/input/TfLiteMotionPredictor.h
@@ -110,6 +110,9 @@
// High jerk means more predictions will be pruned, vice versa for low.
float lowJerk = 0;
float highJerk = 0;
+
+ // Coefficient for the first-order IIR filter for jerk calculation.
+ float jerkForgetFactor = 1;
};
// Creates a model from an encoded Flatbuffer model.
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index cdc7166..de331b7 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -450,8 +450,31 @@
],
}
+soong_config_module_type {
+ name: "libbinder_client_cache_config",
+ module_type: "cc_defaults",
+ config_namespace: "libbinder",
+ bool_variables: ["release_libbinder_client_cache"],
+ properties: [
+ "cflags",
+ ],
+}
+
+libbinder_client_cache_config {
+ name: "libbinder_client_cache_flag",
+ soong_config_variables: {
+ release_libbinder_client_cache: {
+ cflags: ["-DLIBBINDER_CLIENT_CACHE"],
+ conditions_default: {
+ cflags: ["-DNO_LIBBINDER_CLIENT_CACHE"],
+ },
+ },
+ },
+}
+
cc_defaults {
name: "libbinder_kernel_defaults",
+ defaults: ["libbinder_client_cache_flag"],
srcs: [
"BufferedTextOutput.cpp",
"BackendUnifiedServiceManager.cpp",
@@ -771,11 +794,41 @@
"aidl/android/os/IClientCallback.aidl",
"aidl/android/os/IServiceCallback.aidl",
"aidl/android/os/IServiceManager.aidl",
+ "aidl/android/os/Service.aidl",
"aidl/android/os/ServiceDebugInfo.aidl",
+ ":libbinder_accessor_aidl",
],
path: "aidl",
}
+filegroup {
+ name: "libbinder_accessor_aidl",
+ srcs: [
+ "aidl/android/os/IAccessor.aidl",
+ ],
+ path: "aidl",
+}
+
+// TODO(b/353492849): Make this interface private to libbinder.
+aidl_interface {
+ name: "android.os.accessor",
+ srcs: [":libbinder_accessor_aidl"],
+ unstable: true,
+ backend: {
+ rust: {
+ enabled: true,
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
+ },
+ visibility: [
+ ":__subpackages__",
+ "//system/tools/aidl:__subpackages__",
+ "//packages/modules/Virtualization:__subpackages__",
+ ],
+}
+
aidl_interface {
name: "packagemanager_aidl",
unstable: true,
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index b0d3048..54f687b 100644
--- a/libs/binder/BackendUnifiedServiceManager.cpp
+++ b/libs/binder/BackendUnifiedServiceManager.cpp
@@ -15,6 +15,9 @@
*/
#include "BackendUnifiedServiceManager.h"
+#include <android/os/IAccessor.h>
+#include <binder/RpcSession.h>
+
#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__)
#include <android-base/properties.h>
#endif
@@ -22,6 +25,7 @@
namespace android {
using AidlServiceManager = android::os::IServiceManager;
+using IAccessor = android::os::IAccessor;
BackendUnifiedServiceManager::BackendUnifiedServiceManager(const sp<AidlServiceManager>& impl)
: mTheRealServiceManager(impl) {}
@@ -29,14 +33,67 @@
sp<AidlServiceManager> BackendUnifiedServiceManager::getImpl() {
return mTheRealServiceManager;
}
+
binder::Status BackendUnifiedServiceManager::getService(const ::std::string& name,
sp<IBinder>* _aidl_return) {
- return mTheRealServiceManager->getService(name, _aidl_return);
+ os::Service service;
+ binder::Status status = getService2(name, &service);
+ *_aidl_return = service.get<os::Service::Tag::binder>();
+ return status;
}
+
+binder::Status BackendUnifiedServiceManager::getService2(const ::std::string& name,
+ os::Service* _out) {
+ os::Service service;
+ binder::Status status = mTheRealServiceManager->getService2(name, &service);
+ toBinderService(service, _out);
+ return status;
+}
+
binder::Status BackendUnifiedServiceManager::checkService(const ::std::string& name,
- sp<IBinder>* _aidl_return) {
- return mTheRealServiceManager->checkService(name, _aidl_return);
+ os::Service* _out) {
+ os::Service service;
+ binder::Status status = mTheRealServiceManager->checkService(name, &service);
+ toBinderService(service, _out);
+ return status;
}
+
+void BackendUnifiedServiceManager::toBinderService(const os::Service& in, os::Service* _out) {
+ switch (in.getTag()) {
+ case os::Service::Tag::binder: {
+ *_out = in;
+ break;
+ }
+ case os::Service::Tag::accessor: {
+ sp<IBinder> accessorBinder = in.get<os::Service::Tag::accessor>();
+ sp<IAccessor> accessor = interface_cast<IAccessor>(accessorBinder);
+ if (accessor == nullptr) {
+ ALOGE("Service#accessor doesn't have accessor. VM is maybe starting...");
+ *_out = os::Service::make<os::Service::Tag::binder>(nullptr);
+ break;
+ }
+ auto request = [=] {
+ os::ParcelFileDescriptor fd;
+ binder::Status ret = accessor->addConnection(&fd);
+ if (ret.isOk()) {
+ return base::unique_fd(fd.release());
+ } else {
+ ALOGE("Failed to connect to RpcSession: %s", ret.toString8().c_str());
+ return base::unique_fd(-1);
+ }
+ };
+ auto session = RpcSession::make();
+ session->setupPreconnectedClient(base::unique_fd{}, request);
+ session->setSessionSpecificRoot(accessorBinder);
+ *_out = os::Service::make<os::Service::Tag::binder>(session->getRootObject());
+ break;
+ }
+ default: {
+ LOG_ALWAYS_FATAL("Unknown service type: %d", in.getTag());
+ }
+ }
+}
+
binder::Status BackendUnifiedServiceManager::addService(const ::std::string& name,
const sp<IBinder>& service,
bool allowIsolated, int32_t dumpPriority) {
diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h
index d72b5bb..f5d7e66 100644
--- a/libs/binder/BackendUnifiedServiceManager.h
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -27,7 +27,8 @@
sp<os::IServiceManager> getImpl();
binder::Status getService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
- binder::Status checkService(const ::std::string& name, sp<IBinder>* _aidl_return) override;
+ binder::Status getService2(const ::std::string& name, os::Service* out) override;
+ binder::Status checkService(const ::std::string& name, os::Service* out) override;
binder::Status addService(const ::std::string& name, const sp<IBinder>& service,
bool allowIsolated, int32_t dumpPriority) override;
binder::Status listServices(int32_t dumpPriority,
@@ -60,6 +61,7 @@
private:
sp<os::IServiceManager> mTheRealServiceManager;
+ void toBinderService(const os::Service& in, os::Service* _out);
};
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 17e522d..8b80aed 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -26,6 +26,7 @@
#include <android-base/properties.h>
#include <android/os/BnServiceCallback.h>
+#include <android/os/IAccessor.h>
#include <android/os/IServiceManager.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
@@ -57,6 +58,8 @@
using AidlServiceManager = android::os::IServiceManager;
using android::binder::Status;
+using android::os::IAccessor;
+using android::os::Service;
// libbinder's IServiceManager.h can't rely on the values generated by AIDL
// because many places use its headers via include_dirs (meaning, without
@@ -139,7 +142,10 @@
// When implementing ServiceManagerShim, use realGetService instead of
// mUnifiedServiceManager->getService so that it can be overridden in ServiceManagerHostShim.
virtual Status realGetService(const std::string& name, sp<IBinder>* _aidl_return) {
- return mUnifiedServiceManager->getService(name, _aidl_return);
+ Service service;
+ Status status = mUnifiedServiceManager->getService2(name, &service);
+ *_aidl_return = service.get<Service::Tag::binder>();
+ return status;
}
};
@@ -327,11 +333,11 @@
sp<IBinder> ServiceManagerShim::checkService(const String16& name) const
{
- sp<IBinder> ret;
+ Service ret;
if (!mUnifiedServiceManager->checkService(String8(name).c_str(), &ret).isOk()) {
return nullptr;
}
- return ret;
+ return ret.get<Service::Tag::binder>();
}
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index 16a7f9f..49def82 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -801,6 +801,14 @@
return true;
}
+void RpcSession::setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot) {
+ LOG_ALWAYS_FATAL_IF(mSessionSpecificRootObject != nullptr,
+ "Session specific root object already set");
+ LOG_ALWAYS_FATAL_IF(mForServer != nullptr,
+ "Session specific root object cannot be set for a server");
+ mSessionSpecificRootObject = sessionSpecificRoot;
+}
+
sp<RpcSession::RpcConnection> RpcSession::assignIncomingConnectionToThisThread(
std::unique_ptr<RpcTransport> rpcTransport) {
RpcMutexLockGuard _l(mMutex);
diff --git a/libs/binder/aidl/android/os/IAccessor.aidl b/libs/binder/aidl/android/os/IAccessor.aidl
new file mode 100644
index 0000000..a3134a3
--- /dev/null
+++ b/libs/binder/aidl/android/os/IAccessor.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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 android.os;
+
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Interface for accessing the RPC server of a service.
+ *
+ * @hide
+ */
+interface IAccessor {
+ /**
+ * Adds a connection to the RPC server of the service managed by the IAccessor.
+ *
+ * This method can be called multiple times to establish multiple distinct
+ * connections to the same RPC server.
+ *
+ * @return A file descriptor connected to the RPC session of the service managed
+ * by IAccessor.
+ */
+ ParcelFileDescriptor addConnection();
+
+ // TODO(b/350941051): Add API for debugging.
+}
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 0fb1615..1d1f84f 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -18,6 +18,7 @@
import android.os.IClientCallback;
import android.os.IServiceCallback;
+import android.os.Service;
import android.os.ServiceDebugInfo;
import android.os.ConnectionInfo;
@@ -59,17 +60,31 @@
* exists for legacy purposes.
*
* Returns null if the service does not exist.
+ *
+ * @deprecated TODO(b/355394904): Use getService2 instead.
*/
@UnsupportedAppUsage
@nullable IBinder getService(@utf8InCpp String name);
/**
+ * Retrieve an existing service called @a name from the
+ * service manager.
+ *
+ * This is the same as checkService (returns immediately) but
+ * exists for legacy purposes.
+ *
+ * Returns an enum Service that can be of different types. The
+ * enum value is null if the service does not exist.
+ */
+ Service getService2(@utf8InCpp String name);
+
+ /**
* Retrieve an existing service called @a name from the service
* manager. Non-blocking. Returns null if the service does not
* exist.
*/
@UnsupportedAppUsage
- @nullable IBinder checkService(@utf8InCpp String name);
+ Service checkService(@utf8InCpp String name);
/**
* Place a new @a service called @a name into the service
diff --git a/libs/binder/aidl/android/os/Service.aidl b/libs/binder/aidl/android/os/Service.aidl
new file mode 100644
index 0000000..4c52109
--- /dev/null
+++ b/libs/binder/aidl/android/os/Service.aidl
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 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 android.os;
+
+/**
+ * Service is a union of different service types that can be returned
+ * by the internal {@link ServiceManager#getService(name)} API.
+ *
+ * @hide
+ */
+union Service {
+ @nullable IBinder binder;
+ @nullable IBinder accessor;
+}
\ No newline at end of file
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index 40102bb..af37bf2 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -220,6 +220,12 @@
// internal only
LIBBINDER_EXPORTED const std::unique_ptr<RpcState>& state() { return mRpcBinderState; }
+ /**
+ * Sets the session-specific root object. This is the object that will be used to attach
+ * the IAccessor binder to the RpcSession when a binder is set up via accessor.
+ */
+ LIBBINDER_EXPORTED void setSessionSpecificRoot(const sp<IBinder>& sessionSpecificRoot);
+
private:
friend sp<RpcSession>;
friend RpcServer;
diff --git a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
index bfba79f..c1d0e9f 100644
--- a/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
+++ b/libs/binder/ndk/include_cpp/android/persistable_bundle_aidl.h
@@ -25,11 +25,13 @@
// Include llndk-versioning.h only for vendor build as it is not available for NDK headers.
#if defined(__ANDROID_VENDOR__)
#include <android/llndk-versioning.h>
-#else // __ANDROID_VENDOR__
-#if !defined(API_LEVEL_AT_LEAST)
+#elif !defined(API_LEVEL_AT_LEAST)
+#if defined(__BIONIC__)
#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) \
(__builtin_available(android sdk_api_level, *))
-#endif
+#else
+#define API_LEVEL_AT_LEAST(sdk_api_level, vendor_api_level) (true)
+#endif // __BIONIC__
#endif // __ANDROID_VENDOR__
namespace aidl::android::os {
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 14edf2b..e968bac 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -117,9 +117,9 @@
};
/**
- * One of the EXCEPTION_* types.
+ * One of the EX_* enumerators.
*
- * All unrecognized values are coerced into EXCEPTION_TRANSACTION_FAILED.
+ * All unrecognized values are coerced into EX_TRANSACTION_FAILED.
*
* These exceptions values are used by the SDK for parcelables. Also see Parcel.java.
*/
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 18b178b..be99065 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -123,8 +123,11 @@
// We can't send BpBinder for regular binder over RPC.
return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
}
- android::binder::Status checkService(const std::string&,
- android::sp<android::IBinder>*) override {
+ android::binder::Status getService2(const std::string&, android::os::Service*) override {
+ // We can't send BpBinder for regular binder over RPC.
+ return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
+ }
+ android::binder::Status checkService(const std::string&, android::os::Service*) override {
// We can't send BpBinder for regular binder over RPC.
return android::binder::Status::fromStatusT(android::INVALID_OPERATION);
}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 4c7684c..dd50fbd 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -235,6 +235,16 @@
"binder_test_defaults",
],
+ compile_multilib: "both",
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+
static_libs: [
"libbinder_test_utils",
"libbinder_tls_static",
@@ -267,7 +277,6 @@
defaults: [
"binderRpcTest_common_defaults",
],
- compile_multilib: "first",
srcs: [
"binderRpcTest.cpp",
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 9b1b64a..cd78e82 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -19,6 +19,12 @@
#include <aidl/IBinderRpcTest.h>
#endif
+#if defined(__LP64__)
+#define TEST_FILE_SUFFIX "64"
+#else
+#define TEST_FILE_SUFFIX "32"
+#endif
+
#include <chrono>
#include <cstdlib>
#include <iostream>
@@ -259,7 +265,8 @@
std::string path = GetExecutableDirectory();
auto servicePath = path + "/binder_rpc_test_service" +
- (singleThreaded ? "_single_threaded" : "") + (noKernel ? "_no_kernel" : "");
+ (singleThreaded ? "_single_threaded" : "") + (noKernel ? "_no_kernel" : "") +
+ TEST_FILE_SUFFIX;
unique_fd bootstrapClientFd, socketFd;
@@ -1168,7 +1175,8 @@
socklen_t len = sizeof(serverAddr);
ret = getsockname(serverFd.get(), reinterpret_cast<sockaddr*>(&serverAddr), &len);
LOG_ALWAYS_FATAL_IF(0 != ret, "Failed to getsockname: %s", strerror(errno));
- LOG_ALWAYS_FATAL_IF(len < sizeof(serverAddr), "getsockname didn't read the full addr struct");
+ LOG_ALWAYS_FATAL_IF(len < static_cast<socklen_t>(sizeof(serverAddr)),
+ "getsockname didn't read the full addr struct");
ret = TEMP_FAILURE_RETRY(listen(serverFd.get(), 1 /*backlog*/));
LOG_ALWAYS_FATAL_IF(0 != ret, "Could not listen socket on port %u: %s", serverAddr.svm_port,
diff --git a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
index 62b8433..7c19614 100644
--- a/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
+++ b/libs/binder/tests/parcel_fuzzer/random_parcel.cpp
@@ -111,7 +111,9 @@
} else {
binder = getRandomBinder(&provider);
}
- CHECK(OK == p->writeStrongBinder(binder));
+
+ // may fail if mixing kernel binder and RPC binder
+ (void) p->writeStrongBinder(binder);
},
});
diff --git a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
index ff3ae5a..4f293b9 100644
--- a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
+++ b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
@@ -1,7 +1,5 @@
package com.android.graphics.bufferstreamsdemoapp
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -29,10 +27,11 @@
navigationIcon = {
if (canNavigateBack) {
IconButton(onClick = navigateUp) {
- Icon(
- imageVector = Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = stringResource(R.string.back_button)
- )
+ // b/355293776
+ // Icon(
+ // imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ // contentDescription = stringResource(R.string.back_button)
+ // )
}
}
}
diff --git a/libs/cputimeinstate/testtimeinstate.cpp b/libs/cputimeinstate/testtimeinstate.cpp
index 81f6a58..44cdc02 100644
--- a/libs/cputimeinstate/testtimeinstate.cpp
+++ b/libs/cputimeinstate/testtimeinstate.cpp
@@ -41,7 +41,7 @@
static constexpr uint64_t NSEC_PER_YEAR = NSEC_PER_SEC * 60 * 60 * 24 * 365;
// Declare busy loop variable globally to prevent removal during optimization
-static long sum __attribute__((used)) = 0;
+static volatile long sum __attribute__((used)) = 1;
using std::vector;
@@ -579,8 +579,8 @@
// Keeps CPU busy with some number crunching
void useCpu() {
- sum = 0;
- for (int i = 0; i < 100000; i++) {
+ sum = 1;
+ for (int i = 1; i < 100000; i++) {
sum *= i;
}
}
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index f4cf11e..a9bd11e 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <set>
+#include <utility>
#include <android-base/file.h>
#include <android-base/parseint.h>
@@ -115,7 +116,7 @@
/* list of extra hal interfaces to dump containing process during native dumps */
// This is filled when dumpstate is called.
-static std::set<const std::string> extra_hal_interfaces_to_dump;
+static std::set<std::string> extra_hal_interfaces_to_dump;
static void read_extra_hals_to_dump_from_property() {
// extra hals to dump are already filled
@@ -129,7 +130,7 @@
if (trimmed_token.length() == 0) {
continue;
}
- extra_hal_interfaces_to_dump.insert(trimmed_token);
+ extra_hal_interfaces_to_dump.insert(std::move(trimmed_token));
}
}
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 9ef0eac..51d2e53 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -337,9 +337,7 @@
header_libs: [
"jni_headers",
- "libdvr_headers",
"libgui_aidl_headers",
- "libpdx_headers",
],
afdo: true,
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index e6331e7..eeb8f19 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -21,8 +21,11 @@
#include <inttypes.h>
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
+#include <ui/BufferQueueDefs.h>
+#include <ui/GraphicBuffer.h>
#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -87,17 +90,38 @@
status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence) {
- status_t err;
+ Mutex::Autolock _l(mMutex);
+ return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence) {
Mutex::Autolock _l(mMutex);
- err = addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+
+ int slotIndex = getSlotForBufferLocked(buffer);
+ if (slotIndex == INVALID_BUFFER_SLOT) {
+ return BAD_VALUE;
+ }
+
+ return releaseBufferSlotLocked(slotIndex, buffer, releaseFence);
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence) {
+ status_t err;
+
+ err = addReleaseFenceLocked(slotIndex, buffer, releaseFence);
if (err != OK) {
BI_LOGE("Failed to addReleaseFenceLocked");
}
- err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY,
- EGL_NO_SYNC_KHR);
+ err = releaseBufferLocked(slotIndex, buffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
if (err != OK && err != IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
BI_LOGE("Failed to release buffer: %s (%d)",
strerror(-err), err);
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 11f5174..69d25be 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -42,6 +42,8 @@
#include <system/window.h>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
// Macros for include BufferQueueCore information in log messages
@@ -370,79 +372,94 @@
return BAD_VALUE;
}
- std::lock_guard<std::mutex> lock(mCore->mMutex);
+ sp<IProducerListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
- if (mCore->mSharedBufferMode) {
- BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
- return BAD_VALUE;
- }
-
- // Make sure we don't have too many acquired buffers
- int numAcquiredBuffers = 0;
- for (int s : mCore->mActiveBuffers) {
- if (mSlots[s].mBufferState.isAcquired()) {
- ++numAcquiredBuffers;
+ if (mCore->mSharedBufferMode) {
+ BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode");
+ return BAD_VALUE;
}
+
+ // Make sure we don't have too many acquired buffers
+ int numAcquiredBuffers = 0;
+ for (int s : mCore->mActiveBuffers) {
+ if (mSlots[s].mBufferState.isAcquired()) {
+ ++numAcquiredBuffers;
+ }
+ }
+
+ if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
+ BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
+ "(max %d)", numAcquiredBuffers,
+ mCore->mMaxAcquiredBufferCount);
+ return INVALID_OPERATION;
+ }
+
+ if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
+ BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
+ "[queue %u]", buffer->getGenerationNumber(),
+ mCore->mGenerationNumber);
+ return BAD_VALUE;
+ }
+
+ // Find a free slot to put the buffer into
+ int found = BufferQueueCore::INVALID_BUFFER_SLOT;
+ if (!mCore->mFreeSlots.empty()) {
+ auto slot = mCore->mFreeSlots.begin();
+ found = *slot;
+ mCore->mFreeSlots.erase(slot);
+ } else if (!mCore->mFreeBuffers.empty()) {
+ found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+ }
+ if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+ BQ_LOGE("attachBuffer: could not find free buffer slot");
+ return NO_MEMORY;
+ }
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ if (mCore->mBufferAttachedCbEnabled) {
+ listener = mCore->mConnectedProducerListener;
+ }
+#endif
+
+ mCore->mActiveBuffers.insert(found);
+ *outSlot = found;
+ ATRACE_BUFFER_INDEX(*outSlot);
+ BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
+
+ mSlots[*outSlot].mGraphicBuffer = buffer;
+ mSlots[*outSlot].mBufferState.attachConsumer();
+ mSlots[*outSlot].mNeedsReallocation = true;
+ mSlots[*outSlot].mFence = Fence::NO_FENCE;
+ mSlots[*outSlot].mFrameNumber = 0;
+
+ // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
+ // GraphicBuffer pointer on the next acquireBuffer call, which decreases
+ // Binder traffic by not un/flattening the GraphicBuffer. However, it
+ // requires that the consumer maintain a cached copy of the slot <--> buffer
+ // mappings, which is why the consumer doesn't need the valid pointer on
+ // acquire.
+ //
+ // The StreamSplitter is one of the primary users of the attach/detach
+ // logic, and while it is running, all buffers it acquires are immediately
+ // detached, and all buffers it eventually releases are ones that were
+ // attached (as opposed to having been obtained from acquireBuffer), so it
+ // doesn't make sense to maintain the slot/buffer mappings, which would
+ // become invalid for every buffer during detach/attach. By setting this to
+ // false, the valid GraphicBuffer pointer will always be sent with acquire
+ // for attached buffers.
+ mSlots[*outSlot].mAcquireCalled = false;
+
+ VALIDATE_CONSISTENCY();
}
- if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
- BQ_LOGE("attachBuffer: max acquired buffer count reached: %d "
- "(max %d)", numAcquiredBuffers,
- mCore->mMaxAcquiredBufferCount);
- return INVALID_OPERATION;
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ if (listener != nullptr) {
+ listener->onBufferAttached();
}
-
- if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
- BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
- "[queue %u]", buffer->getGenerationNumber(),
- mCore->mGenerationNumber);
- return BAD_VALUE;
- }
-
- // Find a free slot to put the buffer into
- int found = BufferQueueCore::INVALID_BUFFER_SLOT;
- if (!mCore->mFreeSlots.empty()) {
- auto slot = mCore->mFreeSlots.begin();
- found = *slot;
- mCore->mFreeSlots.erase(slot);
- } else if (!mCore->mFreeBuffers.empty()) {
- found = mCore->mFreeBuffers.front();
- mCore->mFreeBuffers.remove(found);
- }
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
- BQ_LOGE("attachBuffer: could not find free buffer slot");
- return NO_MEMORY;
- }
-
- mCore->mActiveBuffers.insert(found);
- *outSlot = found;
- ATRACE_BUFFER_INDEX(*outSlot);
- BQ_LOGV("attachBuffer: returning slot %d", *outSlot);
-
- mSlots[*outSlot].mGraphicBuffer = buffer;
- mSlots[*outSlot].mBufferState.attachConsumer();
- mSlots[*outSlot].mNeedsReallocation = true;
- mSlots[*outSlot].mFence = Fence::NO_FENCE;
- mSlots[*outSlot].mFrameNumber = 0;
-
- // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
- // GraphicBuffer pointer on the next acquireBuffer call, which decreases
- // Binder traffic by not un/flattening the GraphicBuffer. However, it
- // requires that the consumer maintain a cached copy of the slot <--> buffer
- // mappings, which is why the consumer doesn't need the valid pointer on
- // acquire.
- //
- // The StreamSplitter is one of the primary users of the attach/detach
- // logic, and while it is running, all buffers it acquires are immediately
- // detached, and all buffers it eventually releases are ones that were
- // attached (as opposed to having been obtained from acquireBuffer), so it
- // doesn't make sense to maintain the slot/buffer mappings, which would
- // become invalid for every buffer during detach/attach. By setting this to
- // false, the valid GraphicBuffer pointer will always be sent with acquire
- // for attached buffers.
- mSlots[*outSlot].mAcquireCalled = false;
-
- VALIDATE_CONSISTENCY();
+#endif
return NO_ERROR;
}
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index 648db67..e0c5b1f 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -96,6 +96,7 @@
mLinkedToDeath(),
mConnectedProducerListener(),
mBufferReleasedCbEnabled(false),
+ mBufferAttachedCbEnabled(false),
mSlots(),
mQueue(),
mFreeSlots(),
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 69345a9..a4d105d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1360,6 +1360,9 @@
#endif
mCore->mConnectedProducerListener = listener;
mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify();
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ mCore->mBufferAttachedCbEnabled = listener->needsAttachNotify();
+#endif
}
break;
default:
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index b625c3f..19b9c8b 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -30,9 +30,10 @@
#include <cutils/atomic.h>
#include <gui/BufferItem.h>
+#include <gui/ConsumerBase.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
-#include <gui/ConsumerBase.h>
+#include <ui/BufferQueueDefs.h>
#include <private/gui/ComposerService.h>
@@ -40,6 +41,8 @@
#include <utils/String8.h>
#include <utils/Trace.h>
+#include <com_android_graphics_libgui_flags.h>
+
// Macros for including the ConsumerBase name in log messages
#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -96,6 +99,35 @@
abandon();
}
+int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) {
+ if (!buffer) {
+ return BufferQueue::INVALID_BUFFER_SLOT;
+ }
+
+ uint64_t id = buffer->getId();
+ for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
+ auto& slot = mSlots[i];
+ if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) {
+ return i;
+ }
+ }
+
+ return BufferQueue::INVALID_BUFFER_SLOT;
+}
+
+status_t ConsumerBase::detachBufferLocked(int slotIndex) {
+ status_t result = mConsumer->detachBuffer(slotIndex);
+
+ if (result != NO_ERROR) {
+ CB_LOGE("Failed to detach buffer: %d", result);
+ return result;
+ }
+
+ freeBufferLocked(slotIndex);
+
+ return result;
+}
+
void ConsumerBase::freeBufferLocked(int slotIndex) {
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
mSlots[slotIndex].mGraphicBuffer = nullptr;
@@ -252,16 +284,30 @@
return NO_INIT;
}
- status_t result = mConsumer->detachBuffer(slot);
- if (result != NO_ERROR) {
- CB_LOGE("Failed to detach buffer: %d", result);
- return result;
+ return detachBufferLocked(slot);
+}
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) {
+ CB_LOGV("detachBuffer");
+ Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
+ return NO_INIT;
+ }
+ if (buffer == nullptr) {
+ return BAD_VALUE;
}
- freeBufferLocked(slot);
+ int slotIndex = getSlotForBufferLocked(buffer);
+ if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
+ return BAD_VALUE;
+ }
- return result;
+ return detachBufferLocked(slotIndex);
}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
Mutex::Autolock _l(mMutex);
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index 0683087..7700795 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -25,6 +25,9 @@
ON_BUFFER_RELEASED = IBinder::FIRST_CALL_TRANSACTION,
NEEDS_RELEASE_NOTIFY,
ON_BUFFERS_DISCARDED,
+ ON_BUFFER_DETACHED,
+ ON_BUFFER_ATTACHED,
+ NEEDS_ATTACH_NOTIFY,
};
class BpProducerListener : public BpInterface<IProducerListener>
@@ -64,6 +67,38 @@
data.writeInt32Vector(discardedSlots);
remote()->transact(ON_BUFFERS_DISCARDED, data, &reply, IBinder::FLAG_ONEWAY);
}
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ virtual void onBufferDetached(int slot) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+ data.writeInt32(slot);
+ remote()->transact(ON_BUFFER_DETACHED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual void onBufferAttached() {
+ Parcel data, reply;
+ data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+ remote()->transact(ON_BUFFER_ATTACHED, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual bool needsAttachNotify() {
+ bool result;
+ Parcel data, reply;
+ data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
+ status_t err = remote()->transact(NEEDS_ATTACH_NOTIFY, data, &reply);
+ if (err != NO_ERROR) {
+ ALOGE("IProducerListener: binder call \'needsAttachNotify\' failed");
+ return true;
+ }
+ err = reply.readBool(&result);
+ if (err != NO_ERROR) {
+ ALOGE("IProducerListener: malformed binder reply");
+ return true;
+ }
+ return result;
+ }
+#endif
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -115,6 +150,27 @@
onBuffersDiscarded(discardedSlots);
return NO_ERROR;
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ case ON_BUFFER_DETACHED: {
+ CHECK_INTERFACE(IProducerListener, data, reply);
+ int slot;
+ status_t result = data.readInt32(&slot);
+ if (result != NO_ERROR) {
+ ALOGE("ON_BUFFER_DETACHED failed to read slot: %d", result);
+ return result;
+ }
+ onBufferDetached(slot);
+ return NO_ERROR;
+ }
+ case ON_BUFFER_ATTACHED:
+ CHECK_INTERFACE(IProducerListener, data, reply);
+ onBufferAttached();
+ return NO_ERROR;
+ case NEEDS_ATTACH_NOTIFY:
+ CHECK_INTERFACE(IProducerListener, data, reply);
+ reply->writeBool(needsAttachNotify());
+ return NO_ERROR;
+#endif
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index 070f6bf..b97cee3 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -1,6 +1,8 @@
# Bug component: 1075131
+carlosmr@google.com
chrisforbes@google.com
+jshargo@google.com
jreck@google.com
file:/services/surfaceflinger/OWNERS
@@ -9,10 +11,10 @@
# BufferQueue is feature-frozen
per-file BufferQueue* = set noparent
-per-file BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com
+per-file BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com, jshargo@google.com, carlosmr@google.com
per-file IGraphicBuffer* = set noparent
-per-file IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com
+per-file IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com, jshargo@google.com, carlosmr@google.com
per-file include/gui/BufferQueue* = set noparent
-per-file include/gui/BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com
+per-file include/gui/BufferQueue* = jreck@google.com, sumir@google.com, alecmouri@google.com, jshargo@google.com, carlosmr@google.com
per-file include/gui/IGraphicBuffer* = set noparent
-per-file include/gui/IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com
+per-file include/gui/IGraphicBuffer* = jreck@google.com, sumir@google.com, alecmouri@google.com, jshargo@google.com, carlosmr@google.com
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 87fd448..4a8df9e 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -21,6 +21,8 @@
#include <gui/Surface.h>
#include <condition_variable>
+#include <cstddef>
+#include <cstdint>
#include <deque>
#include <mutex>
#include <thread>
@@ -44,8 +46,6 @@
#include <gui/AidlStatusUtil.h>
#include <gui/BufferItem.h>
-#include <gui/IProducerListener.h>
-
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <private/gui/ComposerService.h>
@@ -163,6 +163,12 @@
mReqFormat, mReqUsage);
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t Surface::allowAllocation(bool allowAllocation) {
+ return mGraphicBufferProducer->allowAllocation(allowAllocation);
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
status_t Surface::setGenerationNumber(uint32_t generation) {
status_t result = mGraphicBufferProducer->setGenerationNumber(generation);
if (result == NO_ERROR) {
@@ -695,6 +701,50 @@
return OK;
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence) {
+ if (buffer == nullptr || outFence == nullptr) {
+ return BAD_VALUE;
+ }
+
+ android_native_buffer_t* anb;
+ int fd = -1;
+ status_t res = dequeueBuffer(&anb, &fd);
+ *buffer = GraphicBuffer::from(anb);
+ *outFence = sp<Fence>::make(fd);
+ return res;
+}
+
+status_t Surface::queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd) {
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+ return queueBuffer(buffer.get(), fd ? fd->get() : -1);
+}
+
+status_t Surface::detachBuffer(const sp<GraphicBuffer>& buffer) {
+ if (nullptr == buffer) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+
+ uint64_t bufferId = buffer->getId();
+ for (int slot = 0; slot < Surface::NUM_BUFFER_SLOTS; ++slot) {
+ auto& bufferSlot = mSlots[slot];
+ if (bufferSlot.buffer != nullptr && bufferSlot.buffer->getId() == bufferId) {
+ bufferSlot.buffer = nullptr;
+ bufferSlot.dirtyRegion = Region::INVALID_REGION;
+ return mGraphicBufferProducer->detachBuffer(slot);
+ }
+ }
+
+ return BAD_VALUE;
+}
+
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
using DequeueBufferInput = IGraphicBufferProducer::DequeueBufferInput;
using DequeueBufferOutput = IGraphicBufferProducer::DequeueBufferOutput;
@@ -1118,6 +1168,117 @@
}
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
+ ATRACE_CALL();
+ ALOGV("Surface::queueBuffer");
+
+ IGraphicBufferProducer::QueueBufferOutput output;
+ IGraphicBufferProducer::QueueBufferInput input;
+ int slot;
+ sp<Fence> fence;
+ {
+ Mutex::Autolock lock(mMutex);
+
+ slot = getSlotFromBufferLocked(buffer);
+ if (slot < 0) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+ return slot;
+ }
+ if (mSharedBufferSlot == slot && mSharedBufferHasBeenQueued) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+ return OK;
+ }
+
+ getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
+ applyGrallocMetadataLocked(buffer, input);
+ fence = input.fence;
+ }
+ nsecs_t now = systemTime();
+ // Drop the lock temporarily while we touch the underlying producer. In the case of a local
+ // BufferQueue, the following should be allowable:
+ //
+ // Surface::queueBuffer
+ // -> IConsumerListener::onFrameAvailable callback triggers automatically
+ // -> implementation calls IGraphicBufferConsumer::acquire/release immediately
+ // -> SurfaceListener::onBufferRelesed callback triggers automatically
+ // -> implementation calls Surface::dequeueBuffer
+ status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output);
+ {
+ Mutex::Autolock lock(mMutex);
+
+ mLastQueueDuration = systemTime() - now;
+ if (err != OK) {
+ ALOGE("queueBuffer: error queuing buffer, %d", err);
+ }
+
+ onBufferQueuedLocked(slot, fence, output);
+ }
+
+ return err;
+}
+
+int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers) {
+ ATRACE_CALL();
+ ALOGV("Surface::queueBuffers");
+
+ size_t numBuffers = buffers.size();
+ std::vector<IGraphicBufferProducer::QueueBufferInput> queueBufferInputs(numBuffers);
+ std::vector<IGraphicBufferProducer::QueueBufferOutput> queueBufferOutputs;
+ std::vector<int> bufferSlots(numBuffers, -1);
+ std::vector<sp<Fence>> bufferFences(numBuffers);
+
+ int err;
+ {
+ Mutex::Autolock lock(mMutex);
+
+ if (mSharedBufferMode) {
+ ALOGE("%s: batched operation is not supported in shared buffer mode", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
+ int i = getSlotFromBufferLocked(buffers[batchIdx].buffer);
+ if (i < 0) {
+ if (buffers[batchIdx].fenceFd >= 0) {
+ close(buffers[batchIdx].fenceFd);
+ }
+ return i;
+ }
+ bufferSlots[batchIdx] = i;
+
+ IGraphicBufferProducer::QueueBufferInput input;
+ getQueueBufferInputLocked(buffers[batchIdx].buffer, buffers[batchIdx].fenceFd,
+ buffers[batchIdx].timestamp, &input);
+ bufferFences[batchIdx] = input.fence;
+ queueBufferInputs[batchIdx] = input;
+ }
+ }
+ nsecs_t now = systemTime();
+ err = mGraphicBufferProducer->queueBuffers(queueBufferInputs, &queueBufferOutputs);
+ {
+ Mutex::Autolock lock(mMutex);
+ mLastQueueDuration = systemTime() - now;
+ if (err != OK) {
+ ALOGE("%s: error queuing buffer, %d", __FUNCTION__, err);
+ }
+
+ for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
+ onBufferQueuedLocked(bufferSlots[batchIdx], bufferFences[batchIdx],
+ queueBufferOutputs[batchIdx]);
+ }
+ }
+
+ return err;
+}
+
+#else
+
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
ATRACE_CALL();
ALOGV("Surface::queueBuffer");
@@ -1205,6 +1366,8 @@
return err;
}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
void Surface::querySupportedTimestampsLocked() const {
// mMutex must be locked when calling this method.
@@ -1860,30 +2023,22 @@
}
int Surface::connect(int api) {
- static sp<IProducerListener> listener = new StubProducerListener();
+ static sp<SurfaceListener> listener = new StubSurfaceListener();
return connect(api, listener);
}
-int Surface::connect(int api, const sp<IProducerListener>& listener) {
- return connect(api, listener, false);
-}
-
-int Surface::connect(
- int api, bool reportBufferRemoval, const sp<SurfaceListener>& sListener) {
- if (sListener != nullptr) {
- mListenerProxy = new ProducerListenerProxy(this, sListener);
- }
- return connect(api, mListenerProxy, reportBufferRemoval);
-}
-
-int Surface::connect(
- int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) {
+int Surface::connect(int api, const sp<SurfaceListener>& listener, bool reportBufferRemoval) {
ATRACE_CALL();
ALOGV("Surface::connect");
Mutex::Autolock lock(mMutex);
IGraphicBufferProducer::QueueBufferOutput output;
mReportRemovedBuffers = reportBufferRemoval;
- int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
+ if (listener != nullptr) {
+ mListenerProxy = new ProducerListenerProxy(this, listener);
+ }
+
+ int err =
+ mGraphicBufferProducer->connect(mListenerProxy, api, mProducerControlledByApp, &output);
if (err == NO_ERROR) {
mDefaultWidth = output.width;
mDefaultHeight = output.height;
@@ -1911,7 +2066,6 @@
return err;
}
-
int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) {
ATRACE_CALL();
ALOGV("Surface::disconnect");
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 88d3a7c..e86e13d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -20,6 +20,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <com_android_graphics_libgui_flags.h>
+
#include <android/gui/BnWindowInfosReportedListener.h>
#include <android/gui/DisplayState.h>
#include <android/gui/EdgeExtensionParameters.h>
@@ -2331,6 +2333,10 @@
return *this;
}
+bool SurfaceComposerClient::flagEdgeExtensionEffectUseShader() {
+ return com::android::graphics::libgui::flags::edge_extension_shader();
+}
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setEdgeExtensionEffect(
const sp<SurfaceControl>& sc, const gui::EdgeExtensionParameters& effect) {
layer_state_t* s = getLayerState(sc);
diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h
index a905610..e383a40 100644
--- a/libs/gui/include/gui/BufferItemConsumer.h
+++ b/libs/gui/include/gui/BufferItemConsumer.h
@@ -17,13 +17,15 @@
#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H
#define ANDROID_GUI_BUFFERITEMCONSUMER_H
-#include <gui/ConsumerBase.h>
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueue.h>
+#include <gui/ConsumerBase.h>
#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer"
namespace android {
+class GraphicBuffer;
class String8;
/**
@@ -85,7 +87,15 @@
status_t releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
- private:
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ status_t releaseBuffer(const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence = Fence::NO_FENCE);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+private:
+ status_t releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence);
+
void freeBufferLocked(int slotIndex) override;
// mBufferFreedListener is the listener object that will be called when
diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h
index bb52c8e..d5dd7c8 100644
--- a/libs/gui/include/gui/BufferQueueCore.h
+++ b/libs/gui/include/gui/BufferQueueCore.h
@@ -192,6 +192,10 @@
// callback is registered by the listener. When set to false,
// mConnectedProducerListener will not trigger onBufferReleased() callback.
bool mBufferReleasedCbEnabled;
+ // mBufferAttachedCbEnabled is used to indicate whether onBufferAttached()
+ // callback is registered by the listener. When set to false,
+ // mConnectedProducerListener will not trigger onBufferAttached() callback.
+ bool mBufferAttachedCbEnabled;
// mSlots is an array of buffer slots that must be mirrored on the producer
// side. This allows buffer ownership to be transferred between the producer
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index 8ff0cd0..a031e66 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -17,18 +17,16 @@
#ifndef ANDROID_GUI_CONSUMERBASE_H
#define ANDROID_GUI_CONSUMERBASE_H
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueueDefs.h>
#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/OccupancyTracker.h>
-
#include <ui/PixelFormat.h>
-
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/threads.h>
-
namespace android {
// ----------------------------------------------------------------------------
@@ -81,7 +79,13 @@
void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
// See IGraphicBufferConsumer::detachBuffer
- status_t detachBuffer(int slot);
+ status_t detachBuffer(int slot) __attribute((
+ deprecated("Please use the GraphicBuffer variant--slots are deprecated.")));
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ // See IGraphicBufferConsumer::detachBuffer
+ status_t detachBuffer(const sp<GraphicBuffer>& buffer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
// See IGraphicBufferConsumer::setDefaultBufferSize
status_t setDefaultBufferSize(uint32_t width, uint32_t height);
@@ -150,6 +154,10 @@
virtual void onBuffersReleased() override;
virtual void onSidebandStreamChanged() override;
+ virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer);
+
+ virtual status_t detachBufferLocked(int slotIndex);
+
// freeBufferLocked frees up the given buffer slot. If the slot has been
// initialized this will release the reference to the GraphicBuffer in that
// slot. Otherwise it has no effect.
diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h
index b15f501..3dcc6b6 100644
--- a/libs/gui/include/gui/IProducerListener.h
+++ b/libs/gui/include/gui/IProducerListener.h
@@ -25,6 +25,8 @@
#include <hidl/HybridInterface.h>
#include <utils/RefBase.h>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
// ProducerListener is the interface through which the BufferQueue notifies the
@@ -55,6 +57,16 @@
// This is called without any lock held and can be called concurrently by
// multiple threads.
virtual void onBufferDetached(int /*slot*/) {} // Asynchronous
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ // onBufferAttached is called from IGraphicBufferConsumer::attachBuffer to
+ // notify the producer that a buffer is attached.
+ //
+ // This is called without any lock held and can be called concurrently by
+ // multiple threads. This callback is enabled only when needsAttachNotify()
+ // returns {@code true}.
+ virtual void onBufferAttached() {} // Asynchronous
+ virtual bool needsAttachNotify() { return false; }
+#endif
};
#ifndef NO_BINDER
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index bdcaaf2..39207f8 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -18,6 +18,7 @@
#define ANDROID_GUI_SURFACE_H
#include <android/gui/FrameTimelineInfo.h>
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueueDefs.h>
#include <gui/HdrMetadata.h>
#include <gui/IGraphicBufferProducer.h>
@@ -33,8 +34,12 @@
#include <shared_mutex>
#include <unordered_set>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
+class GraphicBuffer;
+
namespace gui {
class ISurfaceComposer;
} // namespace gui
@@ -56,6 +61,20 @@
virtual bool needsReleaseNotify() = 0;
virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) = 0;
+ virtual void onBufferDetached(int slot) = 0;
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ virtual void onBufferAttached() {}
+ virtual bool needsAttachNotify() { return false; }
+#endif
+};
+
+class StubSurfaceListener : public SurfaceListener {
+public:
+ virtual ~StubSurfaceListener() {}
+ virtual void onBufferReleased() override {}
+ virtual bool needsReleaseNotify() { return false; }
+ virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
+ virtual void onBufferDetached(int /*slot*/) override {}
};
/*
@@ -154,6 +173,11 @@
*/
virtual void allocateBuffers();
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ // See IGraphicBufferProducer::allowAllocation
+ status_t allowAllocation(bool allowAllocation);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
/* Sets the generation number on the IGraphicBufferProducer and updates the
* generation number on any buffers attached to the Surface after this call.
* See IGBP::setGenerationNumber for more information. */
@@ -357,22 +381,15 @@
virtual int unlockAndPost();
virtual int query(int what, int* value) const;
- virtual int connect(int api, const sp<IProducerListener>& listener);
-
// When reportBufferRemoval is true, clients must call getAndFlushRemovedBuffers to fetch
// GraphicBuffers removed from this surface after a dequeueBuffer, detachNextBuffer or
// attachBuffer call. This allows clients with their own buffer caches to free up buffers no
// longer in use by this surface.
- virtual int connect(
- int api, const sp<IProducerListener>& listener,
- bool reportBufferRemoval);
- virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer,
- sp<Fence>* outFence);
+ virtual int connect(int api, const sp<SurfaceListener>& listener,
+ bool reportBufferRemoval = false);
+ virtual int detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence);
virtual int attachBuffer(ANativeWindowBuffer*);
- virtual int connect(
- int api, bool reportBufferRemoval,
- const sp<SurfaceListener>& sListener);
virtual void destroy();
// When client connects to Surface with reportBufferRemoval set to true, any buffers removed
@@ -387,6 +404,20 @@
static status_t attachAndQueueBufferWithDataspace(Surface* surface, sp<GraphicBuffer> buffer,
ui::Dataspace dataspace);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ // Dequeues a buffer and its outFence, which must be signalled before the buffer can be used.
+ status_t dequeueBuffer(sp<GraphicBuffer>* buffer, sp<Fence>* outFence);
+
+ // Queues a buffer, with an optional fd fence that captures pending work on the buffer. This
+ // buffer must have been returned by dequeueBuffer or associated with this Surface via an
+ // attachBuffer operation.
+ status_t queueBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& fd = Fence::NO_FENCE);
+
+ // Detaches this buffer, dissociating it from this Surface. This buffer must have been returned
+ // by queueBuffer or associated with this Surface via an attachBuffer operation.
+ status_t detachBuffer(const sp<GraphicBuffer>& buffer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
// Batch version of dequeueBuffer, cancelBuffer and queueBuffer
// Note that these batched operations are not supported when shared buffer mode is being used.
struct BatchBuffer {
@@ -422,7 +453,18 @@
return mSurfaceListener->needsReleaseNotify();
}
+ virtual void onBufferDetached(int slot) { mSurfaceListener->onBufferDetached(slot); }
+
virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ virtual void onBufferAttached() {
+ mSurfaceListener->onBufferAttached();
+ }
+
+ virtual bool needsAttachNotify() {
+ return mSurfaceListener->needsAttachNotify();
+ }
+#endif
private:
wp<Surface> mParent;
sp<SurfaceListener> mSurfaceListener;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index a10283b..95574ee 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -339,6 +339,8 @@
static std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>
getDisplayDecorationSupport(const sp<IBinder>& displayToken);
+ static bool flagEdgeExtensionEffectUseShader();
+
// ------------------------------------------------------------------------
// surface creation / destruction
diff --git a/libs/gui/libgui_flags.aconfig b/libs/gui/libgui_flags.aconfig
index 792966f..b1b385d 100644
--- a/libs/gui/libgui_flags.aconfig
+++ b/libs/gui/libgui_flags.aconfig
@@ -10,6 +10,14 @@
} # bq_setframerate
flag {
+ name: "bq_consumer_attach_callback"
+ namespace: "core_graphics"
+ description: "Controls IProducerListener to have consumer side attach callback"
+ bug: "353202582"
+ is_fixed_read_only: true
+} # bq_consumer_attach_callback
+
+flag {
name: "frametimestamps_previousrelease"
namespace: "core_graphics"
description: "Controls a fence fixup for timestamp apis"
@@ -35,3 +43,51 @@
purpose: PURPOSE_BUGFIX
}
} # trace_frame_rate_override
+
+flag {
+ name: "wb_consumer_base_owns_bq"
+ namespace: "core_graphics"
+ description: "ConsumerBase-based classes now own their own bufferqueue"
+ bug: "340933754"
+ is_fixed_read_only: true
+} # wb_consumer_base_owns_bq
+
+flag {
+ name: "wb_platform_api_improvements"
+ namespace: "core_graphics"
+ description: "Simple improvements to Surface and ConsumerBase classes"
+ bug: "340933794"
+ is_fixed_read_only: true
+} # wb_platform_api_improvements
+
+flag {
+ name: "wb_stream_splitter"
+ namespace: "core_graphics"
+ description: "Removes IGBP/IGBCs from Camera3StreamSplitter as part of BufferQueue refactors"
+ bug: "340933206"
+ is_fixed_read_only: true
+} # wb_stream_splitter
+
+flag {
+ name: "edge_extension_shader"
+ namespace: "windowing_frontend"
+ description: "Enable edge extension via shader"
+ bug: "322036393"
+ is_fixed_read_only: true
+} # edge_extension_shader
+
+flag {
+ name: "buffer_release_channel"
+ namespace: "window_surfaces"
+ description: "Enable BufferReleaseChannel to optimize buffer releases"
+ bug: "294133380"
+ is_fixed_read_only: true
+} # buffer_release_channel
+
+flag {
+ name: "wb_surface_connect_methods"
+ namespace: "core_graphics"
+ description: "Remove redundant connect methods in Surface."
+ bug: "354273690"
+ is_fixed_read_only: true
+} # wb_surface_connect_methods
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index ea8acbb..b342a7d 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -25,6 +25,7 @@
"-Wthread-safety",
"-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_BQ_SETFRAMERATE=true",
"-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_BQ_EXTENDEDALLOCATE=true",
+ "-DCOM_ANDROID_GRAPHICS_LIBGUI_FLAGS_WB_PLATFORM_API_IMPROVEMENTS=true",
],
srcs: [
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index 946ff05..6852589 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -1269,6 +1269,20 @@
}
};
+class TestSurfaceListener : public SurfaceListener {
+public:
+ sp<IGraphicBufferProducer> mIgbp;
+ TestSurfaceListener(const sp<IGraphicBufferProducer>& igbp) : mIgbp(igbp) {}
+ void onBufferReleased() override {
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ mIgbp->detachNextBuffer(&buffer, &fence);
+ }
+ bool needsReleaseNotify() override { return true; }
+ void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& /*buffers*/) override {}
+ void onBufferDetached(int /*slot*/) {}
+};
+
TEST_F(BLASTBufferQueueTest, CustomProducerListener) {
BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
sp<IGraphicBufferProducer> igbProducer = adapter.getIGraphicBufferProducer();
@@ -1327,7 +1341,7 @@
ASSERT_EQ(ui::Transform::ROT_0, static_cast<ui::Transform::RotationFlags>(transformHint));
ASSERT_EQ(NO_ERROR,
- surface->connect(NATIVE_WINDOW_API_CPU, new TestProducerListener(igbProducer)));
+ surface->connect(NATIVE_WINDOW_API_CPU, new TestSurfaceListener(igbProducer)));
// After connecting to the surface, we should get the correct hint.
surface->query(NATIVE_WINDOW_TRANSFORM_HINT, &transformHint);
diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp
index 6880678..7d33f28 100644
--- a/libs/gui/tests/BufferItemConsumer_test.cpp
+++ b/libs/gui/tests/BufferItemConsumer_test.cpp
@@ -17,10 +17,12 @@
#define LOG_TAG "BufferItemConsumer_test"
//#define LOG_NDEBUG 0
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
+#include <ui/GraphicBuffer.h>
namespace android {
@@ -42,6 +44,17 @@
BufferItemConsumerTest* mTest;
};
+ struct TrackingProducerListener : public BnProducerListener {
+ TrackingProducerListener(BufferItemConsumerTest* test) : mTest(test) {}
+
+ virtual void onBufferReleased() override {}
+ virtual bool needsReleaseNotify() override { return true; }
+ virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
+ virtual void onBufferDetached(int slot) override { mTest->HandleBufferDetached(slot); }
+
+ BufferItemConsumerTest* mTest;
+ };
+
void SetUp() override {
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
mBIC =
@@ -51,7 +64,7 @@
mBFL = new BufferFreedListener(this);
mBIC->setBufferFreedListener(mBFL);
- sp<IProducerListener> producerListener = new StubProducerListener();
+ sp<IProducerListener> producerListener = new TrackingProducerListener(this);
IGraphicBufferProducer::QueueBufferOutput bufferOutput;
ASSERT_EQ(NO_ERROR,
mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
@@ -71,6 +84,13 @@
ALOGD("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
}
+ void HandleBufferDetached(int slot) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mDetachedBufferSlots.push_back(slot);
+ ALOGD("HandleBufferDetached, slot=%d mDetachedBufferSlots-count=%zu", slot,
+ mDetachedBufferSlots.size());
+ }
+
void DequeueBuffer(int* outSlot) {
ASSERT_NE(outSlot, nullptr);
@@ -120,6 +140,7 @@
std::mutex mMutex;
int mFreedBufferCount{0};
+ std::vector<int> mDetachedBufferSlots = {};
sp<BufferItemConsumer> mBIC;
sp<BufferFreedListener> mBFL;
@@ -203,4 +224,19 @@
ASSERT_EQ(1, GetFreedBufferCount());
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+// Test that delete BufferItemConsumer triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) {
+ int slot;
+ // Let buffer go through the cycle at least once.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+ AcquireBuffer(&slot);
+
+ sp<GraphicBuffer> buffer = mBuffers[slot];
+ EXPECT_EQ(OK, mBIC->detachBuffer(buffer));
+ EXPECT_THAT(mDetachedBufferSlots, testing::ElementsAre(slot));
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
} // namespace android
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 272c5ed..590e2c8 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -1262,6 +1262,91 @@
ASSERT_TRUE(result == WOULD_BLOCK || result == TIMED_OUT || result == INVALID_OPERATION);
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+struct BufferAttachedListener : public BnProducerListener {
+public:
+ BufferAttachedListener(bool enable) : mEnabled(enable), mAttached(0) {}
+ virtual ~BufferAttachedListener() = default;
+
+ virtual void onBufferReleased() {}
+ virtual bool needsReleaseNotify() { return true; }
+ virtual void onBufferAttached() {
+ ++mAttached;
+ }
+ virtual bool needsAttachNotify() { return mEnabled; }
+
+ int getNumAttached() const { return mAttached; }
+private:
+ const bool mEnabled;
+ int mAttached;
+};
+
+TEST_F(BufferQueueTest, TestConsumerAttachProducerListener) {
+ createBufferQueue();
+ sp<MockConsumer> mc1(new MockConsumer);
+ ASSERT_EQ(OK, mConsumer->consumerConnect(mc1, true));
+ IGraphicBufferProducer::QueueBufferOutput output;
+ // Do not enable attach callback.
+ sp<BufferAttachedListener> pl1(new BufferAttachedListener(false));
+ ASSERT_EQ(OK, mProducer->connect(pl1, NATIVE_WINDOW_API_CPU, true, &output));
+ ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
+ ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
+
+ sp<Fence> fence = Fence::NO_FENCE;
+ sp<GraphicBuffer> buffer = nullptr;
+
+ int slot;
+ status_t result = OK;
+
+ ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(1));
+
+ result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+ ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
+ ASSERT_EQ(OK, mProducer->detachBuffer(slot));
+
+ // Check # of attach is zero.
+ ASSERT_EQ(0, pl1->getNumAttached());
+
+ // Attach a buffer and check the callback was not called.
+ ASSERT_EQ(OK, mConsumer->attachBuffer(&slot, buffer));
+ ASSERT_EQ(0, pl1->getNumAttached());
+
+ mProducer = nullptr;
+ mConsumer = nullptr;
+ createBufferQueue();
+
+ sp<MockConsumer> mc2(new MockConsumer);
+ ASSERT_EQ(OK, mConsumer->consumerConnect(mc2, true));
+ // Enable attach callback.
+ sp<BufferAttachedListener> pl2(new BufferAttachedListener(true));
+ ASSERT_EQ(OK, mProducer->connect(pl2, NATIVE_WINDOW_API_CPU, true, &output));
+ ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
+ ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
+
+ fence = Fence::NO_FENCE;
+ buffer = nullptr;
+
+ result = OK;
+
+ ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(1));
+
+ result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+ ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
+ ASSERT_EQ(OK, mProducer->detachBuffer(slot));
+
+ // Check # of attach is zero.
+ ASSERT_EQ(0, pl2->getNumAttached());
+
+ // Attach a buffer and check the callback was called.
+ ASSERT_EQ(OK, mConsumer->attachBuffer(&slot, buffer));
+ ASSERT_EQ(1, pl2->getNumAttached());
+}
+#endif
+
TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
createBufferQueue();
sp<MockConsumer> mc(new MockConsumer);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 1d3174c..85f4a42 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -23,25 +23,33 @@
#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/ISurfaceComposer.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware_buffer.h>
#include <binder/ProcessState.h>
+#include <com_android_graphics_libgui_flags.h>
#include <configstore/Utils.h>
#include <gui/AidlStatusUtil.h>
#include <gui/BufferItemConsumer.h>
-#include <gui/IProducerListener.h>
+#include <gui/BufferQueue.h>
+#include <gui/CpuConsumer.h>
+#include <gui/IConsumerListener.h>
+#include <gui/IGraphicBufferConsumer.h>
+#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
-#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <sys/types.h>
+#include <system/window.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
+#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
#include <utils/Errors.h>
#include <utils/String8.h>
+#include <cstddef>
#include <limits>
#include <thread>
@@ -82,7 +90,7 @@
virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) {
mDiscardedBuffers.insert(mDiscardedBuffers.end(), buffers.begin(), buffers.end());
}
-
+ virtual void onBufferDetached(int /*slot*/) {}
int getReleaseNotifyCount() const {
return mBuffersReleased;
}
@@ -143,10 +151,10 @@
if (hasSurfaceListener) {
listener = new FakeSurfaceListener(enableReleasedCb);
}
- ASSERT_EQ(OK, surface->connect(
- NATIVE_WINDOW_API_CPU,
- /*reportBufferRemoval*/true,
- /*listener*/listener));
+ ASSERT_EQ(OK,
+ surface->connect(NATIVE_WINDOW_API_CPU,
+ /*listener*/ listener,
+ /*reportBufferRemoval*/ true));
const int BUFFER_COUNT = 4 + extraDiscardedBuffers;
ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(window.get(), BUFFER_COUNT));
ASSERT_EQ(NO_ERROR, native_window_set_usage(window.get(), TEST_PRODUCER_USAGE_BITS));
@@ -491,11 +499,11 @@
sp<Surface> surface = new Surface(producer);
sp<ANativeWindow> window(surface);
- sp<StubProducerListener> listener = new StubProducerListener();
- ASSERT_EQ(OK, surface->connect(
- NATIVE_WINDOW_API_CPU,
- /*listener*/listener,
- /*reportBufferRemoval*/true));
+ sp<StubSurfaceListener> listener = new StubSurfaceListener();
+ ASSERT_EQ(OK,
+ surface->connect(NATIVE_WINDOW_API_CPU,
+ /*listener*/ listener,
+ /*reportBufferRemoval*/ true));
const int BUFFER_COUNT = 4;
ASSERT_EQ(NO_ERROR, native_window_set_buffer_count(window.get(), BUFFER_COUNT));
ASSERT_EQ(NO_ERROR, native_window_set_usage(window.get(), TEST_PRODUCER_USAGE_BITS));
@@ -2154,7 +2162,7 @@
sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
sp<Surface> surface = new Surface(producer);
sp<ANativeWindow> window(surface);
- sp<StubProducerListener> listener = new StubProducerListener();
+ sp<StubSurfaceListener> listener = new StubSurfaceListener();
ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, /*listener*/listener,
/*reportBufferRemoval*/false));
@@ -2206,7 +2214,7 @@
sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
sp<Surface> surface = new Surface(producer);
sp<ANativeWindow> window(surface);
- sp<StubProducerListener> listener = new StubProducerListener();
+ sp<StubSurfaceListener> listener = new StubSurfaceListener();
ASSERT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, /*listener*/listener,
/*reportBufferRemoval*/false));
@@ -2226,4 +2234,160 @@
ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU));
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+TEST_F(SurfaceTest, PlatformBufferMethods) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ sp<CpuConsumer> cpuConsumer = sp<CpuConsumer>::make(consumer, 1);
+ sp<Surface> surface = sp<Surface>::make(producer);
+ sp<StubSurfaceListener> listener = sp<StubSurfaceListener>::make();
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+
+ EXPECT_EQ(OK,
+ surface->connect(NATIVE_WINDOW_API_CPU, listener, /* reportBufferRemoval */ false));
+
+ //
+ // Verify nullptrs are handled safely:
+ //
+
+ EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer((sp<GraphicBuffer>*)nullptr, nullptr));
+ EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer((sp<GraphicBuffer>*)nullptr, &fence));
+ EXPECT_EQ(BAD_VALUE, surface->dequeueBuffer(&buffer, nullptr));
+ EXPECT_EQ(BAD_VALUE, surface->queueBuffer(nullptr, nullptr));
+ EXPECT_EQ(BAD_VALUE, surface->detachBuffer(nullptr));
+
+ //
+ // Verify dequeue/queue:
+ //
+
+ EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
+ EXPECT_NE(nullptr, buffer);
+ EXPECT_EQ(OK, surface->queueBuffer(buffer, fence));
+
+ //
+ // Verify dequeue/detach:
+ //
+
+ wp<GraphicBuffer> weakBuffer;
+ {
+ EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
+
+ EXPECT_EQ(OK, surface->detachBuffer(buffer));
+
+ weakBuffer = buffer;
+ buffer = nullptr;
+ }
+ EXPECT_EQ(nullptr, weakBuffer.promote()) << "Weak buffer still held by Surface.";
+
+ //
+ // Verify detach without borrowing the buffer does not work:
+ //
+
+ sp<GraphicBuffer> heldTooLongBuffer;
+ EXPECT_EQ(OK, surface->dequeueBuffer(&heldTooLongBuffer, &fence));
+ EXPECT_EQ(OK, surface->queueBuffer(heldTooLongBuffer));
+ EXPECT_EQ(BAD_VALUE, surface->detachBuffer(heldTooLongBuffer));
+}
+
+TEST_F(SurfaceTest, AllowAllocation) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ // controlledByApp must be true to disable blocking
+ sp<CpuConsumer> cpuConsumer = sp<CpuConsumer>::make(consumer, 1, /*controlledByApp*/ true);
+ sp<Surface> surface = sp<Surface>::make(producer, /*controlledByApp*/ true);
+ sp<StubSurfaceListener> listener = sp<StubSurfaceListener>::make();
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+
+ EXPECT_EQ(OK,
+ surface->connect(NATIVE_WINDOW_API_CPU, listener, /* reportBufferRemoval */ false));
+ EXPECT_EQ(OK, surface->allowAllocation(false));
+
+ EXPECT_EQ(OK, surface->setDequeueTimeout(-1));
+ EXPECT_EQ(WOULD_BLOCK, surface->dequeueBuffer(&buffer, &fence));
+
+ EXPECT_EQ(OK, surface->setDequeueTimeout(10));
+ EXPECT_EQ(TIMED_OUT, surface->dequeueBuffer(&buffer, &fence));
+
+ EXPECT_EQ(OK, surface->allowAllocation(true));
+ EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
+}
+
+TEST_F(SurfaceTest, QueueAcquireReleaseDequeue_CalledInStack_DoesNotDeadlock) {
+ class DequeuingSurfaceListener : public SurfaceListener {
+ public:
+ DequeuingSurfaceListener(const wp<Surface>& surface) : mSurface(surface) {}
+
+ virtual void onBufferReleased() override {
+ sp<Surface> surface = mSurface.promote();
+ ASSERT_NE(nullptr, surface);
+ EXPECT_EQ(OK, surface->dequeueBuffer(&mBuffer, &mFence));
+ }
+
+ virtual bool needsReleaseNotify() override { return true; }
+ virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {}
+ virtual void onBufferDetached(int) override {}
+
+ sp<GraphicBuffer> mBuffer;
+ sp<Fence> mFence;
+
+ private:
+ wp<Surface> mSurface;
+ };
+
+ class ImmediateReleaseConsumerListener : public BufferItemConsumer::FrameAvailableListener {
+ public:
+ ImmediateReleaseConsumerListener(const wp<BufferItemConsumer>& consumer)
+ : mConsumer(consumer) {}
+
+ virtual void onFrameAvailable(const BufferItem&) override {
+ sp<BufferItemConsumer> consumer = mConsumer.promote();
+ ASSERT_NE(nullptr, consumer);
+
+ mCalls += 1;
+
+ BufferItem buffer;
+ EXPECT_EQ(OK, consumer->acquireBuffer(&buffer, 0));
+ EXPECT_EQ(OK, consumer->releaseBuffer(buffer));
+ }
+
+ size_t mCalls = 0;
+
+ private:
+ wp<BufferItemConsumer> mConsumer;
+ };
+
+ sp<IGraphicBufferProducer> bqProducer;
+ sp<IGraphicBufferConsumer> bqConsumer;
+ BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+
+ sp<BufferItemConsumer> consumer = sp<BufferItemConsumer>::make(bqConsumer, 3);
+ sp<Surface> surface = sp<Surface>::make(bqProducer);
+ sp<ImmediateReleaseConsumerListener> consumerListener =
+ sp<ImmediateReleaseConsumerListener>::make(consumer);
+ consumer->setFrameAvailableListener(consumerListener);
+
+ sp<DequeuingSurfaceListener> surfaceListener = sp<DequeuingSurfaceListener>::make(surface);
+ EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener, false));
+
+ EXPECT_EQ(OK, surface->setMaxDequeuedBufferCount(2));
+
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
+ EXPECT_EQ(OK, surface->queueBuffer(buffer, fence));
+
+ EXPECT_EQ(1u, consumerListener->mCalls);
+ EXPECT_NE(nullptr, surfaceListener->mBuffer);
+
+ EXPECT_EQ(OK, surface->disconnect(NATIVE_WINDOW_API_CPU));
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
} // namespace android
diff --git a/libs/input/Android.bp b/libs/input/Android.bp
index 45ebc66..8fbf5c6 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -258,7 +258,7 @@
],
shared_libs: [
- "android.companion.virtualdevice.flags-aconfig-cc-host",
+ "android.companion.virtualdevice.flags-aconfig-cc",
"libbase",
"libbinder",
"libbinder_ndk",
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp
index b098147..a2bb345 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -580,7 +580,7 @@
&pointerProperties[pointerCount]);
mSampleEventTimes.clear();
mSamplePointerCoords.clear();
- addSample(eventTime, pointerCoords);
+ addSample(eventTime, pointerCoords, mId);
}
void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
@@ -640,9 +640,9 @@
mSampleEventTimes = other.mSampleEventTimes;
}
-void MotionEvent::addSample(
- int64_t eventTime,
- const PointerCoords* pointerCoords) {
+void MotionEvent::addSample(int64_t eventTime, const PointerCoords* pointerCoords,
+ int32_t eventId) {
+ mId = eventId;
mSampleEventTimes.push_back(eventTime);
mSamplePointerCoords.insert(mSamplePointerCoords.end(), &pointerCoords[0],
&pointerCoords[getPointerCount()]);
diff --git a/libs/input/InputConsumer.cpp b/libs/input/InputConsumer.cpp
index dce528f..1eeb4e6 100644
--- a/libs/input/InputConsumer.cpp
+++ b/libs/input/InputConsumer.cpp
@@ -135,7 +135,7 @@
}
event.setMetaState(event.getMetaState() | msg.body.motion.metaState);
- event.addSample(msg.body.motion.eventTime, pointerCoords);
+ event.addSample(msg.body.motion.eventTime, pointerCoords, msg.body.motion.eventId);
}
void initializeTouchModeEvent(TouchModeEvent& event, const InputMessage& msg) {
@@ -697,7 +697,7 @@
currentCoords.getY(), otherCoords.getX(), otherCoords.getY(), alpha);
}
- event->addSample(sampleTime, touchState.lastResample.pointers);
+ event->addSample(sampleTime, touchState.lastResample.pointers, event->getId());
}
status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {
diff --git a/libs/input/InputConsumerNoResampling.cpp b/libs/input/InputConsumerNoResampling.cpp
index e193983..c145d5c 100644
--- a/libs/input/InputConsumerNoResampling.cpp
+++ b/libs/input/InputConsumerNoResampling.cpp
@@ -114,7 +114,7 @@
// TODO(b/329770983): figure out if it's safe to combine events with mismatching metaState
event.setMetaState(event.getMetaState() | msg.body.motion.metaState);
- event.addSample(msg.body.motion.eventTime, pointerCoords.data());
+ event.addSample(msg.body.motion.eventTime, pointerCoords.data(), msg.body.motion.eventId);
}
std::unique_ptr<TouchModeEvent> createTouchModeEvent(const InputMessage& msg) {
@@ -445,6 +445,27 @@
}
}
+std::pair<std::unique_ptr<MotionEvent>, std::optional<uint32_t>>
+InputConsumerNoResampling::createBatchedMotionEvent(const nsecs_t frameTime,
+ std::queue<InputMessage>& messages) {
+ std::unique_ptr<MotionEvent> motionEvent;
+ std::optional<uint32_t> firstSeqForBatch;
+ while (!messages.empty() && !(messages.front().body.motion.eventTime > frameTime)) {
+ if (motionEvent == nullptr) {
+ motionEvent = createMotionEvent(messages.front());
+ firstSeqForBatch = messages.front().header.seq;
+ const auto [_, inserted] = mBatchedSequenceNumbers.insert({*firstSeqForBatch, {}});
+ LOG_IF(FATAL, !inserted)
+ << "The sequence " << messages.front().header.seq << " was already present!";
+ } else {
+ addSample(*motionEvent, messages.front());
+ mBatchedSequenceNumbers[*firstSeqForBatch].push_back(messages.front().header.seq);
+ }
+ messages.pop();
+ }
+ return std::make_pair(std::move(motionEvent), firstSeqForBatch);
+}
+
bool InputConsumerNoResampling::consumeBatchedInputEvents(
std::optional<nsecs_t> requestedFrameTime) {
ensureCalledOnLooperThread(__func__);
@@ -452,28 +473,8 @@
// infinite frameTime.
const nsecs_t frameTime = requestedFrameTime.value_or(std::numeric_limits<nsecs_t>::max());
bool producedEvents = false;
- for (auto& [deviceId, messages] : mBatches) {
- std::unique_ptr<MotionEvent> motion;
- std::optional<uint32_t> firstSeqForBatch;
- std::vector<uint32_t> sequences;
- while (!messages.empty()) {
- const InputMessage& msg = messages.front();
- if (msg.body.motion.eventTime > frameTime) {
- break;
- }
- if (motion == nullptr) {
- motion = createMotionEvent(msg);
- firstSeqForBatch = msg.header.seq;
- const auto [_, inserted] = mBatchedSequenceNumbers.insert({*firstSeqForBatch, {}});
- if (!inserted) {
- LOG(FATAL) << "The sequence " << msg.header.seq << " was already present!";
- }
- } else {
- addSample(*motion, msg);
- mBatchedSequenceNumbers[*firstSeqForBatch].push_back(msg.header.seq);
- }
- messages.pop();
- }
+ for (auto& [_, messages] : mBatches) {
+ auto [motion, firstSeqForBatch] = createBatchedMotionEvent(frameTime, messages);
if (motion != nullptr) {
LOG_ALWAYS_FATAL_IF(!firstSeqForBatch.has_value());
mCallbacks.onMotionEvent(std::move(motion), *firstSeqForBatch);
diff --git a/libs/input/KeyLayoutMap.cpp b/libs/input/KeyLayoutMap.cpp
index 5088188..f3241c9 100644
--- a/libs/input/KeyLayoutMap.cpp
+++ b/libs/input/KeyLayoutMap.cpp
@@ -240,8 +240,9 @@
std::vector<int32_t> KeyLayoutMap::findScanCodesForKey(int32_t keyCode) const {
std::vector<int32_t> scanCodes;
+ // b/354333072: Only consider keys without FUNCTION flag
for (const auto& [scanCode, key] : mKeysByScanCode) {
- if (keyCode == key.keyCode) {
+ if (keyCode == key.keyCode && !(key.flags & POLICY_FLAG_FUNCTION)) {
scanCodes.push_back(scanCode);
}
}
diff --git a/libs/input/MotionPredictor.cpp b/libs/input/MotionPredictor.cpp
index 5b61d39..9c70535 100644
--- a/libs/input/MotionPredictor.cpp
+++ b/libs/input/MotionPredictor.cpp
@@ -75,6 +75,9 @@
JerkTracker::JerkTracker(bool normalizedDt) : mNormalizedDt(normalizedDt) {}
void JerkTracker::pushSample(int64_t timestamp, float xPos, float yPos) {
+ // If we previously had full samples, we have a previous jerk calculation
+ // to do weighted smoothing.
+ const bool applySmoothing = mTimestamps.size() == mTimestamps.capacity();
mTimestamps.pushBack(timestamp);
const int numSamples = mTimestamps.size();
@@ -115,6 +118,16 @@
}
}
+ if (numSamples == static_cast<int>(mTimestamps.capacity())) {
+ float newJerkMagnitude = std::hypot(newXDerivatives[3], newYDerivatives[3]);
+ ALOGD_IF(isDebug(), "raw jerk: %f", newJerkMagnitude);
+ if (applySmoothing) {
+ mJerkMagnitude = mJerkMagnitude + (mForgetFactor * (newJerkMagnitude - mJerkMagnitude));
+ } else {
+ mJerkMagnitude = newJerkMagnitude;
+ }
+ }
+
std::swap(newXDerivatives, mXDerivatives);
std::swap(newYDerivatives, mYDerivatives);
}
@@ -125,11 +138,19 @@
std::optional<float> JerkTracker::jerkMagnitude() const {
if (mTimestamps.size() == mTimestamps.capacity()) {
- return std::hypot(mXDerivatives[3], mYDerivatives[3]);
+ return mJerkMagnitude;
}
return std::nullopt;
}
+void JerkTracker::setForgetFactor(float forgetFactor) {
+ mForgetFactor = forgetFactor;
+}
+
+float JerkTracker::getForgetFactor() const {
+ return mForgetFactor;
+}
+
// --- MotionPredictor ---
MotionPredictor::MotionPredictor(nsecs_t predictionTimestampOffsetNanos,
@@ -159,6 +180,7 @@
if (!mModel) {
mModel = TfLiteMotionPredictorModel::create();
LOG_ALWAYS_FATAL_IF(!mModel);
+ mJerkTracker.setForgetFactor(mModel->config().jerkForgetFactor);
}
if (!mBuffers) {
@@ -323,7 +345,7 @@
event.getRawTransform(), event.getDownTime(), predictionTime,
event.getPointerCount(), event.getPointerProperties(), &coords);
} else {
- prediction->addSample(predictionTime, &coords);
+ prediction->addSample(predictionTime, &coords, prediction->getId());
}
axisFrom = axisTo;
@@ -357,4 +379,12 @@
return true;
}
+const TfLiteMotionPredictorModel::Config& MotionPredictor::getModelConfig() {
+ if (!mModel) {
+ mModel = TfLiteMotionPredictorModel::create();
+ LOG_ALWAYS_FATAL_IF(!mModel);
+ }
+ return mModel->config();
+}
+
} // namespace android
diff --git a/libs/input/TfLiteMotionPredictor.cpp b/libs/input/TfLiteMotionPredictor.cpp
index b843a4b..b401c98 100644
--- a/libs/input/TfLiteMotionPredictor.cpp
+++ b/libs/input/TfLiteMotionPredictor.cpp
@@ -283,6 +283,7 @@
.distanceNoiseFloor = parseXMLFloat(*configRoot, "distance-noise-floor"),
.lowJerk = parseXMLFloat(*configRoot, "low-jerk"),
.highJerk = parseXMLFloat(*configRoot, "high-jerk"),
+ .jerkForgetFactor = parseXMLFloat(*configRoot, "jerk-forget-factor"),
};
return std::unique_ptr<TfLiteMotionPredictorModel>(
diff --git a/libs/input/input_flags.aconfig b/libs/input/input_flags.aconfig
index cbe021b..500f7b4 100644
--- a/libs/input/input_flags.aconfig
+++ b/libs/input/input_flags.aconfig
@@ -15,7 +15,14 @@
bug: "271455682"
}
- flag {
+flag {
+ name: "remove_input_channel_from_windowstate"
+ namespace: "input"
+ description: "Do not store a copy of input channel inside WindowState."
+ bug: "323450804"
+}
+
+flag {
name: "enable_input_event_tracing"
namespace: "input"
description: "Set to true to enable input event tracing, including always-on tracing on non-user builds"
@@ -30,6 +37,13 @@
}
flag {
+ name: "split_all_touches"
+ namespace: "input"
+ description: "Set FLAG_SPLIT_TOUCHES to true for all windows, regardless of what they specify. This is essentially deprecating this flag by forcefully enabling the split functionality"
+ bug: "239934827"
+}
+
+flag {
name: "a11y_crash_on_inconsistent_event_stream"
namespace: "accessibility"
description: "Brings back fatal logging for inconsistent event streams originating from accessibility."
@@ -143,3 +157,10 @@
description: "Keyboard classifier that classifies all keyboards into alphabetic or non-alphabetic"
bug: "263559234"
}
+
+flag {
+ name: "show_pointers_for_partial_screenshare"
+ namespace: "input"
+ description: "Show touch and pointer indicators when mirroring a single task"
+ bug: "310179437"
+}
diff --git a/libs/input/tests/InputEvent_test.cpp b/libs/input/tests/InputEvent_test.cpp
index 3717f49..a67e1ef 100644
--- a/libs/input/tests/InputEvent_test.cpp
+++ b/libs/input/tests/InputEvent_test.cpp
@@ -371,8 +371,8 @@
mTransform, 2.0f, 2.1f, AMOTION_EVENT_INVALID_CURSOR_POSITION,
AMOTION_EVENT_INVALID_CURSOR_POSITION, mRawTransform, ARBITRARY_DOWN_TIME,
ARBITRARY_EVENT_TIME, 2, mPointerProperties, mSamples[0].pointerCoords);
- event->addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords);
- event->addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords);
+ event->addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords, event->getId());
+ event->addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords, event->getId());
}
void MotionEventTest::assertEqualsEventWithHistory(const MotionEvent* event) {
@@ -591,6 +591,22 @@
ASSERT_EQ(event.getX(0), copy.getX(0));
}
+TEST_F(MotionEventTest, CheckEventIdWithHistoryIsIncremented) {
+ MotionEvent event;
+ constexpr int32_t ARBITRARY_ID = 42;
+ event.initialize(ARBITRARY_ID, 2, AINPUT_SOURCE_TOUCHSCREEN, DISPLAY_ID, INVALID_HMAC,
+ AMOTION_EVENT_ACTION_MOVE, 0, 0, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+ AMOTION_EVENT_BUTTON_PRIMARY, MotionClassification::NONE, mTransform, 0, 0,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ mRawTransform, ARBITRARY_DOWN_TIME, ARBITRARY_EVENT_TIME, 2,
+ mPointerProperties, mSamples[0].pointerCoords);
+ ASSERT_EQ(event.getId(), ARBITRARY_ID);
+ event.addSample(ARBITRARY_EVENT_TIME + 1, mSamples[1].pointerCoords, ARBITRARY_ID + 1);
+ ASSERT_EQ(event.getId(), ARBITRARY_ID + 1);
+ event.addSample(ARBITRARY_EVENT_TIME + 2, mSamples[2].pointerCoords, ARBITRARY_ID + 2);
+ ASSERT_EQ(event.getId(), ARBITRARY_ID + 2);
+}
+
TEST_F(MotionEventTest, SplitPointerDown) {
MotionEvent event = MotionEventBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.downTime(ARBITRARY_DOWN_TIME)
diff --git a/libs/input/tests/MotionPredictorMetricsManager_test.cpp b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
index cc41eeb..0542f39 100644
--- a/libs/input/tests/MotionPredictorMetricsManager_test.cpp
+++ b/libs/input/tests/MotionPredictorMetricsManager_test.cpp
@@ -167,7 +167,8 @@
.y(predictionPoints[i].position[0])
.axis(AMOTION_EVENT_AXIS_PRESSURE, predictionPoints[i].pressure)
.buildCoords();
- predictionEvent.addSample(predictionPoints[i].targetTimestamp, &coords);
+ predictionEvent.addSample(predictionPoints[i].targetTimestamp, &coords,
+ predictionEvent.getId());
}
return predictionEvent;
}
diff --git a/libs/input/tests/MotionPredictor_test.cpp b/libs/input/tests/MotionPredictor_test.cpp
index d077760..5bd5794 100644
--- a/libs/input/tests/MotionPredictor_test.cpp
+++ b/libs/input/tests/MotionPredictor_test.cpp
@@ -88,6 +88,7 @@
TEST(JerkTrackerTest, JerkCalculationNormalizedDtTrue) {
JerkTracker jerkTracker(true);
+ jerkTracker.setForgetFactor(.5);
jerkTracker.pushSample(/*timestamp=*/0, 20, 50);
jerkTracker.pushSample(/*timestamp=*/1, 25, 53);
jerkTracker.pushSample(/*timestamp=*/2, 30, 60);
@@ -118,11 +119,14 @@
* y'': 3 -> -15
* y''': -18
*/
- EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), std::hypot(-50, -18));
+ const float newJerk = (1 - jerkTracker.getForgetFactor()) * std::hypot(10, -1) +
+ jerkTracker.getForgetFactor() * std::hypot(-50, -18);
+ EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), newJerk);
}
TEST(JerkTrackerTest, JerkCalculationNormalizedDtFalse) {
JerkTracker jerkTracker(false);
+ jerkTracker.setForgetFactor(.5);
jerkTracker.pushSample(/*timestamp=*/0, 20, 50);
jerkTracker.pushSample(/*timestamp=*/10, 25, 53);
jerkTracker.pushSample(/*timestamp=*/20, 30, 60);
@@ -153,7 +157,9 @@
* y'': .03 -> -.125 (delta above, divide by 10)
* y''': -.0155 (delta above, divide by 10)
*/
- EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), std::hypot(-.0375, -.0155));
+ const float newJerk = (1 - jerkTracker.getForgetFactor()) * std::hypot(.01, -.001) +
+ jerkTracker.getForgetFactor() * std::hypot(-.0375, -.0155);
+ EXPECT_FLOAT_EQ(jerkTracker.jerkMagnitude().value(), newJerk);
}
TEST(JerkTrackerTest, JerkCalculationAfterReset) {
@@ -291,15 +297,19 @@
MotionPredictor predictor(/*predictionTimestampOffsetNanos=*/0,
[]() { return true /*enable prediction*/; });
- // Jerk is medium (1.05 normalized, which is halfway between LOW_JANK and HIGH_JANK)
- predictor.record(getMotionEvent(DOWN, 0, 5.2, 20ms));
- predictor.record(getMotionEvent(MOVE, 0, 11.5, 30ms));
- predictor.record(getMotionEvent(MOVE, 0, 22, 40ms));
- predictor.record(getMotionEvent(MOVE, 0, 37.75, 50ms));
- predictor.record(getMotionEvent(MOVE, 0, 59.8, 60ms));
+ const float mediumJerk =
+ (predictor.getModelConfig().lowJerk + predictor.getModelConfig().highJerk) / 2;
+ const float a = 3; // initial acceleration
+ const float b = 4; // initial velocity
+ const float c = 5; // initial position
+ predictor.record(getMotionEvent(DOWN, 0, c, 20ms));
+ predictor.record(getMotionEvent(MOVE, 0, c + b, 30ms));
+ predictor.record(getMotionEvent(MOVE, 0, c + 2 * b + a, 40ms));
+ predictor.record(getMotionEvent(MOVE, 0, c + 3 * b + 3 * a + mediumJerk, 50ms));
+ predictor.record(getMotionEvent(MOVE, 0, c + 4 * b + 6 * a + 4 * mediumJerk, 60ms));
std::unique_ptr<MotionEvent> predicted = predictor.predict(82 * NSEC_PER_MSEC);
EXPECT_NE(nullptr, predicted);
- // Halfway between LOW_JANK and HIGH_JANK means that half of the predictions
+ // Halfway between LOW_JERK and HIGH_JERK means that half of the predictions
// will be pruned. If model prediction window is close enough to predict()
// call time window, then half of the model predictions (5/2 -> 2) will be
// ouputted.
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 6fcb3a4..d05ff34 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -326,7 +326,7 @@
* COMPOSER_OVERLAY, the system will try to prioritize the buffer receiving
* an overlay plane & avoid caching it in intermediate composition buffers.
*/
- AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1UL << 32,
+ AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1ULL << 32,
AHARDWAREBUFFER_USAGE_VENDOR_0 = 1ULL << 28,
AHARDWAREBUFFER_USAGE_VENDOR_1 = 1ULL << 29,
diff --git a/libs/renderengine/ExternalTexture.cpp b/libs/renderengine/ExternalTexture.cpp
index 6f2a96a..8d0fbba 100644
--- a/libs/renderengine/ExternalTexture.cpp
+++ b/libs/renderengine/ExternalTexture.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
+#include <common/trace.h>
#include <log/log.h>
#include <renderengine/RenderEngine.h>
#include <renderengine/impl/ExternalTexture.h>
#include <ui/GraphicBuffer.h>
-#include <utils/Trace.h>
namespace android::renderengine::impl {
@@ -35,7 +35,7 @@
}
void ExternalTexture::remapBuffer() {
- ATRACE_CALL();
+ SFTRACE_CALL();
{
auto buf = mBuffer;
mRenderEngine.unmapExternalTextureBuffer(std::move(buf));
diff --git a/libs/renderengine/benchmark/Android.bp b/libs/renderengine/benchmark/Android.bp
index e1a6f6a..f84db0b 100644
--- a/libs/renderengine/benchmark/Android.bp
+++ b/libs/renderengine/benchmark/Android.bp
@@ -57,6 +57,7 @@
"libui",
"libutils",
"server_configurable_flags",
+ "libtracing_perfetto",
],
data: ["resources/*"],
diff --git a/libs/renderengine/skia/AutoBackendTexture.cpp b/libs/renderengine/skia/AutoBackendTexture.cpp
index 8aeef9f..b7b7a4d 100644
--- a/libs/renderengine/skia/AutoBackendTexture.cpp
+++ b/libs/renderengine/skia/AutoBackendTexture.cpp
@@ -25,8 +25,8 @@
#include "compat/SkiaBackendTexture.h"
+#include <common/trace.h>
#include <log/log_main.h>
-#include <utils/Trace.h>
namespace android {
namespace renderengine {
@@ -63,7 +63,7 @@
}
sk_sp<SkImage> AutoBackendTexture::makeImage(ui::Dataspace dataspace, SkAlphaType alphaType) {
- ATRACE_CALL();
+ SFTRACE_CALL();
sk_sp<SkImage> image = mBackendTexture->makeImage(alphaType, dataspace, releaseImageProc, this);
// The following ref will be counteracted by releaseProc, when SkImage is discarded.
@@ -75,7 +75,7 @@
}
sk_sp<SkSurface> AutoBackendTexture::getOrCreateSurface(ui::Dataspace dataspace) {
- ATRACE_CALL();
+ SFTRACE_CALL();
LOG_ALWAYS_FATAL_IF(!mBackendTexture->isOutputBuffer(),
"You can't generate an SkSurface for a read-only texture");
if (!mSurface.get() || mDataspace != dataspace) {
diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp
index d246870..59b0656 100644
--- a/libs/renderengine/skia/Cache.cpp
+++ b/libs/renderengine/skia/Cache.cpp
@@ -729,8 +729,7 @@
const auto externalTexture =
std::make_shared<impl::ExternalTexture>(externalBuffer, *renderengine,
impl::ExternalTexture::Usage::READABLE);
- std::vector<const std::shared_ptr<ExternalTexture>> textures =
- {srcTexture, externalTexture};
+ std::vector<std::shared_ptr<ExternalTexture>> textures = {srcTexture, externalTexture};
// Another external texture with a different pixel format triggers useIsOpaqueWorkaround.
// It doesn't have to be f16, but it can't be the usual 8888.
diff --git a/libs/renderengine/skia/GaneshVkRenderEngine.cpp b/libs/renderengine/skia/GaneshVkRenderEngine.cpp
index 68798bf..a3a43e2 100644
--- a/libs/renderengine/skia/GaneshVkRenderEngine.cpp
+++ b/libs/renderengine/skia/GaneshVkRenderEngine.cpp
@@ -21,9 +21,9 @@
#include <include/gpu/ganesh/vk/GrVkBackendSemaphore.h>
+#include <common/trace.h>
#include <log/log_main.h>
#include <sync/sync.h>
-#include <utils/Trace.h>
namespace android::renderengine::skia {
@@ -78,7 +78,7 @@
sk_sp<SkSurface> dstSurface) {
sk_sp<GrDirectContext> grContext = context->grDirectContext();
{
- ATRACE_NAME("flush surface");
+ SFTRACE_NAME("flush surface");
// TODO: Investigate feasibility of combining this "surface flush" into the "context flush"
// below.
context->grDirectContext()->flush(dstSurface.get());
diff --git a/libs/renderengine/skia/GraphiteVkRenderEngine.cpp b/libs/renderengine/skia/GraphiteVkRenderEngine.cpp
index b5cb21b..390ad6e 100644
--- a/libs/renderengine/skia/GraphiteVkRenderEngine.cpp
+++ b/libs/renderengine/skia/GraphiteVkRenderEngine.cpp
@@ -23,6 +23,7 @@
#include <include/gpu/graphite/BackendSemaphore.h>
#include <include/gpu/graphite/Context.h>
#include <include/gpu/graphite/Recording.h>
+#include <include/gpu/graphite/vk/VulkanGraphiteTypes.h>
#include <log/log_main.h>
#include <sync/sync.h>
@@ -77,7 +78,7 @@
base::unique_fd fenceDup(dupedFd);
VkSemaphore waitSemaphore =
getVulkanInterface(isProtected()).importSemaphoreFromSyncFd(fenceDup.release());
- graphite::BackendSemaphore beSemaphore(waitSemaphore);
+ auto beSemaphore = graphite::BackendSemaphores::MakeVulkan(waitSemaphore);
mStagedWaitSemaphores.push_back(beSemaphore);
}
@@ -92,7 +93,7 @@
// This "signal" semaphore is called after rendering, but it is cleaned up in the same mechanism
// as "wait" semaphores from waitFence.
VkSemaphore vkSignalSemaphore = vulkanInterface.createExportableSemaphore();
- graphite::BackendSemaphore backendSignalSemaphore(vkSignalSemaphore);
+ auto backendSignalSemaphore = graphite::BackendSemaphores::MakeVulkan(vkSignalSemaphore);
// Collect all Vk semaphores that DestroySemaphoreInfo needs to own and delete after GPU work.
std::vector<VkSemaphore> vkSemaphoresToCleanUp;
@@ -100,7 +101,8 @@
vkSemaphoresToCleanUp.push_back(vkSignalSemaphore);
}
for (auto backendWaitSemaphore : mStagedWaitSemaphores) {
- vkSemaphoresToCleanUp.push_back(backendWaitSemaphore.getVkSemaphore());
+ vkSemaphoresToCleanUp.push_back(
+ graphite::BackendSemaphores::GetVkSemaphore(backendWaitSemaphore));
}
DestroySemaphoreInfo* destroySemaphoreInfo = nullptr;
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 48270e1..af24600 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -28,12 +28,11 @@
#include <GrContextOptions.h>
#include <GrTypes.h>
#include <android-base/stringprintf.h>
+#include <common/trace.h>
#include <gl/GrGLInterface.h>
#include <include/gpu/ganesh/gl/GrGLDirectContext.h>
-#include <gui/TraceUtils.h>
#include <sync/sync.h>
#include <ui/DebugUtils.h>
-#include <utils/Trace.h>
#include <cmath>
#include <cstdint>
@@ -332,7 +331,7 @@
void SkiaGLRenderEngine::waitFence(SkiaGpuContext*, base::borrowed_fd fenceFd) {
if (fenceFd.get() >= 0 && !waitGpuFence(fenceFd)) {
- ATRACE_NAME("SkiaGLRenderEngine::waitFence");
+ SFTRACE_NAME("SkiaGLRenderEngine::waitFence");
sync_wait(fenceFd.get(), -1);
}
}
@@ -341,19 +340,19 @@
sk_sp<SkSurface> dstSurface) {
sk_sp<GrDirectContext> grContext = context->grDirectContext();
{
- ATRACE_NAME("flush surface");
+ SFTRACE_NAME("flush surface");
grContext->flush(dstSurface.get());
}
base::unique_fd drawFence = flushGL();
bool requireSync = drawFence.get() < 0;
if (requireSync) {
- ATRACE_BEGIN("Submit(sync=true)");
+ SFTRACE_BEGIN("Submit(sync=true)");
} else {
- ATRACE_BEGIN("Submit(sync=false)");
+ SFTRACE_BEGIN("Submit(sync=false)");
}
bool success = grContext->submit(requireSync ? GrSyncCpu::kYes : GrSyncCpu::kNo);
- ATRACE_END();
+ SFTRACE_END();
if (!success) {
ALOGE("Failed to flush RenderEngine commands");
// Chances are, something illegal happened (Skia's internal GPU object
@@ -400,7 +399,7 @@
}
base::unique_fd SkiaGLRenderEngine::flushGL() {
- ATRACE_CALL();
+ SFTRACE_CALL();
if (!GLExtensions::getInstance().hasNativeFenceSync()) {
return base::unique_fd();
}
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index a609f2d..9709cd1 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -54,8 +54,8 @@
#include <SkTileMode.h>
#include <android-base/stringprintf.h>
#include <common/FlagManager.h>
+#include <common/trace.h>
#include <gui/FenceMonitor.h>
-#include <gui/TraceUtils.h>
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
#include <pthread.h>
#include <src/core/SkTraceEventCommon.h>
@@ -64,7 +64,6 @@
#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
#include <ui/HdrRenderTypeUtils.h>
-#include <utils/Trace.h>
#include <cmath>
#include <cstdint>
@@ -261,7 +260,7 @@
const SkString& description) {
mShadersCachedSinceLastCall++;
mTotalShadersCompiled++;
- ATRACE_FORMAT("SF cache: %i shaders", mTotalShadersCompiled);
+ SFTRACE_FORMAT("SF cache: %i shaders", mTotalShadersCompiled);
}
int SkiaRenderEngine::reportShadersCompiled() {
@@ -416,7 +415,7 @@
if (isProtectedBuffer || isProtected() || !isGpuSampleable) {
return;
}
- ATRACE_CALL();
+ SFTRACE_CALL();
// If we were to support caching protected buffers then we will need to switch the
// currently bound context if we are not already using the protected context (and subsequently
@@ -441,7 +440,7 @@
}
void SkiaRenderEngine::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
- ATRACE_CALL();
+ SFTRACE_CALL();
std::lock_guard<std::mutex> lock(mRenderingMutex);
if (const auto& iter = mGraphicBufferExternalRefs.find(buffer->getId());
iter != mGraphicBufferExternalRefs.end()) {
@@ -498,7 +497,7 @@
}
void SkiaRenderEngine::cleanupPostRender() {
- ATRACE_CALL();
+ SFTRACE_CALL();
std::lock_guard<std::mutex> lock(mRenderingMutex);
mTextureCleanupMgr.cleanup();
}
@@ -696,7 +695,7 @@
const std::shared_ptr<std::promise<FenceResult>>&& resultPromise,
const DisplaySettings& display, const std::vector<LayerSettings>& layers,
const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
- ATRACE_FORMAT("%s for %s", __func__, display.namePlusId.c_str());
+ SFTRACE_FORMAT("%s for %s", __func__, display.namePlusId.c_str());
std::lock_guard<std::mutex> lock(mRenderingMutex);
@@ -788,7 +787,7 @@
logSettings(display);
}
for (const auto& layer : layers) {
- ATRACE_FORMAT("DrawLayer: %s", layer.name.c_str());
+ SFTRACE_FORMAT("DrawLayer: %s", layer.name.c_str());
if (kPrintLayerSettings) {
logSettings(layer);
@@ -882,7 +881,7 @@
// TODO(b/182216890): Filter out empty layers earlier
if (blurRect.width() > 0 && blurRect.height() > 0) {
if (layer.backgroundBlurRadius > 0) {
- ATRACE_NAME("BackgroundBlur");
+ SFTRACE_NAME("BackgroundBlur");
auto blurredImage = mBlurFilter->generate(context, layer.backgroundBlurRadius,
blurInput, blurRect);
@@ -895,7 +894,7 @@
canvas->concat(getSkM44(layer.blurRegionTransform).asM33());
for (auto region : layer.blurRegions) {
if (cachedBlurs[region.blurRadius] == nullptr) {
- ATRACE_NAME("BlurRegion");
+ SFTRACE_NAME("BlurRegion");
cachedBlurs[region.blurRadius] =
mBlurFilter->generate(context, region.blurRadius, blurInput,
blurRect);
@@ -978,7 +977,7 @@
SkPaint paint;
if (layer.source.buffer.buffer) {
- ATRACE_NAME("DrawImage");
+ SFTRACE_NAME("DrawImage");
validateInputBufferUsage(layer.source.buffer.buffer->getBuffer());
const auto& item = layer.source.buffer;
auto imageTextureRef = getOrCreateBackendTexture(item.buffer->getBuffer(), false);
@@ -1111,7 +1110,7 @@
paint.setColorFilter(SkColorFilters::Matrix(colorMatrix));
}
} else {
- ATRACE_NAME("DrawColor");
+ SFTRACE_NAME("DrawColor");
const auto color = layer.source.solidColor;
sk_sp<SkShader> shader = SkShaders::Color(SkColor4f{.fR = color.r,
.fG = color.g,
@@ -1168,7 +1167,7 @@
canvas->drawRect(bounds.rect(), paint);
}
if (kGaneshFlushAfterEveryLayer) {
- ATRACE_NAME("flush surface");
+ SFTRACE_NAME("flush surface");
// No-op in Graphite. If "flushing" Skia's drawing commands after each layer is desired
// in Graphite, then a graphite::Recording would need to be snapped and tracked for each
// layer, which is likely possible but adds non-trivial complexity (in both bookkeeping
@@ -1183,7 +1182,7 @@
LOG_ALWAYS_FATAL_IF(activeSurface != dstSurface);
auto drawFence = sp<Fence>::make(flushAndSubmit(context, dstSurface));
- if (ATRACE_ENABLED()) {
+ if (SFTRACE_ENABLED()) {
static gui::FenceMonitor sMonitor("RE Completion");
sMonitor.queueFence(drawFence);
}
@@ -1201,7 +1200,7 @@
void SkiaRenderEngine::drawShadow(SkCanvas* canvas,
const SkRRect& casterRRect,
const ShadowSettings& settings) {
- ATRACE_CALL();
+ SFTRACE_CALL();
const float casterZ = settings.length / 2.0f;
const auto flags =
settings.casterIsTranslucent ? kTransparentOccluder_ShadowFlag : kNone_ShadowFlag;
diff --git a/libs/renderengine/skia/SkiaVkRenderEngine.cpp b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
index a1f917d..d89e818 100644
--- a/libs/renderengine/skia/SkiaVkRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaVkRenderEngine.cpp
@@ -32,9 +32,8 @@
#include <vk/GrVkTypes.h>
#include <android-base/stringprintf.h>
-#include <gui/TraceUtils.h>
+#include <common/trace.h>
#include <sync/sync.h>
-#include <utils/Trace.h>
#include <memory>
#include <string>
diff --git a/libs/renderengine/skia/compat/GaneshBackendTexture.cpp b/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
index d246466..3fbc6ca 100644
--- a/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
+++ b/libs/renderengine/skia/compat/GaneshBackendTexture.cpp
@@ -32,15 +32,15 @@
#include "skia/compat/SkiaBackendTexture.h"
#include <android/hardware_buffer.h>
+#include <common/trace.h>
#include <log/log_main.h>
-#include <utils/Trace.h>
namespace android::renderengine::skia {
GaneshBackendTexture::GaneshBackendTexture(sk_sp<GrDirectContext> grContext,
AHardwareBuffer* buffer, bool isOutputBuffer)
: SkiaBackendTexture(buffer, isOutputBuffer), mGrContext(grContext) {
- ATRACE_CALL();
+ SFTRACE_CALL();
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
const bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
diff --git a/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp b/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
index 3dd9ed2..a6e93ba 100644
--- a/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
+++ b/libs/renderengine/skia/compat/GraphiteBackendTexture.cpp
@@ -28,16 +28,16 @@
#include "skia/ColorSpaces.h"
#include <android/hardware_buffer.h>
+#include <common/trace.h>
#include <inttypes.h>
#include <log/log_main.h>
-#include <utils/Trace.h>
namespace android::renderengine::skia {
GraphiteBackendTexture::GraphiteBackendTexture(std::shared_ptr<skgpu::graphite::Recorder> recorder,
AHardwareBuffer* buffer, bool isOutputBuffer)
: SkiaBackendTexture(buffer, isOutputBuffer), mRecorder(std::move(recorder)) {
- ATRACE_CALL();
+ SFTRACE_CALL();
AHardwareBuffer_Desc desc;
AHardwareBuffer_describe(buffer, &desc);
const bool createProtectedImage = 0 != (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
diff --git a/libs/renderengine/skia/debug/CommonPool.cpp b/libs/renderengine/skia/debug/CommonPool.cpp
index bf15300..9d7c69b 100644
--- a/libs/renderengine/skia/debug/CommonPool.cpp
+++ b/libs/renderengine/skia/debug/CommonPool.cpp
@@ -20,8 +20,8 @@
#define LOG_TAG "RenderEngine"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <common/trace.h>
#include <sys/resource.h>
-#include <utils/Trace.h>
#include <system/thread_defs.h>
#include <array>
@@ -31,7 +31,7 @@
namespace skia {
CommonPool::CommonPool() {
- ATRACE_CALL();
+ SFTRACE_CALL();
CommonPool* pool = this;
// Create 2 workers
diff --git a/libs/renderengine/skia/debug/SkiaCapture.cpp b/libs/renderengine/skia/debug/SkiaCapture.cpp
index e778884..e6a0e22 100644
--- a/libs/renderengine/skia/debug/SkiaCapture.cpp
+++ b/libs/renderengine/skia/debug/SkiaCapture.cpp
@@ -22,9 +22,9 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
+#include <common/trace.h>
#include <log/log.h>
#include <renderengine/RenderEngine.h>
-#include <utils/Trace.h>
#include "CommonPool.h"
#include "SkCanvas.h"
@@ -48,7 +48,7 @@
}
SkCanvas* SkiaCapture::tryCapture(SkSurface* surface) NO_THREAD_SAFETY_ANALYSIS {
- ATRACE_CALL();
+ SFTRACE_CALL();
// If we are not running yet, set up.
if (CC_LIKELY(!mCaptureRunning)) {
@@ -86,7 +86,7 @@
}
void SkiaCapture::endCapture() NO_THREAD_SAFETY_ANALYSIS {
- ATRACE_CALL();
+ SFTRACE_CALL();
// Don't end anything if we are not running.
if (CC_LIKELY(!mCaptureRunning)) {
return;
@@ -102,7 +102,7 @@
}
SkCanvas* SkiaCapture::tryOffscreenCapture(SkSurface* surface, OffscreenState* state) {
- ATRACE_CALL();
+ SFTRACE_CALL();
// Don't start anything if we are not running.
if (CC_LIKELY(!mCaptureRunning)) {
return surface->getCanvas();
@@ -122,7 +122,7 @@
}
uint64_t SkiaCapture::endOffscreenCapture(OffscreenState* state) {
- ATRACE_CALL();
+ SFTRACE_CALL();
// Don't end anything if we are not running.
if (CC_LIKELY(!mCaptureRunning)) {
return 0;
@@ -151,7 +151,7 @@
}
void SkiaCapture::writeToFile() {
- ATRACE_CALL();
+ SFTRACE_CALL();
// Pass mMultiPic and mOpenMultiPicStream to a background thread, which will
// handle the heavyweight serialization work and destroy them.
// mOpenMultiPicStream is released to a bare pointer because keeping it in
@@ -169,7 +169,7 @@
}
bool SkiaCapture::setupMultiFrameCapture() {
- ATRACE_CALL();
+ SFTRACE_CALL();
ALOGD("Set up multi-frame capture, ms = %llu", mTimerInterval.count());
base::SetProperty(PROPERTY_DEBUG_RENDERENGINE_CAPTURE_FILENAME, "");
diff --git a/libs/renderengine/skia/filters/BlurFilter.cpp b/libs/renderengine/skia/filters/BlurFilter.cpp
index 1e0c4cf..cd1bd71 100644
--- a/libs/renderengine/skia/filters/BlurFilter.cpp
+++ b/libs/renderengine/skia/filters/BlurFilter.cpp
@@ -25,8 +25,8 @@
#include <SkString.h>
#include <SkSurface.h>
#include <SkTileMode.h>
+#include <common/trace.h>
#include <log/log.h>
-#include <utils/Trace.h>
namespace android {
namespace renderengine {
@@ -79,7 +79,7 @@
const uint32_t blurRadius, const float blurAlpha,
const SkRect& blurRect, sk_sp<SkImage> blurredImage,
sk_sp<SkImage> input) {
- ATRACE_CALL();
+ SFTRACE_CALL();
SkPaint paint;
paint.setAlphaf(blurAlpha);
diff --git a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
index c9499cb..8c52c57 100644
--- a/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
+++ b/libs/renderengine/skia/filters/GaussianBlurFilter.cpp
@@ -19,18 +19,18 @@
#include "GaussianBlurFilter.h"
#include <SkBlendMode.h>
#include <SkCanvas.h>
+#include <SkImageFilters.h>
#include <SkPaint.h>
#include <SkRRect.h>
#include <SkRuntimeEffect.h>
-#include <SkImageFilters.h>
#include <SkSize.h>
#include <SkString.h>
#include <SkSurface.h>
#include <SkTileMode.h>
+#include <common/trace.h>
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
-#include "include/gpu/GpuTypes.h" // from Skia
#include <log/log.h>
-#include <utils/Trace.h>
+#include "include/gpu/GpuTypes.h" // from Skia
namespace android {
namespace renderengine {
diff --git a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
index 7a070d7..defaf6e 100644
--- a/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
+++ b/libs/renderengine/skia/filters/KawaseBlurFilter.cpp
@@ -29,10 +29,10 @@
#include <SkString.h>
#include <SkSurface.h>
#include <SkTileMode.h>
+#include <common/trace.h>
#include <include/gpu/GpuTypes.h>
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
#include <log/log.h>
-#include <utils/Trace.h>
namespace android {
namespace renderengine {
diff --git a/libs/renderengine/skia/filters/LinearEffect.cpp b/libs/renderengine/skia/filters/LinearEffect.cpp
index f7dcd3a..3bc3564 100644
--- a/libs/renderengine/skia/filters/LinearEffect.cpp
+++ b/libs/renderengine/skia/filters/LinearEffect.cpp
@@ -19,9 +19,9 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <SkString.h>
+#include <common/trace.h>
#include <log/log.h>
#include <shaders/shaders.h>
-#include <utils/Trace.h>
#include <math/mat4.h>
@@ -30,7 +30,7 @@
namespace skia {
sk_sp<SkRuntimeEffect> buildRuntimeEffect(const shaders::LinearEffect& linearEffect) {
- ATRACE_CALL();
+ SFTRACE_CALL();
SkString shaderString = SkString(shaders::buildLinearEffectSkSL(linearEffect));
auto [shader, error] = SkRuntimeEffect::MakeForShader(shaderString);
@@ -45,7 +45,7 @@
sk_sp<SkRuntimeEffect> runtimeEffect, const mat4& colorTransform, float maxDisplayLuminance,
float currentDisplayLuminanceNits, float maxLuminance, AHardwareBuffer* buffer,
aidl::android::hardware::graphics::composer3::RenderIntent renderIntent) {
- ATRACE_CALL();
+ SFTRACE_CALL();
SkRuntimeShaderBuilder effectBuilder(runtimeEffect);
effectBuilder.child("child") = shader;
diff --git a/libs/renderengine/tests/Android.bp b/libs/renderengine/tests/Android.bp
index 0783714..7fbbf49 100644
--- a/libs/renderengine/tests/Android.bp
+++ b/libs/renderengine/tests/Android.bp
@@ -66,5 +66,6 @@
"libutils",
"server_configurable_flags",
"libaconfig_storage_read_api_cc",
+ "libtracing_perfetto",
],
}
diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp
index d27c151..f5a90fd 100644
--- a/libs/renderengine/threaded/RenderEngineThreaded.cpp
+++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp
@@ -23,9 +23,9 @@
#include <future>
#include <android-base/stringprintf.h>
+#include <common/trace.h>
#include <private/gui/SyncFeatures.h>
#include <processgroup/processgroup.h>
-#include <utils/Trace.h>
using namespace std::chrono_literals;
@@ -39,7 +39,7 @@
RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory)
: RenderEngine(Threaded::YES) {
- ATRACE_CALL();
+ SFTRACE_CALL();
std::lock_guard lockThread(mThreadMutex);
mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory);
@@ -76,7 +76,7 @@
// NO_THREAD_SAFETY_ANALYSIS is because std::unique_lock presently lacks thread safety annotations.
void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_SAFETY_ANALYSIS {
- ATRACE_CALL();
+ SFTRACE_CALL();
if (!SetTaskProfiles(0, {"SFRenderEnginePolicy"})) {
ALOGW("Failed to set render-engine task profile!");
@@ -133,13 +133,13 @@
std::future<void> RenderEngineThreaded::primeCache(PrimeCacheConfig config) {
const auto resultPromise = std::make_shared<std::promise<void>>();
std::future<void> resultFuture = resultPromise->get_future();
- ATRACE_CALL();
+ SFTRACE_CALL();
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([resultPromise, config](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::primeCache");
+ SFTRACE_NAME("REThreaded::primeCache");
if (setSchedFifo(false) != NO_ERROR) {
ALOGW("Couldn't set SCHED_OTHER for primeCache");
}
@@ -163,7 +163,7 @@
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([&resultPromise, &result](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::dump");
+ SFTRACE_NAME("REThreaded::dump");
std::string localResult = result;
instance.dump(localResult);
resultPromise.set_value(std::move(localResult));
@@ -176,13 +176,13 @@
void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
bool isRenderable) {
- ATRACE_CALL();
+ SFTRACE_CALL();
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::mapExternalTextureBuffer");
+ SFTRACE_NAME("REThreaded::mapExternalTextureBuffer");
instance.mapExternalTextureBuffer(buffer, isRenderable);
});
}
@@ -190,14 +190,14 @@
}
void RenderEngineThreaded::unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) {
- ATRACE_CALL();
+ SFTRACE_CALL();
// This function is designed so it can run asynchronously, so we do not need to wait
// for the futures.
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push(
[=, buffer = std::move(buffer)](renderengine::RenderEngine& instance) mutable {
- ATRACE_NAME("REThreaded::unmapExternalTextureBuffer");
+ SFTRACE_NAME("REThreaded::unmapExternalTextureBuffer");
instance.unmapExternalTextureBuffer(std::move(buffer));
});
}
@@ -229,7 +229,7 @@
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([=](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::cleanupPostRender");
+ SFTRACE_NAME("REThreaded::cleanupPostRender");
instance.cleanupPostRender();
});
mNeedsPostRenderCleanup = false;
@@ -252,7 +252,7 @@
ftl::Future<FenceResult> RenderEngineThreaded::drawLayers(
const DisplaySettings& display, const std::vector<LayerSettings>& layers,
const std::shared_ptr<ExternalTexture>& buffer, base::unique_fd&& bufferFence) {
- ATRACE_CALL();
+ SFTRACE_CALL();
const auto resultPromise = std::make_shared<std::promise<FenceResult>>();
std::future<FenceResult> resultFuture = resultPromise->get_future();
int fd = bufferFence.release();
@@ -261,7 +261,7 @@
mNeedsPostRenderCleanup = true;
mFunctionCalls.push(
[resultPromise, display, layers, buffer, fd](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::drawLayers");
+ SFTRACE_NAME("REThreaded::drawLayers");
instance.updateProtectedContext(layers, buffer);
instance.drawLayersInternal(std::move(resultPromise), display, layers, buffer,
base::unique_fd(fd));
@@ -277,7 +277,7 @@
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([&resultPromise](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::getContextPriority");
+ SFTRACE_NAME("REThreaded::getContextPriority");
int priority = instance.getContextPriority();
resultPromise.set_value(priority);
});
@@ -297,7 +297,7 @@
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([size](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
+ SFTRACE_NAME("REThreaded::onActiveDisplaySizeChanged");
instance.onActiveDisplaySizeChanged(size);
});
}
@@ -324,7 +324,7 @@
{
std::lock_guard lock(mThreadMutex);
mFunctionCalls.push([tracingEnabled](renderengine::RenderEngine& instance) {
- ATRACE_NAME("REThreaded::setEnableTracing");
+ SFTRACE_NAME("REThreaded::setEnableTracing");
instance.setEnableTracing(tracingEnabled);
});
}
diff --git a/libs/tracing_perfetto/include/tracing_perfetto.h b/libs/tracing_perfetto/include/tracing_perfetto.h
index 0b2b0af..59c43d6 100644
--- a/libs/tracing_perfetto/include/tracing_perfetto.h
+++ b/libs/tracing_perfetto/include/tracing_perfetto.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef TRACING_PERFETTO_H
-#define TRACING_PERFETTO_H
+#pragma once
#include <stdint.h>
@@ -29,6 +28,8 @@
void traceAsyncBegin(uint64_t category, const char* name, int32_t cookie);
+void traceFormatBegin(uint64_t category, const char* fmt, ...);
+
void traceAsyncEnd(uint64_t category, const char* name, int32_t cookie);
void traceAsyncBeginForTrack(uint64_t category, const char* name,
@@ -39,12 +40,14 @@
void traceInstant(uint64_t category, const char* name);
+void traceFormatInstant(uint64_t category, const char* fmt, ...);
+
void traceInstantForTrack(uint64_t category, const char* trackName,
const char* name);
void traceCounter(uint64_t category, const char* name, int64_t value);
+void traceCounter32(uint64_t category, const char* name, int32_t value);
+
bool isTagEnabled(uint64_t category);
} // namespace tracing_perfetto
-
-#endif // TRACING_PERFETTO_H
diff --git a/libs/tracing_perfetto/tracing_perfetto.cpp b/libs/tracing_perfetto/tracing_perfetto.cpp
index fc5336d..c35e078 100644
--- a/libs/tracing_perfetto/tracing_perfetto.cpp
+++ b/libs/tracing_perfetto/tracing_perfetto.cpp
@@ -17,6 +17,7 @@
#include "tracing_perfetto.h"
#include <cutils/trace.h>
+#include <cstdarg>
#include "perfetto/public/te_category_macros.h"
#include "trace_categories.h"
@@ -39,6 +40,31 @@
}
}
+void traceFormatBegin(uint64_t category, const char* fmt, ...) {
+ struct PerfettoTeCategory* perfettoTeCategory =
+ internal::toPerfettoCategory(category);
+ const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category);
+ const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory);
+ if (CC_LIKELY(!(preferAtrace || preferPerfetto))) {
+ return;
+ }
+
+ const int BUFFER_SIZE = 256;
+ va_list ap;
+ char buf[BUFFER_SIZE];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, BUFFER_SIZE, fmt, ap);
+ va_end(ap);
+
+
+ if (preferAtrace) {
+ atrace_begin(category, buf);
+ } else if (preferPerfetto) {
+ internal::perfettoTraceBegin(*perfettoTeCategory, buf);
+ }
+}
+
void traceEnd(uint64_t category) {
struct PerfettoTeCategory* perfettoTeCategory =
internal::toPerfettoCategory(category);
@@ -107,6 +133,30 @@
}
}
+void traceFormatInstant(uint64_t category, const char* fmt, ...) {
+ struct PerfettoTeCategory* perfettoTeCategory =
+ internal::toPerfettoCategory(category);
+ const bool preferAtrace = internal::shouldPreferAtrace(perfettoTeCategory, category);
+ const bool preferPerfetto = internal::isPerfettoCategoryEnabled(perfettoTeCategory);
+ if (CC_LIKELY(!(preferAtrace || preferPerfetto))) {
+ return;
+ }
+
+ const int BUFFER_SIZE = 256;
+ va_list ap;
+ char buf[BUFFER_SIZE];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, BUFFER_SIZE, fmt, ap);
+ va_end(ap);
+
+ if (preferAtrace) {
+ atrace_instant(category, buf);
+ } else if (preferPerfetto) {
+ internal::perfettoTraceInstant(*perfettoTeCategory, buf);
+ }
+}
+
void traceInstantForTrack(uint64_t category, const char* trackName,
const char* name) {
struct PerfettoTeCategory* perfettoTeCategory =
@@ -130,10 +180,21 @@
}
}
+void traceCounter32(uint64_t category, const char* name, int32_t value) {
+ struct PerfettoTeCategory* perfettoTeCategory = internal::toPerfettoCategory(category);
+ if (internal::shouldPreferAtrace(perfettoTeCategory, category)) {
+ atrace_int(category, name, value);
+ } else if (internal::isPerfettoCategoryEnabled(perfettoTeCategory)) {
+ internal::perfettoTraceCounter(*perfettoTeCategory, name,
+ static_cast<int64_t>(value));
+ }
+}
+
bool isTagEnabled(uint64_t category) {
struct PerfettoTeCategory* perfettoTeCategory =
internal::toPerfettoCategory(category);
return internal::isPerfettoCategoryEnabled(perfettoTeCategory)
|| atrace_is_tag_enabled(category);
}
+
} // namespace tracing_perfetto
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
deleted file mode 100644
index 10f274f..0000000
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BUFFER_HUB_DEFS_H_
-#define ANDROID_BUFFER_HUB_DEFS_H_
-
-#include <atomic>
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wpacked"
-// TODO(b/118893702): remove dependency once DvrNativeBufferMetadata moved out of libdvr
-#include <dvr/dvr_api.h>
-#pragma clang diagnostic pop
-
-namespace android {
-
-namespace BufferHubDefs {
-
-// Single buffer clients (up to 16) ownership signal.
-// 32-bit atomic unsigned int.
-// Each client takes 2 bits. The first bit locates in the first 16 bits of
-// bufferState; the second bit locates in the last 16 bits of bufferState.
-// Client states:
-// Gained state 11. Exclusive write state.
-// Posted state 10.
-// Acquired state 01. Shared read state.
-// Released state 00.
-//
-// MSB LSB
-// | |
-// v v
-// [C15|...|C1|C0|C15| ... |C1|C0]
-
-// Maximum number of clients a buffer can have.
-static constexpr int kMaxNumberOfClients = 16;
-
-// Definition of bit masks.
-// MSB LSB
-// | kHighBitsMask | kLowbitsMask |
-// v v v
-// [b31| ... |b16|b15| ... |b0]
-
-// The location of lower 16 bits in the 32-bit buffer state.
-static constexpr uint32_t kLowbitsMask = (1U << kMaxNumberOfClients) - 1U;
-
-// The location of higher 16 bits in the 32-bit buffer state.
-static constexpr uint32_t kHighBitsMask = ~kLowbitsMask;
-
-// The client bit mask of the first client.
-static constexpr uint32_t kFirstClientBitMask = (1U << kMaxNumberOfClients) + 1U;
-
-// Returns true if any of the client is in gained state.
-static inline bool isAnyClientGained(uint32_t state) {
- uint32_t highBits = state >> kMaxNumberOfClients;
- uint32_t lowBits = state & kLowbitsMask;
- return highBits == lowBits && lowBits != 0U;
-}
-
-// Returns true if the input client is in gained state.
-static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
- return state == client_bit_mask;
-}
-
-// Returns true if any of the client is in posted state.
-static inline bool isAnyClientPosted(uint32_t state) {
- uint32_t highBits = state >> kMaxNumberOfClients;
- uint32_t lowBits = state & kLowbitsMask;
- uint32_t postedOrAcquired = highBits ^ lowBits;
- return postedOrAcquired & highBits;
-}
-
-// Returns true if the input client is in posted state.
-static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
- uint32_t clientBits = state & client_bit_mask;
- if (clientBits == 0U) return false;
- uint32_t lowBits = clientBits & kLowbitsMask;
- return lowBits == 0U;
-}
-
-// Return true if any of the client is in acquired state.
-static inline bool isAnyClientAcquired(uint32_t state) {
- uint32_t highBits = state >> kMaxNumberOfClients;
- uint32_t lowBits = state & kLowbitsMask;
- uint32_t postedOrAcquired = highBits ^ lowBits;
- return postedOrAcquired & lowBits;
-}
-
-// Return true if the input client is in acquired state.
-static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
- uint32_t clientBits = state & client_bit_mask;
- if (clientBits == 0U) return false;
- uint32_t highBits = clientBits & kHighBitsMask;
- return highBits == 0U;
-}
-
-// Returns true if the input client is in released state.
-static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
- return (state & client_bit_mask) == 0U;
-}
-
-// Returns the next available buffer client's client_state_masks.
-// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
- uint32_t lowUnion = union_bits & kLowbitsMask;
- if (lowUnion == kLowbitsMask) return 0U;
- uint32_t incremented = lowUnion + 1U;
- uint32_t difference = incremented ^ lowUnion;
- uint32_t newLowBit = (difference + 1U) >> 1;
- return newLowBit + (newLowBit << kMaxNumberOfClients);
-}
-
-struct __attribute__((aligned(8))) MetadataHeader {
- // Internal data format, which can be updated as long as the size, padding and field alignment
- // of the struct is consistent within the same ABI. As this part is subject for future updates,
- // it's not stable cross Android version, so don't have it visible from outside of the Android
- // platform (include Apps and vendor HAL).
-
- // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // bufferState.
- std::atomic<uint32_t> bufferState;
-
- // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
- // bits are there for easier manipulation, but the value should be ignored.
- std::atomic<uint32_t> fenceState;
-
- // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
- // activeClientsBitMask.
- std::atomic<uint32_t> activeClientsBitMask;
-
- // Explicit padding 4 bytes.
- uint32_t padding;
-
- // The index of the buffer queue where the buffer belongs to.
- uint64_t queueIndex;
-
- // Public data format, which should be updated with caution. See more details in dvr_api.h
- DvrNativeBufferMetadata metadata;
-};
-
-static_assert(sizeof(MetadataHeader) == 128, "Unexpected MetadataHeader size");
-static constexpr size_t kMetadataHeaderSize = sizeof(MetadataHeader);
-
-/**
- * android.frameworks.bufferhub@1.0::BufferTraits.bufferInfo is an opaque handle. See
- * https://cs.corp.google.com/android/frameworks/hardware/interfaces/bufferhub/1.0/types.hal for
- * more details about android.frameworks.bufferhub@1.0::BufferTraits.
- *
- * This definition could be changed, but implementation of BufferHubService::buildBufferInfo
- * (frameworks/native/services/bufferhub), VtsHalBufferHubV1_0TargetTest
- * (frameworks/hardware/interfaces/bufferhub) and BufferHubBuffer::readBufferTraits (libui) will
- * also need to be updated.
- *
- * It's definition should follow the following format:
- * {
- * NumFds = 2,
- * NumInts = 3,
- * data[0] = Ashmem fd for BufferHubMetadata,
- * data[1] = event fd,
- * data[2] = buffer id,
- * data[3] = client state bit mask,
- * data[4] = user metadata size,
- * }
- */
-static constexpr int kBufferInfoNumFds = 2;
-static constexpr int kBufferInfoNumInts = 3;
-
-} // namespace BufferHubDefs
-
-} // namespace android
-
-#endif // ANDROID_BUFFER_HUB_DEFS_H_
diff --git a/libs/vr/.clang-format b/libs/vr/.clang-format
deleted file mode 100644
index 04d7970..0000000
--- a/libs/vr/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
-BasedOnStyle: Google
-DerivePointerAlignment: false
-PointerAlignment: Left
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
diff --git a/libs/vr/CPPLINT.cfg b/libs/vr/CPPLINT.cfg
deleted file mode 100644
index 87fb641..0000000
--- a/libs/vr/CPPLINT.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-set noparent
-filter=-build/include_order,-legal/copyright,-build/include,-build/c++11,+build/include_alpha
diff --git a/libs/vr/OWNERS b/libs/vr/OWNERS
deleted file mode 100644
index 098c80e..0000000
--- a/libs/vr/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-hendrikw@google.com
-jwcai@google.com
-steventhomas@google.com
-patplunkett@google.com
diff --git a/libs/vr/libbroadcastring/Android.bp b/libs/vr/libbroadcastring/Android.bp
deleted file mode 100644
index e72ca74..0000000
--- a/libs/vr/libbroadcastring/Android.bp
+++ /dev/null
@@ -1,43 +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: "libbroadcastring",
-
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- export_include_dirs: ["include"],
- shared_libs: [
- "libbase",
- ],
- export_shared_lib_headers: [
- "libbase",
- ],
-}
-
-cc_test {
- name: "broadcast_ring_tests",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- srcs: [
- "broadcast_ring_test.cc",
- ],
- static_libs: [
- "libbroadcastring",
- ],
- shared_libs: [
- "libbase",
- ],
-}
diff --git a/libs/vr/libbroadcastring/broadcast_ring_test.cc b/libs/vr/libbroadcastring/broadcast_ring_test.cc
deleted file mode 100644
index dfdd4ef..0000000
--- a/libs/vr/libbroadcastring/broadcast_ring_test.cc
+++ /dev/null
@@ -1,866 +0,0 @@
-#include "libbroadcastring/broadcast_ring.h"
-
-#include <stdlib.h>
-#include <memory>
-#include <thread> // NOLINT
-#include <sys/mman.h>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace dvr {
-namespace {
-
-template <uint32_t N>
-struct alignas(8) Aligned {
- char v[N];
-};
-
-template <uint32_t N>
-struct alignas(8) Sized {
- Sized() { Clear(); }
- explicit Sized(char c) { Fill(c); }
- char v[sizeof(Aligned<N>)];
- void Clear() { memset(v, 0, sizeof(v)); }
- void Fill(char c) { memset(v, c, sizeof(v)); }
- static Sized Pattern(uint8_t c) {
- Sized sized;
- for (size_t i = 0; i < sizeof(v); ++i) {
- sized.v[i] = static_cast<char>(c + i);
- }
- return sized;
- }
- bool operator==(const Sized& right) const {
- static_assert(sizeof(*this) == sizeof(v), "Size mismatch");
- return !memcmp(v, right.v, sizeof(v));
- }
- template <typename SmallerSized>
- SmallerSized Truncate() const {
- SmallerSized val;
- static_assert(sizeof(val.v) <= sizeof(v), "Cannot truncate to larger size");
- memcpy(val.v, v, sizeof(val.v));
- return val;
- }
-};
-
-char FillChar(int val) { return static_cast<char>(val); }
-
-struct FakeMmap {
- explicit FakeMmap(size_t size) : size(size), data(new char[size]) {}
- size_t size;
- std::unique_ptr<char[]> data;
- void* mmap() { return static_cast<void*>(data.get()); }
-};
-
-template <typename Ring>
-FakeMmap CreateRing(Ring* ring, uint32_t count) {
- FakeMmap mmap(Ring::MemorySize(count));
- *ring = Ring::Create(mmap.mmap(), mmap.size, count);
- return mmap;
-}
-
-template <typename RecordType, bool StaticSize = false,
- uint32_t StaticCount = 0, uint32_t MaxReserved = 1,
- uint32_t MinAvailable = 0>
-struct Traits {
- using Record = RecordType;
- static constexpr bool kUseStaticRecordSize = StaticSize;
- static constexpr uint32_t kStaticRecordCount = StaticCount;
- static constexpr uint32_t kMaxReservedRecords = MaxReserved;
- static constexpr uint32_t kMinAvailableRecords = MinAvailable;
- static constexpr uint32_t kMinRecordCount = MaxReserved + MinAvailable;
-};
-
-template <typename Record, bool StaticSize = false, uint32_t MaxReserved = 1,
- uint32_t MinAvailable = 7>
-struct TraitsDynamic
- : public Traits<Record, StaticSize, 0, MaxReserved, MinAvailable> {
- using Ring = BroadcastRing<Record, TraitsDynamic>;
- static uint32_t MinCount() { return MaxReserved + MinAvailable; }
-};
-
-template <typename Record, uint32_t StaticCount = 1, bool StaticSize = true,
- uint32_t MaxReserved = 1, uint32_t MinAvailable = 0>
-struct TraitsStatic
- : public Traits<Record, true, StaticCount, MaxReserved, MinAvailable> {
- using Ring = BroadcastRing<Record, TraitsStatic>;
- static uint32_t MinCount() { return StaticCount; }
-};
-
-using Dynamic_8_NxM = TraitsDynamic<Sized<8>>;
-using Dynamic_16_NxM = TraitsDynamic<Sized<16>>;
-using Dynamic_32_NxM = TraitsDynamic<Sized<32>>;
-using Dynamic_32_32xM = TraitsDynamic<Sized<32>, true>;
-using Dynamic_16_NxM_1plus0 = TraitsDynamic<Sized<16>, false, 1, 0>;
-using Dynamic_16_NxM_1plus1 = TraitsDynamic<Sized<16>, false, 1, 1>;
-using Dynamic_16_NxM_5plus11 = TraitsDynamic<Sized<16>, false, 5, 11>;
-using Dynamic_256_NxM_1plus0 = TraitsDynamic<Sized<256>, false, 1, 0>;
-
-using Static_8_8x1 = TraitsStatic<Sized<8>, 1>;
-using Static_8_8x16 = TraitsStatic<Sized<8>, 16>;
-using Static_16_16x8 = TraitsStatic<Sized<16>, 8>;
-using Static_16_16x16 = TraitsStatic<Sized<16>, 16>;
-using Static_16_16x32 = TraitsStatic<Sized<16>, 32>;
-using Static_32_Nx8 = TraitsStatic<Sized<32>, 8, false>;
-
-using TraitsList = ::testing::Types<Dynamic_8_NxM, //
- Dynamic_16_NxM, //
- Dynamic_32_NxM, //
- Dynamic_32_32xM, //
- Dynamic_16_NxM_1plus0, //
- Dynamic_16_NxM_1plus1, //
- Dynamic_16_NxM_5plus11, //
- Dynamic_256_NxM_1plus0, //
- Static_8_8x1, //
- Static_8_8x16, //
- Static_16_16x8, //
- Static_16_16x16, //
- Static_16_16x32, //
- Static_32_Nx8>;
-
-} // namespace
-
-template <typename T>
-class BroadcastRingTest : public ::testing::Test {};
-
-TYPED_TEST_CASE(BroadcastRingTest, TraitsList);
-
-TYPED_TEST(BroadcastRingTest, Geometry) {
- using Record = typename TypeParam::Record;
- using Ring = typename TypeParam::Ring;
- Ring ring;
- auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
- EXPECT_EQ(Ring::Traits::MinCount(), ring.record_count());
- EXPECT_EQ(sizeof(Record), ring.record_size());
-}
-
-TYPED_TEST(BroadcastRingTest, PutGet) {
- using Record = typename TypeParam::Record;
- using Ring = typename TypeParam::Ring;
- Ring ring;
- auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
- const uint32_t oldest_sequence_at_start = ring.GetOldestSequence();
- const uint32_t next_sequence_at_start = ring.GetNextSequence();
- {
- uint32_t sequence = oldest_sequence_at_start;
- Record record;
- EXPECT_FALSE(ring.Get(&sequence, &record));
- EXPECT_EQ(oldest_sequence_at_start, sequence);
- EXPECT_EQ(Record(), record);
- }
- const Record original_record(0x1a);
- ring.Put(original_record);
- {
- uint32_t sequence = next_sequence_at_start;
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(next_sequence_at_start, sequence);
- EXPECT_EQ(original_record, record);
- }
- {
- uint32_t sequence = next_sequence_at_start + 1;
- Record record;
- EXPECT_FALSE(ring.Get(&sequence, &record));
- EXPECT_EQ(next_sequence_at_start + 1, sequence);
- EXPECT_EQ(Record(), record);
- }
-}
-
-TYPED_TEST(BroadcastRingTest, FillOnce) {
- using Record = typename TypeParam::Record;
- using Ring = typename TypeParam::Ring;
- Ring ring;
- auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
- const uint32_t next_sequence_at_start = ring.GetNextSequence();
- for (uint32_t i = 0; i < ring.record_count(); ++i)
- ring.Put(Record(FillChar(i)));
- for (uint32_t i = 0; i < ring.record_count(); ++i) {
- const uint32_t expected_sequence = next_sequence_at_start + i;
- const Record expected_record(FillChar(i));
- {
- uint32_t sequence = ring.GetOldestSequence() + i;
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(expected_sequence, sequence);
- EXPECT_EQ(expected_record, record);
- }
- }
- {
- uint32_t sequence = ring.GetOldestSequence() + ring.record_count();
- Record record;
- EXPECT_FALSE(ring.Get(&sequence, &record));
- }
-}
-
-TYPED_TEST(BroadcastRingTest, FillTwice) {
- using Record = typename TypeParam::Record;
- using Ring = typename TypeParam::Ring;
- Ring ring;
- auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
- const uint32_t next_sequence_at_start = ring.GetNextSequence();
- for (uint32_t i = 0; i < 2 * ring.record_count(); ++i) {
- const Record newest_record(FillChar(i));
- ring.Put(newest_record);
-
- const uint32_t newest_sequence = next_sequence_at_start + i;
- const uint32_t records_available = std::min(i + 1, ring.record_count());
- const uint32_t oldest_sequence = newest_sequence - records_available + 1;
- EXPECT_EQ(newest_sequence, ring.GetNewestSequence());
- EXPECT_EQ(oldest_sequence, ring.GetOldestSequence());
- EXPECT_EQ(newest_sequence + 1, ring.GetNextSequence());
-
- for (uint32_t j = 0; j < records_available; ++j) {
- const uint32_t sequence_jth_newest = newest_sequence - j;
- const Record record_jth_newest(FillChar(i - j));
-
- {
- uint32_t sequence = sequence_jth_newest;
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(sequence_jth_newest, sequence);
- EXPECT_EQ(record_jth_newest, record);
- }
-
- {
- uint32_t sequence = sequence_jth_newest;
- Record record;
- EXPECT_TRUE(ring.GetNewest(&sequence, &record));
- EXPECT_EQ(newest_sequence, sequence);
- EXPECT_EQ(newest_record, record);
- }
- }
-
- const Record oldest_record(
- FillChar(i + (oldest_sequence - newest_sequence)));
- const uint32_t sequence_0th_overwritten = oldest_sequence - 1;
- const uint32_t sequence_0th_future = newest_sequence + 1;
- const uint32_t sequence_1st_future = newest_sequence + 2;
-
- {
- uint32_t sequence = sequence_0th_overwritten;
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(oldest_sequence, sequence);
- EXPECT_EQ(oldest_record, record);
- }
-
- {
- uint32_t sequence = sequence_0th_overwritten;
- Record record;
- EXPECT_TRUE(ring.GetNewest(&sequence, &record));
- EXPECT_EQ(newest_sequence, sequence);
- EXPECT_EQ(newest_record, record);
- }
-
- {
- uint32_t sequence = sequence_0th_future;
- Record record;
- EXPECT_FALSE(ring.Get(&sequence, &record));
- EXPECT_EQ(sequence_0th_future, sequence);
- EXPECT_EQ(Record(), record);
- }
-
- {
- uint32_t sequence = sequence_0th_future;
- Record record;
- EXPECT_FALSE(ring.GetNewest(&sequence, &record));
- EXPECT_EQ(sequence_0th_future, sequence);
- EXPECT_EQ(Record(), record);
- }
-
- {
- uint32_t sequence = sequence_1st_future;
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(oldest_sequence, sequence);
- EXPECT_EQ(oldest_record, record);
- }
-
- {
- uint32_t sequence = sequence_1st_future;
- Record record;
- EXPECT_TRUE(ring.GetNewest(&sequence, &record));
- EXPECT_EQ(newest_sequence, sequence);
- EXPECT_EQ(newest_record, record);
- }
- }
-}
-
-TYPED_TEST(BroadcastRingTest, Import) {
- using Record = typename TypeParam::Record;
- using Ring = typename TypeParam::Ring;
- Ring ring;
- auto mmap = CreateRing(&ring, Ring::Traits::MinCount());
-
- const uint32_t sequence_0 = ring.GetNextSequence();
- const uint32_t sequence_1 = ring.GetNextSequence() + 1;
- const Record record_0 = Record::Pattern(0x00);
- const Record record_1 = Record::Pattern(0x80);
- ring.Put(record_0);
- ring.Put(record_1);
-
- {
- Ring imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) = Ring::Import(mmap.mmap(), mmap.size);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(ring.record_count(), imported_ring.record_count());
-
- if (ring.record_count() != 1) {
- uint32_t sequence = sequence_0;
- Record imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(sequence_0, sequence);
- EXPECT_EQ(record_0, imported_record);
- }
-
- {
- uint32_t sequence = sequence_1;
- Record imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(sequence_1, sequence);
- EXPECT_EQ(record_1, imported_record);
- }
- }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfStaticSizeMismatch) {
- using OriginalRing = typename Static_16_16x16::Ring;
- using RecordSizeMismatchRing = typename Static_8_8x16::Ring;
- using RecordCountMismatchRing = typename Static_16_16x8::Ring;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
- {
- using ImportedRing = RecordSizeMismatchRing;
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_FALSE(import_ok);
- auto mmap_imported =
- CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
- EXPECT_NE(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
- }
-
- {
- using ImportedRing = RecordCountMismatchRing;
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_FALSE(import_ok);
- auto mmap_imported =
- CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_NE(original_ring.record_count(), imported_ring.record_count());
- }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfDynamicSizeGrows) {
- using OriginalRing = typename Dynamic_8_NxM::Ring;
- using RecordSizeGrowsRing = typename Dynamic_16_NxM::Ring;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
- {
- using ImportedRing = RecordSizeGrowsRing;
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_FALSE(import_ok);
- auto mmap_imported =
- CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
- EXPECT_LT(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
- }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfCountTooSmall) {
- using OriginalRing = typename Dynamic_16_NxM_1plus0::Ring;
- using MinCountRing = typename Dynamic_16_NxM_1plus1::Ring;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
- {
- using ImportedRing = MinCountRing;
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_FALSE(import_ok);
- auto mmap_imported =
- CreateRing(&imported_ring, ImportedRing::Traits::MinCount());
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_LT(original_ring.record_count(), imported_ring.record_count());
- }
-}
-
-TEST(BroadcastRingTest, ShouldFailImportIfMmapTooSmall) {
- using OriginalRing = typename Dynamic_16_NxM::Ring;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
- {
- using ImportedRing = OriginalRing;
- ImportedRing imported_ring;
- bool import_ok;
- const size_t kMinSize =
- ImportedRing::MemorySize(original_ring.record_count());
- std::tie(imported_ring, import_ok) = ImportedRing::Import(mmap.mmap(), 0);
- EXPECT_FALSE(import_ok);
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), kMinSize - 1);
- EXPECT_FALSE(import_ok);
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), kMinSize);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
- }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfDynamicSizeShrinks) {
- using OriginalRing = typename Dynamic_16_NxM::Ring;
- using RecordSizeShrinksRing = typename Dynamic_8_NxM::Ring;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, OriginalRing::Traits::MinCount());
-
- using OriginalRecord = typename OriginalRing::Record;
- const uint32_t original_sequence_0 = original_ring.GetNextSequence();
- const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
- const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
- const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
- original_ring.Put(original_record_0);
- original_ring.Put(original_record_1);
-
- {
- using ImportedRing = RecordSizeShrinksRing;
- using ImportedRecord = typename ImportedRing::Record;
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
- EXPECT_GT(sizeof(OriginalRecord), sizeof(ImportedRecord));
-
- {
- uint32_t sequence = original_sequence_0;
- ImportedRecord shrunk_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record));
- EXPECT_EQ(original_sequence_0, sequence);
- EXPECT_EQ(original_record_0.Truncate<ImportedRecord>(), shrunk_record);
- }
-
- {
- uint32_t sequence = original_sequence_1;
- ImportedRecord shrunk_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &shrunk_record));
- EXPECT_EQ(original_sequence_1, sequence);
- EXPECT_EQ(original_record_1.Truncate<ImportedRecord>(), shrunk_record);
- }
- }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfCompatibleDynamicToStatic) {
- using OriginalRing = typename Dynamic_16_NxM::Ring;
- using ImportedRing = typename Static_16_16x16::Ring;
- using OriginalRecord = typename OriginalRing::Record;
- using ImportedRecord = typename ImportedRing::Record;
- using StaticRing = ImportedRing;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount());
-
- const uint32_t original_sequence_0 = original_ring.GetNextSequence();
- const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
- const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
- const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
- original_ring.Put(original_record_0);
- original_ring.Put(original_record_1);
-
- {
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-
- {
- uint32_t sequence = original_sequence_0;
- ImportedRecord imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(original_sequence_0, sequence);
- EXPECT_EQ(original_record_0, imported_record);
- }
-
- {
- uint32_t sequence = original_sequence_1;
- ImportedRecord imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(original_sequence_1, sequence);
- EXPECT_EQ(original_record_1, imported_record);
- }
- }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfCompatibleStaticToDynamic) {
- using OriginalRing = typename Static_16_16x16::Ring;
- using ImportedRing = typename Dynamic_16_NxM::Ring;
- using OriginalRecord = typename OriginalRing::Record;
- using ImportedRecord = typename ImportedRing::Record;
- using StaticRing = OriginalRing;
-
- OriginalRing original_ring;
- auto mmap = CreateRing(&original_ring, StaticRing::Traits::MinCount());
-
- const uint32_t original_sequence_0 = original_ring.GetNextSequence();
- const uint32_t original_sequence_1 = original_ring.GetNextSequence() + 1;
- const OriginalRecord original_record_0 = OriginalRecord::Pattern(0x00);
- const OriginalRecord original_record_1 = OriginalRecord::Pattern(0x80);
- original_ring.Put(original_record_0);
- original_ring.Put(original_record_1);
-
- {
- ImportedRing imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) =
- ImportedRing::Import(mmap.mmap(), mmap.size);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(original_ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(original_ring.record_count(), imported_ring.record_count());
-
- {
- uint32_t sequence = original_sequence_0;
- ImportedRecord imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(original_sequence_0, sequence);
- EXPECT_EQ(original_record_0, imported_record);
- }
-
- {
- uint32_t sequence = original_sequence_1;
- ImportedRecord imported_record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &imported_record));
- EXPECT_EQ(original_sequence_1, sequence);
- EXPECT_EQ(original_record_1, imported_record);
- }
- }
-}
-
-TEST(BroadcastRingTest, ShouldImportIfReadonlyMmap) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
-
- uint32_t record_count = Ring::Traits::MinCount();
- size_t ring_size = Ring::MemorySize(record_count);
-
- size_t page_size = sysconf(_SC_PAGESIZE);
- size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
- ASSERT_GE(mmap_size, ring_size);
-
- void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- ASSERT_NE(MAP_FAILED, mmap_base);
-
- Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
- for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i)));
-
- ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ));
-
- {
- Ring imported_ring;
- bool import_ok;
- std::tie(imported_ring, import_ok) = Ring::Import(mmap_base, mmap_size);
- EXPECT_TRUE(import_ok);
- EXPECT_EQ(ring.record_size(), imported_ring.record_size());
- EXPECT_EQ(ring.record_count(), imported_ring.record_count());
-
- uint32_t oldest_sequence = imported_ring.GetOldestSequence();
- for (uint32_t i = 0; i < record_count; ++i) {
- uint32_t sequence = oldest_sequence + i;
- Record record;
- EXPECT_TRUE(imported_ring.Get(&sequence, &record));
- EXPECT_EQ(Record(FillChar(i)), record);
- }
- }
-
- ASSERT_EQ(0, munmap(mmap_base, mmap_size));
-}
-
-TEST(BroadcastRingTest, ShouldDieIfPutReadonlyMmap) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
-
- uint32_t record_count = Ring::Traits::MinCount();
- size_t ring_size = Ring::MemorySize(record_count);
-
- size_t page_size = sysconf(_SC_PAGESIZE);
- size_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
- ASSERT_GE(mmap_size, ring_size);
-
- void* mmap_base = mmap(nullptr, mmap_size, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
- ASSERT_NE(MAP_FAILED, mmap_base);
-
- Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
- for (uint32_t i = 0; i < record_count; ++i) ring.Put(Record(FillChar(i)));
-
- ASSERT_EQ(0, mprotect(mmap_base, mmap_size, PROT_READ));
-
- EXPECT_DEATH_IF_SUPPORTED({ ring.Put(Record(7)); }, "");
-
- ASSERT_EQ(0, munmap(mmap_base, mmap_size));
-}
-
-TEST(BroadcastRingTest, ShouldDieIfCreationMmapTooSmall) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
-
- uint32_t record_count = Ring::Traits::MinCount();
- size_t ring_size = Ring::MemorySize(record_count);
- FakeMmap mmap(ring_size);
-
- EXPECT_DEATH_IF_SUPPORTED({
- Ring ring = Ring::Create(mmap.mmap(), ring_size - 1, record_count);
- }, "");
-
- Ring ring = Ring::Create(mmap.mmap(), ring_size, record_count);
-
- ring.Put(Record(3));
-
- {
- uint32_t sequence = ring.GetNewestSequence();
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(Record(3), record);
- }
-}
-
-TEST(BroadcastRingTest, ShouldDieIfCreationMmapMisaligned) {
- using Ring = Static_8_8x1::Ring;
- using Record = Ring::Record;
-
- constexpr int kAlign = Ring::mmap_alignment();
- constexpr int kMisalign = kAlign / 2;
- size_t ring_size = Ring::MemorySize();
- std::unique_ptr<char[]> buf(new char[ring_size + kMisalign]);
-
- EXPECT_DEATH_IF_SUPPORTED(
- { Ring ring = Ring::Create(buf.get() + kMisalign, ring_size); }, "");
-
- Ring ring = Ring::Create(buf.get(), ring_size);
-
- ring.Put(Record(3));
-
- {
- uint32_t sequence = ring.GetNewestSequence();
- Record record;
- EXPECT_TRUE(ring.Get(&sequence, &record));
- EXPECT_EQ(Record(3), record);
- }
-}
-
-template <typename Ring>
-std::unique_ptr<std::thread> CopyTask(std::atomic<bool>* quit, void* in_base,
- size_t in_size, void* out_base,
- size_t out_size) {
- return std::unique_ptr<std::thread>(
- new std::thread([quit, in_base, in_size, out_base, out_size]() {
- using Record = typename Ring::Record;
-
- bool import_ok;
- Ring in_ring;
- Ring out_ring;
- std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size);
- ASSERT_TRUE(import_ok);
- std::tie(out_ring, import_ok) = Ring::Import(out_base, out_size);
- ASSERT_TRUE(import_ok);
-
- uint32_t sequence = in_ring.GetOldestSequence();
- while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) {
- Record record;
- if (in_ring.Get(&sequence, &record)) {
- out_ring.Put(record);
- sequence++;
- }
- }
- }));
-}
-
-TEST(BroadcastRingTest, ThreadedCopySingle) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
- Ring in_ring;
- auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
- Ring out_ring;
- auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
- std::atomic<bool> quit(false);
- std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
- &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
- const Record out_record(0x1c);
- out_ring.Put(out_record);
-
- uint32_t in_sequence = in_ring.GetOldestSequence();
- Record in_record;
- while (!in_ring.Get(&in_sequence, &in_record)) {
- // Do nothing.
- }
-
- EXPECT_EQ(out_record, in_record);
- std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
- copy_task->join();
-}
-
-TEST(BroadcastRingTest, ThreadedCopyLossless) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
- Ring in_ring;
- auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
- Ring out_ring;
- auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
- std::atomic<bool> quit(false);
- std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
- &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
- constexpr uint32_t kRecordsToProcess = 10000;
- uint32_t out_records = 0;
- uint32_t in_records = 0;
- uint32_t in_sequence = in_ring.GetNextSequence();
- while (out_records < kRecordsToProcess || in_records < kRecordsToProcess) {
- if (out_records < kRecordsToProcess &&
- out_records - in_records < out_ring.record_count()) {
- const Record out_record(FillChar(out_records));
- out_ring.Put(out_record);
- out_records++;
- }
-
- Record in_record;
- while (in_ring.Get(&in_sequence, &in_record)) {
- EXPECT_EQ(Record(FillChar(in_records)), in_record);
- in_records++;
- in_sequence++;
- }
- }
-
- EXPECT_EQ(kRecordsToProcess, out_records);
- EXPECT_EQ(kRecordsToProcess, in_records);
-
- std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
- copy_task->join();
-}
-
-TEST(BroadcastRingTest, ThreadedCopyLossy) {
- using Ring = Dynamic_32_NxM::Ring;
- using Record = Ring::Record;
- Ring in_ring;
- auto in_mmap = CreateRing(&in_ring, Ring::Traits::MinCount());
-
- Ring out_ring;
- auto out_mmap = CreateRing(&out_ring, Ring::Traits::MinCount());
-
- std::atomic<bool> quit(false);
- std::unique_ptr<std::thread> copy_task = CopyTask<Ring>(
- &quit, out_mmap.mmap(), out_mmap.size, in_mmap.mmap(), in_mmap.size);
-
- constexpr uint32_t kRecordsToProcess = 100000;
- uint32_t out_records = 0;
- uint32_t in_records = 0;
- uint32_t in_sequence = in_ring.GetNextSequence();
- while (out_records < kRecordsToProcess) {
- const Record out_record(FillChar(out_records));
- out_ring.Put(out_record);
- out_records++;
-
- Record in_record;
- if (in_ring.GetNewest(&in_sequence, &in_record)) {
- EXPECT_EQ(Record(in_record.v[0]), in_record);
- in_records++;
- in_sequence++;
- }
- }
-
- EXPECT_EQ(kRecordsToProcess, out_records);
- EXPECT_GE(kRecordsToProcess, in_records);
-
- std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
- copy_task->join();
-}
-
-template <typename Ring>
-std::unique_ptr<std::thread> CheckFillTask(std::atomic<bool>* quit,
- void* in_base, size_t in_size) {
- return std::unique_ptr<std::thread>(
- new std::thread([quit, in_base, in_size]() {
- using Record = typename Ring::Record;
-
- bool import_ok;
- Ring in_ring;
- std::tie(in_ring, import_ok) = Ring::Import(in_base, in_size);
- ASSERT_TRUE(import_ok);
-
- uint32_t sequence = in_ring.GetOldestSequence();
- while (!std::atomic_load_explicit(quit, std::memory_order_relaxed)) {
- Record record;
- if (in_ring.Get(&sequence, &record)) {
- ASSERT_EQ(Record(record.v[0]), record);
- sequence++;
- }
- }
- }));
-}
-
-template <typename Ring>
-void ThreadedOverwriteTorture() {
- using Record = typename Ring::Record;
-
- // Maximize overwrites by having few records.
- const int kMinRecordCount = 1;
- const int kMaxRecordCount = 4;
-
- for (int count = kMinRecordCount; count <= kMaxRecordCount; count *= 2) {
- Ring out_ring;
- auto out_mmap = CreateRing(&out_ring, count);
-
- std::atomic<bool> quit(false);
- std::unique_ptr<std::thread> check_task =
- CheckFillTask<Ring>(&quit, out_mmap.mmap(), out_mmap.size);
-
- constexpr int kIterations = 10000;
- for (int i = 0; i < kIterations; ++i) {
- const Record record(FillChar(i));
- out_ring.Put(record);
- }
-
- std::atomic_store_explicit(&quit, true, std::memory_order_relaxed);
- check_task->join();
- }
-}
-
-TEST(BroadcastRingTest, ThreadedOverwriteTortureSmall) {
- ThreadedOverwriteTorture<Dynamic_16_NxM_1plus0::Ring>();
-}
-
-TEST(BroadcastRingTest, ThreadedOverwriteTortureLarge) {
- ThreadedOverwriteTorture<Dynamic_256_NxM_1plus0::Ring>();
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h b/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
deleted file mode 100644
index f2e5034..0000000
--- a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
+++ /dev/null
@@ -1,692 +0,0 @@
-#ifndef ANDROID_DVR_BROADCAST_RING_H_
-#define ANDROID_DVR_BROADCAST_RING_H_
-
-#include <inttypes.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <atomic>
-#include <limits>
-#include <tuple>
-#include <type_traits>
-#include <utility>
-
-#include "android-base/logging.h"
-
-#if ATOMIC_LONG_LOCK_FREE != 2 || ATOMIC_INT_LOCK_FREE != 2
-#error "This file requires lock free atomic uint32_t and long"
-#endif
-
-namespace android {
-namespace dvr {
-
-struct DefaultRingTraits {
- // Set this to false to allow compatibly expanding the record size.
- static constexpr bool kUseStaticRecordSize = false;
-
- // Set this to a nonzero value to fix the number of records in the ring.
- static constexpr uint32_t kStaticRecordCount = 0;
-
- // Set this to the max number of records that can be written simultaneously.
- static constexpr uint32_t kMaxReservedRecords = 1;
-
- // Set this to the min number of records that must be readable.
- static constexpr uint32_t kMinAvailableRecords = 1;
-};
-
-// Nonblocking ring suitable for concurrent single-writer, multi-reader access.
-//
-// Readers never block the writer and thus this is a nondeterministically lossy
-// transport in the absence of external synchronization. Don't use this as a
-// transport when deterministic behavior is required.
-//
-// Readers may have a read-only mapping; each reader's state is a single local
-// sequence number.
-//
-// The implementation takes care to avoid data races on record access.
-// Inconsistent data can only be returned if at least 2^32 records are written
-// during the read-side critical section.
-//
-// In addition, both readers and the writer are careful to avoid accesses
-// outside the bounds of the mmap area passed in during initialization even if
-// there is a misbehaving or malicious task with write access to the mmap area.
-//
-// When dynamic record size is enabled, readers use the record size in the ring
-// header when indexing the ring, so that it is possible to extend the record
-// type without breaking the read-side ABI.
-//
-// Avoid calling Put() in a tight loop; there should be significantly more time
-// between successive puts than it takes to read one record from memory to
-// ensure Get() completes quickly. This requirement should not be difficult to
-// achieve for most practical uses; 4kB puts at 10,000Hz is well below the
-// scaling limit on current mobile chips.
-//
-// Example Writer Usage:
-//
-// using Record = MyRecordType;
-// using Ring = BroadcastRing<Record>;
-//
-// uint32_t record_count = kMyDesiredCount;
-// uint32_t ring_size = Ring::MemorySize(record_count);
-//
-// size_t page_size = sysconf(_SC_PAGESIZE);
-// uint32_t mmap_size = (ring_size + (page_size - 1)) & ~(page_size - 1);
-//
-// // Allocate & map via your preferred mechanism, e.g.
-// int fd = open("/dev/shm/ring_test", O_CREAT|O_RDWR|O_CLOEXEC, 0600);
-// CHECK(fd >= 0);
-// CHECK(!ftruncate(fd, ring_size));
-// void *mmap_base = mmap(nullptr, mmap_size, PROT_READ|PROT_WRITE,
-// MAP_SHARED, fd, 0);
-// CHECK(mmap_base != MAP_FAILED);
-// close(fd);
-//
-// Ring ring = Ring::Create(mmap_base, mmap_size, record_count);
-//
-// while (!done)
-// ring.Put(BuildNextRecordBlocking());
-//
-// CHECK(!munmap(mmap_base, mmap_size));
-//
-// Example Reader Usage:
-//
-// using Record = MyRecordType;
-// using Ring = BroadcastRing<Record>;
-//
-// // Map via your preferred mechanism, e.g.
-// int fd = open("/dev/shm/ring_test", O_RDONLY|O_CLOEXEC);
-// CHECK(fd >= 0);
-// struct stat st;
-// CHECK(!fstat(fd, &st));
-// size_t mmap_size = st.st_size;
-// void *mmap_base = mmap(nullptr, mmap_size, PROT_READ,
-// MAP_SHARED, fd, 0);
-// CHECK(mmap_base != MAP_FAILED);
-// close(fd);
-//
-// Ring ring;
-// bool import_ok;
-// std::tie(ring, import_ok) = Ring::Import(mmap_base, mmap_size);
-// CHECK(import_ok);
-//
-// uint32_t sequence;
-//
-// // Choose starting point (using "0" is unpredictable but not dangerous)
-// sequence = ring.GetOldestSequence(); // The oldest available
-// sequence = ring.GetNewestSequence(); // The newest available
-// sequence = ring.GetNextSequence(); // The next one produced
-//
-// while (!done) {
-// Record record;
-//
-// if (you_want_to_process_all_available_records) {
-// while (ring.Get(&sequence, &record)) {
-// ProcessRecord(sequence, record);
-// sequence++;
-// }
-// } else if (you_want_to_skip_to_the_newest_record) {
-// if (ring.GetNewest(&sequence, &record)) {
-// ProcessRecord(sequence, record);
-// sequence++;
-// }
-// }
-//
-// DoSomethingExpensiveOrBlocking();
-// }
-//
-// CHECK(!munmap(mmap_base, mmap_size));
-//
-template <typename RecordType, typename BaseTraits = DefaultRingTraits>
-class BroadcastRing {
- public:
- using Record = RecordType;
- struct Traits : public BaseTraits {
- // Must have enough space for writers, plus enough space for readers.
- static constexpr int kMinRecordCount =
- BaseTraits::kMaxReservedRecords + BaseTraits::kMinAvailableRecords;
-
- // Count of zero means dynamic, non-zero means static.
- static constexpr bool kUseStaticRecordCount =
- (BaseTraits::kStaticRecordCount != 0);
-
- // If both record size and count are static then the overall size is too.
- static constexpr bool kIsStaticSize =
- BaseTraits::kUseStaticRecordSize && kUseStaticRecordCount;
- };
-
- static constexpr bool IsPowerOfTwo(uint32_t size) {
- return (size & (size - 1)) == 0;
- }
-
- // Sanity check the options provided in Traits.
- static_assert(Traits::kMinRecordCount >= 1, "Min record count too small");
- static_assert(!Traits::kUseStaticRecordCount ||
- Traits::kStaticRecordCount >= Traits::kMinRecordCount,
- "Static record count is too small");
- static_assert(!Traits::kStaticRecordCount ||
- IsPowerOfTwo(Traits::kStaticRecordCount),
- "Static record count is not a power of two");
- static_assert(std::is_standard_layout<Record>::value,
- "Record type must be standard layout");
-
- BroadcastRing() {}
-
- // Creates a new ring at |mmap| with |record_count| records.
- //
- // There must be at least |MemorySize(record_count)| bytes of space already
- // allocated at |mmap|. The ring does not take ownership.
- static BroadcastRing Create(void* mmap, size_t mmap_size,
- uint32_t record_count) {
- BroadcastRing ring(mmap);
- CHECK(ring.ValidateGeometry(mmap_size, sizeof(Record), record_count));
- ring.InitializeHeader(sizeof(Record), record_count);
- return ring;
- }
-
- // Creates a new ring at |mmap|.
- //
- // There must be at least |MemorySize()| bytes of space already allocated at
- // |mmap|. The ring does not take ownership.
- static BroadcastRing Create(void* mmap, size_t mmap_size) {
- return Create(mmap, mmap_size,
- Traits::kUseStaticRecordCount
- ? Traits::kStaticRecordCount
- : BroadcastRing::GetRecordCount(mmap_size));
- }
-
- // Imports an existing ring at |mmap|.
- //
- // Import may fail if the ring parameters in the mmap header are not sensible.
- // In this case the returned boolean is false; make sure to check this value.
- static std::tuple<BroadcastRing, bool> Import(void* mmap, size_t mmap_size) {
- BroadcastRing ring(mmap);
- uint32_t record_size = 0;
- uint32_t record_count = 0;
- if (mmap_size >= sizeof(Header)) {
- record_size = std::atomic_load_explicit(&ring.header_mmap()->record_size,
- std::memory_order_relaxed);
- record_count = std::atomic_load_explicit(
- &ring.header_mmap()->record_count, std::memory_order_relaxed);
- }
- bool ok = ring.ValidateGeometry(mmap_size, record_size, record_count);
- return std::make_tuple(ring, ok);
- }
-
- ~BroadcastRing() {}
-
- // Calculates the space necessary for a ring of size |record_count|.
- //
- // Use this function for dynamically sized rings.
- static constexpr size_t MemorySize(uint32_t record_count) {
- return sizeof(Header) + sizeof(Record) * record_count;
- }
-
- // Calculates the space necessary for a statically sized ring.
- //
- // Use this function for statically sized rings.
- static constexpr size_t MemorySize() {
- static_assert(
- Traits::kUseStaticRecordCount,
- "Wrong MemorySize() function called for dynamic record count");
- return MemorySize(Traits::kStaticRecordCount);
- }
-
- static uint32_t NextPowerOf2(uint32_t n) {
- if (n == 0)
- return 0;
- n -= 1;
- n |= n >> 16;
- n |= n >> 8;
- n |= n >> 4;
- n |= n >> 2;
- n |= n >> 1;
- return n + 1;
- }
-
- // Gets the biggest power of 2 record count that can fit into this mmap.
- //
- // The header size has been taken into account.
- static uint32_t GetRecordCount(size_t mmap_size) {
- if (mmap_size <= sizeof(Header)) {
- return 0;
- }
- uint32_t count =
- static_cast<uint32_t>((mmap_size - sizeof(Header)) / sizeof(Record));
- return IsPowerOfTwo(count) ? count : (NextPowerOf2(count) / 2);
- }
-
- // Writes a record to the ring.
- //
- // The oldest record is overwritten unless the ring is not already full.
- void Put(const Record& record) {
- const int kRecordCount = 1;
- Reserve(kRecordCount);
- Geometry geometry = GetGeometry();
- PutRecordInternal(&record, record_mmap_writer(geometry.tail_index));
- Publish(kRecordCount);
- }
-
- // Gets sequence number of the oldest currently available record.
- uint32_t GetOldestSequence() const {
- return std::atomic_load_explicit(&header_mmap()->head,
- std::memory_order_relaxed);
- }
-
- // Gets sequence number of the first future record.
- //
- // If the returned value is passed to Get() and there is no concurrent Put(),
- // Get() will return false.
- uint32_t GetNextSequence() const {
- return std::atomic_load_explicit(&header_mmap()->tail,
- std::memory_order_relaxed);
- }
-
- // Gets sequence number of the newest currently available record.
- uint32_t GetNewestSequence() const { return GetNextSequence() - 1; }
-
- // Copies the oldest available record with sequence at least |*sequence| to
- // |record|.
- //
- // Returns false if there is no recent enough record available.
- //
- // Updates |*sequence| with the sequence number of the record returned. To get
- // the following record, increment this number by one.
- //
- // This function synchronizes with two other operations:
- //
- // (1) Load-Acquire of |tail|
- //
- // Together with the store-release in Publish(), this load-acquire
- // ensures each store to a record in PutRecordInternal() happens-before
- // any corresponding load in GetRecordInternal().
- //
- // i.e. the stores for the records with sequence numbers < |tail| have
- // completed from our perspective
- //
- // (2) Acquire Fence between record access & final load of |head|
- //
- // Together with the release fence in Reserve(), this ensures that if
- // GetRecordInternal() loads a value stored in some execution of
- // PutRecordInternal(), then the store of |head| in the Reserve() that
- // preceeded it happens-before our final load of |head|.
- //
- // i.e. if we read a record with sequence number >= |final_head| then
- // no later store to that record has completed from our perspective
- bool Get(uint32_t* sequence /*inout*/, Record* record /*out*/) const {
- for (;;) {
- uint32_t tail = std::atomic_load_explicit(&header_mmap()->tail,
- std::memory_order_acquire);
- uint32_t head = std::atomic_load_explicit(&header_mmap()->head,
- std::memory_order_relaxed);
-
- if (tail - head > record_count())
- continue; // Concurrent modification; re-try.
-
- if (*sequence - head > tail - head)
- *sequence = head; // Out of window, skip forward to first available.
-
- if (*sequence == tail) return false; // No new records available.
-
- Geometry geometry =
- CalculateGeometry(record_count(), record_size(), *sequence, tail);
-
- // Compute address explicitly in case record_size > sizeof(Record).
- RecordStorage* record_storage = record_mmap_reader(geometry.head_index);
-
- GetRecordInternal(record_storage, record);
-
- // NB: It is not sufficient to change this to a load-acquire of |head|.
- std::atomic_thread_fence(std::memory_order_acquire);
-
- uint32_t final_head = std::atomic_load_explicit(
- &header_mmap()->head, std::memory_order_relaxed);
-
- if (final_head - head > *sequence - head)
- continue; // Concurrent modification; re-try.
-
- // Note: Combining the above 4 comparisons gives:
- // 0 <= final_head - head <= sequence - head < tail - head <= record_count
- //
- // We can also write this as:
- // head <=* final_head <=* sequence <* tail <=* head + record_count
- //
- // where <* orders by difference from head: x <* y if x - head < y - head.
- // This agrees with the order of sequence updates during "put" operations.
- return true;
- }
- }
-
- // Copies the newest available record with sequence at least |*sequence| to
- // |record|.
- //
- // Returns false if there is no recent enough record available.
- //
- // Updates |*sequence| with the sequence number of the record returned. To get
- // the following record, increment this number by one.
- bool GetNewest(uint32_t* sequence, Record* record) const {
- uint32_t newest_sequence = GetNewestSequence();
- if (*sequence == newest_sequence + 1) return false;
- *sequence = newest_sequence;
- return Get(sequence, record);
- }
-
- // Returns true if this instance has been created or imported.
- bool is_valid() const { return !!data_.mmap; }
-
- uint32_t record_count() const { return record_count_internal(); }
- uint32_t record_size() const { return record_size_internal(); }
- static constexpr uint32_t mmap_alignment() { return alignof(Mmap); }
-
- private:
- struct Header {
- // Record size for reading out of the ring. Writers always write the full
- // length; readers may need to read a prefix of each record.
- std::atomic<uint32_t> record_size;
-
- // Number of records in the ring.
- std::atomic<uint32_t> record_count;
-
- // Readable region is [head % record_count, tail % record_count).
- //
- // The region in [tail % record_count, head % record_count) was either never
- // populated or is being updated.
- //
- // These are sequences numbers, not indexes - indexes should be computed
- // with a modulus.
- //
- // To ensure consistency:
- //
- // (1) Writes advance |head| past any updated records before writing to
- // them, and advance |tail| after they are written.
- // (2) Readers check |tail| before reading data and |head| after,
- // making sure to discard any data that was written to concurrently.
- std::atomic<uint32_t> head;
- std::atomic<uint32_t> tail;
- };
-
- // Store using the standard word size.
- using StorageType = long; // NOLINT
-
- // Always require 8 byte alignment so that the same record sizes are legal on
- // 32 and 64 bit builds.
- static constexpr size_t kRecordAlignment = 8;
- static_assert(kRecordAlignment % sizeof(StorageType) == 0,
- "Bad record alignment");
-
- struct RecordStorage {
- // This is accessed with relaxed atomics to prevent data races on the
- // contained data, which would be undefined behavior.
- std::atomic<StorageType> data[sizeof(Record) / sizeof(StorageType)];
- };
-
- static_assert(sizeof(StorageType) *
- std::extent<decltype(RecordStorage::data)>() ==
- sizeof(Record),
- "Record length must be a multiple of sizeof(StorageType)");
-
- struct Geometry {
- // Static geometry.
- uint32_t record_count;
- uint32_t record_size;
-
- // Copy of atomic sequence counts.
- uint32_t head;
- uint32_t tail;
-
- // First index of readable region.
- uint32_t head_index;
-
- // First index of writable region.
- uint32_t tail_index;
-
- // Number of records in readable region.
- uint32_t count;
-
- // Number of records in writable region.
- uint32_t space;
- };
-
- // Mmap area layout.
- //
- // Readers should not index directly into |records| as this is not valid when
- // dynamic record sizes are used; use record_mmap_reader() instead.
- struct Mmap {
- Header header;
- RecordStorage records[];
- };
-
- static_assert(std::is_standard_layout<Mmap>::value,
- "Mmap must be standard layout");
- static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t),
- "Lockless atomics contain extra state");
- static_assert(sizeof(std::atomic<StorageType>) == sizeof(StorageType),
- "Lockless atomics contain extra state");
-
- explicit BroadcastRing(void* mmap) {
- CHECK_EQ(0U, reinterpret_cast<uintptr_t>(mmap) % alignof(Mmap));
- data_.mmap = reinterpret_cast<Mmap*>(mmap);
- }
-
- // Initializes the mmap area header for a new ring.
- void InitializeHeader(uint32_t record_size, uint32_t record_count) {
- constexpr uint32_t kInitialSequence = -256; // Force an early wrap.
- std::atomic_store_explicit(&header_mmap()->record_size, record_size,
- std::memory_order_relaxed);
- std::atomic_store_explicit(&header_mmap()->record_count, record_count,
- std::memory_order_relaxed);
- std::atomic_store_explicit(&header_mmap()->head, kInitialSequence,
- std::memory_order_relaxed);
- std::atomic_store_explicit(&header_mmap()->tail, kInitialSequence,
- std::memory_order_relaxed);
- }
-
- // Validates ring geometry.
- //
- // Ring geometry is validated carefully on import and then cached. This allows
- // us to avoid out-of-range accesses even if the parameters in the header are
- // later changed.
- bool ValidateGeometry(size_t mmap_size, uint32_t header_record_size,
- uint32_t header_record_count) {
- set_record_size(header_record_size);
- set_record_count(header_record_count);
-
- if (record_size() != header_record_size) return false;
- if (record_count() != header_record_count) return false;
- if (record_count() < Traits::kMinRecordCount) return false;
- if (record_size() < sizeof(Record)) return false;
- if (record_size() % kRecordAlignment != 0) return false;
- if (!IsPowerOfTwo(record_count())) return false;
-
- size_t memory_size = record_count() * record_size();
- if (memory_size / record_size() != record_count()) return false;
- if (memory_size + sizeof(Header) < memory_size) return false;
- if (memory_size + sizeof(Header) > mmap_size) return false;
-
- return true;
- }
-
- // Copies a record into the ring.
- //
- // This is done with relaxed atomics because otherwise it is racy according to
- // the C++ memory model. This is very low overhead once optimized.
- static inline void PutRecordInternal(const Record* in, RecordStorage* out) {
- StorageType data[sizeof(Record) / sizeof(StorageType)];
- memcpy(data, in, sizeof(*in));
- for (size_t i = 0; i < std::extent<decltype(data)>(); ++i) {
- std::atomic_store_explicit(&out->data[i], data[i],
- std::memory_order_relaxed);
- }
- }
-
- // Copies a record out of the ring.
- //
- // This is done with relaxed atomics because otherwise it is racy according to
- // the C++ memory model. This is very low overhead once optimized.
- static inline void GetRecordInternal(RecordStorage* in, Record* out) {
- StorageType data[sizeof(Record) / sizeof(StorageType)];
- for (size_t i = 0; i < std::extent<decltype(data)>(); ++i) {
- data[i] =
- std::atomic_load_explicit(&in->data[i], std::memory_order_relaxed);
- }
- memcpy(out, &data, sizeof(*out));
- }
-
- // Converts a record's sequence number into a storage index.
- static uint32_t SequenceToIndex(uint32_t sequence, uint32_t record_count) {
- return sequence & (record_count - 1);
- }
-
- // Computes readable & writable ranges from ring parameters.
- static Geometry CalculateGeometry(uint32_t record_count, uint32_t record_size,
- uint32_t head, uint32_t tail) {
- Geometry geometry;
- geometry.record_count = record_count;
- geometry.record_size = record_size;
- DCHECK_EQ(0U, geometry.record_size % kRecordAlignment);
- geometry.head = head;
- geometry.tail = tail;
- geometry.head_index = SequenceToIndex(head, record_count);
- geometry.tail_index = SequenceToIndex(tail, record_count);
- geometry.count = geometry.tail - geometry.head;
- DCHECK_LE(geometry.count, record_count);
- geometry.space = geometry.record_count - geometry.count;
- return geometry;
- }
-
- // Gets the current ring readable & writable regions.
- //
- // This this is always safe from the writing thread since it is the only
- // thread allowed to update the header.
- Geometry GetGeometry() const {
- return CalculateGeometry(
- record_count(), record_size(),
- std::atomic_load_explicit(&header_mmap()->head,
- std::memory_order_relaxed),
- std::atomic_load_explicit(&header_mmap()->tail,
- std::memory_order_relaxed));
- }
-
- // Makes space for at least |reserve_count| records.
- //
- // There is nothing to prevent overwriting records that have concurrent
- // readers. We do however ensure that this situation can be detected: the
- // fence ensures the |head| update will be the first update seen by readers,
- // and readers check this value after reading and discard data that may have
- // been concurrently modified.
- void Reserve(uint32_t reserve_count) {
- Geometry geometry = GetGeometry();
- DCHECK_LE(reserve_count, Traits::kMaxReservedRecords);
- uint32_t needed =
- (geometry.space >= reserve_count ? 0 : reserve_count - geometry.space);
-
- std::atomic_store_explicit(&header_mmap()->head, geometry.head + needed,
- std::memory_order_relaxed);
-
- // NB: It is not sufficient to change this to a store-release of |head|.
- std::atomic_thread_fence(std::memory_order_release);
- }
-
- // Makes |publish_count| records visible to readers.
- //
- // Space must have been reserved by a previous call to Reserve().
- void Publish(uint32_t publish_count) {
- Geometry geometry = GetGeometry();
- DCHECK_LE(publish_count, geometry.space);
- std::atomic_store_explicit(&header_mmap()->tail,
- geometry.tail + publish_count,
- std::memory_order_release);
- }
-
- // Helpers to compute addresses in mmap area.
- Mmap* mmap() const { return data_.mmap; }
- Header* header_mmap() const { return &data_.mmap->header; }
- RecordStorage* record_mmap_writer(uint32_t index) const {
- DCHECK_EQ(sizeof(Record), record_size());
- return &data_.mmap->records[index];
- }
- RecordStorage* record_mmap_reader(uint32_t index) const {
- if (Traits::kUseStaticRecordSize) {
- return &data_.mmap->records[index];
- } else {
- // Calculate the location of a record in the ring without assuming that
- // sizeof(Record) == record_size.
- return reinterpret_cast<RecordStorage*>(
- reinterpret_cast<char*>(data_.mmap->records) + index * record_size());
- }
- }
-
- // The following horrifying template gunk enables us to store just the mmap
- // base pointer for compile-time statically sized rings. Dynamically sized
- // rings also store the validated copy of the record size & count.
- //
- // This boils down to: use a compile time constant if available, and otherwise
- // load the value that was validated on import from a member variable.
- template <typename T = Traits>
- typename std::enable_if<T::kUseStaticRecordSize, uint32_t>::type
- record_size_internal() const {
- return sizeof(Record);
- }
-
- template <typename T = Traits>
- typename std::enable_if<!T::kUseStaticRecordSize, uint32_t>::type
- record_size_internal() const {
- return data_.record_size;
- }
-
- template <typename T = Traits>
- typename std::enable_if<T::kUseStaticRecordSize, void>::type set_record_size(
- uint32_t /*record_size*/) {}
-
- template <typename T = Traits>
- typename std::enable_if<!T::kUseStaticRecordSize, void>::type set_record_size(
- uint32_t record_size) {
- data_.record_size = record_size;
- }
-
- template <typename T = Traits>
- typename std::enable_if<T::kUseStaticRecordCount, uint32_t>::type
- record_count_internal() const {
- return Traits::kStaticRecordCount;
- }
-
- template <typename T = Traits>
- typename std::enable_if<!T::kUseStaticRecordCount, uint32_t>::type
- record_count_internal() const {
- return data_.record_count;
- }
-
- template <typename T = Traits>
- typename std::enable_if<T::kUseStaticRecordCount, void>::type
- set_record_count(uint32_t /*record_count*/) const {}
-
- template <typename T = Traits>
- typename std::enable_if<!T::kUseStaticRecordCount, void>::type
- set_record_count(uint32_t record_count) {
- data_.record_count = record_count;
- }
-
- // Data we need to store for statically sized rings.
- struct DataStaticSize {
- Mmap* mmap = nullptr;
- };
-
- // Data we need to store for dynamically sized rings.
- struct DataDynamicSize {
- Mmap* mmap = nullptr;
-
- // These are cached to make sure misbehaving writers cannot cause
- // out-of-bounds memory accesses by updating the values in the mmap header.
- uint32_t record_size = 0;
- uint32_t record_count = 0;
- };
-
- using DataStaticOrDynamic =
- typename std::conditional<Traits::kIsStaticSize, DataStaticSize,
- DataDynamicSize>::type;
-
- DataStaticOrDynamic data_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BROADCAST_RING_H_
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
deleted file mode 100644
index 583ad1d..0000000
--- a/libs/vr/libbufferhub/Android.bp
+++ /dev/null
@@ -1,83 +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"],
-}
-
-cc_library_headers {
- name: "libbufferhub_headers",
- export_include_dirs: ["include"],
- vendor_available: true, // TODO(b/112338314): Does shouldn't be available to vendor.
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- "com.android.media.swcodec",
- ],
- min_sdk_version: "29",
-}
-
-sourceFiles = [
- "buffer_hub_base.cpp",
- "buffer_hub_rpc.cpp",
- "consumer_buffer.cpp",
- "ion_buffer.cpp",
- "producer_buffer.cpp",
-]
-
-sharedLibraries = [
- "libbase",
- "libcutils",
- "liblog",
- "libui",
- "libutils",
- "libpdx_default_transport",
-]
-
-headerLibraries = [
- "libbufferhub_headers",
- "libdvr_headers",
- "libnativebase_headers",
-]
-
-cc_library {
- srcs: sourceFiles,
- cflags: [
- "-DLOG_TAG=\"libbufferhub\"",
- "-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- "-Wall",
- "-Werror",
- ],
- shared_libs: sharedLibraries,
- header_libs: headerLibraries,
- name: "libbufferhub",
- export_header_lib_headers: [
- "libbufferhub_headers",
- "libnativebase_headers",
- ],
-}
-
-cc_test {
- srcs: ["buffer_hub-test.cpp"],
- static_libs: ["libbufferhub"],
- shared_libs: sharedLibraries,
- header_libs: headerLibraries,
- name: "buffer_hub-test",
-}
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
deleted file mode 100644
index 27ab024..0000000
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ /dev/null
@@ -1,906 +0,0 @@
-#include <gtest/gtest.h>
-#include <poll.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_buffer.h>
-#include <private/dvr/producer_buffer.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <ui/BufferHubDefs.h>
-
-#include <mutex>
-#include <thread>
-
-namespace {
-#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::BufferHubDefs::isAnyClientAcquired;
-using android::BufferHubDefs::isAnyClientGained;
-using android::BufferHubDefs::isAnyClientPosted;
-using android::BufferHubDefs::isClientAcquired;
-using android::BufferHubDefs::isClientPosted;
-using android::BufferHubDefs::isClientReleased;
-using android::BufferHubDefs::kFirstClientBitMask;
-using android::dvr::ConsumerBuffer;
-using android::dvr::ProducerBuffer;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using LibBufferHubTest = ::testing::Test;
-
-const int kWidth = 640;
-const int kHeight = 480;
-const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
-const int kUsage = 0;
-// Maximum number of consumers for the buffer that only has one producer in the
-// test.
-const size_t kMaxConsumerCount =
- android::BufferHubDefs::kMaxNumberOfClients - 1;
-const int kPollTimeoutMs = 100;
-
-// Helper function to poll the eventfd in BufferHubBase.
-template <class BufferHubBase>
-int PollBufferEvent(const std::unique_ptr<BufferHubBase>& buffer,
- int timeout_ms = kPollTimeoutMs) {
- pollfd p = {buffer->event_fd(), POLLIN, 0};
- return poll(&p, 1, timeout_ms);
-}
-
-} // namespace
-
-TEST_F(LibBufferHubTest, TestBasicUsage) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c1 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c1.get() != nullptr);
- // Check that consumers can spawn other consumers.
- std::unique_ptr<ConsumerBuffer> c2 =
- ConsumerBuffer::Import(c1->CreateConsumer());
- ASSERT_TRUE(c2.get() != nullptr);
-
- // Checks the state masks of client p, c1 and c2.
- EXPECT_EQ(p->client_state_mask(), kFirstClientBitMask);
- EXPECT_EQ(c1->client_state_mask(), kFirstClientBitMask << 1);
- EXPECT_EQ(c2->client_state_mask(), kFirstClientBitMask << 2);
-
- // Initial state: producer not available, consumers not available.
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-
- EXPECT_EQ(0, p->GainAsync());
- EXPECT_EQ(0, p->Post(LocalHandle()));
-
- // New state: producer not available, consumers available.
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
-
- LocalHandle fence;
- EXPECT_EQ(0, c1->Acquire(&fence));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(c2)));
-
- EXPECT_EQ(0, c2->Acquire(&fence));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
-
- EXPECT_EQ(0, c1->Release(LocalHandle()));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(0, c2->Discard());
- EXPECT_EQ(1, RETRY_EINTR(PollBufferEvent(p)));
-
- EXPECT_EQ(0, p->Gain(&fence));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
-}
-
-TEST_F(LibBufferHubTest, TestEpoll) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
-
- LocalHandle epoll_fd{epoll_create1(EPOLL_CLOEXEC)};
- ASSERT_TRUE(epoll_fd.IsValid());
-
- epoll_event event;
- std::array<epoll_event, 64> events;
-
- auto event_sources = p->GetEventSources();
- ASSERT_LT(event_sources.size(), events.size());
-
- for (const auto& event_source : event_sources) {
- event = {.events = event_source.event_mask | EPOLLET,
- .data = {.fd = p->event_fd()}};
- ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
- &event));
- }
-
- event_sources = c->GetEventSources();
- ASSERT_LT(event_sources.size(), events.size());
-
- for (const auto& event_source : event_sources) {
- event = {.events = event_source.event_mask | EPOLLET,
- .data = {.fd = c->event_fd()}};
- ASSERT_EQ(0, epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_source.event_fd,
- &event));
- }
-
- // No events should be signaled initially.
- ASSERT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(), 0));
-
- // Gain and post the producer and check for consumer signal.
- EXPECT_EQ(0, p->GainAsync());
- EXPECT_EQ(0, p->Post({}));
- ASSERT_EQ(1, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
- ASSERT_TRUE(events[0].events & EPOLLIN);
- ASSERT_EQ(c->event_fd(), events[0].data.fd);
-
- // Save the event bits to translate later.
- event = events[0];
-
- // Check for events again. Edge-triggered mode should prevent any.
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
-
- // Translate the events.
- auto event_status = c->GetEventMask(event.events);
- ASSERT_TRUE(event_status);
- ASSERT_TRUE(event_status.get() & EPOLLIN);
-
- // Check for events again. Edge-triggered mode should prevent any.
- EXPECT_EQ(0, epoll_wait(epoll_fd.Get(), events.data(), events.size(),
- kPollTimeoutMs));
-}
-
-TEST_F(LibBufferHubTest, TestStateMask) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
-
- // It's ok to create up to kMaxConsumerCount consumer buffers.
- uint32_t client_state_masks = p->client_state_mask();
- std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
- for (size_t i = 0; i < kMaxConsumerCount; i++) {
- cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(cs[i].get() != nullptr);
- // Expect all buffers have unique state mask.
- EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
- client_state_masks |= cs[i]->client_state_mask();
- }
- EXPECT_EQ(client_state_masks, ~0U);
-
- // The 64th creation will fail with out-of-memory error.
- auto state = p->CreateConsumer();
- EXPECT_EQ(state.error(), E2BIG);
-
- // Release any consumer should allow us to re-create.
- for (size_t i = 0; i < kMaxConsumerCount; i++) {
- client_state_masks &= ~cs[i]->client_state_mask();
- cs[i] = nullptr;
- cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(cs[i].get() != nullptr);
- // The released state mask will be reused.
- EXPECT_EQ(client_state_masks & cs[i]->client_state_mask(), 0U);
- client_state_masks |= cs[i]->client_state_mask();
- }
-}
-
-TEST_F(LibBufferHubTest, TestStateTransitions) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
-
- LocalHandle fence;
- EXPECT_EQ(0, p->GainAsync());
-
- // Acquire in gained state should fail.
- EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-
- // Post in gained state should succeed.
- EXPECT_EQ(0, p->Post(LocalHandle()));
-
- // Post and gain in posted state should fail.
- EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
- EXPECT_EQ(-EBUSY, p->Gain(&fence));
-
- // Acquire in posted state should succeed.
- EXPECT_EQ(0, c->Acquire(&fence));
-
- // Acquire, post, and gain in acquired state should fail.
- EXPECT_EQ(-EBUSY, c->Acquire(&fence));
- EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
- EXPECT_EQ(-EBUSY, p->Gain(&fence));
-
- // Release in acquired state should succeed.
- EXPECT_EQ(0, c->Release(LocalHandle()));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
- // Acquire and post in released state should fail.
- EXPECT_EQ(-EBUSY, c->Acquire(&fence));
- EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
-
- // Gain in released state should succeed.
- EXPECT_EQ(0, p->Gain(&fence));
-
- // Acquire in gained state should fail.
- EXPECT_EQ(-EBUSY, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestAsyncStateTransitions) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
-
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
- EXPECT_EQ(0, p->GainAsync());
-
- // Acquire in gained state should fail.
- EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
- EXPECT_FALSE(invalid_fence.IsValid());
-
- // Post in gained state should succeed.
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_EQ(p->buffer_state(), c->buffer_state());
- EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
-
- // Post and gain in posted state should fail.
- EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
- EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
-
- // Acquire in posted state should succeed.
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
- EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
- EXPECT_EQ(p->buffer_state(), c->buffer_state());
- EXPECT_TRUE(isAnyClientAcquired(p->buffer_state()));
-
- // Acquire, post, and gain in acquired state should fail.
- EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
- EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
- EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
-
- // Release in acquired state should succeed.
- EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(p->buffer_state(), c->buffer_state());
- EXPECT_TRUE(p->is_released());
-
- // Acquire and post in released state should fail.
- EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
- EXPECT_EQ(-EBUSY, p->PostAsync(&metadata, invalid_fence));
-
- // Gain in released state should succeed.
- EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
- EXPECT_EQ(p->buffer_state(), c->buffer_state());
- EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
- // Acquire and gain in gained state should fail.
- EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_FALSE(invalid_fence.IsValid());
-}
-
-TEST_F(LibBufferHubTest, TestGainTwiceByTheSameProducer) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
-
- ASSERT_EQ(0, p->GainAsync());
- ASSERT_EQ(0, p->GainAsync());
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBuffer) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- ASSERT_EQ(0, p->GainAsync());
- ASSERT_EQ(0, p->Post(LocalHandle()));
- ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
- // Gain in posted state should only succeed with gain_posted_buffer = true.
- LocalHandle invalid_fence;
- EXPECT_EQ(-EBUSY, p->Gain(&invalid_fence, false));
- EXPECT_EQ(0, p->Gain(&invalid_fence, true));
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBufferAsync) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- ASSERT_EQ(0, p->GainAsync());
- ASSERT_EQ(0, p->Post(LocalHandle()));
- ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
- // GainAsync in posted state should only succeed with gain_posted_buffer
- // equals true.
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
- EXPECT_EQ(-EBUSY, p->GainAsync(&metadata, &invalid_fence, false));
- EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence, true));
-}
-
-TEST_F(LibBufferHubTest, TestGainPostedBuffer_noConsumer) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- ASSERT_EQ(0, p->GainAsync());
- ASSERT_EQ(0, p->Post(LocalHandle()));
- // Producer state bit is in released state after post, other clients shall be
- // in posted state although there is no consumer of this buffer yet.
- ASSERT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
- ASSERT_TRUE(p->is_released());
- ASSERT_TRUE(isAnyClientPosted(p->buffer_state()));
-
- // Gain in released state should succeed.
- LocalHandle invalid_fence;
- EXPECT_EQ(0, p->Gain(&invalid_fence, false));
-}
-
-TEST_F(LibBufferHubTest, TestMaxConsumers) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- uint32_t producer_state_mask = p->client_state_mask();
-
- std::array<std::unique_ptr<ConsumerBuffer>, kMaxConsumerCount> cs;
- for (size_t i = 0; i < kMaxConsumerCount; ++i) {
- cs[i] = ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(cs[i].get() != nullptr);
- EXPECT_TRUE(cs[i]->is_released());
- EXPECT_NE(producer_state_mask, cs[i]->client_state_mask());
- }
-
- EXPECT_EQ(0, p->GainAsync());
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
-
- // Post the producer should trigger all consumers to be available.
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_TRUE(isClientReleased(p->buffer_state(), p->client_state_mask()));
- for (size_t i = 0; i < kMaxConsumerCount; ++i) {
- EXPECT_TRUE(
- isClientPosted(cs[i]->buffer_state(), cs[i]->client_state_mask()));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(cs[i])));
- EXPECT_EQ(0, cs[i]->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_TRUE(
- isClientAcquired(p->buffer_state(), cs[i]->client_state_mask()));
- }
-
- // All consumers have to release before the buffer is considered to be
- // released.
- for (size_t i = 0; i < kMaxConsumerCount; i++) {
- EXPECT_FALSE(p->is_released());
- EXPECT_EQ(0, cs[i]->ReleaseAsync(&metadata, invalid_fence));
- }
-
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_TRUE(p->is_released());
-
- // Buffer state cross all clients must be consistent.
- for (size_t i = 0; i < kMaxConsumerCount; i++) {
- EXPECT_EQ(p->buffer_state(), cs[i]->buffer_state());
- }
-}
-
-TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferGained) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
- EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_TRUE(isAnyClientGained(c->buffer_state()));
-
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
-
- // Post the gained buffer should signal already created consumer.
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_TRUE(isAnyClientPosted(p->buffer_state()));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
- EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_TRUE(isAnyClientAcquired(c->buffer_state()));
-}
-
-TEST_F(LibBufferHubTest, TestCreateTheFirstConsumerAfterPostingBuffer) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
- EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
-
- // Post the gained buffer before any consumer gets created.
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_TRUE(p->is_released());
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(p)));
-
- // Newly created consumer will be signalled for the posted buffer although it
- // is created after producer posting.
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_TRUE(isClientPosted(c->buffer_state(), c->client_state_mask()));
- EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-}
-
-TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
-
- std::unique_ptr<ConsumerBuffer> c1 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c1.get() != nullptr);
-
- EXPECT_EQ(0, p->GainAsync());
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
-
- // Post, acquire, and release the buffer..
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(0, c1->AcquireAsync(&metadata, &invalid_fence));
- EXPECT_EQ(0, c1->ReleaseAsync(&metadata, invalid_fence));
-
- // Note that the next PDX call is on the producer channel, which may be
- // executed before Release impulse gets executed by bufferhubd. Thus, here we
- // need to wait until the releasd is confirmed before creating another
- // consumer.
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_TRUE(p->is_released());
-
- // Create another consumer immediately after the release, should not make the
- // buffer un-released.
- std::unique_ptr<ConsumerBuffer> c2 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c2.get() != nullptr);
-
- EXPECT_TRUE(p->is_released());
- EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
- EXPECT_TRUE(isAnyClientGained(p->buffer_state()));
-}
-
-TEST_F(LibBufferHubTest, TestWithCustomMetadata) {
- struct Metadata {
- int64_t field1;
- int64_t field2;
- };
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
- Metadata m = {1, 3};
- EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(Metadata)));
- EXPECT_LE(0, RETRY_EINTR(PollBufferEvent(c)));
- LocalHandle fence;
- Metadata m2 = {};
- EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
- EXPECT_EQ(m.field1, m2.field1);
- EXPECT_EQ(m.field2, m2.field2);
- EXPECT_EQ(0, c->Release(LocalHandle()));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p, /*timeout_ms=*/0)));
-}
-
-TEST_F(LibBufferHubTest, TestPostWithWrongMetaSize) {
- struct Metadata {
- int64_t field1;
- int64_t field2;
- };
- struct OverSizedMetadata {
- int64_t field1;
- int64_t field2;
- int64_t field3;
- };
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- // It is illegal to post metadata larger than originally requested during
- // buffer allocation.
- OverSizedMetadata evil_meta = {};
- EXPECT_NE(0, p->Post(LocalHandle(), &evil_meta, sizeof(OverSizedMetadata)));
- EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c)));
-
- // It is ok to post metadata smaller than originally requested during
- // buffer allocation.
- EXPECT_EQ(0, p->Post(LocalHandle()));
-}
-
-TEST_F(LibBufferHubTest, TestAcquireWithWrongMetaSize) {
- struct Metadata {
- int64_t field1;
- int64_t field2;
- };
- struct OverSizedMetadata {
- int64_t field1;
- int64_t field2;
- int64_t field3;
- };
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(Metadata));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- Metadata m = {1, 3};
- EXPECT_EQ(0, p->Post(LocalHandle(), &m, sizeof(m)));
-
- LocalHandle fence;
- int64_t sequence;
- OverSizedMetadata e;
-
- // It is illegal to acquire metadata larger than originally requested during
- // buffer allocation.
- EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
-
- // It is ok to acquire metadata smaller than originally requested during
- // buffer allocation.
- EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
- EXPECT_EQ(m.field1, sequence);
-}
-
-TEST_F(LibBufferHubTest, TestAcquireWithNoMeta) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- int64_t sequence = 3;
- EXPECT_EQ(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
-
- LocalHandle fence;
- EXPECT_EQ(0, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestWithNoMeta) {
- std::unique_ptr<ProducerBuffer> p =
- ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- LocalHandle fence;
-
- EXPECT_EQ(0, p->Post(LocalHandle()));
- EXPECT_EQ(0, c->Acquire(&fence));
-}
-
-TEST_F(LibBufferHubTest, TestFailureToPostMetaFromABufferWithoutMeta) {
- std::unique_ptr<ProducerBuffer> p =
- ProducerBuffer::Create(kWidth, kHeight, kFormat, kUsage);
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- int64_t sequence = 3;
- EXPECT_NE(0, p->Post(LocalHandle(), &sequence, sizeof(sequence)));
-}
-
-namespace {
-
-int PollFd(int fd, int timeout_ms) {
- pollfd p = {fd, POLLIN, 0};
- return poll(&p, 1, timeout_ms);
-}
-
-} // namespace
-
-TEST_F(LibBufferHubTest, TestAcquireFence) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, /*metadata_size=*/0);
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c.get() != nullptr);
- EXPECT_EQ(0, p->GainAsync());
-
- DvrNativeBufferMetadata meta;
- LocalHandle f1(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
-
- // Post with unsignaled fence.
- EXPECT_EQ(0, p->PostAsync(&meta, f1));
-
- // Should acquire a valid fence.
- LocalHandle f2;
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
- EXPECT_EQ(0, c->AcquireAsync(&meta, &f2));
- EXPECT_TRUE(f2.IsValid());
- // The original fence and acquired fence should have different fd number.
- EXPECT_NE(f1.Get(), f2.Get());
- EXPECT_GE(0, PollFd(f2.Get(), 0));
-
- // Signal the original fence will trigger the new fence.
- eventfd_write(f1.Get(), 1);
- // Now the original FD has been signaled.
- EXPECT_LT(0, PollFd(f2.Get(), kPollTimeoutMs));
-
- // Release the consumer with an invalid fence.
- EXPECT_EQ(0, c->ReleaseAsync(&meta, LocalHandle()));
-
- // Should gain an invalid fence.
- LocalHandle f3;
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(0, p->GainAsync(&meta, &f3));
- EXPECT_FALSE(f3.IsValid());
-
- // Post with a signaled fence.
- EXPECT_EQ(0, p->PostAsync(&meta, f1));
-
- // Should acquire a valid fence and it's already signalled.
- LocalHandle f4;
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c)));
- EXPECT_EQ(0, c->AcquireAsync(&meta, &f4));
- EXPECT_TRUE(f4.IsValid());
- EXPECT_LT(0, PollFd(f4.Get(), kPollTimeoutMs));
-
- // Release with an unsignalled fence and signal it immediately after release
- // without producer gainning.
- LocalHandle f5(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
- EXPECT_EQ(0, c->ReleaseAsync(&meta, f5));
- eventfd_write(f5.Get(), 1);
-
- // Should gain a valid fence, which is already signaled.
- LocalHandle f6;
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
- EXPECT_EQ(0, p->GainAsync(&meta, &f6));
- EXPECT_TRUE(f6.IsValid());
- EXPECT_LT(0, PollFd(f6.Get(), kPollTimeoutMs));
-}
-
-TEST_F(LibBufferHubTest, TestOrphanedAcquire) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c1 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c1.get() != nullptr);
- const uint32_t client_state_mask1 = c1->client_state_mask();
-
- EXPECT_EQ(0, p->GainAsync());
- DvrNativeBufferMetadata meta;
- EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
-
- LocalHandle fence;
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
- EXPECT_EQ(0, c1->AcquireAsync(&meta, &fence));
-
- // Destroy the consumer who has acquired but not released the buffer.
- c1 = nullptr;
-
- // The buffer is now available for the producer to gain.
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
- // Newly added consumer is not able to acquire the buffer.
- std::unique_ptr<ConsumerBuffer> c2 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c2.get() != nullptr);
- const uint32_t client_state_mask2 = c2->client_state_mask();
- EXPECT_NE(client_state_mask1, client_state_mask2);
- EXPECT_EQ(0, RETRY_EINTR(PollBufferEvent(c2)));
- EXPECT_EQ(-EBUSY, c2->AcquireAsync(&meta, &fence));
-
- // Producer should be able to gain.
- EXPECT_EQ(0, p->GainAsync(&meta, &fence, false));
-}
-
-TEST_F(LibBufferHubTest, TestAcquireLastPosted) {
- std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p.get() != nullptr);
- std::unique_ptr<ConsumerBuffer> c1 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c1.get() != nullptr);
- const uint32_t client_state_mask1 = c1->client_state_mask();
-
- EXPECT_EQ(0, p->GainAsync());
- DvrNativeBufferMetadata meta;
- EXPECT_EQ(0, p->PostAsync(&meta, LocalHandle()));
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c1)));
-
- // c2 is created when the buffer is in posted state. buffer state for c1 is
- // posted. Thus, c2 should be automatically set to posted and able to acquire.
- std::unique_ptr<ConsumerBuffer> c2 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c2.get() != nullptr);
- const uint32_t client_state_mask2 = c2->client_state_mask();
- EXPECT_NE(client_state_mask1, client_state_mask2);
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c2)));
- LocalHandle invalid_fence;
- EXPECT_EQ(0, c2->AcquireAsync(&meta, &invalid_fence));
-
- EXPECT_EQ(0, c1->AcquireAsync(&meta, &invalid_fence));
-
- // c3 is created when the buffer is in acquired state. buffer state for c1 and
- // c2 are acquired. Thus, c3 should be automatically set to posted and able to
- // acquire.
- std::unique_ptr<ConsumerBuffer> c3 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c3.get() != nullptr);
- const uint32_t client_state_mask3 = c3->client_state_mask();
- EXPECT_NE(client_state_mask1, client_state_mask3);
- EXPECT_NE(client_state_mask2, client_state_mask3);
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(c3)));
- EXPECT_EQ(0, c3->AcquireAsync(&meta, &invalid_fence));
-
- // Releasing c2 and c3 in normal ways.
- EXPECT_EQ(0, c2->Release(LocalHandle()));
- EXPECT_EQ(0, c3->ReleaseAsync(&meta, LocalHandle()));
-
- // Destroy the c1 who has not released the buffer.
- c1 = nullptr;
-
- // The buffer is now available for the producer to gain.
- EXPECT_LT(0, RETRY_EINTR(PollBufferEvent(p)));
-
- // C4 is created in released state. Thus, it cannot gain the just posted
- // buffer.
- std::unique_ptr<ConsumerBuffer> c4 =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(c4.get() != nullptr);
- const uint32_t client_state_mask4 = c4->client_state_mask();
- EXPECT_NE(client_state_mask3, client_state_mask4);
- EXPECT_GE(0, RETRY_EINTR(PollBufferEvent(c3)));
- EXPECT_EQ(-EBUSY, c3->AcquireAsync(&meta, &invalid_fence));
-
- // Producer should be able to gain.
- EXPECT_EQ(0, p->GainAsync(&meta, &invalid_fence));
-}
-
-TEST_F(LibBufferHubTest, TestDetachBufferFromProducer) {
- // TODO(b/112338294) rewrite test after migration
- return;
-
- /* std::unique_ptr<ProducerBuffer> p = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- std::unique_ptr<ConsumerBuffer> c =
- ConsumerBuffer::Import(p->CreateConsumer());
- ASSERT_TRUE(p.get() != nullptr);
- ASSERT_TRUE(c.get() != nullptr);
-
- DvrNativeBufferMetadata metadata;
- LocalHandle invalid_fence;
- int p_id = p->id();
-
- // Detach in posted state should fail.
- EXPECT_EQ(0, p->GainAsync());
- EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
- EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
- auto s1 = p->Detach();
- EXPECT_FALSE(s1);
-
- // Detach in acquired state should fail.
- EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
- s1 = p->Detach();
- EXPECT_FALSE(s1);
-
- // Detach in released state should fail.
- EXPECT_EQ(0, c->ReleaseAsync(&metadata, invalid_fence));
- EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
- s1 = p->Detach();
- EXPECT_FALSE(s1);
-
- // Detach in gained state should succeed.
- EXPECT_EQ(0, p->GainAsync(&metadata, &invalid_fence));
- s1 = p->Detach();
- EXPECT_TRUE(s1);
-
- LocalChannelHandle handle = s1.take();
- EXPECT_TRUE(handle.valid());
-
- // Both producer and consumer should have hangup.
- EXPECT_GT(RETRY_EINTR(PollBufferEvent(p)), 0);
- auto s2 = p->GetEventMask(POLLHUP);
- EXPECT_TRUE(s2);
- EXPECT_EQ(s2.get(), POLLHUP);
-
- EXPECT_GT(RETRY_EINTR(PollBufferEvent(c)), 0);
- s2 = p->GetEventMask(POLLHUP);
- EXPECT_TRUE(s2);
- EXPECT_EQ(s2.get(), POLLHUP);
-
- auto s3 = p->CreateConsumer();
- EXPECT_FALSE(s3);
- // Note that here the expected error code is EOPNOTSUPP as the socket towards
- // ProducerChannel has been teared down.
- EXPECT_EQ(s3.error(), EOPNOTSUPP);
-
- s3 = c->CreateConsumer();
- EXPECT_FALSE(s3);
- // Note that here the expected error code is EPIPE returned from
- // ConsumerChannel::HandleMessage as the socket is still open but the producer
- // is gone.
- EXPECT_EQ(s3.error(), EPIPE);
-
- // Detached buffer handle can be use to construct a new BufferHubBuffer
- // object.
- auto d = BufferHubBuffer::Import(std::move(handle));
- EXPECT_FALSE(handle.valid());
- EXPECT_TRUE(d->IsConnected());
- EXPECT_TRUE(d->IsValid());
-
- EXPECT_EQ(d->id(), p_id); */
-}
-
-TEST_F(LibBufferHubTest, TestDetach) {
- // TODO(b/112338294) rewrite test after migration
- return;
-
- /* std::unique_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
- kWidth, kHeight, kFormat, kUsage, sizeof(uint64_t));
- ASSERT_TRUE(p1.get() != nullptr);
- int p1_id = p1->id();
-
- // Detached the producer from gained state.
- EXPECT_EQ(0, p1->GainAsync());
- auto status_or_handle = p1->Detach();
- EXPECT_TRUE(status_or_handle.ok());
- LocalChannelHandle h1 = status_or_handle.take();
- EXPECT_TRUE(h1.valid());
-
- // Detached buffer handle can be use to construct a new BufferHubBuffer
- // object.
- auto b1 = BufferHubBuffer::Import(std::move(h1));
- EXPECT_FALSE(h1.valid());
- EXPECT_TRUE(b1->IsValid());
- int b1_id = b1->id();
- EXPECT_EQ(b1_id, p1_id); */
-}
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
deleted file mode 100644
index 17930b4..0000000
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-#include <poll.h>
-#include <sys/epoll.h>
-
-#include <pdx/default_transport/client_channel.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <private/dvr/buffer_hub_base.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using android::pdx::default_transport::ClientChannel;
-using android::pdx::default_transport::ClientChannelFactory;
-
-namespace android {
-namespace dvr {
-
-BufferHubBase::BufferHubBase(LocalChannelHandle channel_handle)
- : Client{pdx::default_transport::ClientChannel::Create(
- std::move(channel_handle))},
- id_(-1),
- cid_(-1) {}
-BufferHubBase::BufferHubBase(const std::string& endpoint_path)
- : Client{pdx::default_transport::ClientChannelFactory::Create(
- endpoint_path)},
- id_(-1),
- cid_(-1) {}
-
-BufferHubBase::~BufferHubBase() {
- // buffer_state and fence_state are not reset here. They will be used to
- // clean up epoll fd if necessary in ProducerChannel::RemoveConsumer method.
- if (metadata_header_ != nullptr) {
- metadata_buffer_.Unlock();
- }
-}
-
-Status<LocalChannelHandle> BufferHubBase::CreateConsumer() {
- Status<LocalChannelHandle> status =
- InvokeRemoteMethod<BufferHubRPC::NewConsumer>();
- ALOGE_IF(!status,
- "BufferHub::CreateConsumer: Failed to create consumer channel: %s",
- status.GetErrorMessage().c_str());
- return status;
-}
-
-int BufferHubBase::ImportBuffer() {
- ATRACE_NAME("BufferHubBase::ImportBuffer");
-
- Status<BufferDescription<LocalHandle>> status =
- InvokeRemoteMethod<BufferHubRPC::GetBuffer>();
- if (!status) {
- ALOGE("BufferHubBase::ImportBuffer: Failed to get buffer: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
- } else if (status.get().id() < 0) {
- ALOGE("BufferHubBase::ImportBuffer: Received an invalid id!");
- return -EIO;
- }
-
- auto buffer_desc = status.take();
-
- // Stash the buffer id to replace the value in id_.
- const int new_id = buffer_desc.id();
-
- // Import the buffer.
- IonBuffer ion_buffer;
- ALOGD_IF(TRACE, "BufferHubBase::ImportBuffer: id=%d.", buffer_desc.id());
-
- if (const int ret = buffer_desc.ImportBuffer(&ion_buffer))
- return ret;
-
- // Import the metadata.
- IonBuffer metadata_buffer;
- if (const int ret = buffer_desc.ImportMetadata(&metadata_buffer)) {
- ALOGE("Failed to import metadata buffer, error=%d", ret);
- return ret;
- }
- size_t metadata_buf_size = metadata_buffer.width();
- if (metadata_buf_size < BufferHubDefs::kMetadataHeaderSize) {
- ALOGE("BufferHubBase::ImportBuffer: metadata buffer too small: %zu",
- metadata_buf_size);
- return -ENOMEM;
- }
-
- // If all imports succee, replace the previous buffer and id.
- buffer_ = std::move(ion_buffer);
- metadata_buffer_ = std::move(metadata_buffer);
- metadata_buf_size_ = metadata_buf_size;
- user_metadata_size_ = metadata_buf_size_ - BufferHubDefs::kMetadataHeaderSize;
-
- void* metadata_ptr = nullptr;
- if (const int ret =
- metadata_buffer_.Lock(BufferHubDefs::kMetadataUsage, /*x=*/0,
- /*y=*/0, metadata_buf_size_,
- /*height=*/1, &metadata_ptr)) {
- ALOGE("BufferHubBase::ImportBuffer: Failed to lock metadata.");
- return ret;
- }
-
- // Set up shared fences.
- shared_acquire_fence_ = buffer_desc.take_acquire_fence();
- shared_release_fence_ = buffer_desc.take_release_fence();
- if (!shared_acquire_fence_ || !shared_release_fence_) {
- ALOGE("BufferHubBase::ImportBuffer: Failed to import shared fences.");
- return -EIO;
- }
-
- metadata_header_ =
- reinterpret_cast<BufferHubDefs::MetadataHeader*>(metadata_ptr);
- if (user_metadata_size_) {
- user_metadata_ptr_ =
- reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(metadata_ptr) +
- BufferHubDefs::kMetadataHeaderSize);
- } else {
- user_metadata_ptr_ = nullptr;
- }
-
- id_ = new_id;
- cid_ = buffer_desc.buffer_cid();
- client_state_mask_ = buffer_desc.client_state_mask();
-
- // Note that here the buffer_state, fence_state and active_clients_bit_mask
- // are mapped from shared memory as an atomic object. The std::atomic's
- // constructor will not be called so that the original value stored in the
- // memory region will be preserved.
- buffer_state_ = &metadata_header_->bufferState;
- ALOGD_IF(TRACE,
- "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
- id(), buffer_state_->load(std::memory_order_acquire));
- fence_state_ = &metadata_header_->fenceState;
- ALOGD_IF(TRACE,
- "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
- fence_state_->load(std::memory_order_acquire));
- active_clients_bit_mask_ = &metadata_header_->activeClientsBitMask;
- ALOGD_IF(
- TRACE,
- "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
- ".",
- id(), active_clients_bit_mask_->load(std::memory_order_acquire));
-
- return 0;
-}
-
-int BufferHubBase::CheckMetadata(size_t user_metadata_size) const {
- if (user_metadata_size && !user_metadata_ptr_) {
- ALOGE("BufferHubBase::CheckMetadata: doesn't support custom metadata.");
- return -EINVAL;
- }
- if (user_metadata_size > user_metadata_size_) {
- ALOGE("BufferHubBase::CheckMetadata: too big: %zu, maximum: %zu.",
- user_metadata_size, user_metadata_size_);
- return -E2BIG;
- }
- return 0;
-}
-
-int BufferHubBase::UpdateSharedFence(const LocalHandle& new_fence,
- const LocalHandle& shared_fence) {
- if (pending_fence_fd_.Get() != new_fence.Get()) {
- // First, replace the old fd if there was already one. Skipping if the new
- // one is the same as the old.
- if (pending_fence_fd_.IsValid()) {
- const int ret = epoll_ctl(shared_fence.Get(), EPOLL_CTL_DEL,
- pending_fence_fd_.Get(), nullptr);
- ALOGW_IF(ret,
- "BufferHubBase::UpdateSharedFence: failed to remove old fence "
- "fd from epoll set, error: %s.",
- strerror(errno));
- }
-
- if (new_fence.IsValid()) {
- // If ready fence is valid, we put that into the epoll set.
- epoll_event event;
- event.events = EPOLLIN;
- event.data.u32 = client_state_mask();
- pending_fence_fd_ = new_fence.Duplicate();
- if (epoll_ctl(shared_fence.Get(), EPOLL_CTL_ADD, pending_fence_fd_.Get(),
- &event) < 0) {
- const int error = errno;
- ALOGE(
- "BufferHubBase::UpdateSharedFence: failed to add new fence fd "
- "into epoll set, error: %s.",
- strerror(error));
- return -error;
- }
- // Set bit in fence state to indicate that there is a fence from this
- // producer or consumer.
- fence_state_->fetch_or(client_state_mask());
- } else {
- // Unset bit in fence state to indicate that there is no fence, so that
- // when consumer to acquire or producer to acquire, it knows no need to
- // check fence for this buffer.
- fence_state_->fetch_and(~client_state_mask());
- }
- }
-
- return 0;
-}
-
-int BufferHubBase::Lock(int usage, int x, int y, int width, int height,
- void** address) {
- return buffer_.Lock(usage, x, y, width, height, address);
-}
-
-int BufferHubBase::Unlock() { return buffer_.Unlock(); }
-
-int BufferHubBase::GetBlobReadWritePointer(size_t size, void** addr) {
- int width = static_cast<int>(size);
- int height = 1;
- int ret = Lock(usage(), 0, 0, width, height, addr);
- if (ret == 0)
- Unlock();
- return ret;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhub/buffer_hub_rpc.cpp b/libs/vr/libbufferhub/buffer_hub_rpc.cpp
deleted file mode 100644
index 9a67faa..0000000
--- a/libs/vr/libbufferhub/buffer_hub_rpc.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "include/private/dvr/bufferhub_rpc.h"
-
-namespace android {
-namespace dvr {
-
-constexpr char BufferHubRPC::kClientPath[];
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhub/consumer_buffer.cpp b/libs/vr/libbufferhub/consumer_buffer.cpp
deleted file mode 100644
index 7823e36..0000000
--- a/libs/vr/libbufferhub/consumer_buffer.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-#include <private/dvr/consumer_buffer.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-ConsumerBuffer::ConsumerBuffer(LocalChannelHandle channel)
- : BASE(std::move(channel)) {
- const int ret = ImportBuffer();
- if (ret < 0) {
- ALOGE("ConsumerBuffer::ConsumerBuffer: Failed to import buffer: %s",
- strerror(-ret));
- Close(ret);
- }
-}
-
-std::unique_ptr<ConsumerBuffer> ConsumerBuffer::Import(
- LocalChannelHandle channel) {
- ATRACE_NAME("ConsumerBuffer::Import");
- ALOGD_IF(TRACE, "ConsumerBuffer::Import: channel=%d", channel.value());
- return ConsumerBuffer::Create(std::move(channel));
-}
-
-std::unique_ptr<ConsumerBuffer> ConsumerBuffer::Import(
- Status<LocalChannelHandle> status) {
- return Import(status ? status.take()
- : LocalChannelHandle{nullptr, -status.error()});
-}
-
-int ConsumerBuffer::LocalAcquire(DvrNativeBufferMetadata* out_meta,
- LocalHandle* out_fence) {
- if (!out_meta)
- return -EINVAL;
-
- // The buffer can be acquired iff the buffer state for this client is posted.
- uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- if (!BufferHubDefs::isClientPosted(current_buffer_state,
- client_state_mask())) {
- ALOGE(
- "%s: Failed to acquire the buffer. The buffer is not posted, id=%d "
- "state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
- __FUNCTION__, id(), current_buffer_state, client_state_mask());
- return -EBUSY;
- }
-
- // Change the buffer state for this consumer from posted to acquired.
- uint32_t updated_buffer_state = current_buffer_state ^ client_state_mask();
- while (!buffer_state_->compare_exchange_weak(
- current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
- std::memory_order_acquire)) {
- if (!BufferHubDefs::isClientPosted(current_buffer_state,
- client_state_mask())) {
- ALOGE(
- "%s: Failed to acquire the buffer. The buffer is no longer posted, "
- "id=%d state=%" PRIx32 " client_state_mask=%" PRIx32 ".",
- __FUNCTION__, id(), current_buffer_state, client_state_mask());
- return -EBUSY;
- }
- // The failure of compare_exchange_weak updates current_buffer_state.
- updated_buffer_state = current_buffer_state ^ client_state_mask();
- }
-
- // Copy the canonical metadata.
- void* metadata_ptr = reinterpret_cast<void*>(&metadata_header_->metadata);
- memcpy(out_meta, metadata_ptr, sizeof(DvrNativeBufferMetadata));
- // Fill in the user_metadata_ptr in address space of the local process.
- if (out_meta->user_metadata_size) {
- out_meta->user_metadata_ptr =
- reinterpret_cast<uint64_t>(user_metadata_ptr_);
- } else {
- out_meta->user_metadata_ptr = 0;
- }
-
- uint32_t fence_state = fence_state_->load(std::memory_order_acquire);
- // If there is an acquire fence from producer, we need to return it.
- // The producer state bit mask is kFirstClientBitMask for now.
- if (fence_state & BufferHubDefs::kFirstClientBitMask) {
- *out_fence = shared_acquire_fence_.Duplicate();
- }
-
- return 0;
-}
-
-int ConsumerBuffer::Acquire(LocalHandle* ready_fence) {
- return Acquire(ready_fence, nullptr, 0);
-}
-
-int ConsumerBuffer::Acquire(LocalHandle* ready_fence, void* meta,
- size_t user_metadata_size) {
- ATRACE_NAME("ConsumerBuffer::Acquire");
-
- if (const int error = CheckMetadata(user_metadata_size))
- return error;
-
- DvrNativeBufferMetadata canonical_meta;
- if (const int error = LocalAcquire(&canonical_meta, ready_fence))
- return error;
-
- 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("ConsumerBuffer::Acquire: no user-defined metadata.");
- }
- }
-
- auto status = InvokeRemoteMethod<BufferHubRPC::ConsumerAcquire>();
- if (!status)
- return -status.error();
- return 0;
-}
-
-int ConsumerBuffer::AcquireAsync(DvrNativeBufferMetadata* out_meta,
- LocalHandle* out_fence) {
- ATRACE_NAME("ConsumerBuffer::AcquireAsync");
-
- if (const int error = LocalAcquire(out_meta, out_fence))
- return error;
-
- auto status = SendImpulse(BufferHubRPC::ConsumerAcquire::Opcode);
- if (!status)
- return -status.error();
- return 0;
-}
-
-int ConsumerBuffer::LocalRelease(const DvrNativeBufferMetadata* meta,
- const LocalHandle& release_fence) {
- if (const int error = CheckMetadata(meta->user_metadata_size))
- return error;
-
- // Set the buffer state of this client to released if it is not already in
- // released state.
- uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- if (BufferHubDefs::isClientReleased(current_buffer_state,
- client_state_mask())) {
- return 0;
- }
- uint32_t updated_buffer_state = current_buffer_state & (~client_state_mask());
- while (!buffer_state_->compare_exchange_weak(
- current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
- std::memory_order_acquire)) {
- // The failure of compare_exchange_weak updates current_buffer_state.
- updated_buffer_state = current_buffer_state & (~client_state_mask());
- }
-
- // On release, only the user requested metadata is copied back into the shared
- // memory for metadata. Since there are multiple consumers, it doesn't make
- // sense to send the canonical metadata back to the producer. However, one of
- // the consumer can still choose to write up to user_metadata_size bytes of
- // data into user_metadata_ptr.
- if (meta->user_metadata_ptr && meta->user_metadata_size) {
- void* metadata_src = reinterpret_cast<void*>(meta->user_metadata_ptr);
- memcpy(user_metadata_ptr_, metadata_src, meta->user_metadata_size);
- }
-
- // Send out the release fence through the shared epoll fd. Note that during
- // releasing the producer is not expected to be polling on the fence.
- if (const int error = UpdateSharedFence(release_fence, shared_release_fence_))
- return error;
-
- return 0;
-}
-
-int ConsumerBuffer::Release(const LocalHandle& release_fence) {
- ATRACE_NAME("ConsumerBuffer::Release");
-
- DvrNativeBufferMetadata meta;
- if (const int error = LocalRelease(&meta, release_fence))
- return error;
-
- return ReturnStatusOrError(InvokeRemoteMethod<BufferHubRPC::ConsumerRelease>(
- BorrowedFence(release_fence.Borrow())));
-}
-
-int ConsumerBuffer::ReleaseAsync() {
- DvrNativeBufferMetadata meta;
- return ReleaseAsync(&meta, LocalHandle());
-}
-
-int ConsumerBuffer::ReleaseAsync(const DvrNativeBufferMetadata* meta,
- const LocalHandle& release_fence) {
- ATRACE_NAME("ConsumerBuffer::ReleaseAsync");
-
- if (const int error = LocalRelease(meta, release_fence))
- return error;
-
- return ReturnStatusOrError(
- SendImpulse(BufferHubRPC::ConsumerRelease::Opcode));
-}
-
-int ConsumerBuffer::Discard() { return Release(LocalHandle()); }
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
deleted file mode 100644
index 8a490d9..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ /dev/null
@@ -1,169 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_BASE_H_
-#define ANDROID_DVR_BUFFER_HUB_BASE_H_
-
-#include <vector>
-
-#include <private/dvr/bufferhub_rpc.h>
-
-namespace android {
-namespace dvr {
-
-// Base class of two types of BufferHub clients: dvr::ProducerBuffer and
-// dvr::ConsumerBuffer.
-class BufferHubBase : public pdx::Client {
- public:
- using LocalHandle = pdx::LocalHandle;
- using LocalChannelHandle = pdx::LocalChannelHandle;
- template <typename T>
- using Status = pdx::Status<T>;
-
- // Create a new consumer channel that is attached to the producer. Returns
- // a file descriptor for the new channel or a negative error code.
- Status<LocalChannelHandle> CreateConsumer();
-
- // Gets a blob buffer that was created with ProducerBuffer::CreateBlob.
- // Locking and Unlocking is handled internally. There's no need to Unlock
- // after calling this method.
- int GetBlobReadWritePointer(size_t size, void** addr);
-
- // Returns a dup'd file descriptor for accessing the blob shared memory. The
- // caller takes ownership of the file descriptor and must close it or pass on
- // ownership. Some GPU API extensions can take file descriptors to bind shared
- // memory gralloc buffers to GPU buffer objects.
- LocalHandle GetBlobFd() const {
- // Current GPU vendor puts the buffer allocation in one FD. If we change GPU
- // vendors and this is the wrong fd, late-latching and EDS will very clearly
- // stop working and we will need to correct this. The alternative is to use
- // a GL context in the pose service to allocate this buffer or to use the
- // ION API directly instead of gralloc.
- return LocalHandle(dup(native_handle()->data[0]));
- }
-
- using Client::event_fd;
-
- Status<int> GetEventMask(int events) {
- if (auto* client_channel = GetChannel()) {
- return client_channel->GetEventMask(events);
- } else {
- return pdx::ErrorStatus(EINVAL);
- }
- }
-
- std::vector<pdx::ClientChannel::EventSource> GetEventSources() const {
- if (auto* client_channel = GetChannel()) {
- return client_channel->GetEventSources();
- } else {
- return {};
- }
- }
-
- native_handle_t* native_handle() const {
- return const_cast<native_handle_t*>(buffer_.handle());
- }
-
- IonBuffer* buffer() { return &buffer_; }
- const IonBuffer* buffer() const { return &buffer_; }
-
- // Gets ID of the buffer client. All BufferHub clients derived from the same
- // buffer in bufferhubd share the same buffer id.
- int id() const { return id_; }
-
- // Gets the channel id of the buffer client. Each BufferHub client has its
- // system unique channel id.
- int cid() const { return cid_; }
-
- // Returns the buffer buffer state.
- uint32_t buffer_state() {
- return buffer_state_->load(std::memory_order_acquire);
- };
-
- // Returns whether the buffer is already released by all current clients.
- bool is_released() {
- return (buffer_state() &
- active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
- }
-
- // A state mask which is unique to a buffer hub client among all its siblings
- // sharing the same concrete graphic buffer.
- uint32_t client_state_mask() const { return client_state_mask_; }
-
- // The following methods return settings of the first buffer. Currently,
- // it is only possible to create multi-buffer BufferHubBases with the same
- // settings.
- uint32_t width() const { return buffer_.width(); }
- uint32_t height() const { return buffer_.height(); }
- uint32_t stride() const { return buffer_.stride(); }
- uint32_t format() const { return buffer_.format(); }
- uint32_t usage() const { return buffer_.usage(); }
- uint32_t layer_count() const { return buffer_.layer_count(); }
-
- uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
- void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
-
- protected:
- explicit BufferHubBase(LocalChannelHandle channel);
- explicit BufferHubBase(const std::string& endpoint_path);
- virtual ~BufferHubBase();
-
- // Initialization helper.
- int ImportBuffer();
-
- // Check invalid metadata operation. Returns 0 if requested metadata is valid.
- int CheckMetadata(size_t user_metadata_size) const;
-
- // Send out the new fence by updating the shared fence (shared_release_fence
- // for producer and shared_acquire_fence for consumer). Note that during this
- // should only be used in LocalPost() or LocalRelease, and the shared fence
- // shouldn't be poll'ed by the other end.
- int UpdateSharedFence(const LocalHandle& new_fence,
- const LocalHandle& shared_fence);
-
- // Locks the area specified by (x, y, width, height) for a specific usage. If
- // the usage is software then |addr| will be updated to point to the address
- // of the buffer in virtual memory. The caller should only access/modify the
- // pixels in the specified area. anything else is undefined behavior.
- int Lock(int usage, int x, int y, int width, int height, void** addr);
-
- // Must be called after Lock() when the caller has finished changing the
- // buffer.
- int Unlock();
-
- // IonBuffer that is shared between bufferhubd, producer, and consumers.
- size_t metadata_buf_size_{0};
- size_t user_metadata_size_{0};
- BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
- void* user_metadata_ptr_ = nullptr;
- std::atomic<uint32_t>* buffer_state_ = nullptr;
- std::atomic<uint32_t>* fence_state_ = nullptr;
- std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
-
- LocalHandle shared_acquire_fence_;
- LocalHandle shared_release_fence_;
-
- // A local fence fd that holds the ownership of the fence fd on Post (for
- // producer) and Release (for consumer).
- LocalHandle pending_fence_fd_;
-
- private:
- BufferHubBase(const BufferHubBase&) = delete;
- void operator=(const BufferHubBase&) = delete;
-
- // Global id for the buffer that is consistent across processes. It is meant
- // for logging and debugging purposes only and should not be used for lookup
- // or any other functional purpose as a security precaution.
- int id_;
-
- // Channel id.
- int cid_;
-
- // Client bit mask which indicates the locations of this client object in the
- // buffer_state_.
- uint32_t client_state_mask_{0U};
- IonBuffer buffer_;
- IonBuffer metadata_buffer_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFER_HUB_BASE_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
deleted file mode 100644
index e610e18..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_defs.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_HUB_DEFS_H_
-#define ANDROID_DVR_BUFFER_HUB_DEFS_H_
-
-#include <dvr/dvr_api.h>
-#include <hardware/gralloc.h>
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <private/dvr/native_handle_wrapper.h>
-#include <ui/BufferHubDefs.h>
-
-namespace android {
-namespace dvr {
-
-namespace BufferHubDefs {
-
-static constexpr uint32_t kMetadataFormat = HAL_PIXEL_FORMAT_BLOB;
-static constexpr uint32_t kMetadataUsage =
- GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-
-// See more details in libs/ui/include/ui/BufferHubDefs.h
-static constexpr int kMaxNumberOfClients =
- android::BufferHubDefs::kMaxNumberOfClients;
-static constexpr uint32_t kLowbitsMask = android::BufferHubDefs::kLowbitsMask;
-static constexpr uint32_t kHighBitsMask = android::BufferHubDefs::kHighBitsMask;
-static constexpr uint32_t kFirstClientBitMask =
- android::BufferHubDefs::kFirstClientBitMask;
-
-static inline bool isAnyClientGained(uint32_t state) {
- return android::BufferHubDefs::isAnyClientGained(state);
-}
-
-static inline bool isClientGained(uint32_t state, uint32_t client_bit_mask) {
- return android::BufferHubDefs::isClientGained(state, client_bit_mask);
-}
-
-static inline bool isAnyClientPosted(uint32_t state) {
- return android::BufferHubDefs::isAnyClientPosted(state);
-}
-
-static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
- return android::BufferHubDefs::isClientPosted(state, client_bit_mask);
-}
-
-static inline bool isAnyClientAcquired(uint32_t state) {
- return android::BufferHubDefs::isAnyClientAcquired(state);
-}
-
-static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
- return android::BufferHubDefs::isClientAcquired(state, client_bit_mask);
-}
-
-static inline bool isClientReleased(uint32_t state, uint32_t client_bit_mask) {
- return android::BufferHubDefs::isClientReleased(state, client_bit_mask);
-}
-
-// Returns the next available buffer client's client_state_masks.
-// @params union_bits. Union of all existing clients' client_state_masks.
-static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
- return android::BufferHubDefs::findNextAvailableClientStateMask(union_bits);
-}
-
-using MetadataHeader = android::BufferHubDefs::MetadataHeader;
-static constexpr size_t kMetadataHeaderSize =
- android::BufferHubDefs::kMetadataHeaderSize;
-
-} // namespace BufferHubDefs
-
-template <typename FileHandleType>
-class BufferTraits {
- public:
- BufferTraits() = default;
- BufferTraits(const native_handle_t* buffer_handle,
- const FileHandleType& metadata_handle, int id,
- uint32_t client_state_mask, uint64_t metadata_size,
- uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage, uint32_t stride,
- const FileHandleType& acquire_fence_fd,
- const FileHandleType& release_fence_fd)
- : id_(id),
- client_state_mask_(client_state_mask),
- metadata_size_(metadata_size),
- width_(width),
- height_(height),
- layer_count_(layer_count),
- format_(format),
- usage_(usage),
- stride_(stride),
- buffer_handle_(buffer_handle),
- metadata_handle_(metadata_handle.Borrow()),
- acquire_fence_fd_(acquire_fence_fd.Borrow()),
- release_fence_fd_(release_fence_fd.Borrow()) {}
-
- BufferTraits(BufferTraits&& other) = default;
- BufferTraits& operator=(BufferTraits&& other) = default;
-
- // ID of the buffer client. All BufferHubBuffer clients derived from the same
- // buffer in bufferhubd share the same buffer id.
- int id() const { return id_; }
-
- // State mask of the buffer client. Each BufferHubBuffer client backed by the
- // same buffer channel has uniqued state bit among its siblings. For a
- // producer buffer the bit must be kFirstClientBitMask; for a consumer the bit
- // must be one of the kConsumerStateMask.
- uint32_t client_state_mask() const { return client_state_mask_; }
- uint64_t metadata_size() const { return metadata_size_; }
-
- uint32_t width() { return width_; }
- uint32_t height() { return height_; }
- uint32_t layer_count() { return layer_count_; }
- uint32_t format() { return format_; }
- uint64_t usage() { return usage_; }
- uint32_t stride() { return stride_; }
-
- const NativeHandleWrapper<FileHandleType>& buffer_handle() const {
- return buffer_handle_;
- }
-
- NativeHandleWrapper<FileHandleType> take_buffer_handle() {
- return std::move(buffer_handle_);
- }
- FileHandleType take_metadata_handle() { return std::move(metadata_handle_); }
- FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
- FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
-
- private:
- // BufferHub specific traits.
- int id_ = -1;
- uint32_t client_state_mask_;
- uint64_t metadata_size_;
-
- // Traits for a GraphicBuffer.
- uint32_t width_;
- uint32_t height_;
- uint32_t layer_count_;
- uint32_t format_;
- uint64_t usage_;
- uint32_t stride_;
-
- // Native handle for the graphic buffer.
- NativeHandleWrapper<FileHandleType> buffer_handle_;
-
- // File handle of an ashmem that holds buffer metadata.
- FileHandleType metadata_handle_;
-
- // Pamameters for shared fences.
- FileHandleType acquire_fence_fd_;
- FileHandleType release_fence_fd_;
-
- PDX_SERIALIZABLE_MEMBERS(BufferTraits<FileHandleType>, id_,
- client_state_mask_, metadata_size_, stride_, width_,
- height_, layer_count_, format_, usage_,
- buffer_handle_, metadata_handle_, acquire_fence_fd_,
- release_fence_fd_);
-
- BufferTraits(const BufferTraits&) = delete;
- void operator=(const BufferTraits&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFER_HUB_DEFS_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
deleted file mode 100644
index f1cd0b4..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ /dev/null
@@ -1,377 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUB_RPC_H_
-#define ANDROID_DVR_BUFFERHUB_RPC_H_
-
-#include "buffer_hub_defs.h"
-
-#include <cutils/native_handle.h>
-#include <ui/BufferQueueDefs.h>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <private/dvr/ion_buffer.h>
-
-namespace android {
-namespace dvr {
-
-template <typename FileHandleType>
-class NativeBufferHandle {
- public:
- NativeBufferHandle() { Clear(); }
- NativeBufferHandle(const IonBuffer& buffer, int id)
- : id_(id),
- stride_(buffer.stride()),
- width_(buffer.width()),
- height_(buffer.height()),
- layer_count_(buffer.layer_count()),
- format_(buffer.format()),
- usage_(buffer.usage()) {
- // Populate the fd and int vectors: native_handle->data[] is an array of fds
- // followed by an array of opaque ints.
- const int fd_count = buffer.handle()->numFds;
- const int int_count = buffer.handle()->numInts;
- for (int i = 0; i < fd_count; i++) {
- fds_.emplace_back(FileHandleType::AsDuplicate(buffer.handle()->data[i]));
- }
- for (int i = 0; i < int_count; i++) {
- opaque_ints_.push_back(buffer.handle()->data[fd_count + i]);
- }
- }
- NativeBufferHandle(NativeBufferHandle&& other) noexcept = default;
- NativeBufferHandle& operator=(NativeBufferHandle&& other) noexcept = default;
-
- // Imports the native handle into the given IonBuffer instance.
- int Import(IonBuffer* buffer) {
- // This is annoying, but we need to convert the vector of FileHandles into a
- // vector of ints for the Import API.
- std::vector<int> fd_ints;
- for (const auto& fd : fds_)
- fd_ints.push_back(fd.Get());
-
- const int ret =
- buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
- opaque_ints_.size(), width_, height_, layer_count_,
- stride_, format_, usage_);
- if (ret < 0)
- return ret;
-
- // Import succeeded, release the file handles which are now owned by the
- // IonBuffer and clear members.
- for (auto& fd : fds_)
- fd.Release();
- opaque_ints_.clear();
- Clear();
-
- return 0;
- }
-
- int id() const { return id_; }
- size_t IntCount() const { return opaque_ints_.size(); }
- size_t FdCount() const { return fds_.size(); }
-
- private:
- int id_;
- uint32_t stride_;
- uint32_t width_;
- uint32_t height_;
- uint32_t layer_count_;
- uint32_t format_;
- uint64_t usage_;
- std::vector<int> opaque_ints_;
- std::vector<FileHandleType> fds_;
-
- void Clear() {
- id_ = -1;
- stride_ = width_ = height_ = format_ = usage_ = 0;
- }
-
- PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
- width_, height_, layer_count_, format_, usage_,
- opaque_ints_, fds_);
-
- NativeBufferHandle(const NativeBufferHandle&) = delete;
- void operator=(const NativeBufferHandle&) = delete;
-};
-
-template <typename FileHandleType>
-class BufferDescription {
- public:
- BufferDescription() = default;
- BufferDescription(const IonBuffer& buffer, const IonBuffer& metadata, int id,
- int buffer_cid, uint32_t client_state_mask,
- const FileHandleType& acquire_fence_fd,
- const FileHandleType& release_fence_fd)
- : id_(id),
- buffer_cid_(buffer_cid),
- client_state_mask_(client_state_mask),
- buffer_(buffer, id),
- metadata_(metadata, id),
- acquire_fence_fd_(acquire_fence_fd.Borrow()),
- release_fence_fd_(release_fence_fd.Borrow()) {}
-
- BufferDescription(BufferDescription&& other) noexcept = default;
- BufferDescription& operator=(BufferDescription&& other) noexcept = default;
-
- // ID of the buffer client. All BufferHub clients derived from the same buffer
- // in bufferhubd share the same buffer id.
- int id() const { return id_; }
-
- // Channel ID of the buffer client. Each BufferHub client has its system
- // unique channel id.
- int buffer_cid() const { return buffer_cid_; }
-
- // State mask of the buffer client. Each BufferHub client backed by the
- // same buffer channel has uniqued state bit among its siblings.
- uint32_t client_state_mask() const { return client_state_mask_; }
- FileHandleType take_acquire_fence() { return std::move(acquire_fence_fd_); }
- FileHandleType take_release_fence() { return std::move(release_fence_fd_); }
-
- int ImportBuffer(IonBuffer* buffer) { return buffer_.Import(buffer); }
- int ImportMetadata(IonBuffer* metadata) { return metadata_.Import(metadata); }
-
- private:
- int id_{-1};
- int buffer_cid_{-1};
- uint32_t client_state_mask_{0U};
- // Two IonBuffers: one for the graphic buffer and one for metadata.
- NativeBufferHandle<FileHandleType> buffer_;
- NativeBufferHandle<FileHandleType> metadata_;
-
- // Pamameters for shared fences.
- FileHandleType acquire_fence_fd_;
- FileHandleType release_fence_fd_;
-
- PDX_SERIALIZABLE_MEMBERS(BufferDescription<FileHandleType>, id_, buffer_cid_,
- client_state_mask_, buffer_, metadata_,
- acquire_fence_fd_, release_fence_fd_);
-
- BufferDescription(const BufferDescription&) = delete;
- void operator=(const BufferDescription&) = delete;
-};
-
-using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
-using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
-
-template <typename FileHandleType>
-class FenceHandle {
- public:
- FenceHandle() = default;
- explicit FenceHandle(int fence) : fence_{fence} {}
- explicit FenceHandle(FileHandleType&& fence) : fence_{std::move(fence)} {}
- FenceHandle(FenceHandle&&) noexcept = default;
- FenceHandle& operator=(FenceHandle&&) noexcept = default;
-
- explicit operator bool() const { return fence_.IsValid(); }
-
- const FileHandleType& get() const { fence_; }
- FileHandleType&& take() { return std::move(fence_); }
-
- int get_fd() const { return fence_.Get(); }
- void close() { fence_.Close(); }
-
- FenceHandle<pdx::BorrowedHandle> borrow() const {
- return FenceHandle<pdx::BorrowedHandle>(fence_.Borrow());
- }
-
- private:
- FileHandleType fence_;
-
- PDX_SERIALIZABLE_MEMBERS(FenceHandle<FileHandleType>, fence_);
-
- FenceHandle(const FenceHandle&) = delete;
- void operator=(const FenceHandle&) = delete;
-};
-
-using LocalFence = FenceHandle<pdx::LocalHandle>;
-using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
-
-struct ProducerQueueConfig {
- // 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;
-
- // Default buffer width that is set during ProducerQueue's creation.
- uint32_t default_width;
-
- // Default buffer height that is set during ProducerQueue's creation.
- uint32_t default_height;
-
- // Default buffer format that is set during ProducerQueue's creation.
- uint32_t default_format;
-
- // Size of the meta data associated with all the buffers allocated from the
- // queue.
- size_t user_metadata_size;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width,
- default_height, default_format, user_metadata_size);
-};
-
-class ProducerQueueConfigBuilder {
- public:
- // Build a ProducerQueueConfig object.
- ProducerQueueConfig Build() {
- return {is_async_, default_width_, default_height_, default_format_,
- user_metadata_size_};
- }
-
- ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
- is_async_ = is_async;
- return *this;
- }
-
- ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
- default_width_ = width;
- return *this;
- }
-
- ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
- default_height_ = height;
- return *this;
- }
-
- ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
- default_format_ = format;
- return *this;
- }
-
- template <typename Meta>
- ProducerQueueConfigBuilder& SetMetadata() {
- user_metadata_size_ = sizeof(Meta);
- return *this;
- }
-
- ProducerQueueConfigBuilder& SetMetadataSize(size_t user_metadata_size) {
- user_metadata_size_ = user_metadata_size;
- return *this;
- }
-
- private:
- bool is_async_{false};
- uint32_t default_width_{1};
- uint32_t default_height_{1};
- uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888
- size_t user_metadata_size_{0};
-};
-
-// Explicit specializations of ProducerQueueConfigBuilder::Build for void
-// metadata type.
-template <>
-inline ProducerQueueConfigBuilder&
-ProducerQueueConfigBuilder::SetMetadata<void>() {
- user_metadata_size_ = 0;
- return *this;
-}
-
-struct QueueInfo {
- ProducerQueueConfig producer_config;
- int id;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(QueueInfo, producer_config, id);
-};
-
-struct UsagePolicy {
- uint64_t usage_set_mask{0};
- uint64_t usage_clear_mask{0};
- uint64_t usage_deny_set_mask{0};
- uint64_t usage_deny_clear_mask{0};
-
- private:
- PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
-};
-
-// BufferHub Service RPC interface. Defines the endpoints, op codes, and method
-// type signatures supported by bufferhubd.
-struct BufferHubRPC {
- // Service path.
- static constexpr char kClientPath[] = "system/buffer_hub/client";
-
- // |BufferHubQueue| will keep track of at most this value of buffers.
- // Attempts at runtime to increase the number of buffers past this
- // will fail. Note that the value is in sync with |android::BufferQueue|, so
- // that slot id can be shared between |android::dvr::BufferHubQueueProducer|
- // and |android::BufferQueueProducer| which both implements the same
- // interface: |android::IGraphicBufferProducer|.
- static constexpr size_t kMaxQueueCapacity =
- android::BufferQueueDefs::NUM_BUFFER_SLOTS;
-
- // Op codes.
- enum {
- kOpCreateBuffer = 0,
- kOpGetBuffer,
- kOpNewConsumer,
- kOpProducerPost,
- kOpProducerGain,
- kOpConsumerAcquire,
- kOpConsumerRelease,
- kOpConsumerBufferDetach,
- kOpCreateProducerQueue,
- kOpCreateConsumerQueue,
- kOpGetQueueInfo,
- kOpProducerQueueAllocateBuffers,
- kOpProducerQueueInsertBuffer,
- kOpProducerQueueRemoveBuffer,
- kOpConsumerQueueImportBuffers,
- // TODO(b/77153033): Separate all those RPC operations into subclasses.
- };
-
- // Aliases.
- using LocalChannelHandle = pdx::LocalChannelHandle;
- using LocalHandle = pdx::LocalHandle;
- using Void = pdx::rpc::Void;
-
- // Methods.
- PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
- void(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t user_metadata_size));
- PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
- BufferDescription<LocalHandle>(Void));
- PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
- PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
- void(LocalFence acquire_fence));
- PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
- PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire, LocalFence(Void));
- PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
- void(LocalFence release_fence));
-
- // Detaches a ConsumerBuffer from an existing producer/consumer set. Can only
- // be called when the consumer is the only consumer and it has exclusive
- // access to the buffer (i.e. in the acquired'ed state). On the successful
- // return of the IPC call, a new DetachedBufferChannel handle will be returned
- // and all existing producer and consumer channels will be closed. Further
- // IPCs towards those channels will return error.
- PDX_REMOTE_METHOD(ConsumerBufferDetach, kOpConsumerBufferDetach,
- LocalChannelHandle(Void));
-
- // Buffer Queue Methods.
- PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
- QueueInfo(const ProducerQueueConfig& producer_config,
- const UsagePolicy& usage_policy));
- PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
- LocalChannelHandle(bool silent_queue));
- PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
- PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
- kOpProducerQueueAllocateBuffers,
- std::vector<std::pair<LocalChannelHandle, size_t>>(
- uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage, size_t buffer_count));
- PDX_REMOTE_METHOD(ProducerQueueInsertBuffer, kOpProducerQueueInsertBuffer,
- size_t(int buffer_cid));
- PDX_REMOTE_METHOD(ProducerQueueRemoveBuffer, kOpProducerQueueRemoveBuffer,
- void(size_t slot));
- PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
- std::vector<std::pair<LocalChannelHandle, size_t>>(Void));
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUB_RPC_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
deleted file mode 100644
index 726f035..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_DVR_CONSUMER_BUFFER_H_
-#define ANDROID_DVR_CONSUMER_BUFFER_H_
-
-#include <private/dvr/buffer_hub_base.h>
-
-namespace android {
-namespace dvr {
-
-// This is a connection to a producer buffer, which can be located in another
-// application. When that buffer is Post()ed, this fd will be signaled and
-// Acquire allows read access. The user is responsible for making sure that
-// Acquire is called with the correct metadata structure. The only guarantee the
-// API currently provides is that an Acquire() with metadata of the wrong size
-// will fail.
-class ConsumerBuffer : public pdx::ClientBase<ConsumerBuffer, BufferHubBase> {
- public:
- // This call assumes ownership of |fd|.
- static std::unique_ptr<ConsumerBuffer> Import(LocalChannelHandle channel);
- static std::unique_ptr<ConsumerBuffer> Import(
- Status<LocalChannelHandle> status);
-
- // Attempt to retrieve a post event from buffer hub. If successful,
- // |ready_fence| will be set to a fence to wait on until the buffer is ready.
- // This call will only succeed after the fd is signalled. This call may be
- // performed as an alternative to the Acquire() with metadata. In such cases
- // the metadata is not read.
- //
- // This returns zero or negative unix error code.
- int Acquire(LocalHandle* ready_fence);
-
- // Attempt to retrieve a post event from buffer hub. If successful,
- // |ready_fence| is set to a fence signaling that the contents of the buffer
- // are available. This call will only succeed if the buffer is in the posted
- // state.
- // Returns zero on success, or a negative errno code otherwise.
- int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size);
-
- // Asynchronously acquires a bufer.
- int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
-
- // Releases the buffer from any buffer state. If the fence is valid the fence
- // determines the buffer usage, otherwise the buffer is released immediately.
- // This returns zero or a negative unix error code.
- int Release(const LocalHandle& release_fence);
- int ReleaseAsync();
-
- // Asynchronously releases a buffer. Similar to the synchronous version above,
- // except that it does not wait for BufferHub to reply with success or error.
- // The fence and metadata are passed to consumer via shared fd and shared
- // memory.
- int ReleaseAsync(const DvrNativeBufferMetadata* meta,
- const LocalHandle& release_fence);
-
- // May be called after or instead of Acquire to indicate that the consumer
- // does not need to access the buffer this cycle. This returns zero or a
- // negative unix error code.
- int Discard();
-
- private:
- friend BASE;
-
- explicit ConsumerBuffer(LocalChannelHandle channel);
-
- // Local state transition helpers.
- int LocalAcquire(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
- int LocalRelease(const DvrNativeBufferMetadata* meta,
- const LocalHandle& release_fence);
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_CONSUMER_BUFFER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
deleted file mode 100644
index ed38e7f..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-#ifndef ANDROID_DVR_ION_BUFFER_H_
-#define ANDROID_DVR_ION_BUFFER_H_
-
-#include <hardware/gralloc.h>
-#include <log/log.h>
-#include <ui/GraphicBuffer.h>
-
-namespace android {
-namespace dvr {
-
-// IonBuffer is an abstraction of Ion/Gralloc buffers.
-class IonBuffer {
- public:
- IonBuffer();
- IonBuffer(uint32_t width, uint32_t height, uint32_t format, uint64_t usage);
- IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage);
- IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage);
- ~IonBuffer();
-
- IonBuffer(IonBuffer&& other) noexcept;
- IonBuffer& operator=(IonBuffer&& other) noexcept;
-
- // Returns check this IonBuffer holds a valid Gralloc buffer.
- bool IsValid() const { return buffer_ && buffer_->initCheck() == OK; }
-
- // Frees the underlying native handle and leaves the instance initialized to
- // empty.
- void FreeHandle();
-
- // Allocates a new native handle with the given parameters, freeing the
- // previous native handle if necessary. Returns 0 on success or a negative
- // errno code otherwise. If allocation fails the previous native handle is
- // left intact.
- int Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage);
-
- // Resets the underlying native handle and parameters, freeing the previous
- // native handle if necessary.
- void Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage);
-
- // Like Reset but also registers the native handle, which is necessary for
- // native handles received over IPC. Returns 0 on success or a negative errno
- // code otherwise. If import fails the previous native handle is left intact.
- int Import(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage);
-
- // Like Reset but imports a native handle from raw fd and int arrays. Returns
- // 0 on success or a negative errno code otherwise. If import fails the
- // previous native handle is left intact.
- int Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage);
-
- // Duplicates the native handle underlying |other| and then imports it. This
- // is useful for creating multiple, independent views of the same Ion/Gralloc
- // buffer. Returns 0 on success or a negative errno code otherwise. If
- // duplication or import fail the previous native handle is left intact.
- int Duplicate(const IonBuffer* other);
-
- int Lock(uint32_t usage, int x, int y, int width, int height, void** address);
- int LockYUV(uint32_t usage, int x, int y, int width, int height,
- struct android_ycbcr* yuv);
- int Unlock();
-
- sp<GraphicBuffer>& buffer() { return buffer_; }
- const sp<GraphicBuffer>& buffer() const { return buffer_; }
- buffer_handle_t handle() const {
- return buffer_.get() ? buffer_->handle : nullptr;
- }
- uint32_t width() const { return buffer_.get() ? buffer_->getWidth() : 0; }
- uint32_t height() const { return buffer_.get() ? buffer_->getHeight() : 0; }
- uint32_t layer_count() const {
- return buffer_.get() ? buffer_->getLayerCount() : 0;
- }
- uint32_t stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
- uint32_t format() const {
- return buffer_.get() ? buffer_->getPixelFormat() : 0;
- }
- uint64_t usage() const {
- return buffer_.get() ? static_cast<uint64_t>(buffer_->getUsage()) : 0;
- }
-
- private:
- sp<GraphicBuffer> buffer_;
-
- IonBuffer(const IonBuffer&) = delete;
- void operator=(const IonBuffer&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_ION_BUFFER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h b/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
deleted file mode 100644
index a5c6ca2..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/native_handle_wrapper.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
-#define ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
-
-#include <cutils/native_handle.h>
-#include <log/log.h>
-#include <pdx/rpc/serializable.h>
-
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-// A PDX-friendly wrapper to maintain the life cycle of a native_handle_t
-// object.
-//
-// See https://source.android.com/devices/architecture/hidl/types#handle_t for
-// more information about native_handle_t.
-template <typename FileHandleType>
-class NativeHandleWrapper {
- public:
- NativeHandleWrapper() = default;
- NativeHandleWrapper(NativeHandleWrapper&& other) = default;
- NativeHandleWrapper& operator=(NativeHandleWrapper&& other) = default;
-
- // Create a new NativeHandleWrapper by duplicating the handle.
- explicit NativeHandleWrapper(const native_handle_t* handle) {
- const int fd_count = handle->numFds;
- const int int_count = handle->numInts;
-
- // Populate the fd and int vectors: native_handle->data[] is an array of fds
- // followed by an array of opaque ints.
- for (int i = 0; i < fd_count; i++) {
- fds_.emplace_back(FileHandleType::AsDuplicate(handle->data[i]));
- }
- for (int i = 0; i < int_count; i++) {
- ints_.push_back(handle->data[fd_count + i]);
- }
- }
-
- size_t int_count() const { return ints_.size(); }
- size_t fd_count() const { return fds_.size(); }
- bool IsValid() const { return ints_.size() != 0 || fds_.size() != 0; }
-
- // Duplicate a native handle from the wrapper.
- native_handle_t* DuplicateHandle() const {
- if (!IsValid()) {
- return nullptr;
- }
-
- // numFds + numInts ints.
- std::vector<FileHandleType> fds;
- for (const auto& fd : fds_) {
- if (!fd.IsValid()) {
- return nullptr;
- }
- fds.emplace_back(fd.Duplicate());
- }
-
- return FromFdsAndInts(std::move(fds), ints_);
- }
-
- // Takes the native handle out of the wrapper.
- native_handle_t* TakeHandle() {
- if (!IsValid()) {
- return nullptr;
- }
-
- return FromFdsAndInts(std::move(fds_), std::move(ints_));
- }
-
- private:
- NativeHandleWrapper(const NativeHandleWrapper&) = delete;
- void operator=(const NativeHandleWrapper&) = delete;
-
- static native_handle_t* FromFdsAndInts(std::vector<FileHandleType> fds,
- std::vector<int> ints) {
- native_handle_t* handle = native_handle_create(fds.size(), ints.size());
- if (!handle) {
- ALOGE("NativeHandleWrapper::TakeHandle: Failed to create new handle.");
- return nullptr;
- }
-
- // numFds + numInts ints.
- for (int i = 0; i < handle->numFds; i++) {
- handle->data[i] = fds[i].Release();
- }
- memcpy(&handle->data[handle->numFds], ints.data(),
- sizeof(int) * handle->numInts);
-
- return handle;
- }
-
- std::vector<int> ints_;
- std::vector<FileHandleType> fds_;
-
- PDX_SERIALIZABLE_MEMBERS(NativeHandleWrapper<FileHandleType>, ints_, fds_);
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_NATIVE_HANDLE_WRAPPER_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
deleted file mode 100644
index 7ec345c..0000000
--- a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifndef ANDROID_DVR_PRODUCER_BUFFER_H_
-#define ANDROID_DVR_PRODUCER_BUFFER_H_
-
-#include <private/dvr/buffer_hub_base.h>
-
-namespace android {
-namespace dvr {
-
-// This represents a writable buffer. Calling Post notifies all clients and
-// makes the buffer read-only. Call Gain to acquire write access. A buffer
-// may have many consumers.
-//
-// The user of ProducerBuffer is responsible with making sure that the Post() is
-// done with the correct metadata type and size. The user is also responsible
-// for making sure that remote ends (ConsumerBuffers) are also using the correct
-// metadata when acquiring the buffer. The API guarantees that a Post() with a
-// metadata of wrong size will fail. However, it currently does not do any
-// type checking.
-// The API also assumes that metadata is a serializable type (plain old data).
-class ProducerBuffer : public pdx::ClientBase<ProducerBuffer, BufferHubBase> {
- public:
- // Imports a bufferhub producer channel, assuming ownership of its handle.
- static std::unique_ptr<ProducerBuffer> Import(LocalChannelHandle channel);
- static std::unique_ptr<ProducerBuffer> Import(
- Status<LocalChannelHandle> status);
-
- // Asynchronously posts a buffer. The fence and metadata are passed to
- // consumer via shared fd and shared memory.
- int PostAsync(const DvrNativeBufferMetadata* meta,
- const LocalHandle& ready_fence);
-
- // Post this buffer, passing |ready_fence| to the consumers. The bytes in
- // |meta| are passed unaltered to the consumers. The producer must not modify
- // the buffer until it is re-gained.
- // This returns zero or a negative unix error code.
- int Post(const LocalHandle& ready_fence, const void* meta,
- size_t user_metadata_size);
-
- int Post(const LocalHandle& ready_fence) {
- return Post(ready_fence, nullptr, 0);
- }
-
- // Attempt to re-gain the buffer for writing. If |release_fence| is valid, it
- // must be waited on before using the buffer. If it is not valid then the
- // buffer is free for immediate use. This call will succeed if the buffer
- // is in the released state, or in posted state and gain_posted_buffer is
- // true.
- //
- // @param release_fence output fence.
- // @param gain_posted_buffer whether to gain posted buffer or not.
- // @return This returns zero or a negative unix error code.
- int Gain(LocalHandle* release_fence, bool gain_posted_buffer = false);
-
- // Asynchronously marks a released buffer as gained. This method is similar to
- // the synchronous version above, except that it does not wait for BufferHub
- // to acknowledge success or failure. Because of the asynchronous nature of
- // the underlying message, no error is returned if this method is called when
- // the buffer is in an incorrect state. Returns zero if sending the message
- // succeeded, or a negative errno code if local error check fails.
- // 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.
- int GainAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
- bool gain_posted_buffer = false);
- int GainAsync();
-
- // Detaches a ProducerBuffer from an existing producer/consumer set. Can only
- // be called when a producer buffer has exclusive access to the buffer (i.e.
- // in the gain'ed state). On the successful return of the IPC call, a new
- // LocalChannelHandle representing a detached buffer will be returned and all
- // existing producer and consumer channels will be closed. Further IPCs
- // towards those channels will return error.
- Status<LocalChannelHandle> Detach();
-
- private:
- friend BASE;
-
- // Constructors are automatically exposed through ProducerBuffer::Create(...)
- // static template methods inherited from ClientBase, which take the same
- // arguments as the constructors.
-
- // Constructs a buffer with the given geometry and parameters.
- ProducerBuffer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t metadata_size = 0);
-
- // Constructs a blob (flat) buffer with the given usage flags.
- ProducerBuffer(uint64_t usage, size_t size);
-
- // Imports the given file handle to a producer channel, taking ownership.
- explicit ProducerBuffer(LocalChannelHandle channel);
-
- // Local state transition helpers.
- int LocalGain(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence,
- bool gain_posted_buffer = false);
- int LocalPost(const DvrNativeBufferMetadata* meta,
- const LocalHandle& ready_fence);
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PRODUCER_BUFFER_H_
diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp
deleted file mode 100644
index 1965410..0000000
--- a/libs/vr/libbufferhub/ion_buffer.cpp
+++ /dev/null
@@ -1,240 +0,0 @@
-#include <private/dvr/ion_buffer.h>
-
-#include <log/log.h>
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Trace.h>
-
-#include <mutex>
-
-namespace {
-
-constexpr uint32_t kDefaultGraphicBufferLayerCount = 1;
-
-} // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0) {}
-
-IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage)
- : IonBuffer() {
- Alloc(width, height, kDefaultGraphicBufferLayerCount, format, usage);
-}
-
-IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage)
- : IonBuffer(handle, width, height, kDefaultGraphicBufferLayerCount, stride,
- format, usage) {}
-
-IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage)
- : buffer_(nullptr) {
- ALOGD_IF(TRACE,
- "IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u "
- "stride=%u format=%u usage=%" PRIx64,
- handle, width, height, layer_count, stride, format, usage);
- if (handle != 0) {
- Import(handle, width, height, layer_count, stride, format, usage);
- }
-}
-
-IonBuffer::~IonBuffer() {
- ALOGD_IF(TRACE,
- "IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u "
- "format=%u usage=%" PRIx64,
- handle(), width(), height(), stride(), format(), usage());
- FreeHandle();
-}
-
-IonBuffer::IonBuffer(IonBuffer&& other) noexcept : IonBuffer() {
- *this = std::move(other);
-}
-
-IonBuffer& IonBuffer::operator=(IonBuffer&& other) noexcept {
- ALOGD_IF(TRACE, "IonBuffer::operator=: handle_=%p other.handle_=%p", handle(),
- other.handle());
-
- if (this != &other) {
- buffer_ = other.buffer_;
- other.FreeHandle();
- }
- return *this;
-}
-
-void IonBuffer::FreeHandle() {
- if (buffer_.get()) {
- // GraphicBuffer unregisters and cleans up the handle if needed
- buffer_ = nullptr;
- }
-}
-
-int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage) {
- ALOGD_IF(TRACE,
- "IonBuffer::Alloc: width=%u height=%u layer_count=%u format=%u "
- "usage=%" PRIx64, width, height, layer_count, format, usage);
-
- sp<GraphicBuffer> buffer =
- new GraphicBuffer(width, height, format, layer_count, usage);
- if (buffer->initCheck() != OK) {
- ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
- return -EINVAL;
- } else {
- buffer_ = buffer;
- return 0;
- }
-}
-
-void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage) {
- ALOGD_IF(TRACE,
- "IonBuffer::Reset: handle=%p width=%u height=%u layer_count=%u "
- "stride=%u format=%u usage=%" PRIx64,
- handle, width, height, layer_count, stride, format, usage);
- Import(handle, width, height, layer_count, stride, format, usage);
-}
-
-int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage) {
- ATRACE_NAME("IonBuffer::Import1");
- ALOGD_IF(TRACE,
- "IonBuffer::Import: handle=%p width=%u height=%u layer_count=%u "
- "stride=%u format=%u usage=%" PRIx64,
- handle, width, height, layer_count, stride, format, usage);
- FreeHandle();
- sp<GraphicBuffer> buffer =
- new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width,
- height, format, layer_count, usage, stride);
- if (buffer->initCheck() != OK) {
- ALOGE("IonBuffer::Import: Failed to import buffer");
- return -EINVAL;
- } else {
- buffer_ = buffer;
- return 0;
- }
-}
-
-int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t format,
- uint64_t usage) {
- ATRACE_NAME("IonBuffer::Import2");
- ALOGD_IF(TRACE,
- "IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u "
- "layer_count=%u stride=%u format=%u usage=%" PRIx64,
- fd_count, int_count, width, height, layer_count, stride, format,
- usage);
-
- if (fd_count < 0 || int_count < 0) {
- ALOGE("IonBuffer::Import: invalid arguments.");
- return -EINVAL;
- }
-
- native_handle_t* handle = native_handle_create(fd_count, int_count);
- if (!handle) {
- ALOGE("IonBuffer::Import: failed to create new native handle.");
- return -ENOMEM;
- }
-
- // Copy fd_array into the first part of handle->data and int_array right
- // after it.
- memcpy(handle->data, fd_array, sizeof(int) * fd_count);
- memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
-
- const int ret =
- Import(handle, width, height, layer_count, stride, format, usage);
- if (ret < 0) {
- ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
- strerror(-ret));
- native_handle_close(handle);
- native_handle_delete(handle);
- }
-
- return ret;
-}
-
-int IonBuffer::Duplicate(const IonBuffer* other) {
- if (!other->handle())
- return -EINVAL;
-
- const int fd_count = other->handle()->numFds;
- const int int_count = other->handle()->numInts;
-
- if (fd_count < 0 || int_count < 0)
- return -EINVAL;
-
- native_handle_t* handle = native_handle_create(fd_count, int_count);
- if (!handle) {
- ALOGE("IonBuffer::Duplicate: Failed to create new native handle.");
- return -ENOMEM;
- }
-
- // Duplicate the file descriptors from the other native handle.
- for (int i = 0; i < fd_count; i++)
- handle->data[i] = dup(other->handle()->data[i]);
-
- // Copy the ints after the file descriptors.
- memcpy(handle->data + fd_count, other->handle()->data + fd_count,
- sizeof(int) * int_count);
-
- const int ret =
- Import(handle, other->width(), other->height(), other->layer_count(),
- other->stride(), other->format(), other->usage());
- if (ret < 0) {
- ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
- strerror(-ret));
- native_handle_close(handle);
- native_handle_delete(handle);
- }
-
- return ret;
-}
-
-int IonBuffer::Lock(uint32_t usage, int x, int y, int width, int height,
- void** address) {
- ATRACE_NAME("IonBuffer::Lock");
- ALOGD_IF(TRACE,
- "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d "
- "address=%p",
- handle(), usage, x, y, width, height, address);
-
- status_t err =
- buffer_->lock(usage, Rect(x, y, x + width, y + height), address);
- if (err != OK)
- return -EINVAL;
- else
- return 0;
-}
-
-int IonBuffer::LockYUV(uint32_t usage, int x, int y, int width, int height,
- struct android_ycbcr* yuv) {
- ATRACE_NAME("IonBuffer::LockYUV");
- ALOGD_IF(TRACE,
- "IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
- handle(), usage, x, y, width, height);
-
- status_t err =
- buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height), yuv);
- if (err != OK)
- return -EINVAL;
- else
- return 0;
-}
-
-int IonBuffer::Unlock() {
- ATRACE_NAME("IonBuffer::Unlock");
- ALOGD_IF(TRACE, "IonBuffer::Unlock: handle=%p", handle());
-
- status_t err = buffer_->unlock();
- if (err != OK)
- return -EINVAL;
- else
- return 0;
-}
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
deleted file mode 100644
index aa9d072..0000000
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ /dev/null
@@ -1,296 +0,0 @@
-#include <private/dvr/producer_buffer.h>
-
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-
-namespace android {
-namespace dvr {
-
-ProducerBuffer::ProducerBuffer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t user_metadata_size)
- : BASE(BufferHubRPC::kClientPath) {
- ATRACE_NAME("ProducerBuffer::ProducerBuffer");
- ALOGD_IF(TRACE,
- "ProducerBuffer::ProducerBuffer: fd=%d width=%u height=%u format=%u "
- "usage=%" PRIx64 " user_metadata_size=%zu",
- event_fd(), width, height, format, usage, user_metadata_size);
-
- auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, usage, user_metadata_size);
- if (!status) {
- ALOGE(
- "ProducerBuffer::ProducerBuffer: Failed to create producer buffer: %s",
- status.GetErrorMessage().c_str());
- Close(-status.error());
- return;
- }
-
- const int ret = ImportBuffer();
- if (ret < 0) {
- ALOGE(
- "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
- strerror(-ret));
- Close(ret);
- }
-}
-
-ProducerBuffer::ProducerBuffer(uint64_t usage, size_t size)
- : BASE(BufferHubRPC::kClientPath) {
- ATRACE_NAME("ProducerBuffer::ProducerBuffer");
- ALOGD_IF(TRACE, "ProducerBuffer::ProducerBuffer: usage=%" PRIx64 " size=%zu",
- usage, size);
- const int width = static_cast<int>(size);
- const int height = 1;
- const int format = HAL_PIXEL_FORMAT_BLOB;
- const size_t user_metadata_size = 0;
-
- auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, usage, user_metadata_size);
- if (!status) {
- ALOGE("ProducerBuffer::ProducerBuffer: Failed to create blob: %s",
- status.GetErrorMessage().c_str());
- Close(-status.error());
- return;
- }
-
- const int ret = ImportBuffer();
- if (ret < 0) {
- ALOGE(
- "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
- strerror(-ret));
- Close(ret);
- }
-}
-
-ProducerBuffer::ProducerBuffer(LocalChannelHandle channel)
- : BASE(std::move(channel)) {
- const int ret = ImportBuffer();
- if (ret < 0) {
- ALOGE(
- "ProducerBuffer::ProducerBuffer: Failed to import producer buffer: %s",
- strerror(-ret));
- Close(ret);
- }
-}
-
-int ProducerBuffer::LocalPost(const DvrNativeBufferMetadata* meta,
- const LocalHandle& ready_fence) {
- if (const int error = CheckMetadata(meta->user_metadata_size))
- return error;
-
- // The buffer can be posted iff the buffer state for this client is gained.
- uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- if (!BufferHubDefs::isClientGained(current_buffer_state,
- client_state_mask())) {
- ALOGE("%s: not gained, id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
- current_buffer_state);
- return -EBUSY;
- }
-
- // Set the producer client buffer state to released, that of all other clients
- // (both existing and non-existing clients) to posted.
- uint32_t updated_buffer_state =
- (~client_state_mask()) & BufferHubDefs::kHighBitsMask;
- while (!buffer_state_->compare_exchange_weak(
- current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
- std::memory_order_acquire)) {
- if (!BufferHubDefs::isClientGained(current_buffer_state,
- client_state_mask())) {
- ALOGE(
- "%s: Failed to post the buffer. The buffer is no longer gained, "
- "id=%d state=%" PRIx32 ".",
- __FUNCTION__, id(), current_buffer_state);
- return -EBUSY;
- }
- }
-
- // Copy the canonical metadata.
- void* metadata_ptr = reinterpret_cast<void*>(&metadata_header_->metadata);
- memcpy(metadata_ptr, meta, sizeof(DvrNativeBufferMetadata));
- // Copy extra user requested metadata.
- if (meta->user_metadata_ptr && meta->user_metadata_size) {
- void* metadata_src = reinterpret_cast<void*>(meta->user_metadata_ptr);
- memcpy(user_metadata_ptr_, metadata_src, meta->user_metadata_size);
- }
-
- // Send out the acquire fence through the shared epoll fd. Note that during
- // posting no consumer is not expected to be polling on the fence.
- if (const int error = UpdateSharedFence(ready_fence, shared_acquire_fence_))
- return error;
-
- return 0;
-}
-
-int ProducerBuffer::Post(const LocalHandle& ready_fence, const void* meta,
- size_t user_metadata_size) {
- ATRACE_NAME("ProducerBuffer::Post");
-
- // Populate cononical metadata for posting.
- DvrNativeBufferMetadata canonical_meta;
- canonical_meta.user_metadata_ptr = reinterpret_cast<uint64_t>(meta);
- canonical_meta.user_metadata_size = user_metadata_size;
-
- if (const int error = LocalPost(&canonical_meta, ready_fence))
- return error;
-
- return ReturnStatusOrError(InvokeRemoteMethod<BufferHubRPC::ProducerPost>(
- BorrowedFence(ready_fence.Borrow())));
-}
-
-int ProducerBuffer::PostAsync(const DvrNativeBufferMetadata* meta,
- const LocalHandle& ready_fence) {
- ATRACE_NAME("ProducerBuffer::PostAsync");
-
- if (const int error = LocalPost(meta, ready_fence))
- return error;
-
- return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerPost::Opcode));
-}
-
-int ProducerBuffer::LocalGain(DvrNativeBufferMetadata* out_meta,
- LocalHandle* out_fence, bool gain_posted_buffer) {
- if (!out_meta)
- return -EINVAL;
-
- uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- ALOGD_IF(TRACE, "%s: buffer=%d, state=%" PRIx32 ".", __FUNCTION__, id(),
- current_buffer_state);
-
- if (BufferHubDefs::isClientGained(current_buffer_state,
- client_state_mask())) {
- ALOGV("%s: already gained id=%d.", __FUNCTION__, id());
- return 0;
- }
- if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
- BufferHubDefs::isAnyClientGained(current_buffer_state) ||
- (BufferHubDefs::isAnyClientPosted(
- current_buffer_state &
- active_clients_bit_mask_->load(std::memory_order_acquire)) &&
- !gain_posted_buffer)) {
- ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
- current_buffer_state);
- return -EBUSY;
- }
- // Change the buffer state to gained state.
- uint32_t updated_buffer_state = client_state_mask();
- while (!buffer_state_->compare_exchange_weak(
- current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
- std::memory_order_acquire)) {
- if (BufferHubDefs::isAnyClientAcquired(current_buffer_state) ||
- BufferHubDefs::isAnyClientGained(current_buffer_state) ||
- (BufferHubDefs::isAnyClientPosted(
- current_buffer_state &
- active_clients_bit_mask_->load(std::memory_order_acquire)) &&
- !gain_posted_buffer)) {
- ALOGE(
- "%s: Failed to gain the buffer. The buffer is no longer released. "
- "id=%d state=%" PRIx32 ".",
- __FUNCTION__, id(), current_buffer_state);
- return -EBUSY;
- }
- }
-
- // Canonical metadata is undefined on Gain. Except for user_metadata and
- // release_fence_mask. Fill in the user_metadata_ptr in address space of the
- // local process.
- if (metadata_header_->metadata.user_metadata_size && user_metadata_ptr_) {
- out_meta->user_metadata_size =
- metadata_header_->metadata.user_metadata_size;
- out_meta->user_metadata_ptr =
- reinterpret_cast<uint64_t>(user_metadata_ptr_);
- } else {
- out_meta->user_metadata_size = 0;
- out_meta->user_metadata_ptr = 0;
- }
-
- uint32_t current_fence_state = fence_state_->load(std::memory_order_acquire);
- uint32_t current_active_clients_bit_mask =
- active_clients_bit_mask_->load(std::memory_order_acquire);
- // If there are release fence(s) from consumer(s), we need to return it to the
- // consumer(s).
- // TODO(b/112007999) add an atomic variable in metadata header in shared
- // memory to indicate which client is the last producer of the buffer.
- // Currently, assume the first client is the only producer to the buffer.
- if (current_fence_state & current_active_clients_bit_mask &
- (~BufferHubDefs::kFirstClientBitMask)) {
- *out_fence = shared_release_fence_.Duplicate();
- out_meta->release_fence_mask = current_fence_state &
- current_active_clients_bit_mask &
- (~BufferHubDefs::kFirstClientBitMask);
- }
-
- return 0;
-}
-
-int ProducerBuffer::Gain(LocalHandle* release_fence, bool gain_posted_buffer) {
- ATRACE_NAME("ProducerBuffer::Gain");
-
- DvrNativeBufferMetadata meta;
- if (const int error = LocalGain(&meta, release_fence, gain_posted_buffer))
- return error;
-
- auto status = InvokeRemoteMethod<BufferHubRPC::ProducerGain>();
- if (!status)
- return -status.error();
- return 0;
-}
-
-int ProducerBuffer::GainAsync(DvrNativeBufferMetadata* out_meta,
- LocalHandle* release_fence,
- bool gain_posted_buffer) {
- ATRACE_NAME("ProducerBuffer::GainAsync");
-
- if (const int error = LocalGain(out_meta, release_fence, gain_posted_buffer))
- return error;
-
- return ReturnStatusOrError(SendImpulse(BufferHubRPC::ProducerGain::Opcode));
-}
-
-int ProducerBuffer::GainAsync() {
- DvrNativeBufferMetadata meta;
- LocalHandle fence;
- return GainAsync(&meta, &fence);
-}
-
-std::unique_ptr<ProducerBuffer> ProducerBuffer::Import(
- LocalChannelHandle channel) {
- ALOGD_IF(TRACE, "ProducerBuffer::Import: channel=%d", channel.value());
- return ProducerBuffer::Create(std::move(channel));
-}
-
-std::unique_ptr<ProducerBuffer> ProducerBuffer::Import(
- Status<LocalChannelHandle> status) {
- return Import(status ? status.take()
- : LocalChannelHandle{nullptr, -status.error()});
-}
-
-Status<LocalChannelHandle> ProducerBuffer::Detach() {
- // TODO(b/112338294) remove after migrate producer buffer to binder
- ALOGW("ProducerBuffer::Detach: not supported operation during migration");
- return {};
-
- // TODO(b/112338294) Keep here for reference. Remove it after new logic is
- // written.
- /* uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
- if (!BufferHubDefs::isClientGained(
- buffer_state, BufferHubDefs::kFirstClientStateMask)) {
- // Can only detach a ProducerBuffer when it's in gained state.
- ALOGW("ProducerBuffer::Detach: The buffer (id=%d, state=0x%" PRIx32
- ") is not in gained state.",
- id(), buffer_state);
- return {};
- }
-
- Status<LocalChannelHandle> status =
- InvokeRemoteMethod<BufferHubRPC::ProducerBufferDetach>();
- ALOGE_IF(!status,
- "ProducerBuffer::Detach: Failed to detach buffer (id=%d): %s.", id(),
- status.GetErrorMessage().c_str());
- return status; */
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
deleted file mode 100644
index 9dbeacb..0000000
--- a/libs/vr/libdvr/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_native_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_library_headers {
- name: "libdvr_headers",
- export_include_dirs: ["include"],
- vendor_available: true,
- apex_available: [
- "//apex_available:platform",
- "com.android.media",
- "com.android.media.swcodec",
- ],
- min_sdk_version: "29",
-}
diff --git a/libs/vr/libdvr/include/CPPLINT.cfg b/libs/vr/libdvr/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libdvr/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
deleted file mode 100644
index b7abb99..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ /dev/null
@@ -1,503 +0,0 @@
-#ifndef ANDROID_DVR_API_H_
-#define ANDROID_DVR_API_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <cstdio>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_hardware_composer_types.h>
-#include <dvr/dvr_pose.h>
-#include <dvr/dvr_tracking_types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __GNUC__
-#define ALIGNED_DVR_STRUCT(x) __attribute__((packed, aligned(x)))
-#else
-#define ALIGNED_DVR_STRUCT(x)
-#endif
-
-typedef struct ANativeWindow ANativeWindow;
-
-typedef struct DvrPoseAsync DvrPoseAsync;
-
-typedef uint64_t DvrSurfaceUpdateFlags;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrPoseClient DvrPoseClient;
-typedef struct DvrPoseDataCaptureRequest DvrPoseDataCaptureRequest;
-typedef struct DvrVSyncClient DvrVSyncClient;
-typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct AHardwareBuffer AHardwareBuffer;
-
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata;
-
-typedef struct DvrSurface DvrSurface;
-typedef uint64_t DvrSurfaceAttributeType;
-typedef int32_t DvrSurfaceAttributeKey;
-typedef int32_t DvrGlobalBufferKey;
-
-typedef struct DvrSurfaceAttributeValue DvrSurfaceAttributeValue;
-typedef struct DvrSurfaceAttribute DvrSurfaceAttribute;
-
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrTrackingCamera DvrTrackingCamera;
-typedef struct DvrTrackingFeatureExtractor DvrTrackingFeatureExtractor;
-typedef struct DvrTrackingSensors DvrTrackingSensors;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-
-// Note: To avoid breaking others during active development, only modify this
-// struct by appending elements to the end.
-// If you do feel we should to re-arrange or remove elements, please make a
-// note of it, and wait until we're about to finalize for an API release to do
-// so.
-typedef struct DvrNativeDisplayMetrics {
- uint32_t display_width;
- uint32_t display_height;
- uint32_t display_x_dpi;
- uint32_t display_y_dpi;
- uint32_t vsync_period_ns;
-} DvrNativeDisplayMetrics;
-
-// native_handle contains the fds for the underlying ION allocations inside
-// the gralloc buffer. This is needed temporarily while GPU vendors work on
-// better support for AHardwareBuffer via glBindSharedBuffer APIs. See
-// b/37207909. For now we can declare the native_handle struct where it is
-// used for GPU late latching. See cutils/native_handle.h for the struct layout.
-struct native_handle;
-
-// Device metrics data type enums.
-enum {
- // Request the device lens metrics protobuf. This matches cardboard protos.
- DVR_CONFIGURATION_DATA_LENS_METRICS = 0,
- // Request the device metrics protobuf.
- DVR_CONFIGURATION_DATA_DEVICE_METRICS = 1,
- // Request the per device configuration data file.
- DVR_CONFIGURATION_DATA_DEVICE_CONFIG = 2,
- // Request the edid data for the display.
- DVR_CONFIGURATION_DATA_DEVICE_EDID = 3,
-};
-
-// dvr_display_manager.h
-typedef int (*DvrDisplayManagerCreatePtr)(DvrDisplayManager** client_out);
-typedef void (*DvrDisplayManagerDestroyPtr)(DvrDisplayManager* client);
-typedef int (*DvrDisplayManagerGetEventFdPtr)(DvrDisplayManager* client);
-typedef int (*DvrDisplayManagerTranslateEpollEventMaskPtr)(
- DvrDisplayManager* client, int in_events, int* out_events);
-typedef int (*DvrDisplayManagerGetSurfaceStatePtr)(
- DvrDisplayManager* client, DvrSurfaceState* surface_state);
-typedef int (*DvrDisplayManagerGetReadBufferQueuePtr)(
- DvrDisplayManager* client, int surface_id, int queue_id,
- DvrReadBufferQueue** queue_out);
-typedef int (*DvrConfigurationDataGetPtr)(int config_type, uint8_t** data,
- size_t* data_size);
-typedef void (*DvrConfigurationDataDestroyPtr)(uint8_t* data);
-typedef int (*DvrSurfaceStateCreatePtr)(DvrSurfaceState** surface_state);
-typedef void (*DvrSurfaceStateDestroyPtr)(DvrSurfaceState* surface_state);
-typedef int (*DvrSurfaceStateGetSurfaceCountPtr)(DvrSurfaceState* surface_state,
- size_t* count_out);
-typedef int (*DvrSurfaceStateGetUpdateFlagsPtr)(
- DvrSurfaceState* surface_state, size_t surface_index,
- DvrSurfaceUpdateFlags* flags_out);
-typedef int (*DvrSurfaceStateGetSurfaceIdPtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- int* surface_id_out);
-typedef int (*DvrSurfaceStateGetProcessIdPtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- int* process_id_out);
-typedef int (*DvrSurfaceStateGetQueueCountPtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- size_t* count_out);
-typedef ssize_t (*DvrSurfaceStateGetQueueIdsPtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- int* queue_ids,
- size_t max_count);
-typedef int (*DvrSurfaceStateGetZOrderPtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- int* z_order_out);
-typedef int (*DvrSurfaceStateGetVisiblePtr)(DvrSurfaceState* surface_state,
- size_t surface_index,
- bool* visible_out);
-typedef int (*DvrSurfaceStateGetAttributeCountPtr)(
- DvrSurfaceState* surface_state, size_t surface_index, size_t* count_out);
-typedef ssize_t (*DvrSurfaceStateGetAttributesPtr)(
- DvrSurfaceState* surface_state, size_t surface_index,
- DvrSurfaceAttribute* attributes, size_t max_attribute_count);
-
-// dvr_buffer.h
-typedef void (*DvrWriteBufferCreateEmptyPtr)(DvrWriteBuffer** write_buffer_out);
-typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferIsValidPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferClearPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferGetIdPtr)(DvrWriteBuffer* write_buffer);
-typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
- DvrWriteBuffer* write_buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* write_buffer,
- int ready_fence_fd, const void* meta,
- size_t meta_size_bytes);
-typedef int (*DvrWriteBufferGainPtr)(DvrWriteBuffer* write_buffer,
- int* release_fence_fd);
-typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* write_buffer);
-typedef const struct native_handle* (*DvrWriteBufferGetNativeHandlePtr)(
- DvrWriteBuffer* write_buffer);
-
-typedef void (*DvrReadBufferCreateEmptyPtr)(DvrReadBuffer** read_buffer_out);
-typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferIsValidPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferClearPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferGetIdPtr)(DvrReadBuffer* read_buffer);
-typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
- DvrReadBuffer* read_buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* read_buffer,
- int* ready_fence_fd, void* meta,
- size_t meta_size_bytes);
-typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* read_buffer,
- int release_fence_fd);
-typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* read_buffer);
-typedef const struct native_handle* (*DvrReadBufferGetNativeHandlePtr)(
- DvrReadBuffer* read_buffer);
-
-typedef void (*DvrBufferDestroyPtr)(DvrBuffer* buffer);
-typedef int (*DvrBufferGetAHardwareBufferPtr)(
- DvrBuffer* buffer, AHardwareBuffer** hardware_buffer);
-typedef int (*DvrBufferGlobalLayoutVersionGetPtr)();
-typedef const struct native_handle* (*DvrBufferGetNativeHandlePtr)(
- DvrBuffer* buffer);
-
-// dvr_buffer_queue.h
-typedef int (*DvrWriteBufferQueueCreatePtr)(uint32_t width, uint32_t height,
- uint32_t format,
- uint32_t layer_count,
- uint64_t usage, size_t capacity,
- size_t metadata_size,
- DvrWriteBufferQueue** queue_out);
-typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
-typedef ssize_t (*DvrWriteBufferQueueGetCapacityPtr)(
- DvrWriteBufferQueue* write_queue);
-typedef int (*DvrWriteBufferQueueGetIdPtr)(DvrWriteBufferQueue* write_queue);
-typedef int (*DvrWriteBufferQueueGetExternalSurfacePtr)(
- DvrWriteBufferQueue* write_queue, ANativeWindow** out_window);
-typedef int (*DvrWriteBufferQueueGetANativeWindowPtr)(
- DvrWriteBufferQueue* write_queue, ANativeWindow** out_window);
-typedef int (*DvrWriteBufferQueueCreateReadQueuePtr)(
- DvrWriteBufferQueue* write_queue, DvrReadBufferQueue** out_read_queue);
-typedef int (*DvrWriteBufferQueueDequeuePtr)(DvrWriteBufferQueue* write_queue,
- int timeout,
- DvrWriteBuffer* out_buffer,
- int* out_fence_fd);
-typedef int (*DvrWriteBufferQueueGainBufferPtr)(
- DvrWriteBufferQueue* write_queue, int timeout,
- DvrWriteBuffer** out_write_buffer, DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd);
-typedef int (*DvrWriteBufferQueuePostBufferPtr)(
- DvrWriteBufferQueue* write_queue, DvrWriteBuffer* write_buffer,
- const DvrNativeBufferMetadata* meta, int ready_fence_fd);
-typedef int (*DvrWriteBufferQueueResizeBufferPtr)(
- DvrWriteBufferQueue* write_queue, uint32_t width, uint32_t height);
-typedef void (*DvrReadBufferQueueDestroyPtr)(DvrReadBufferQueue* read_queue);
-typedef ssize_t (*DvrReadBufferQueueGetCapacityPtr)(
- DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueGetIdPtr)(DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueGetEventFdPtr)(DvrReadBufferQueue* read_queue);
-typedef int (*DvrReadBufferQueueCreateReadQueuePtr)(
- DvrReadBufferQueue* read_queue, DvrReadBufferQueue** out_read_queue);
-typedef int (*DvrReadBufferQueueDequeuePtr)(DvrReadBufferQueue* read_queue,
- int timeout,
- DvrReadBuffer* out_buffer,
- int* out_fence_fd, void* out_meta,
- size_t meta_size_bytes);
-typedef int (*DvrReadBufferQueueAcquireBufferPtr)(
- DvrReadBufferQueue* read_queue, int timeout,
- DvrReadBuffer** out_read_buffer, DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd);
-typedef int (*DvrReadBufferQueueReleaseBufferPtr)(
- DvrReadBufferQueue* read_queue, DvrReadBuffer* read_buffer,
- const DvrNativeBufferMetadata* meta, int release_fence_fd);
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-typedef int (*DvrReadBufferQueueSetBufferAvailableCallbackPtr)(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
- void* context);
-typedef int (*DvrReadBufferQueueSetBufferRemovedCallbackPtr)(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-typedef int (*DvrReadBufferQueueHandleEventsPtr)(
- DvrReadBufferQueue* read_queue);
-
-// dvr_surface.h
-typedef int (*DvrSetupGlobalBufferPtr)(DvrGlobalBufferKey key, size_t size,
- uint64_t usage, DvrBuffer** buffer_out);
-typedef int (*DvrDeleteGlobalBufferPtr)(DvrGlobalBufferKey key);
-typedef int (*DvrGetGlobalBufferPtr)(DvrGlobalBufferKey key,
- DvrBuffer** out_buffer);
-typedef int (*DvrSurfaceCreatePtr)(const DvrSurfaceAttribute* attributes,
- size_t attribute_count,
- DvrSurface** surface_out);
-typedef void (*DvrSurfaceDestroyPtr)(DvrSurface* surface);
-typedef int (*DvrSurfaceGetIdPtr)(DvrSurface* surface);
-typedef int (*DvrSurfaceSetAttributesPtr)(DvrSurface* surface,
- const DvrSurfaceAttribute* attributes,
- size_t attribute_count);
-typedef int (*DvrSurfaceCreateWriteBufferQueuePtr)(
- DvrSurface* surface, uint32_t width, uint32_t height, uint32_t format,
- uint32_t layer_count, uint64_t usage, size_t capacity, size_t metadata_size,
- DvrWriteBufferQueue** queue_out);
-typedef int (*DvrGetNativeDisplayMetricsPtr)(size_t sizeof_metrics,
- DvrNativeDisplayMetrics* metrics);
-
-// dvr_vsync.h
-typedef int (*DvrVSyncClientCreatePtr)(DvrVSyncClient** client_out);
-typedef void (*DvrVSyncClientDestroyPtr)(DvrVSyncClient* client);
-typedef int (*DvrVSyncClientGetSchedInfoPtr)(DvrVSyncClient* client,
- int64_t* vsync_period_ns,
- int64_t* next_timestamp_ns,
- uint32_t* next_vsync_count);
-
-// libs/vr/libvrsensor/include/dvr/pose_client.h
-typedef DvrPoseClient* (*DvrPoseClientCreatePtr)();
-typedef void (*DvrPoseClientDestroyPtr)(DvrPoseClient* client);
-typedef int (*DvrPoseClientGetPtr)(DvrPoseClient* client, uint32_t vsync_count,
- DvrPoseAsync* out_pose);
-typedef uint32_t (*DvrPoseClientGetVsyncCountPtr)(DvrPoseClient* client);
-typedef int (*DvrPoseClientGetControllerPtr)(DvrPoseClient* client,
- int32_t controller_id,
- uint32_t vsync_count,
- DvrPoseAsync* out_pose);
-typedef int (*DvrPoseClientSensorsEnablePtr)(DvrPoseClient* client,
- bool enabled);
-typedef int (*DvrPoseClientDataCapturePtr)(DvrPoseClient* client,
- const DvrPoseDataCaptureRequest* request);
-typedef int (*DvrPoseClientDataReaderDestroyPtr)(DvrPoseClient* client,
- uint64_t data_type);
-
-// dvr_pose.h
-typedef int (*DvrPoseClientGetDataReaderPtr)(DvrPoseClient* client,
- uint64_t data_type,
- DvrReadBufferQueue** read_queue);
-
-// services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
-
-// Touchpad IDs for *Touch*() and *ButtonState*() calls.
-enum {
- DVR_VIRTUAL_TOUCHPAD_PRIMARY = 0,
- DVR_VIRTUAL_TOUCHPAD_VIRTUAL = 1,
-};
-typedef DvrVirtualTouchpad* (*DvrVirtualTouchpadCreatePtr)();
-typedef void (*DvrVirtualTouchpadDestroyPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadAttachPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadDetachPtr)(DvrVirtualTouchpad* client);
-typedef int (*DvrVirtualTouchpadTouchPtr)(DvrVirtualTouchpad* client,
- int touchpad, float x, float y,
- float pressure);
-typedef int (*DvrVirtualTouchpadButtonStatePtr)(DvrVirtualTouchpad* client,
- int touchpad, int buttons);
-typedef int (*DvrVirtualTouchpadScrollPtr)(DvrVirtualTouchpad* client,
- int touchpad, float x, float y);
-
-// dvr_hardware_composer_client.h
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-typedef int (*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
-typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
- void* client_state);
-typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
-typedef void (*DvrHwcFrameDestroyPtr)(DvrHwcFrame* frame);
-typedef DvrHwcDisplay (*DvrHwcFrameGetDisplayIdPtr)(DvrHwcFrame* frame);
-typedef int32_t (*DvrHwcFrameGetDisplayWidthPtr)(DvrHwcFrame* frame);
-typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
-typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
-typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
-typedef DvrHwcLayer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetActiveConfigPtr)(DvrHwcFrame* frame);
-typedef uint32_t (*DvrHwcFrameGetColorModePtr)(DvrHwcFrame* frame);
-typedef void (*DvrHwcFrameGetColorTransformPtr)(DvrHwcFrame* frame,
- float* out_matrix,
- int32_t* out_hint);
-typedef uint32_t (*DvrHwcFrameGetPowerModePtr)(DvrHwcFrame* frame);
-typedef uint32_t (*DvrHwcFrameGetVsyncEnabledPtr)(DvrHwcFrame* frame);
-typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerDisplayFramePtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef DvrHwcRectf (*DvrHwcFrameGetLayerCropPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef DvrHwcBlendMode (*DvrHwcFrameGetLayerBlendModePtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef float (*DvrHwcFrameGetLayerAlphaPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerTypePtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerApplicationIdPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef uint32_t (*DvrHwcFrameGetLayerZOrderPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-
-typedef void (*DvrHwcFrameGetLayerCursorPtr)(DvrHwcFrame* frame,
- size_t layer_index, int32_t* out_x,
- int32_t* out_y);
-
-typedef uint32_t (*DvrHwcFrameGetLayerTransformPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerDataspacePtr)(DvrHwcFrame* frame,
- size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerColorPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerNumVisibleRegionsPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerVisibleRegionPtr)(DvrHwcFrame* frame,
- size_t layer_index,
- size_t index);
-
-typedef uint32_t (*DvrHwcFrameGetLayerNumDamagedRegionsPtr)(DvrHwcFrame* frame,
- size_t layer_index);
-typedef DvrHwcRecti (*DvrHwcFrameGetLayerDamagedRegionPtr)(DvrHwcFrame* frame,
- size_t layer_index,
- size_t index);
-
-// dvr_performance.h
-typedef int (*DvrPerformanceSetSchedulerPolicyPtr)(
- pid_t task_id, const char* scheduler_policy);
-
-// dvr_tracking.h
-typedef int (*DvrTrackingCameraCreatePtr)(DvrTrackingCamera** out_camera);
-typedef void (*DvrTrackingCameraDestroyPtr)(DvrTrackingCamera* camera);
-typedef int (*DvrTrackingCameraStartPtr)(DvrTrackingCamera* camera,
- DvrWriteBufferQueue* write_queue);
-typedef int (*DvrTrackingCameraStopPtr)(DvrTrackingCamera* camera);
-
-typedef int (*DvrTrackingFeatureExtractorCreatePtr)(
- DvrTrackingFeatureExtractor** out_extractor);
-typedef void (*DvrTrackingFeatureExtractorDestroyPtr)(
- DvrTrackingFeatureExtractor* extractor);
-typedef void (*DvrTrackingFeatureCallback)(void* context,
- const DvrTrackingFeatures* event);
-typedef int (*DvrTrackingFeatureExtractorStartPtr)(
- DvrTrackingFeatureExtractor* extractor,
- DvrTrackingFeatureCallback callback, void* context);
-typedef int (*DvrTrackingFeatureExtractorStopPtr)(
- DvrTrackingFeatureExtractor* extractor);
-typedef int (*DvrTrackingFeatureExtractorProcessBufferPtr)(
- DvrTrackingFeatureExtractor* extractor, DvrReadBuffer* buffer,
- const DvrTrackingBufferMetadata* metadata, bool* out_skipped);
-
-typedef void (*DvrTrackingSensorEventCallback)(void* context,
- DvrTrackingSensorEvent* event);
-typedef int (*DvrTrackingSensorsCreatePtr)(DvrTrackingSensors** out_sensors,
- const char* mode);
-typedef void (*DvrTrackingSensorsDestroyPtr)(DvrTrackingSensors* sensors);
-typedef int (*DvrTrackingSensorsStartPtr)(
- DvrTrackingSensors* sensors, DvrTrackingSensorEventCallback callback,
- void* context);
-typedef int (*DvrTrackingSensorsStopPtr)(DvrTrackingSensors* sensors);
-
-// The buffer metadata that an Android Surface (a.k.a. ANativeWindow)
-// will populate. A DvrWriteBufferQueue must be created with this metadata iff
-// ANativeWindow access is needed. Please do not remove, modify, or reorder
-// existing data members. If new fields need to be added, please take extra care
-// to make sure that new data field is padded properly the size of the struct
-// stays same.
-// TODO(b/118893702): move the definition to libnativewindow or libui
-struct ALIGNED_DVR_STRUCT(8) DvrNativeBufferMetadata {
-#ifdef __cplusplus
- DvrNativeBufferMetadata()
- : timestamp(0),
- is_auto_timestamp(0),
- dataspace(0),
- crop_left(0),
- crop_top(0),
- crop_right(0),
- crop_bottom(0),
- scaling_mode(0),
- transform(0),
- index(0),
- user_metadata_size(0),
- user_metadata_ptr(0),
- release_fence_mask(0),
- reserved{0} {}
-#endif
- // Timestamp of the frame.
- int64_t timestamp;
-
- // Whether the buffer is using auto timestamp.
- int32_t is_auto_timestamp;
-
- // Must be one of the HAL_DATASPACE_XXX value defined in system/graphics.h
- int32_t dataspace;
-
- // Crop extracted from an ACrop or android::Crop object.
- int32_t crop_left;
- int32_t crop_top;
- int32_t crop_right;
- int32_t crop_bottom;
-
- // Must be one of the NATIVE_WINDOW_SCALING_MODE_XXX value defined in
- // system/window.h.
- int32_t scaling_mode;
-
- // Must be one of the ANATIVEWINDOW_TRANSFORM_XXX value defined in
- // android/native_window.h
- int32_t transform;
-
- // The index of the frame.
- int64_t index;
-
- // Size of additional metadata requested by user.
- uint64_t user_metadata_size;
-
- // Raw memory address of the additional user defined metadata. Only valid when
- // user_metadata_size is non-zero.
- uint64_t user_metadata_ptr;
-
- // Only applicable for metadata retrieved from GainAsync. This indicates which
- // consumer has pending fence that producer should epoll on.
- uint32_t release_fence_mask;
-
- // Reserved bytes for so that the struct is forward compatible and padding to
- // 104 bytes so the size is a multiple of 8.
- int32_t reserved[9];
-};
-
-#ifdef __cplusplus
-// Warning: DvrNativeBufferMetadata is part of the DVR API and changing its size
-// will cause compatiblity issues between different DVR API releases.
-static_assert(sizeof(DvrNativeBufferMetadata) == 104,
- "Unexpected size for DvrNativeBufferMetadata");
-#endif
-
-struct DvrApi_v1 {
-// Defines an API entry for V1 (no version suffix).
-#define DVR_V1_API_ENTRY(name) Dvr##name##Ptr name
-#define DVR_V1_API_ENTRY_DEPRECATED(name) Dvr##name##Ptr name
-
-#include "dvr_api_entries.h"
-
-// Undefine macro definitions to play nice with Google3 style rules.
-#undef DVR_V1_API_ENTRY
-#undef DVR_V1_API_ENTRY_DEPRECATED
-};
-
-int dvrGetApi(void* api, size_t struct_size, int version);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_API_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
deleted file mode 100644
index 3006b61..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h
+++ /dev/null
@@ -1,200 +0,0 @@
-// dvr_api_entries.h
-//
-// Defines the DVR platform library API entries.
-//
-// Do not include this header directly.
-
-#ifndef DVR_V1_API_ENTRY
-#error Do not include this header directly.
-#endif
-
-#ifndef DVR_V1_API_ENTRY_DEPRECATED
-#error Do not include this header directly.
-#endif
-
-// Do not delete this line: BEGIN CODEGEN OUTPUT
-// Display manager client
-DVR_V1_API_ENTRY(DisplayManagerCreate);
-DVR_V1_API_ENTRY(DisplayManagerDestroy);
-DVR_V1_API_ENTRY(DisplayManagerGetEventFd);
-DVR_V1_API_ENTRY(DisplayManagerTranslateEpollEventMask);
-DVR_V1_API_ENTRY(DisplayManagerGetSurfaceState);
-DVR_V1_API_ENTRY(DisplayManagerGetReadBufferQueue);
-DVR_V1_API_ENTRY(ConfigurationDataGet);
-DVR_V1_API_ENTRY(ConfigurationDataDestroy);
-DVR_V1_API_ENTRY(SurfaceStateCreate);
-DVR_V1_API_ENTRY(SurfaceStateDestroy);
-DVR_V1_API_ENTRY(SurfaceStateGetSurfaceCount);
-DVR_V1_API_ENTRY(SurfaceStateGetUpdateFlags);
-DVR_V1_API_ENTRY(SurfaceStateGetSurfaceId);
-DVR_V1_API_ENTRY(SurfaceStateGetProcessId);
-DVR_V1_API_ENTRY(SurfaceStateGetQueueCount);
-DVR_V1_API_ENTRY(SurfaceStateGetQueueIds);
-DVR_V1_API_ENTRY(SurfaceStateGetZOrder);
-DVR_V1_API_ENTRY(SurfaceStateGetVisible);
-DVR_V1_API_ENTRY(SurfaceStateGetAttributeCount);
-DVR_V1_API_ENTRY(SurfaceStateGetAttributes);
-
-// Write buffer
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferCreateEmpty);
-DVR_V1_API_ENTRY(WriteBufferDestroy);
-DVR_V1_API_ENTRY(WriteBufferIsValid);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferClear);
-DVR_V1_API_ENTRY(WriteBufferGetId);
-DVR_V1_API_ENTRY(WriteBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferPost);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGain);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGainAsync);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferGetNativeHandle);
-
-// Read buffer
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferCreateEmpty);
-DVR_V1_API_ENTRY(ReadBufferDestroy);
-DVR_V1_API_ENTRY(ReadBufferIsValid);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferClear);
-DVR_V1_API_ENTRY(ReadBufferGetId);
-DVR_V1_API_ENTRY(ReadBufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferAcquire);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferRelease);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferReleaseAsync);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferGetNativeHandle);
-
-// Buffer
-DVR_V1_API_ENTRY(BufferDestroy);
-DVR_V1_API_ENTRY(BufferGetAHardwareBuffer);
-DVR_V1_API_ENTRY_DEPRECATED(BufferGetNativeHandle);
-DVR_V1_API_ENTRY(BufferGlobalLayoutVersionGet);
-
-// Write buffer queue
-DVR_V1_API_ENTRY(WriteBufferQueueDestroy);
-DVR_V1_API_ENTRY(WriteBufferQueueGetCapacity);
-DVR_V1_API_ENTRY(WriteBufferQueueGetId);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueGetExternalSurface);
-DVR_V1_API_ENTRY(WriteBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY_DEPRECATED(WriteBufferQueueDequeue);
-DVR_V1_API_ENTRY(WriteBufferQueueResizeBuffer);
-
-// Read buffer queue
-DVR_V1_API_ENTRY(ReadBufferQueueDestroy);
-DVR_V1_API_ENTRY(ReadBufferQueueGetCapacity);
-DVR_V1_API_ENTRY(ReadBufferQueueGetId);
-DVR_V1_API_ENTRY(ReadBufferQueueCreateReadQueue);
-DVR_V1_API_ENTRY_DEPRECATED(ReadBufferQueueDequeue);
-DVR_V1_API_ENTRY(ReadBufferQueueSetBufferAvailableCallback);
-DVR_V1_API_ENTRY(ReadBufferQueueSetBufferRemovedCallback);
-DVR_V1_API_ENTRY(ReadBufferQueueHandleEvents);
-
-// V-Sync client
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientCreate);
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientDestroy);
-DVR_V1_API_ENTRY_DEPRECATED(VSyncClientGetSchedInfo);
-
-// Display surface
-DVR_V1_API_ENTRY(SurfaceCreate);
-DVR_V1_API_ENTRY(SurfaceDestroy);
-DVR_V1_API_ENTRY(SurfaceGetId);
-DVR_V1_API_ENTRY(SurfaceSetAttributes);
-DVR_V1_API_ENTRY(SurfaceCreateWriteBufferQueue);
-DVR_V1_API_ENTRY(SetupGlobalBuffer);
-DVR_V1_API_ENTRY(DeleteGlobalBuffer);
-DVR_V1_API_ENTRY(GetGlobalBuffer);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientCreate);
-DVR_V1_API_ENTRY(PoseClientDestroy);
-DVR_V1_API_ENTRY(PoseClientGet);
-DVR_V1_API_ENTRY(PoseClientGetVsyncCount);
-DVR_V1_API_ENTRY(PoseClientGetController);
-
-// Virtual touchpad client
-DVR_V1_API_ENTRY(VirtualTouchpadCreate);
-DVR_V1_API_ENTRY(VirtualTouchpadDestroy);
-DVR_V1_API_ENTRY(VirtualTouchpadAttach);
-DVR_V1_API_ENTRY(VirtualTouchpadDetach);
-DVR_V1_API_ENTRY(VirtualTouchpadTouch);
-DVR_V1_API_ENTRY(VirtualTouchpadButtonState);
-
-// VR HWComposer client
-DVR_V1_API_ENTRY(HwcClientCreate);
-DVR_V1_API_ENTRY(HwcClientDestroy);
-DVR_V1_API_ENTRY(HwcFrameDestroy);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayId);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayWidth);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayHeight);
-DVR_V1_API_ENTRY(HwcFrameGetDisplayRemoved);
-DVR_V1_API_ENTRY(HwcFrameGetActiveConfig);
-DVR_V1_API_ENTRY(HwcFrameGetColorMode);
-DVR_V1_API_ENTRY(HwcFrameGetColorTransform);
-DVR_V1_API_ENTRY(HwcFrameGetPowerMode);
-DVR_V1_API_ENTRY(HwcFrameGetVsyncEnabled);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCount);
-DVR_V1_API_ENTRY(HwcFrameGetLayerId);
-DVR_V1_API_ENTRY(HwcFrameGetLayerBuffer);
-DVR_V1_API_ENTRY(HwcFrameGetLayerFence);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDisplayFrame);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCrop);
-DVR_V1_API_ENTRY(HwcFrameGetLayerBlendMode);
-DVR_V1_API_ENTRY(HwcFrameGetLayerAlpha);
-DVR_V1_API_ENTRY(HwcFrameGetLayerType);
-DVR_V1_API_ENTRY(HwcFrameGetLayerApplicationId);
-DVR_V1_API_ENTRY(HwcFrameGetLayerZOrder);
-DVR_V1_API_ENTRY(HwcFrameGetLayerCursor);
-DVR_V1_API_ENTRY(HwcFrameGetLayerTransform);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDataspace);
-DVR_V1_API_ENTRY(HwcFrameGetLayerColor);
-DVR_V1_API_ENTRY(HwcFrameGetLayerNumVisibleRegions);
-DVR_V1_API_ENTRY(HwcFrameGetLayerVisibleRegion);
-DVR_V1_API_ENTRY(HwcFrameGetLayerNumDamagedRegions);
-DVR_V1_API_ENTRY(HwcFrameGetLayerDamagedRegion);
-
-// New entries added at the end to allow the DVR platform library API
-// to be updated before updating VrCore.
-
-// Virtual touchpad client
-DVR_V1_API_ENTRY(VirtualTouchpadScroll);
-
-// Read the native display metrics from the hardware composer
-DVR_V1_API_ENTRY(GetNativeDisplayMetrics);
-
-// Performance
-DVR_V1_API_ENTRY(PerformanceSetSchedulerPolicy);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientSensorsEnable);
-
-// Read buffer queue
-DVR_V1_API_ENTRY(ReadBufferQueueGetEventFd);
-
-// Create write buffer queue locally
-DVR_V1_API_ENTRY(WriteBufferQueueCreate);
-
-// Gets an ANativeWindow from DvrWriteBufferQueue.
-DVR_V1_API_ENTRY(WriteBufferQueueGetANativeWindow);
-
-// Dvr{Read,Write}BufferQueue API for asynchronous IPC.
-DVR_V1_API_ENTRY(WriteBufferQueueGainBuffer);
-DVR_V1_API_ENTRY(WriteBufferQueuePostBuffer);
-DVR_V1_API_ENTRY(ReadBufferQueueAcquireBuffer);
-DVR_V1_API_ENTRY(ReadBufferQueueReleaseBuffer);
-
-// Pose client
-DVR_V1_API_ENTRY(PoseClientGetDataReader);
-DVR_V1_API_ENTRY(PoseClientDataCapture);
-DVR_V1_API_ENTRY(PoseClientDataReaderDestroy);
-
-// Tracking
-DVR_V1_API_ENTRY(TrackingCameraCreate);
-DVR_V1_API_ENTRY(TrackingCameraDestroy);
-DVR_V1_API_ENTRY(TrackingCameraStart);
-DVR_V1_API_ENTRY(TrackingCameraStop);
-
-DVR_V1_API_ENTRY(TrackingFeatureExtractorCreate);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorDestroy);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorStart);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorStop);
-DVR_V1_API_ENTRY(TrackingFeatureExtractorProcessBuffer);
-
-DVR_V1_API_ENTRY(TrackingSensorsCreate);
-DVR_V1_API_ENTRY(TrackingSensorsDestroy);
-DVR_V1_API_ENTRY(TrackingSensorsStart);
-DVR_V1_API_ENTRY(TrackingSensorsStop);
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
deleted file mode 100644
index 4234844..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_H_
-#define ANDROID_DVR_BUFFER_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-#include <memory>
-
-__BEGIN_DECLS
-
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrBuffer DvrBuffer;
-typedef struct AHardwareBuffer AHardwareBuffer;
-struct native_handle;
-
-// Destroys the write buffer.
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
-
-// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
-int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer);
-
-// Returns the global BufferHub id of this buffer.
-int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
-
-// Returns an AHardwareBuffer for the underlying buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
- AHardwareBuffer** hardware_buffer);
-
-// Destroys the read buffer.
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
-
-// Returns 1 if the given write buffer object contains a buffer, 0 otherwise.
-int dvrReadBufferIsValid(DvrReadBuffer* read_buffer);
-
-// Returns the global BufferHub id of this buffer.
-int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
-
-// Returns an AHardwareBuffer for the underlying buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
- AHardwareBuffer** hardware_buffer);
-
-// Destroys the buffer.
-void dvrBufferDestroy(DvrBuffer* buffer);
-
-// Gets an AHardwareBuffer from the buffer.
-// Caller must call AHardwareBuffer_release on hardware_buffer.
-int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
- AHardwareBuffer** hardware_buffer);
-
-// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h.
-int dvrBufferGlobalLayoutVersionGet();
-
-__END_DECLS
-
-#endif // ANDROID_DVR_BUFFER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
deleted file mode 100644
index ac789da..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
+++ /dev/null
@@ -1,263 +0,0 @@
-#ifndef ANDROID_DVR_BUFFER_QUEUE_H_
-#define ANDROID_DVR_BUFFER_QUEUE_H_
-
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_buffer.h>
-
-__BEGIN_DECLS
-
-typedef struct ANativeWindow ANativeWindow;
-
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-// Creates a write buffer queue to be used locally.
-//
-// Note that this API is mostly for testing purpose. For now there is no
-// mechanism to send a DvrWriteBufferQueue cross process. Use
-// dvrSurfaceCreateWriteBufferQueue if cross-process buffer transport is
-// intended.
-//
-// @param width The width of the buffers that this queue will produce.
-// @param height The height of buffers that this queue will produce.
-// @param format The format of the buffers that this queue will produce. This
-// must be one of the AHARDWAREBUFFER_FORMAT_XXX enums.
-// @param layer_count The number of layers of the buffers that this queue will
-// produce.
-// @param usage The usage of the buffers that this queue will produce. This
-// must a combination of the AHARDWAREBUFFER_USAGE_XXX flags.
-// @param capacity The number of buffer that this queue will allocate. Note that
-// all buffers will be allocated on create. Currently, the number of buffers
-// is the queue cannot be changed after creation though DVR API. However,
-// ANativeWindow can choose to reallocate, attach, or detach buffers from
-// a DvrWriteBufferQueue through Android platform logic.
-// @param metadata_size The size of metadata in bytes.
-// @param out_write_queue The pointer of a DvrWriteBufferQueue will be filled
-// here if the method call succeeds. The metadata size must match
-// the metadata size in dvrWriteBufferPost/dvrReadBufferAcquire.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format,
- uint32_t layer_count, uint64_t usage,
- size_t capacity, size_t metadata_size,
- DvrWriteBufferQueue** out_write_queue);
-
-// Destroy a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
-
-// Get the total number of buffers in a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @return The capacity on success; or negative error code.
-ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue);
-
-// Get the system unique queue id of a write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @return Queue id on success; or negative error code.
-int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue);
-
-// Gets an ANativeWindow backed by the DvrWriteBufferQueue
-//
-// Can be casted to a Java Surface using ANativeWindow_toSurface NDK API. Note
-// that the native window is lazily created at the first time |GetNativeWindow|
-// is called, and the created ANativeWindow will be cached so that multiple
-// calls to this method will return the same object. Also note that this method
-// does not acquire an additional reference to the ANativeWindow returned, don't
-// call ANativeWindow_release on it.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param out_window The pointer of an ANativeWindow will be filled here if
-// the method call succeeds.
-// @return Zero on success; or -EINVAL if this DvrWriteBufferQueue does not
-// support being used as an android Surface.
-int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue,
- ANativeWindow** out_window);
-
-// Create a read buffer queue from an existing write buffer queue.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param out_read_queue The pointer of a DvrReadBufferQueue will be filled here
-// if the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
- DvrReadBufferQueue** out_read_queue);
-
-// Gains a buffer to write into.
-//
-// @param write_queue The DvrWriteBufferQueue to gain buffer from.
-// @param timeout Specifies the number of milliseconds that the method will
-// block. Specifying a timeout of -1 causes it to block indefinitely,
-// while specifying a timeout equal to zero cause it to return immediately,
-// even if no buffers are available.
-// @param out_buffer A targeting DvrWriteBuffer object to hold the output of the
-// dequeue operation.
-// @param out_meta A DvrNativeBufferMetadata object populated by the
-// corresponding dvrReadBufferQueueReleaseBuffer API.
-// @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which
-// signals the release of underlying buffer. The producer should wait until
-// this fence clears before writing data into it.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout,
- DvrWriteBuffer** out_write_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd);
-
-// Posts a buffer and signals its readiness to be read from.
-//
-// @param write_queue The DvrWriteBufferQueue to post buffer into.
-// @param write_buffer The buffer to be posted.
-// @param meta The buffer metadata describing the buffer.
-// @param ready_fence_fd A sync fence fd defined in NDK's sync.h API, which
-// signals the readdiness of underlying buffer. When a valid fence gets
-// passed in, the consumer will wait the fence to be ready before it starts
-// to ready from the buffer.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue,
- DvrWriteBuffer* write_buffer,
- const DvrNativeBufferMetadata* meta,
- int ready_fence_fd);
-
-// Overrides buffer dimension with new width and height.
-//
-// After the call successfully returns, each |dvrWriteBufferQueueDequeue| call
-// will return buffer with newly assigned |width| and |height|. When necessary,
-// old buffer will be removed from the buffer queue and replaced with new buffer
-// matching the new buffer size.
-//
-// @param write_queue The DvrWriteBufferQueue of interest.
-// @param width Desired width, cannot be Zero.
-// @param height Desired height, cannot be Zero.
-// @return Zero on success, or negative error code.
-int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue,
- uint32_t width, uint32_t height);
-
-// Destroy a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
-
-// Get the total number of buffers in a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return The capacity on success; or negative error code.
-ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue);
-
-// Get the system unique queue id of a read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Queue id on success; or negative error code.
-int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue);
-
-// Get the event fd that signals when queue updates occur.
-//
-// Use ReadBufferQueueHandleEvents to trigger registered event callbacks.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Fd on success; or negative error code.
-int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue);
-
-// Create a read buffer queue from an existing read buffer queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param out_read_queue The pointer of a DvrReadBufferQueue will be filled here
-// if the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
- DvrReadBufferQueue** out_read_queue);
-
-// Dequeues a buffer to read from.
-//
-// @param read_queue The DvrReadBufferQueue to acquire buffer from.
-// @param timeout Specifies the number of milliseconds that the method will
-// block. Specifying a timeout of -1 causes it to block indefinitely,
-// while specifying a timeout equal to zero cause it to return immediately,
-// even if no buffers are available.
-// @param out_buffer A targeting DvrReadBuffer object to hold the output of the
-// dequeue operation. Must be created by |dvrReadBufferCreateEmpty|.
-// @param out_meta A DvrNativeBufferMetadata object populated by the
-// corresponding dvrWriteBufferQueuePostBuffer API.
-// @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which
-// signals the release of underlying buffer. The consumer should wait until
-// this fence clears before reading data from it.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout,
- DvrReadBuffer** out_read_buffer,
- DvrNativeBufferMetadata* out_meta,
- int* out_fence_fd);
-
-// Releases a buffer and signals its readiness to be written into.
-//
-// @param read_queue The DvrReadBufferQueue to release buffer into.
-// @param read_buffer The buffer to be released.
-// @param meta The buffer metadata describing the buffer.
-// @param release_fence_fd A sync fence fd defined in NDK's sync.h API, which
-// signals the readdiness of underlying buffer. When a valid fence gets
-// passed in, the producer will wait the fence to be ready before it starts
-// to write into the buffer again.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue,
- DvrReadBuffer* read_buffer,
- const DvrNativeBufferMetadata* meta,
- int release_fence_fd);
-
-// Callback function which will be called when a buffer is avaiable.
-//
-// Note that there is no guarantee of thread safety and on which thread the
-// callback will be fired.
-//
-// @param context User provided opaque pointer.
-typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context);
-
-// Set buffer avaiable callback.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param callback The callback function. Set this to NULL if caller no longer
-// needs to listen to new buffer available events.
-// @param context User provided opaque pointer, will be passed back during
-// callback. The caller is responsible for ensuring the validity of the
-// context through the life cycle of the DvrReadBufferQueue.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueSetBufferAvailableCallback(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferAvailableCallback callback, void* context);
-
-// Callback function which will be called when a buffer is about to be removed.
-//
-// Note that there is no guarantee of thread safety and on which thread the
-// callback will be fired.
-//
-// @param buffer The buffer being removed. Once the callbacks returns, this
-// buffer will be dereferenced from the buffer queue. If user has ever
-// cached other DvrReadBuffer/AHardwareBuffer/EglImageKHR objects derived
-// from this buffer, it's the user's responsibility to clean them up.
-// Note that the ownership of the read buffer is not passed to this
-// callback, so it should call dvrReadBufferDestroy on the buffer.
-// @param context User provided opaque pointer.
-typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer,
- void* context);
-
-// Set buffer removed callback.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @param callback The callback function. Set this to NULL if caller no longer
-// needs to listen to buffer removed events.
-// @param context User provided opaque pointer, will be passed back during
-// callback. The caller is responsible for ensuring the validity of the
-// context through the life cycle of the DvrReadBufferQueue.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueSetBufferRemovedCallback(
- DvrReadBufferQueue* read_queue,
- DvrReadBufferQueueBufferRemovedCallback callback, void* context);
-
-// Handle all pending events on the read queue.
-//
-// @param read_queue The DvrReadBufferQueue of interest.
-// @return Zero on success, or negative error code.
-int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue);
-
-__END_DECLS
-
-#endif // ANDROID_DVR_BUFFER_QUEUE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_config.h b/libs/vr/libdvr/include/dvr/dvr_config.h
deleted file mode 100644
index 3d2c066..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_config.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef ANDROID_DVR_CONFIG_H
-#define ANDROID_DVR_CONFIG_H
-
-// This header is shared by VrCore and Android and must be kept in sync.
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// This is a shared memory buffer for passing config data from VrCore to
-// libvrflinger in SurfaceFlinger.
-struct __attribute__((packed, aligned(16))) DvrConfig {
- // Offset before vsync to submit frames to hardware composer.
- int32_t frame_post_offset_ns{4000000};
-
- // If the number of pending fences goes over this count at the point when we
- // are about to submit a new frame to HWC, we will drop the frame. This
- // should be a signal that the display driver has begun queuing frames. Note
- // that with smart displays (with RAM), the fence is signaled earlier than
- // the next vsync, at the point when the DMA to the display completes.
- // Currently we use a smart display and the EDS timing coincides with zero
- // pending fences, so this is 0.
- int32_t allowed_pending_fence_count{0};
-
- // New fields should always be added to the end for backwards compat.
-
- // Reserved padding to 16 bytes.
- uint8_t pad[8];
-};
-
-__END_DECLS
-
-#endif // ANDROID_DVR_CONFIG_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_configuration_data.h b/libs/vr/libdvr/include/dvr/dvr_configuration_data.h
deleted file mode 100644
index 22a509f..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_configuration_data.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef DVR_CONFIGURATION_DATA_H_
-#define DVR_CONFIGURATION_DATA_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-__BEGIN_DECLS
-
-// Loads device configuration data of DVR_CONFIGURATION_DATA_*.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrConfigurationDataGet(int config_type,
- uint8_t** data, size_t* data_size);
-
-// Destroy the configuration data returned from dvrGetConfigurationData.
-void dvrConfigurationDataDestroy(uint8_t* data);
-
-__END_DECLS
-
-#endif // DVR_CONFIGURATION_DATA_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_deleter.h b/libs/vr/libdvr/include/dvr/dvr_deleter.h
deleted file mode 100644
index fe59d1f..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_deleter.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_DVR_DELETER_H_
-#define ANDROID_DVR_DELETER_H_
-
-#include <sys/cdefs.h>
-
-#include <memory>
-
-// Header-only C++ helper to delete opaque DVR objects.
-
-__BEGIN_DECLS
-
-// Use forward declarations to avoid dependency on other headers.
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrSurface DvrSurface;
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-
-void dvrBufferDestroy(DvrBuffer* buffer);
-void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
-void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
-void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
-void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
-void dvrDisplayManagerDestroy(DvrDisplayManager* client);
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
-void dvrSurfaceDestroy(DvrSurface* surface);
-void dvrHwcClientDestroy(DvrHwcClient* client);
-void dvrHwcFrameDestroy(DvrHwcFrame* frame);
-
-__END_DECLS
-
-// Avoid errors if this header is included in C code.
-#if defined(__cplusplus)
-
-namespace android {
-namespace dvr {
-
-// Universal DVR object deleter. May be passed to smart pointer types to handle
-// deletion of DVR API objects.
-struct DvrObjectDeleter {
- void operator()(DvrBuffer* p) { dvrBufferDestroy(p); }
- void operator()(DvrReadBuffer* p) { dvrReadBufferDestroy(p); }
- void operator()(DvrWriteBuffer* p) { dvrWriteBufferDestroy(p); }
- void operator()(DvrReadBufferQueue* p) { dvrReadBufferQueueDestroy(p); }
- void operator()(DvrWriteBufferQueue* p) { dvrWriteBufferQueueDestroy(p); }
- void operator()(DvrDisplayManager* p) { dvrDisplayManagerDestroy(p); }
- void operator()(DvrSurfaceState* p) { dvrSurfaceStateDestroy(p); }
- void operator()(DvrSurface* p) { dvrSurfaceDestroy(p); }
- void operator()(DvrHwcClient* p) { dvrHwcClientDestroy(p); }
- void operator()(DvrHwcFrame* p) { dvrHwcFrameDestroy(p); }
-};
-
-// Helper to define unique pointers for DVR object types.
-template <typename T>
-using MakeUniqueDvrPointer = std::unique_ptr<T, DvrObjectDeleter>;
-
-// Unique pointer types for DVR objects.
-using UniqueDvrBuffer = MakeUniqueDvrPointer<DvrBuffer>;
-using UniqueDvrReadBuffer = MakeUniqueDvrPointer<DvrReadBuffer>;
-using UniqueDvrWriteBuffer = MakeUniqueDvrPointer<DvrWriteBuffer>;
-using UniqueDvrReadBufferQueue = MakeUniqueDvrPointer<DvrReadBufferQueue>;
-using UniqueDvrWriteBufferQueue = MakeUniqueDvrPointer<DvrWriteBufferQueue>;
-using UniqueDvrDisplayManager = MakeUniqueDvrPointer<DvrDisplayManager>;
-using UniqueDvrSurfaceState = MakeUniqueDvrPointer<DvrSurfaceState>;
-using UniqueDvrSurface = MakeUniqueDvrPointer<DvrSurface>;
-using UniqueDvrHwcClient = MakeUniqueDvrPointer<DvrHwcClient>;
-using UniqueDvrHwcFrame = MakeUniqueDvrPointer<DvrHwcFrame>;
-
-// TODO(eieio): Add an adapter for std::shared_ptr that injects the deleter into
-// the relevant constructors.
-
-} // namespace dvr
-} // namespace android
-
-#endif // defined(__cplusplus)
-
-#endif // ANDROID_DVR_DELETER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_manager.h b/libs/vr/libdvr/include/dvr/dvr_display_manager.h
deleted file mode 100644
index f910d61..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_display_manager.h
+++ /dev/null
@@ -1,133 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_MANAGER_H_
-#define ANDROID_DVR_DISPLAY_MANAGER_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_display_types.h>
-#include <dvr/dvr_surface.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrBuffer DvrBuffer;
-typedef struct DvrDisplayManager DvrDisplayManager;
-typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-typedef uint64_t DvrSurfaceUpdateFlags;
-
-// Attempts to connect to the display manager service.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerCreate(DvrDisplayManager** client_out);
-
-// Destroys the display manager client object.
-void dvrDisplayManagerDestroy(DvrDisplayManager* client);
-
-// Returns an fd used to signal when surface updates occur. Note that depending
-// on the underlying transport, only a subset of the real event bits may be
-// supported. Use dvrDisplayManagerClientTranslateEpollEventMask to get the real
-// event flags.
-// @return the fd on success. Otherwise returns a negative error value.
-int dvrDisplayManagerGetEventFd(DvrDisplayManager* client);
-
-// @param in_events pass in the epoll revents that were initially returned by
-// poll/epoll.
-// @param on success, this value will be overwritten with the true poll/epoll
-// values.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client,
- int in_events, int* out_events);
-
-// Queries the display manager service for the current state of the display
-// surfaces and stores the results in the given surface state object.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client,
- DvrSurfaceState* surface_state);
-
-// Gets a read buffer queue from the surface |surface_id| named |queue_id|. Each
-// call returns a different read buffer queue connected to the same write buffer
-// queue. Callers should cache these instead of requesting new ones when
-// possible.
-int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client,
- int surface_id, int queue_id,
- DvrReadBufferQueue** queue_out);
-
-// Creates a new surface state object. This object may be used to receive the
-// results of a surface state query. More than one state object may be created
-// to keep multiple snapshots, if desired.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateCreate(DvrSurfaceState** surface_state);
-
-// Destorys the surface state object.
-void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state);
-
-// Writes the number of surfaces described in the state object into |count_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state,
- size_t* count_out);
-
-// Returns the update flags for the surface at |surface_index| in the state
-// object. The flags may be used to determine what changes, if any, occurred to
-// the surface since the last state update.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state,
- size_t surface_index,
- DvrSurfaceUpdateFlags* flags_out);
-
-// Returns the unique identifier of surface at |surface_index| in the state
-// object. The identifier may be used to distinguish between surfaces.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state,
- size_t surface_index, int* surface_id_out);
-
-// Returns the process id of surface at |surface_index| in the state object.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state,
- size_t surface_index, int* process_id_out);
-
-// Writes the number of queues in the surface at |surface_index| in the state
-// object into |count_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state,
- size_t surface_index, size_t* count_out);
-
-// Returns up to |max_count| queue ids for the queues belonging to the surface
-// at |surface_index| in the state object.
-// @return The number of queue ids written on success. Otherwise returns a
-// negative error value.
-ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state,
- size_t surface_index, int* queue_ids,
- size_t max_count);
-
-// Writes the z-order of the surface at |surface_index| in surface state object
-// into |z_order_out|.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state,
- size_t surface_index, int* z_order_out);
-
-// Writes the visible state of the surface at |surface_index| in the surface
-// state object into |visible_out|.
-// @return 0 on success. Otherwise it returns a negative error value.
-int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state,
- size_t surface_index, bool* visible_out);
-
-// Writes the number of attributes on the surface at |surface_index| in the
-// state object into |count_out|.
-// @return 0 on success. Otherwise it returns a negative error value.
-int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state,
- size_t surface_index, size_t* count_out);
-
-// Writes the list of attribute key/value pairs for the surface at
-// |surface_index| in the surface state object into |attributes|.
-// @return The number of attributes written on success. Otherwise returns a
-// negative error value.
-ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state,
- size_t surface_index,
- DvrSurfaceAttribute* attributes,
- size_t max_count);
-
-__END_DECLS
-
-#endif // ANDROID_DVR_DISPLAY_MANAGER_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_display_types.h b/libs/vr/libdvr/include/dvr/dvr_display_types.h
deleted file mode 100644
index fd69843..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_display_types.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef ANDROID_DVR_DISPLAY_TYPES_H_
-#define ANDROID_DVR_DISPLAY_TYPES_H_
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// Define types used in pose buffer fields. These types have atomicity
-// guarantees that are useful in lock-free shared memory ring buffers.
-#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
-
-// VrFlinger display manager surface state snapshots per surface flags
-// indicating what changed since the last snapshot.
-enum {
- // No changes.
- DVR_SURFACE_UPDATE_FLAGS_NONE = 0,
- // This surface is new.
- DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE = (1 << 0),
- // Buffer queues added/removed.
- DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED = (1 << 1),
- // Visibility/z-order changed.
- DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED = (1 << 2),
- // Generic attributes changed.
- DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED = (1 << 3),
-};
-
-// Surface attribute keys. VrFlinger defines keys in the negative integer space.
-// The compositor is free to use keys in the positive integer space for
-// implementation-defined purposes.
-enum {
- // DIRECT: bool
- // Determines whether a direct surface is created (compositor output) or an
- // application surface. Defaults to false (application surface). May only be
- // set to true by a process with either UID=root or UID validated with
- // IsTrustedUid() (VrCore).
- DVR_SURFACE_ATTRIBUTE_DIRECT = -3,
- // Z_ORDER: int32_t
- // Interpreted by VrFlinger only on direct surfaces to order the corresponding
- // hardware layers. More positive values render on top of more negative
- // values.
- DVR_SURFACE_ATTRIBUTE_Z_ORDER = -2,
- // VISIBLE: bool
- // Interpreted by VrFlinger only on direct surfaces to determine whether a
- // surface is assigned to a hardware layer or ignored.
- DVR_SURFACE_ATTRIBUTE_VISIBLE = -1,
- // INVALID
- // Invalid key. No attributes should have this key.
- DVR_SURFACE_ATTRIBUTE_INVALID = 0,
- // FIRST_USER_KEY
- // VrFlinger ingores any keys with this value or greater, passing them to the
- // compositor through surface state query results.
- DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY = 1,
-};
-
-__END_DECLS
-
-#endif // ANDROID_DVR_DISPLAY_TYPES_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
deleted file mode 100644
index 0ba76e2..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_client.h
+++ /dev/null
@@ -1,199 +0,0 @@
-#ifndef ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
-#define ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
-
-#include <dvr/dvr_hardware_composer_types.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct AHardwareBuffer AHardwareBuffer;
-typedef struct DvrHwcClient DvrHwcClient;
-typedef struct DvrHwcFrame DvrHwcFrame;
-
-// Called when a new frame has arrived.
-//
-// @param client_state Pointer to client state passed in |dvrHwcCreateClient()|.
-// @param frame New frame. Owned by the client.
-// @return fence FD for the release of the last frame.
-typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
-
-// @param callback Called when a new frame is available.
-// @param client_state Pointer to client state passed back in the callback.
-DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback,
- void* client_state);
-
-// Called to free the DvrHwcClient pointer.
-void dvrHwcClientDestroy(DvrHwcClient* client);
-
-// Called to free the frame information.
-// @param frame Pointer for the valid frame used for the query.
-void dvrHwcFrameDestroy(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return Identifier for the display associated by the frame.
-DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return width of the physical display associated with |frame|. This does not
-// take into account any orientation changes.
-int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return height of the physical display associated with |frame|. This does not
-// take into account any orientation changes.
-int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return True if the display has been removed. In this case the current frame
-// does not contain any valid layers to display. It is a signal to clean up any
-// display related state.
-bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return Number of layers in the frame.
-size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The ID of the currently active display configuration.
-uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The ID of the current color mode. See HAL_COLOR_MODE_* for valid
-// values.
-uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param out_matrix Output parameter for a float[16] array which will be filled
-// with the color transform matrix.
-// @param out_hint Output parameter which will contain the color transform hint.
-// See HAL_COLOR_TRANSFORM_* for valid values.
-void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix,
- int32_t* out_hint);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The current power mode for the display. See HWC2_POWER_MODE_* for
-// valid values.
-uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @return The current state of vsync. See HWC2_VSYNC_* for valid values.
-uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return A unique ID for the layer.
-DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index);
-
-// Return the graphic buffer associated with the layer at |layer_index| in
-// |frame|.
-//
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return Graphic buffer. Caller owns the buffer and is responsible for freeing
-// it. (see AHardwareBuffer_release())
-AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame,
- size_t layer_index);
-
-// Returns the fence FD for the layer at index |layer_index| in |frame|.
-//
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return Fence FD. Caller owns the FD and is responsible for closing it.
-int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return describing the portion of the display covered by the layer. Will
-// not exceed the display dimensions.
-DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame,
- size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return describing the portion of the layer that will fill the display
-// frame. Will not exceed the layer dimensions.
-DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The blend mode of the layer.
-DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame,
- size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The alpha value to be applied to the whole layer. Will be in the
-// [0.0, 1.0] range.
-float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The type of the layer assigned by the window manager.
-uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The application id the layer belongs to.
-uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame,
- size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The z-order for the layer.
-uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param out_x Output parameter for the x coordinate of the cursor location.
-// @param out_y Output parameter for the y coordinate of the cursor location.
-void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index,
- int32_t* out_x, int32_t* out_y);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The transformation that needs to be applied to the layer before
-// presenting it. See DVR_HWC_TRANSFORM_* for valid values.
-uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The dataspace which represents how the pixel values should be
-// interpreted. See HAL_DATASPACE_* for valid values.
-uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The color of the layer if layer composition is SOLID_COLOR.
-uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The number of visible regions.
-uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame,
- size_t layer_index);
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param index The index of the visible region for the layer.
-// @return The rectangle describing the visible region.
-DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame,
- size_t layer_index, size_t index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @return The number of damanged regions.
-uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame,
- size_t layer_index);
-
-// @param frame Pointer for the valid frame used for the query.
-// @param layer_index The index of the layer in the frame.
-// @param index The index of the damanged region for the layer.
-// @return The rectangle describing the damaged region.
-DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame,
- size_t layer_index, size_t index);
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_CLIENT_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h b/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h
deleted file mode 100644
index 1d5eda6..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_hardware_composer_types.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
-#define ANDROID_VR_HARDWARE_COMPOSER_DEFS_H
-
-#include <inttypes.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// NOTE: These definitions must match the ones in
-// //hardware/libhardware/include/hardware/hwcomposer2.h. They are used by the
-// client side which does not have access to hwc2 headers.
-enum DvrHwcBlendMode {
- DVR_HWC_BLEND_MODE_INVALID = 0,
- DVR_HWC_BLEND_MODE_NONE = 1,
- DVR_HWC_BLEND_MODE_PREMULTIPLIED = 2,
- DVR_HWC_BLEND_MODE_COVERAGE = 3,
-};
-
-enum DvrHwcComposition {
- DVR_HWC_COMPOSITION_INVALID = 0,
- DVR_HWC_COMPOSITION_CLIENT = 1,
- DVR_HWC_COMPOSITION_DEVICE = 2,
- DVR_HWC_COMPOSITION_SOLID_COLOR = 3,
- DVR_HWC_COMPOSITION_CURSOR = 4,
- DVR_HWC_COMPOSITION_SIDEBAND = 5,
-};
-
-enum DvrHwcTransform {
- DVR_HWC_TRANSFORM_NONE = 0,
- DVR_HWC_TRANSFORM_FLIP_H = 1,
- DVR_HWC_TRANSFORM_FLIP_V = 2,
- DVR_HWC_TRANSFORM_ROT_90 = 4,
- DVR_HWC_TRANSFORM_ROT_180 = 3,
- DVR_HWC_TRANSFORM_ROT_270 = 7,
-};
-
-typedef uint64_t DvrHwcDisplay;
-typedef uint64_t DvrHwcLayer;
-
-struct DvrHwcRecti {
- int32_t left;
- int32_t top;
- int32_t right;
- int32_t bottom;
-};
-
-struct DvrHwcRectf {
- float left;
- float top;
- float right;
- float bottom;
-};
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_HARDWARE_COMPOSER_DEFS_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_performance.h b/libs/vr/libdvr/include/dvr/dvr_performance.h
deleted file mode 100644
index 5df35ad..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_performance.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_H_
-#define ANDROID_DVR_PERFORMANCE_H_
-
-#include <stddef.h>
-#include <unistd.h>
-
-__BEGIN_DECLS
-
-/// Sets the scheduler policy for a task.
-///
-/// Sets the scheduler policy for a task to the class described by a semantic
-/// string.
-///
-/// Supported policies are device-specific.
-///
-/// @param task_id The task id of task to set the policy for. When task_id is 0
-/// the current task id is substituted.
-/// @param scheduler_policy NULL-terminated ASCII string containing the desired
-/// scheduler policy.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrPerformanceSetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
-__END_DECLS
-
-#endif // ANDROID_DVR_PERFORMANCE_H_
-
diff --git a/libs/vr/libdvr/include/dvr/dvr_pose.h b/libs/vr/libdvr/include/dvr/dvr_pose.h
deleted file mode 100644
index 8752751..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_pose.h
+++ /dev/null
@@ -1,154 +0,0 @@
-#ifndef ANDROID_DVR_PUBLIC_POSE_H_
-#define ANDROID_DVR_PUBLIC_POSE_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#ifdef __ARM_NEON
-#include <arm_neon.h>
-#else
-#ifndef __FLOAT32X4T_86
-#define __FLOAT32X4T_86
-typedef float float32x4_t __attribute__((__vector_size__(16)));
-#endif
-#endif
-
-typedef struct DvrPoseClient DvrPoseClient;
-typedef struct DvrReadBufferQueue DvrReadBufferQueue;
-
-// Represents an estimated pose, accessed asynchronously through a shared ring
-// buffer. No assumptions should be made about the data in padding space.
-// The size of this struct is 128 bytes.
-typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync {
- // Left eye head-from-start orientation quaternion x,y,z,w.
- float32x4_t orientation;
- // Left eye head-from-start position x,y,z,pad in meters.
- float32x4_t position;
- // Right eye head-from-start orientation quaternion x,y,z,w.
- float32x4_t right_orientation;
- // Right eye head-from-start position x,y,z,pad in meters.
- float32x4_t right_position;
- // Start-space angular velocity x,y,z,pad in radians per second.
- float32x4_t angular_velocity;
- // Start-space positional velocity x,y,z,pad in meters per second.
- float32x4_t velocity;
- // Timestamp of when this pose is predicted for, typically halfway through
- // scanout.
- int64_t timestamp_ns;
- // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose.
- //
- // If DVR_POSE_FLAG_INVALID is set, the pose is indeterminate.
- uint64_t flags;
- // Reserved padding to 128 bytes.
- uint8_t pad[16];
-} DvrPoseAsync;
-
-enum {
- DVR_POSE_FLAG_INVALID = (1ULL << 0), // This pose is invalid.
- DVR_POSE_FLAG_INITIALIZING = (1ULL << 1), // The pose delivered during
- // initialization and it may not be
- // correct.
- DVR_POSE_FLAG_3DOF =
- (1ULL << 2), // This pose is derived from 3Dof sensors. If
- // this is not set, pose is derived using
- // 3Dof and 6Dof sensors.
- DVR_POSE_FLAG_FLOOR_HEIGHT_INVALID =
- (1ULL << 3), // If set the floor height is invalid.
-
- // Bits that indicate the tracking system state.
- DVR_POSE_FLAG_SERVICE_EXCEPTION = (1ULL << 32),
- DVR_POSE_FLAG_FISHEYE_OVER_EXPOSED = (1ULL << 33),
- DVR_POSE_FLAG_FISHEYE_UNDER_EXPOSED = (1ULL << 34),
- DVR_POSE_FLAG_COLOR_OVER_EXPOSED = (1ULL << 35),
- DVR_POSE_FLAG_COLOR_UNDER_EXPOSED = (1ULL << 36),
- DVR_POSE_FLAG_TOO_FEW_FEATURES_TRACKED = (1ULL << 37)
-};
-
-// Represents a sensor pose sample.
-typedef struct __attribute__((packed, aligned(16))) DvrPose {
- // Head-from-start orientation quaternion x,y,z,w.
- float32x4_t orientation;
-
- // The angular velocity where the x,y,z is the rotation axis and the
- // magnitude is the radians / second in the same coordinate frame as
- // orientation.
- float32x4_t angular_velocity;
-
- // Head-from-start position x,y,z,pad in meters.
- float32x4_t position;
-
- // In meters / second in the same coordinate frame as position.
- float32x4_t velocity;
-
- // In meters / second ^ 2 in the same coordinate frame as position.
- float32x4_t acceleration;
-
- // Timestamp for the measurement in nanoseconds.
- int64_t timestamp_ns;
-
- // The combination of flags above.
- uint64_t flags;
-
- // The current floor height. May be updated at a lower cadence than pose.
- float floor_height;
-
- // Padding to 112 bytes so the size is a multiple of 16.
- uint8_t padding[12];
-} DvrPose;
-
-// Represents a data type that can be streamed from pose service.
-enum {
- DVR_POSE_RAW_DATA_STEREO_IMAGE = (1ULL << 0),
- DVR_POSE_RAW_DATA_POINT_CLOUD = (1ULL << 1),
- DVR_POSE_RAW_DATA_FEATURES = (1ULL << 2),
-
- // Always last.
- DVR_POSE_RAW_DATA_COUNT = (1ULL << 3),
-};
-
-// A request to retrieve data from the pose service. Expects that a buffer
-// queue has been initialized through dvrPoseClientGetDataReader().
-typedef struct DvrPoseDataCaptureRequest {
- // The type of data to capture. Refer to enum DVR_POSE_RAW_DATA_* for types.
- uint64_t data_type;
- // The sample interval. This can be used to skip samples. For example, a
- // value of 5 will capture every fifth frame and discard the 4 frames in
- // between. Set to 1 to capture all frames.
- uint32_t sample_interval;
- // The length of time to capture samples in milliseconds. Set to 0 to capture
- // indefinitely.
- uint32_t capture_time_ms;
- // Reserved fields.
- uint32_t reserved0;
- uint32_t reserved1;
- uint32_t reserved2;
- uint32_t reserved3;
- uint32_t reserved4;
-} DvrPoseDataCaptureRequest;
-
-// Gets a read buffer queue for the data type |data_type|. Each call returns a
-// different read buffer queue connected to the same write buffer queue. A
-// separate write buffer queue exists for each |data_type|.
-//
-// PoseService supports a single consumer per write buffer queue. The consumer
-// is expected to hold a single DvrReadBufferQueue at a time. Callers should
-// cache these instead of requesting new ones when possible. If the consumer
-// disconnects from the queue, it can regain a read buffer queue for the same
-// producer by calling this function.
-//
-// For data_type DVR_POSE_RAW_DATA_STEREO_IMAGE, each buffer consists of two
-// images formatted as a AHARDWAREBUFFER_FORMAT_BLOB, where height is 1 and
-// width is the total size of both images. The size of an individual image can
-// be found in the metadata struct DvrNativeBufferMetadata, where width is
-// |crop_right| and height is |crop_bottom|/2. Each image is contiguous in
-// memory with stride equal to width.
-int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type,
- DvrReadBufferQueue** queue_out);
-
-// TODO(b/65067592): Move pose api's from pose_client.h to here.
-
-__END_DECLS
-
-#endif // ANDROID_DVR_PUBLIC_POSE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
deleted file mode 100644
index 63c7385..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef ANDROID_DVR_SHARED_BUFFERS_H_
-#define ANDROID_DVR_SHARED_BUFFERS_H_
-
-#include <dvr/dvr_config.h>
-#include <dvr/dvr_pose.h>
-#include <dvr/dvr_vsync.h>
-#include <libbroadcastring/broadcast_ring.h>
-
-// This header is shared by VrCore and Android and must be kept in sync.
-namespace android {
-namespace dvr {
-
-// Increment when the layout for the buffers change.
-enum : uint32_t { kSharedBufferLayoutVersion = 2 };
-
-// Note: These buffers will be mapped from various system processes as well
-// as VrCore and the application processes in a r/w manner.
-//
-// Therefore it is possible for the application to mess with the contents of
-// these buffers.
-//
-// While using them, assume garbage memory: Your logic must not crash or lead
-// to execution of unsafe code as a function of the contents of these buffers.
-
-// Sanity check for basic type sizes.
-static_assert(sizeof(DvrPoseAsync) == 128, "Unexpected size for DvrPoseAsync");
-static_assert(sizeof(DvrPose) == 112, "Unexpected size for DvrPose");
-static_assert(sizeof(DvrVsync) == 32, "Unexpected size for DvrVsync");
-static_assert(sizeof(DvrConfig) == 16, "Unexpected size for DvrConfig");
-
-// A helper class that provides compile time sized traits for the BroadcastRing.
-template <class DvrType, size_t StaticCount>
-class DvrRingBufferTraits {
- public:
- using Record = DvrType;
- static constexpr bool kUseStaticRecordSize = false;
- static constexpr uint32_t kStaticRecordCount = StaticCount;
- static constexpr int kMaxReservedRecords = 1;
- static constexpr int kMinAvailableRecords = 1;
-};
-
-// Traits classes.
-using DvrPoseTraits = DvrRingBufferTraits<DvrPose, 0>;
-using DvrVsyncTraits = DvrRingBufferTraits<DvrVsync, 2>;
-using DvrConfigTraits = DvrRingBufferTraits<DvrConfig, 2>;
-
-// The broadcast ring classes that will expose the data.
-using DvrPoseRing = BroadcastRing<DvrPose, DvrPoseTraits>;
-using DvrVsyncRing = BroadcastRing<DvrVsync, DvrVsyncTraits>;
-using DvrConfigRing = BroadcastRing<DvrConfig, DvrConfigTraits>;
-
-// This is a shared memory buffer for passing pose data estimated at vsyncs.
-//
-// This will be primarily used for late latching and EDS where we bind this
-// buffer in a shader and extract the right vsync-predicted pose.
-struct __attribute__((packed, aligned(16))) DvrVsyncPoseBuffer {
- enum : int {
- // The number vsync predicted poses to keep in the ring buffer.
- // Must be a power of 2.
- kSize = 8,
- kIndexMask = kSize - 1,
-
- // The number of vsyncs (from the current vsync) we predict in vsync buffer.
- // The other poses are left alone.
- kMinFutureCount = 4
- };
-
- // The vsync predicted poses.
- // The pose for the vsync n is:
- // vsync_poses[n % kSize]
- //
- // This buffer is unsynchronized: It is possible to get torn reads as the
- // sensor service updates the predictions as new sensor measurements come
- // in. In particular, it is possible to get the position and an updated
- // orientation while reading.
- DvrPoseAsync vsync_poses[kSize];
-
- // The latest sensor pose for GPU usage.
- DvrPose current_pose;
-
- // Current vsync_count (where sensord is writing poses from).
- uint32_t vsync_count;
-
- // For 16 byte alignment.
- uint8_t padding[12];
-};
-
-static_assert(sizeof(DvrVsyncPoseBuffer) == 1152,
- "Unexpected size for DvrVsyncPoseBuffer");
-
-// The keys for the dvr global buffers.
-enum DvrGlobalBuffers : int32_t {
- kVsyncPoseBuffer = 1,
- kVsyncBuffer = 2,
- kSensorPoseBuffer = 3,
- kVrFlingerConfigBufferKey = 4
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SHARED_BUFFERS_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
deleted file mode 100644
index 74a68a1..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef ANDROID_DVR_SURFACE_H_
-#define ANDROID_DVR_SURFACE_H_
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_api.h>
-#include <dvr/dvr_buffer.h>
-#include <dvr/dvr_buffer_queue.h>
-#include <dvr/dvr_display_types.h>
-
-__BEGIN_DECLS
-
-// Attribute types. The values are one-hot encoded to support singluar types or
-// masks of supported types.
-enum {
- DVR_SURFACE_ATTRIBUTE_TYPE_NONE = 0,
- DVR_SURFACE_ATTRIBUTE_TYPE_INT32 = (1 << 0),
- DVR_SURFACE_ATTRIBUTE_TYPE_INT64 = (1 << 1),
- DVR_SURFACE_ATTRIBUTE_TYPE_BOOL = (1 << 2),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT = (1 << 3),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2 = (1 << 4),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3 = (1 << 5),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4 = (1 << 6),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8 = (1 << 7),
- DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16 = (1 << 8),
-};
-
-typedef uint64_t DvrSurfaceAttributeType;
-typedef int32_t DvrSurfaceAttributeKey;
-
-typedef struct DvrSurfaceAttributeValue {
- DvrSurfaceAttributeType type;
- union {
- int32_t int32_value;
- int64_t int64_value;
- bool bool_value;
- float float_value;
- float float2_value[2];
- float float3_value[3];
- float float4_value[4];
- float float8_value[8];
- float float16_value[16];
- };
-} DvrSurfaceAttributeValue;
-
-typedef struct DvrSurfaceAttribute {
- DvrSurfaceAttributeKey key;
- DvrSurfaceAttributeValue value;
-} DvrSurfaceAttribute;
-
-// Creates a new display surface with the given attributes.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes,
- size_t attribute_count, DvrSurface** surface_out);
-
-// Destroys the display surface.
-void dvrSurfaceDestroy(DvrSurface* surface);
-
-// Gets the DisplayService global id for this surface.
-int dvrSurfaceGetId(DvrSurface* surface);
-
-// Sets attributes on the given display surface.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceSetAttributes(DvrSurface* surface,
- const DvrSurfaceAttribute* attributes,
- size_t attribute_count);
-
-// Creates a new write-side buffer queue on the given surface. Direct surfaces
-// may only have one queue, the latest call replacing any prior queue. Replaced
-// queues are still referenced and should be destryoed using the queue destroy
-// API.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
- uint32_t height, uint32_t format,
- uint32_t layer_count, uint64_t usage,
- size_t capacity, size_t metadata_size,
- DvrWriteBufferQueue** queue_out);
-
-// Sets up a named buffer for shared memory data transfer between display
-// clients and the system. Protected API that may only be called with sufficient
-// privilege.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage,
- DvrBuffer** buffer_out);
-
-// Deletes a named buffer. WARNING: This is dangerous because any existing
-// clients of this buffer will not be notified and will remain attached to
-// the old buffer. This is useful for tests, but probably not for production
-// code.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key);
-
-// Get a global buffer from the display service.
-// @return 0 on success. Otherwise returns a negative error value.
-int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer);
-
-// Read the native device display metrics as reported by the hardware composer.
-// This is useful as otherwise the device metrics are only reported as
-// relative to the current device orientation.
-// @param sizeof_metrics the size of the passed in metrics struct. This is used
-// to ensure we don't break each other during active development.
-// @param metrics on success holds the retrieved device metrics.
-// @return 0 on success. Otherwise returns a negative error value (typically
-// this means the display service is not available).
-int dvrGetNativeDisplayMetrics(size_t metrics_struct_size,
- DvrNativeDisplayMetrics* metrics);
-
-__END_DECLS
-
-#endif // ANDROID_DVR_SURFACE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_tracking.h b/libs/vr/libdvr/include/dvr/dvr_tracking.h
deleted file mode 100644
index 5e388f3..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_tracking.h
+++ /dev/null
@@ -1,185 +0,0 @@
-#ifndef ANDROID_DVR_TRACKING_H_
-#define ANDROID_DVR_TRACKING_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-#include <dvr/dvr_tracking_types.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrReadBuffer DvrReadBuffer;
-typedef struct DvrTrackingCamera DvrTrackingCamera;
-typedef struct DvrTrackingFeatureExtractor DvrTrackingFeatureExtractor;
-typedef struct DvrTrackingSensors DvrTrackingSensors;
-typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
-
-// The callback for DvrTrackingFeatureExtractor that will deliver the feature
-// events. This callback is passed to dvrTrackingFeatureExtractorStart.
-typedef void (*DvrTrackingFeatureCallback)(void* context,
- const DvrTrackingFeatures* event);
-
-// The callback for DvrTrackingSensors session that will deliver the events.
-// This callback is passed to dvrTrackingSensorsStart.
-typedef void (*DvrTrackingSensorEventCallback)(void* context,
- DvrTrackingSensorEvent* event);
-
-// Creates a DvrTrackingCamera session.
-//
-// On creation, the session is not in operating mode. Client code must call
-// dvrTrackingCameraStart to bootstrap the underlying camera stack.
-//
-// There is no plan to expose camera configuration through this API. All camera
-// parameters are determined by the system optimized for better tracking
-// results. See b/78662281 for detailed deprecation plan of this API and the
-// Stage 2 of VR tracking data source refactoring.
-//
-// @param out_camera The pointer of a DvrTrackingCamera will be filled here if
-// the method call succeeds.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraCreate(DvrTrackingCamera** out_camera);
-
-// Destroys a DvrTrackingCamera handle.
-//
-// @param camera The DvrTrackingCamera of interest.
-void dvrTrackingCameraDestroy(DvrTrackingCamera* camera);
-
-// Starts the DvrTrackingCamera.
-//
-// On successful return, all DvrReadBufferQueue's associated with the given
-// write_queue will start to receive buffers from the camera stack. Note that
-// clients of this API should not assume the buffer dimension, format, and/or
-// usage of the outcoming buffers, as they are governed by the underlying camera
-// logic. Also note that it's the client's responsibility to consume buffers
-// from DvrReadBufferQueue on time and return them back to the producer;
-// otherwise the camera stack might be blocked.
-//
-// @param camera The DvrTrackingCamera of interest.
-// @param write_queue A DvrWriteBufferQueue that the camera stack can use to
-// populate the buffer into. The queue must be empty and the camera stack
-// will request buffer allocation with proper buffer dimension, format, and
-// usage. Note that the write queue must be created with user_metadata_size
-// set to sizeof(DvrTrackingBufferMetadata). On success, the write_queue
-// handle will become invalid and the ownership of the queue handle will be
-// transferred into the camera; otherwise, the write_queue handle will keep
-// untouched and the caller still has the ownership.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraStart(DvrTrackingCamera* camera,
- DvrWriteBufferQueue* write_queue);
-
-// Stops the DvrTrackingCamera.
-//
-// On successful return, the DvrWriteBufferQueue set during
-// dvrTrackingCameraStart will stop getting new buffers from the camera stack.
-//
-// @param camera The DvrTrackingCamera of interest.
-// @return Zero on success, or negative error code.
-int dvrTrackingCameraStop(DvrTrackingCamera* camera);
-
-// Creates a DvrTrackingSensors session.
-//
-// This will initialize but not start device sensors (gyro / accel). Upon
-// successfull creation, the clients can call dvrTrackingSensorsStart to start
-// receiving sensor events.
-//
-// @param out_sensors The pointer of a DvrTrackingSensors will be filled here if
-// the method call succeeds.
-// @param mode The sensor mode.
-// mode="ndk": Use the Android NDK.
-// mode="direct": Use direct mode sensors (lower latency).
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsCreate(DvrTrackingSensors** out_sensors,
- const char* mode);
-
-// Destroys a DvrTrackingSensors session.
-//
-// @param sensors The DvrTrackingSensors struct to destroy.
-void dvrTrackingSensorsDestroy(DvrTrackingSensors* sensors);
-
-// Starts the tracking sensor session.
-//
-// This will start the device sensors and start pumping the feature and sensor
-// events as they arrive.
-//
-// @param client A tracking client created by dvrTrackingSensorsCreate.
-// @param context A client supplied pointer that will be passed to the callback.
-// @param callback A callback that will receive the sensor events on an
-// arbitrary thread.
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsStart(DvrTrackingSensors* sensors,
- DvrTrackingSensorEventCallback callback,
- void* context);
-
-// Stops a DvrTrackingSensors session.
-//
-// This will stop the device sensors. dvrTrackingSensorsStart can be called to
-// restart them again.
-//
-// @param client A tracking client created by dvrTrackingClientCreate.
-// @return Zero on success, or negative error code.
-int dvrTrackingSensorsStop(DvrTrackingSensors* sensors);
-
-// Creates a tracking feature extractor.
-//
-// This will initialize but not start the feature extraction session. Upon
-// successful creation, the client can call dvrTrackingFeatureExtractorStart to
-// start receiving features.
-//
-// @param out_extractor The pointer of a DvrTrackingFeatureExtractor will be
-// filled here if the method call succeeds.
-int dvrTrackingFeatureExtractorCreate(
- DvrTrackingFeatureExtractor** out_extractor);
-
-// Destroys a tracking feature extractor.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor* extractor);
-
-// Starts the tracking feature extractor.
-//
-// This will start the extractor and start pumping the output feature events to
-// the registered callback. Note that this method will create one or more
-// threads to handle feature processing.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor* extractor,
- DvrTrackingFeatureCallback callback,
- void* context);
-
-// Stops the tracking feature extractor.
-//
-// This will stop the extractor session and clean up all internal resourcse
-// related to this extractor. On succssful return, all internal therad started
-// by dvrTrackingFeatureExtractorStart should be stopped.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor* extractor);
-
-// Processes one buffer to extract features from.
-//
-// The buffer will be sent over to DSP for feature extraction. Once the process
-// is done, the processing thread will invoke DvrTrackingFeatureCallback with
-// newly extracted features. Note that not all buffers will be processed, as the
-// underlying DSP can only process buffers at a certain framerate. If a buffer
-// needs to be skipped, out_skipped filed will be set to true. Also note that
-// for successfully processed stereo buffer, two callbacks (one for each eye)
-// will be fired.
-//
-// @param extractor The DvrTrackingFeatureExtractor to destroy.
-// @param buffer The buffer to extract features from. Note that the buffer must
-// be in acquired state for the buffer to be processed. Also note that the
-// buffer will be released back to its producer on successful return of the
-// method.
-// @param metadata The metadata associated with the buffer. Should be populated
-// by DvrTrackingCamera session as user defined metadata.
-// @param out_skipped On successful return, the field will be set to true iff
-// the buffer was skipped; and false iff the buffer was processed. This
-// field is optional and nullptr can be passed here to ignore the field.
-// @return Zero on success, or negative error code.
-int dvrTrackingFeatureExtractorProcessBuffer(
- DvrTrackingFeatureExtractor* extractor, DvrReadBuffer* buffer,
- const DvrTrackingBufferMetadata* metadata, bool* out_skipped);
-
-__END_DECLS
-
-#endif // ANDROID_DVR_TRACKING_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_tracking_types.h b/libs/vr/libdvr/include/dvr/dvr_tracking_types.h
deleted file mode 100644
index 81310d2..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_tracking_types.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef ANDROID_DVR_TRACKING_TYPES_H_
-#define ANDROID_DVR_TRACKING_TYPES_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-typedef struct DvrTrackingBufferMetadata {
- // Specifies the source of this image.
- uint32_t camera_mask;
- // Specifies the memory format of this image.
- uint32_t format;
- /// The width of the image data.
- uint32_t width;
- /// The height of the image data.
- uint32_t height;
- /// The number of bytes per scanline of image data.
- uint32_t stride;
- /// The frame number of this image.
- int32_t frame_number;
- /// The timestamp of this image in nanoseconds. Taken in the middle of the
- /// exposure interval.
- int64_t timestamp_ns;
- // This is the timestamp for recording when the system using the HAL
- // received the callback. It will not be populated by the HAL.
- int64_t callback_timestamp_ns;
- /// The exposure duration of this image in nanoseconds.
- int64_t exposure_duration_ns;
-} DvrTrackingBufferMetadata;
-
-// Represents a set of features extracted from a camera frame. Note that this
-// should be in sync with TangoHalCallbacks defined in tango-hal.h.
-typedef struct DvrTrackingFeatures {
- // Specifies the source of the features.
- uint32_t camera_mask;
-
- // This is unused.
- uint32_t unused;
-
- // The timestamp in nanoseconds from the image that generated the features.
- // Taken in the middle of the exposure interval.
- int64_t timestamp_ns;
-
- // This is the timestamp for recording when the system using the HAL
- // received the callback. It will not be populated by the HAL.
- int64_t callback_timestamp_ns;
-
- // The frame number from the image that generated the features.
- int64_t frame_number;
-
- // The number of features.
- int count;
-
- // An array of 2D image points for each feature in the current image.
- // This is sub-pixel refined extremum location at the fine resolution.
- float (*positions)[2];
-
- // The id of these measurements.
- int32_t* ids;
-
- // The feature descriptors.
- uint64_t (*descriptors)[8];
-
- // Laplacian scores for each feature.
- float* scores;
-
- // Is this feature a minimum or maximum in the Laplacian image.
- // 0 if the feature is a maximum, 1 if it is a minimum.
- int32_t* is_minimum;
-
- // This corresponds to the sub-pixel index of the laplacian image
- // that the extremum was found.
- float* scales;
-
- // Computed orientation of keypoint as part of FREAK extraction, except
- // it's represented in radians and measured anti-clockwise.
- float* angles;
-
- // Edge scores for each feature.
- float* edge_scores;
-} DvrTrackingFeatures;
-
-// Represents a sensor event.
-typedef struct DvrTrackingSensorEvent {
- // The sensor type.
- int32_t sensor;
-
- // Event type.
- int32_t type;
-
- // This is the timestamp recorded from the device. Taken in the middle
- // of the integration interval and adjusted for any low pass filtering.
- int64_t timestamp_ns;
-
- // The event data.
- float x;
- float y;
- float z;
-} DvrTrackingSensorEvent;
-
-__END_DECLS
-
-#endif // ANDROID_DVR_TRACKING_TYPES_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_vsync.h b/libs/vr/libdvr/include/dvr/dvr_vsync.h
deleted file mode 100644
index 498bb5c..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_vsync.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef ANDROID_DVR_VSYNC_H_
-#define ANDROID_DVR_VSYNC_H_
-
-#include <stdint.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-// Represents a vsync sample. The size of this struct is 32 bytes.
-typedef struct __attribute__((packed, aligned(16))) DvrVsync {
- // The timestamp for the last vsync in nanoseconds.
- uint64_t vsync_timestamp_ns;
-
- // The index of the last vsync.
- uint32_t vsync_count;
-
- // Scan out for the left eye = vsync_timestamp_ns + vsync_left_eye_offset_ns.
- int32_t vsync_left_eye_offset_ns;
-
- // Scan out for the right eye = vsync_timestamp_ns + vsync_right_eye_offset_ns
- int32_t vsync_right_eye_offset_ns;
-
- // The period of a vsync in nanoseconds.
- uint32_t vsync_period_ns;
-
- // Padding to 32 bytes so the size is a multiple of 16.
- uint8_t padding[8];
-} DvrVsync;
-
-__END_DECLS
-
-#endif // ANDROID_DVR_VSYNC_H_
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
deleted file mode 100644
index fe4dfc7..0000000
--- a/libs/vr/libdvrcommon/Android.bp
+++ /dev/null
@@ -1,87 +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"],
-}
-
-localIncludeFiles = [
- "include",
-]
-
-sharedLibraries = [
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
- "libEGL",
- "libGLESv2",
- "libui",
- "libgui",
- "libhardware",
- "libpdx_default_transport",
-]
-
-staticLibraries = ["libbroadcastring"]
-
-headerLibraries = [
- "libeigen",
-]
-
-cc_library {
- local_include_dirs: localIncludeFiles,
-
- cflags: [
- "-DLOG_TAG=\"libdvrcommon\"",
- "-DTRACE=0",
- "-Wall",
- "-Werror",
- ],
- export_include_dirs: localIncludeFiles,
-
- header_libs: headerLibraries,
- export_header_lib_headers: headerLibraries,
-
- name: "libdvrcommon",
-}
-
-testFiles = [
- "tests/numeric_test.cpp",
- "tests/pose_test.cpp",
-]
-
-cc_test {
- name: "libdvrcommon_test",
-
- srcs: testFiles,
- cflags: [
- "-Wall",
- "-Werror",
- "-Wno-unused-parameter",
- ],
-
- shared_libs: sharedLibraries,
-
- static_libs: [
- "libgmock_main",
- "libgmock",
- "libgtest",
- "libdvrcommon",
- ] + staticLibraries,
-}
diff --git a/libs/vr/libdvrcommon/include/private/dvr/benchmark.h b/libs/vr/libdvrcommon/include/private/dvr/benchmark.h
deleted file mode 100644
index 7eeab16..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/benchmark.h
+++ /dev/null
@@ -1,86 +0,0 @@
-#ifndef ANDROID_DVR_BENCHMARK_H_
-#define ANDROID_DVR_BENCHMARK_H_
-
-#include <stdio.h>
-#include <time.h>
-
-#include <cutils/trace.h>
-
-#include <private/dvr/clock_ns.h>
-
-// Set benchmark traces, using Android systrace.
-//
-// The simplest one-parameter version of btrace automatically sets the
-// timestamp with the system clock. The other versions can optionally set the
-// timestamp manually, or pass additional data to be written to the log line.
-//
-// Example:
-// Btrace("Start execution");
-// ... code to benchmark ...
-// Btrace("End execution");
-//
-// Use compute_benchmarks.py
-// with the trace path "Start execution,End execution",
-// to report the elapsed time between the two calls.
-//
-// Btrace will either output to standard atrace, or to a file if specified.
-// The versions BtraceData also allow an int64_t to be included in the trace.
-
-// Btrace without data payload.
-static inline void Btrace(const char* name, int64_t nanoseconds_monotonic);
-static inline void Btrace(const char* name);
-static inline void Btrace(FILE* file, const char* name,
- int64_t nanoseconds_monotonic);
-static inline void Btrace(FILE* file, const char* name);
-
-// Btrace with data payload.
-static inline void BtraceData(const char* name, int64_t nanoseconds_monotonic,
- int64_t data);
-static inline void BtraceData(const char* name, int64_t data);
-static inline void BtraceData(FILE* file, const char* name,
- int64_t nanoseconds_monotonic, int64_t data);
-static inline void BtraceData(FILE* file, const char* name, int64_t data);
-
-static inline void Btrace(const char* name, int64_t nanoseconds_monotonic) {
- const int kLogMessageLength = 256;
- char log_message[kLogMessageLength];
- snprintf(log_message, kLogMessageLength, "#btrace#%s", name);
- atrace_int64(ATRACE_TAG_WEBVIEW, log_message, nanoseconds_monotonic);
-}
-
-static inline void Btrace(const char* name) {
- Btrace(name, android::dvr::GetSystemClockNs());
-}
-
-static inline void Btrace(FILE* file, const char* name,
- int64_t nanoseconds_monotonic) {
- fprintf(file, "#btrace#%s|%" PRId64 "\n", name, nanoseconds_monotonic);
-}
-
-static inline void Btrace(FILE* file, const char* name) {
- Btrace(file, name, android::dvr::GetSystemClockNs());
-}
-
-static inline void BtraceData(const char* name, int64_t nanoseconds_monotonic,
- int64_t data) {
- const int kLogMessageLength = 256;
- char log_message[kLogMessageLength];
- snprintf(log_message, kLogMessageLength, "#btrace#%s|%" PRId64, name, data);
- atrace_int64(ATRACE_TAG_WEBVIEW, log_message, nanoseconds_monotonic);
-}
-
-static inline void BtraceData(const char* name, int64_t data) {
- BtraceData(name, android::dvr::GetSystemClockNs(), data);
-}
-
-static inline void BtraceData(FILE* file, const char* name,
- int64_t nanoseconds_monotonic, int64_t data) {
- fprintf(file, "#btrace#%s|%" PRId64 "|%" PRId64 "\n", name, data,
- nanoseconds_monotonic);
-}
-
-static inline void BtraceData(FILE* file, const char* name, int64_t data) {
- BtraceData(file, name, android::dvr::GetSystemClockNs(), data);
-}
-
-#endif // ANDROID_DVR_BENCHMARK_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h b/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h
deleted file mode 100644
index 8e777ed..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/clock_ns.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef ANDROID_DVR_CLOCK_NS_H_
-#define ANDROID_DVR_CLOCK_NS_H_
-
-#include <stdint.h>
-#include <time.h>
-
-namespace android {
-namespace dvr {
-
-constexpr int64_t kNanosPerSecond = 1000000000ll;
-
-// Returns the standard Dream OS monotonic system time that corresponds with all
-// timestamps found in Dream OS APIs.
-static inline timespec GetSystemClock() {
- timespec t;
- clock_gettime(CLOCK_MONOTONIC, &t);
- return t;
-}
-
-static inline timespec GetSystemClockRaw() {
- timespec t;
- clock_gettime(CLOCK_MONOTONIC_RAW, &t);
- return t;
-}
-
-static inline int64_t GetSystemClockNs() {
- timespec t = GetSystemClock();
- int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
- return ns;
-}
-
-static inline int64_t GetSystemClockRawNs() {
- timespec t = GetSystemClockRaw();
- int64_t ns = kNanosPerSecond * (int64_t)t.tv_sec + (int64_t)t.tv_nsec;
- return ns;
-}
-
-static inline double NsToSec(int64_t nanoseconds) {
- return nanoseconds / static_cast<double>(kNanosPerSecond);
-}
-
-static inline double GetSystemClockSec() { return NsToSec(GetSystemClockNs()); }
-
-static inline double GetSystemClockMs() { return GetSystemClockSec() * 1000.0; }
-
-// Converts a nanosecond timestamp to a timespec. Based on the kernel function
-// of the same name.
-static inline timespec NsToTimespec(int64_t ns) {
- timespec t;
- int32_t remainder;
-
- t.tv_sec = ns / kNanosPerSecond;
- remainder = ns % kNanosPerSecond;
- if (remainder < 0) {
- t.tv_nsec--;
- remainder += kNanosPerSecond;
- }
- t.tv_nsec = remainder;
-
- return t;
-}
-
-// Timestamp comparison functions that handle wrapping values correctly.
-static inline bool TimestampLT(int64_t a, int64_t b) {
- return static_cast<int64_t>(static_cast<uint64_t>(a) -
- static_cast<uint64_t>(b)) < 0;
-}
-static inline bool TimestampLE(int64_t a, int64_t b) {
- return static_cast<int64_t>(static_cast<uint64_t>(a) -
- static_cast<uint64_t>(b)) <= 0;
-}
-static inline bool TimestampGT(int64_t a, int64_t b) {
- return static_cast<int64_t>(static_cast<uint64_t>(a) -
- static_cast<uint64_t>(b)) > 0;
-}
-static inline bool TimestampGE(int64_t a, int64_t b) {
- return static_cast<int64_t>(static_cast<uint64_t>(a) -
- static_cast<uint64_t>(b)) >= 0;
-}
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_CLOCK_NS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/debug.h b/libs/vr/libdvrcommon/include/private/dvr/debug.h
deleted file mode 100644
index c31a385..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/debug.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef ANDROID_DVR_DEBUG_H_
-#define ANDROID_DVR_DEBUG_H_
-
-#include <GLES3/gl3.h>
-#include <math.h>
-
-#include <log/log.h>
-
-#ifndef NDEBUG
-#define CHECK_GL() \
- do { \
- const GLenum err = glGetError(); \
- if (err != GL_NO_ERROR) { \
- ALOGE("OpenGL error %d", err); \
- } \
- } while (0)
-
-#define CHECK_GL_FBO() \
- do { \
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); \
- switch (status) { \
- case GL_FRAMEBUFFER_COMPLETE: \
- break; \
- case GL_FRAMEBUFFER_UNSUPPORTED: \
- ALOGE("GL_FRAMEBUFFER_UNSUPPORTED"); \
- break; \
- default: \
- ALOGE("FBO user error: %d", status); \
- break; \
- } \
- } while (0)
-#else
-#define CHECK_GL()
-#define CHECK_GL_FBO()
-#endif
-
-#endif // ANDROID_DVR_DEBUG_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/eigen.h b/libs/vr/libdvrcommon/include/private/dvr/eigen.h
deleted file mode 100644
index defaf58..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/eigen.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef ANDROID_DVR_EIGEN_H_
-#define ANDROID_DVR_EIGEN_H_
-
-#include <Eigen/Core>
-#include <Eigen/Geometry>
-
-namespace Eigen {
-
-// Eigen doesn't take advantage of C++ template typedefs, but we can
-template <class T, int N>
-using Vector = Matrix<T, N, 1>;
-
-template <class T>
-using Vector2 = Vector<T, 2>;
-
-template <class T>
-using Vector3 = Vector<T, 3>;
-
-template <class T>
-using Vector4 = Vector<T, 4>;
-
-template <class T, int N>
-using RowVector = Matrix<T, 1, N>;
-
-template <class T>
-using RowVector2 = RowVector<T, 2>;
-
-template <class T>
-using RowVector3 = RowVector<T, 3>;
-
-template <class T>
-using RowVector4 = RowVector<T, 4>;
-
-// In Eigen, the type you should be using for transformation matrices is the
-// `Transform` class, instead of a raw `Matrix`.
-// The `Projective` option means this will not make any assumptions about the
-// last row of the object, making this suitable for use as general OpenGL
-// projection matrices (which is the most common use-case). The one caveat
-// is that in order to apply this transformation to non-homogeneous vectors
-// (e.g., vec3), you must use the `.linear()` method to get the affine part of
-// the matrix.
-//
-// Example:
-// mat4 transform;
-// vec3 position;
-// vec3 transformed = transform.linear() * position;
-//
-// Note, the use of N-1 is because the parameter passed to Eigen is the ambient
-// dimension of the transformation, not the size of the matrix iself.
-// However graphics programmers sometimes get upset when they see a 3 next
-// to a matrix when they expect a 4, so I'm hoping this will avoid that.
-template <class T, int N>
-using AffineMatrix = Transform<T, N-1, Projective>;
-
-} // namespace Eigen
-
-#endif // ANDROID_DVR_EIGEN_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h b/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h
deleted file mode 100644
index d0ee69c..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/field_of_view.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef ANDROID_DVR_FIELD_OF_VIEW_H_
-#define ANDROID_DVR_FIELD_OF_VIEW_H_
-
-#include <cmath>
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// Encapsulates a generalized, asymmetric field of view with four half angles.
-// Each half angle denotes the angle between the corresponding frustum plane.
-// Together with a near and far plane, a FieldOfView forms the frustum of an
-// off-axis perspective projection.
-class FieldOfView {
- public:
- // The default constructor sets an angle of 0 (in any unit) for all four
- // half-angles.
- FieldOfView() : left_(0.0f), right_(0.0f), bottom_(0.0f), top_(0.0f) {}
-
- // Constructs a FieldOfView from four angles.
- FieldOfView(float left, float right, float bottom, float top)
- : left_(left), right_(right), bottom_(bottom), top_(top) {}
-
- explicit FieldOfView(const float* fov)
- : FieldOfView(fov[0], fov[1], fov[2], fov[3]) {}
-
- // Accessors for all four half-angles.
- float GetLeft() const { return left_; }
- float GetRight() const { return right_; }
- float GetBottom() const { return bottom_; }
- float GetTop() const { return top_; }
-
- // Setters for all four half-angles.
- void SetLeft(float left) { left_ = left; }
- void SetRight(float right) { right_ = right; }
- void SetBottom(float bottom) { bottom_ = bottom; }
- void SetTop(float top) { top_ = top; }
-
- Eigen::AffineMatrix<float, 4> GetProjectionMatrix(float z_near,
- float z_far) const {
- float x_left = -std::tan(left_) * z_near;
- float x_right = std::tan(right_) * z_near;
- float y_bottom = -std::tan(bottom_) * z_near;
- float y_top = std::tan(top_) * z_near;
-
- float zero = 0.0f;
- if (x_left == x_right || y_bottom == y_top || z_near == z_far ||
- z_near <= zero || z_far <= zero) {
- return Eigen::AffineMatrix<float, 4>::Identity();
- }
-
- float x = (2 * z_near) / (x_right - x_left);
- float y = (2 * z_near) / (y_top - y_bottom);
- float a = (x_right + x_left) / (x_right - x_left);
- float b = (y_top + y_bottom) / (y_top - y_bottom);
- float c = (z_near + z_far) / (z_near - z_far);
- float d = (2 * z_near * z_far) / (z_near - z_far);
-
- // Note: Eigen matrix initialization syntax is always 'column-major'
- // even if the storage is row-major. Or in other words, just write the
- // matrix like you'd see in a math textbook.
- Eigen::AffineMatrix<float, 4> result;
- result.matrix() << x, 0, a, 0,
- 0, y, b, 0,
- 0, 0, c, d,
- 0, 0, -1, 0;
- return result;
- }
-
- static FieldOfView FromProjectionMatrix(
- const Eigen::AffineMatrix<float, 4>& m) {
- // Compute tangents.
- float tan_vert_fov = 1.0f / m(1, 1);
- float tan_horz_fov = 1.0f / m(0, 0);
- float t = (m(1, 2) + 1.0f) * tan_vert_fov;
- float b = (m(1, 2) - 1.0f) * tan_vert_fov;
- float l = (m(0, 2) - 1.0f) * tan_horz_fov;
- float r = (m(0, 2) + 1.0f) * tan_horz_fov;
-
- return FieldOfView(std::atan(-l), std::atan(r), std::atan(-b),
- std::atan(t));
- }
-
- private:
- float left_;
- float right_;
- float bottom_;
- float top_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_FIELD_OF_VIEW_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h b/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h
deleted file mode 100644
index 12ef622..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/log_helpers.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef ANDROID_DVR_LOG_HELPERS_H_
-#define ANDROID_DVR_LOG_HELPERS_H_
-
-#include <iomanip>
-#include <ostream>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/field_of_view.h>
-
-namespace android {
-namespace dvr {
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
- const Eigen::Vector<T, 2>& vec) {
- return out << "vec2(" << vec.x() << ',' << vec.y() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
- const Eigen::Vector<T, 3>& vec) {
- return out << "vec3(" << vec.x() << ',' << vec.y() << ',' << vec.z() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
- const Eigen::Vector<T, 4>& vec) {
- return out << "vec4(" << vec.x() << ',' << vec.y() << ',' << vec.z() << ','
- << vec.w() << ')';
-}
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& out,
- const Eigen::AffineMatrix<T, 4>& mat) {
- out << std::setfill(' ') << std::setprecision(4) << std::fixed
- << std::showpos;
- out << "\nmat4[";
- out << std::setw(10) << mat(0, 0) << " " << std::setw(10) << mat(0, 1) << " "
- << std::setw(10) << mat(0, 2) << " " << std::setw(10) << mat(0, 3);
- out << "]\n [";
- out << std::setw(10) << mat(1, 0) << " " << std::setw(10) << mat(1, 1) << " "
- << std::setw(10) << mat(1, 2) << " " << std::setw(10) << mat(1, 3);
- out << "]\n [";
- out << std::setw(10) << mat(2, 0) << " " << std::setw(10) << mat(2, 1) << " "
- << std::setw(10) << mat(2, 2) << " " << std::setw(10) << mat(2, 3);
- out << "]\n [";
- out << std::setw(10) << mat(3, 0) << " " << std::setw(10) << mat(3, 1) << " "
- << std::setw(10) << mat(3, 2) << " " << std::setw(10) << mat(3, 3);
- out << "]\n";
-
- return out;
-}
-
-inline std::ostream& operator<<(std::ostream& out, const FieldOfView& fov) {
- return out << "fov(" << (fov.GetLeft() * 180.0f / M_PI) << ','
- << (fov.GetRight() * 180.0f / M_PI) << ','
- << (fov.GetBottom() * 180.0f / M_PI) << ','
- << (fov.GetTop() * 180.0f / M_PI) << ')';
-}
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_LOG_HELPERS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h b/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
deleted file mode 100644
index aef7146..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef ANDROID_DVR_MATRIX_HELPERS_H_
-#define ANDROID_DVR_MATRIX_HELPERS_H_
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-// A helper function for creating a mat4 directly.
-inline mat4 MakeMat4(float m00, float m01, float m02, float m03, float m10,
- float m11, float m12, float m13, float m20, float m21,
- float m22, float m23, float m30, float m31, float m32,
- float m33) {
- Eigen::Matrix4f matrix;
-
- matrix << m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30,
- m31, m32, m33;
-
- return mat4(matrix);
-}
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_LOG_HELPERS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/numeric.h b/libs/vr/libdvrcommon/include/private/dvr/numeric.h
deleted file mode 100644
index 4545893..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/numeric.h
+++ /dev/null
@@ -1,175 +0,0 @@
-#ifndef ANDROID_DVR_NUMERIC_H_
-#define ANDROID_DVR_NUMERIC_H_
-
-#include <cmath>
-#include <limits>
-#include <random>
-#include <type_traits>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-template <typename FT>
-static inline FT ToDeg(FT f) {
- return f * static_cast<FT>(180.0 / M_PI);
-}
-
-template <typename FT>
-static inline FT ToRad(FT f) {
- return f * static_cast<FT>(M_PI / 180.0);
-}
-
-// Adjusts `x` to the periodic range `[lo, hi]` (to normalize angle values
-// for example).
-template <typename T>
-T NormalizePeriodicRange(T x, T lo, T hi) {
- T range_size = hi - lo;
-
- while (x < lo) {
- x += range_size;
- }
-
- while (x > hi) {
- x -= range_size;
- }
-
- return x;
-}
-
-// Normalizes a measurement in radians.
-// @param x the angle to be normalized
-// @param centre the point around which to normalize the range
-// @return the value of x, normalized to the range [centre - 180, centre + 180]
-template <typename T>
-T NormalizeDegrees(T x, T centre = static_cast<T>(180.0)) {
- return NormalizePeriodicRange(x, centre - static_cast<T>(180.0),
- centre + static_cast<T>(180.0));
-}
-
-// Normalizes a measurement in radians.
-// @param x the angle to be normalized
-// @param centre the point around which to normalize the range
-// @return the value of x, normalized to the range
-// [centre - M_PI, centre + M_PI]
-// @remark the centre parameter is to make it possible to specify a different
-// periodic range. This is useful if you are planning on comparing two
-// angles close to 0 or M_PI, so that one might not accidentally end
-// up on the other side of the range
-template <typename T>
-T NormalizeRadians(T x, T centre = static_cast<T>(M_PI)) {
- return NormalizePeriodicRange(x, centre - static_cast<T>(M_PI),
- centre + static_cast<T>(M_PI));
-}
-
-static inline vec2i Round(const vec2& v) {
- return vec2i(roundf(v.x()), roundf(v.y()));
-}
-
-static inline vec2i Scale(const vec2i& v, float scale) {
- return vec2i(roundf(static_cast<float>(v.x()) * scale),
- roundf(static_cast<float>(v.y()) * scale));
-}
-
-// Re-maps `x` from `[lba,uba]` to `[lbb,ubb]`.
-template <typename T>
-T ConvertRange(T x, T lba, T uba, T lbb, T ubb) {
- return (((x - lba) * (ubb - lbb)) / (uba - lba)) + lbb;
-}
-
-template <typename R1, typename R2>
-static inline vec2 MapPoint(const vec2& pt, const R1& from, const R2& to) {
- vec2 normalized((pt - vec2(from.p1)).array() / vec2(from.GetSize()).array());
- return (normalized * vec2(to.GetSize())) + vec2(to.p1);
-}
-
-template <typename T>
-inline bool IsZero(const T& v,
- const T& tol = std::numeric_limits<T>::epsilon()) {
- return std::abs(v) <= tol;
-}
-
-template <typename T>
-inline bool IsEqual(const T& a, const T& b,
- const T& tol = std::numeric_limits<T>::epsilon()) {
- return std::abs(b - a) <= tol;
-}
-
-template <typename T>
-T Square(const T& x) {
- return x * x;
-}
-
-template <typename T>
-T RandomInRange(T lo, T hi,
- typename
- std::enable_if<std::is_floating_point<T>::value>::type* = 0) {
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_real_distribution<T> distro(lo, hi);
- return distro(gen);
-}
-
-template <typename T>
-T RandomInRange(T lo, T hi,
- typename
- std::enable_if<std::is_integral<T>::value>::type* = 0) {
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_int_distribution<T> distro(lo, hi);
- return distro(gen);
-}
-
-template <typename Derived1, typename Derived2>
-Derived1 RandomInRange(
- const Eigen::MatrixBase<Derived1>& lo,
- const Eigen::MatrixBase<Derived2>& hi) {
- EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived1, Derived2);
-
- Derived1 result = Eigen::MatrixBase<Derived1>::Zero();
-
- for (int row = 0; row < result.rows(); ++row) {
- for (int col = 0; col < result.cols(); ++col) {
- result(row, col) = RandomInRange(lo(row, col), hi(row, col));
- }
- }
-
- return result;
-}
-
-template <typename T>
-T RandomRange(T x) {
- return RandomInRange(-x, x);
-}
-
-template <typename T>
-T Clamp(T x, T lo, T hi) {
- return std::min(std::max(x, lo), hi);
-}
-
-inline mat3 ScaleMatrix(const vec2& scale_xy) {
- return mat3(Eigen::Scaling(scale_xy[0], scale_xy[1], 1.0f));
-}
-
-inline mat3 TranslationMatrix(const vec2& translation) {
- return mat3(Eigen::Translation2f(translation));
-}
-
-inline mat4 TranslationMatrix(const vec3& translation) {
- return mat4(Eigen::Translation3f(translation));
-}
-
-inline vec2 TransformPoint(const mat3& m, const vec2& p) {
- return m.linear() * p + m.translation();
-}
-
-inline vec2 TransformVector(const mat3& m, const vec2& p) {
- return m.linear() * p;
-}
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_NUMERIC_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/ortho.h b/libs/vr/libdvrcommon/include/private/dvr/ortho.h
deleted file mode 100644
index fc0bce3..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/ortho.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ANDROID_DVR_ORTHO_H_
-#define ANDROID_DVR_ORTHO_H_
-
-#include <private/dvr/types.h>
-
-namespace android {
-namespace dvr {
-
-template <class T>
-Eigen::AffineMatrix<T, 4> OrthoMatrix(T left, T right, T bottom, T top,
- T znear, T zfar) {
- Eigen::AffineMatrix<T, 4> result;
- const T t2 = static_cast<T>(2);
- const T a = t2 / (right - left);
- const T b = t2 / (top - bottom);
- const T c = t2 / (zfar - znear);
- const T xoff = -(right + left) / (right - left);
- const T yoff = -(top + bottom) / (top - bottom);
- const T zoff = -(zfar + znear) / (zfar - znear);
- const T t1 = static_cast<T>(1);
- result.matrix() << a, 0, 0, xoff,
- 0, b, 0, yoff,
- 0, 0, c, zoff,
- 0, 0, 0, t1;
- return result;
-}
-
-} // namespace android
-} // namespace dvr
-
-#endif // ANDROID_DVR_ORTHO_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/pose.h b/libs/vr/libdvrcommon/include/private/dvr/pose.h
deleted file mode 100644
index 97944e8..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/pose.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef ANDROID_DVR_POSE_H_
-#define ANDROID_DVR_POSE_H_
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// Encapsulates a 3D pose (rotation and position).
-//
-// @tparam T Data type for storing the position coordinate and rotation
-// quaternion.
-template <typename T>
-class Pose {
- public:
- // Creates identity pose.
- Pose()
- : rotation_(Eigen::Quaternion<T>::Identity()),
- position_(Eigen::Vector3<T>::Zero()) {}
-
- // Initializes a pose with given rotation and position.
- //
- // rotation Initial rotation.
- // position Initial position.
- Pose(Eigen::Quaternion<T> rotation, Eigen::Vector3<T> position)
- : rotation_(rotation), position_(position) {}
-
- void Invert() {
- rotation_ = rotation_.inverse();
- position_ = rotation_ * -position_;
- }
-
- Pose Inverse() const {
- Pose result(*this);
- result.Invert();
- return result;
- }
-
- // Compute the composition of this pose with another, storing the result
- // in the current object
- void ComposeInPlace(const Pose& other) {
- position_ = position_ + rotation_ * other.position_;
- rotation_ = rotation_ * other.rotation_;
- }
-
- // Computes the composition of this pose with another, and returns the result
- Pose Compose(const Pose& other) const {
- Pose result(*this);
- result.ComposeInPlace(other);
- return result;
- }
-
- Eigen::Vector3<T> TransformPoint(const Eigen::Vector3<T>& v) const {
- return rotation_ * v + position_;
- }
-
- Eigen::Vector3<T> Transform(const Eigen::Vector3<T>& v) const {
- return rotation_ * v;
- }
-
- Pose& operator*=(const Pose& other) {
- ComposeInPlace(other);
- return *this;
- }
-
- Pose operator*(const Pose& other) const { return Compose(other); }
-
- // Gets the rotation of the 3D pose.
- Eigen::Quaternion<T> GetRotation() const { return rotation_; }
-
- // Gets the position of the 3D pose.
- Eigen::Vector3<T> GetPosition() const { return position_; }
-
- // Sets the rotation of the 3D pose.
- void SetRotation(Eigen::Quaternion<T> rotation) { rotation_ = rotation; }
-
- // Sets the position of the 3D pose.
- void SetPosition(Eigen::Vector3<T> position) { position_ = position; }
-
- // Gets a 4x4 matrix representing a transform from the reference space (that
- // the rotation and position of the pose are relative to) to the object space.
- Eigen::AffineMatrix<T, 4> GetObjectFromReferenceMatrix() const;
-
- // Gets a 4x4 matrix representing a transform from the object space to the
- // reference space (that the rotation and position of the pose are relative
- // to).
- Eigen::AffineMatrix<T, 4> GetReferenceFromObjectMatrix() const;
-
- private:
- Eigen::Quaternion<T> rotation_;
- Eigen::Vector3<T> position_;
-};
-
-template <typename T>
-Eigen::AffineMatrix<T, 4> Pose<T>::GetObjectFromReferenceMatrix() const {
- // The transfrom from the reference is the inverse of the pose.
- Eigen::AffineMatrix<T, 4> matrix(rotation_.inverse().toRotationMatrix());
- return matrix.translate(-position_);
-}
-
-template <typename T>
-Eigen::AffineMatrix<T, 4> Pose<T>::GetReferenceFromObjectMatrix() const {
- // The transfrom to the reference.
- Eigen::AffineMatrix<T, 4> matrix(rotation_.toRotationMatrix());
- return matrix.pretranslate(position_);
-}
-
-//------------------------------------------------------------------------------
-// Type-specific typedefs.
-//------------------------------------------------------------------------------
-
-using Posef = Pose<float>;
-using Posed = Pose<double>;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_POSE_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/range.h b/libs/vr/libdvrcommon/include/private/dvr/range.h
deleted file mode 100644
index 1d06c96..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/range.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef ANDROID_DVR_RANGE_H_
-#define ANDROID_DVR_RANGE_H_
-
-#include <private/dvr/eigen.h>
-
-namespace android {
-namespace dvr {
-
-// TODO(skiazyk): Replace all instances of this with Eigen::AlignedBox
-
-// Container of two points that define a 2D range.
-template <class T, int d>
-struct Range {
- // Construct an uninitialized Range.
- Range() {}
- Range(Eigen::Vector<T, d> p1, Eigen::Vector<T, d> p2) : p1(p1), p2(p2) {}
-
- static Range<T, d> FromSize(Eigen::Vector<T, d> p1,
- Eigen::Vector<T, d> size) {
- return Range<T, d>(p1, p1 + size);
- }
-
- bool operator==(const Range<T, d>& rhs) const {
- return p1 == rhs.p1 && p2 == rhs.p2;
- }
-
- Eigen::Vector<T, d> GetMinPoint() const { return p1; }
-
- Eigen::Vector<T, d> GetMaxPoint() const { return p2; }
-
- Eigen::Vector<T, d> GetSize() const { return p2 - p1; }
-
- Eigen::Vector<T, d> p1;
- Eigen::Vector<T, d> p2;
-};
-
-typedef Range<int, 2> Range2i;
-typedef Range<float, 2> Range2f;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_RANGE_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h b/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h
deleted file mode 100644
index 1824241..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/ring_buffer.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef ANDROID_DVR_RING_BUFFER_H_
-#define ANDROID_DVR_RING_BUFFER_H_
-
-#include <utility>
-#include <vector>
-
-namespace android {
-namespace dvr {
-
-// A simple ring buffer implementation.
-//
-// A vector works but you either have to keep track of start_ and size_ yourself
-// or erase() from the front which is inefficient.
-//
-// A deque works but the common usage pattern of Append() PopFront() Append()
-// PopFront() looks like it allocates each time size goes from 0 --> 1, which we
-// don't want. This class allocates only once.
-template <typename T>
-class RingBuffer {
- public:
- RingBuffer() { Reset(0); }
-
- explicit RingBuffer(size_t capacity) { Reset(capacity); }
-
- RingBuffer(const RingBuffer& other) = default;
- RingBuffer(RingBuffer&& other) noexcept = default;
- RingBuffer& operator=(const RingBuffer& other) = default;
- RingBuffer& operator=(RingBuffer&& other) noexcept = default;
-
- void Append(const T& val) {
- if (IsFull())
- PopFront();
- Get(size_) = val;
- size_++;
- }
-
- void Append(T&& val) {
- if (IsFull())
- PopFront();
- Get(size_) = std::move(val);
- size_++;
- }
-
- bool IsEmpty() const { return size_ == 0; }
-
- bool IsFull() const { return size_ == buffer_.size(); }
-
- size_t GetSize() const { return size_; }
-
- size_t GetCapacity() const { return buffer_.size(); }
-
- T& Get(size_t i) { return buffer_[(start_ + i) % buffer_.size()]; }
-
- const T& Get(size_t i) const {
- return buffer_[(start_ + i) % buffer_.size()];
- }
-
- const T& Back() const { return Get(size_ - 1); }
-
- T& Back() { return Get(size_ - 1); }
-
- const T& Front() const { return Get(0); }
-
- T& Front() { return Get(0); }
-
- void PopBack() {
- if (size_ != 0) {
- Get(size_ - 1) = T();
- size_--;
- }
- }
-
- void PopFront() {
- if (size_ != 0) {
- Get(0) = T();
- start_ = (start_ + 1) % buffer_.size();
- size_--;
- }
- }
-
- void Clear() { Reset(GetCapacity()); }
-
- void Reset(size_t capacity) {
- start_ = size_ = 0;
- buffer_.clear();
- buffer_.resize(capacity);
- }
-
- private:
- // Ideally we'd allocate our own memory and use placement new to instantiate
- // instances of T instead of using a vector, but the vector is simpler.
- std::vector<T> buffer_;
- size_t start_, size_;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_RING_BUFFER_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h b/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h
deleted file mode 100644
index 6048652..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/test/test_macros.h
+++ /dev/null
@@ -1,124 +0,0 @@
-#ifndef LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
-#define LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
-
-#include <gtest/gtest.h>
-
-#include <cmath>
-
-#include <private/dvr/numeric.h>
-
-namespace android {
-namespace dvr {
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpArrayLikeFloatEq(
- const char* expectedStr, const char* actualStr, const char* toleranceStr,
- const A& expected, const B& actual, const T& tolerance) {
- for (int i = 0; i < N; ++i) {
- if (!IsEqual(expected[i], actual[i], tolerance)) {
- return ::testing::AssertionFailure()
- << "\"" << expectedStr << "\" and \"" << actualStr
- << "\" differ at element " << i << " by at least " << tolerance
- << " : "
- << " Expected \"" << expected[i] << "\", was \"" << actual[i]
- << "\".";
- }
- }
-
- return ::testing::AssertionSuccess();
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpMatrixLikeFloatEq(
- const char* expectedStr, const char* actualStr, const char* toleranceStr,
- const A& expected, const B& actual, const T& tolerance) {
- for (int r = 0; r < N; ++r) {
- for (int c = 0; c < N; ++c) {
- if (!IsEqual(expected(r, c), actual(r, c), tolerance)) {
- return ::testing::AssertionFailure()
- << "\"" << expectedStr << "\" and \"" << actualStr
- << "\" differ at (" << r << "," << c << ")"
- << " by at least " << tolerance << " : "
- << " Expected \"" << expected(r, c) << "\", was \""
- << actual(r, c) << "\".";
- }
- }
- }
-
- return ::testing::AssertionSuccess();
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpArrayLikeFloatNe(
- const char* expectedStr, const char* actualStr, const char* toleranceStr,
- const A& expected, const B& actual, const T& tolerance) {
- for (int i = 0; i < N; ++i) {
- if (!IsEqual(expected[i], actual[i], tolerance)) {
- return ::testing::AssertionSuccess();
- }
- }
-
- ::testing::Message message;
- message << "Expected \"" << expectedStr
- << "\" to differ from provided value \"" << actualStr
- << "\" by at least " << tolerance << ".";
-
- return ::testing::AssertionFailure(message);
-}
-
-template <int N, typename A, typename B, typename T>
-::testing::AssertionResult CmpMatrixLikeFloatNe(
- const char* expectedStr, const char* actualStr, const char* toleranceStr,
- const A& expected, const B& actual, const T& tolerance) {
- for (int r = 0; r < N; ++r) {
- for (int c = 0; c < N; ++c) {
- if (!IsEqual(expected(r, c), actual(r, c), tolerance)) {
- return ::testing::AssertionSuccess();
- }
- }
- }
-
- ::testing::Message message;
- message << "Expected \"" << expectedStr
- << "\" to differ from provided value \"" << actualStr
- << "\" by at least " << tolerance << ".";
-
- return ::testing::AssertionFailure(message);
-}
-
-} // namespace dvr
-} // namespace android
-
-#define EXPECT_VEC3_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatEq<3>, expected, actual, \
- tol)
-
-#define EXPECT_VEC3_NOT_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatNe<3>, expected, actual, \
- tol)
-
-#define EXPECT_QUAT_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatEq<3>, expected.coeffs(), \
- actual.coeffs(), tol)
-
-#define EXPECT_QUAT_NOT_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpArrayLikeFloatNe<3>, expected.coeffs(), \
- actual.coeffs(), tol)
-
-#define EXPECT_MAT4_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatEq<4>, expected, actual, \
- tol)
-
-#define EXPECT_MAT4_NOT_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatNe<4>, expected, actual, \
- tol)
-
-#define EXPECT_MAT3_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr \
- : CmpMatrixLikeFloatEq<3>, expected, actual, tol)
-
-#define EXPECT_MAT3_NOT_NEAR(expected, actual, tol) \
- EXPECT_PRED_FORMAT3(android::dvr::CmpMatrixLikeFloatNe<3>, expected, actual, \
- tol)
-
-#endif // LIBS_VR_LIBDVRCOMMON_INCLUDE_PRIVATE_DVR_TEST_TEST_MACROS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/types.h b/libs/vr/libdvrcommon/include/private/dvr/types.h
deleted file mode 100644
index 1fa54af..0000000
--- a/libs/vr/libdvrcommon/include/private/dvr/types.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef ANDROID_DVR_TYPES_H_
-#define ANDROID_DVR_TYPES_H_
-
-// All basic types used by VR code.
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/field_of_view.h>
-#include <private/dvr/pose.h>
-#include <private/dvr/range.h>
-
-namespace android {
-namespace dvr {
-
-enum RgbColorChannel { kRed, kGreen, kBlue };
-
-// EyeType: 0 for left, 1 for right.
-enum EyeType { kLeftEye = 0, kRightEye = 1 };
-
-// In the context of VR, vector types are used as much as base types.
-
-using vec2f = Eigen::Vector2f;
-using vec2d = Eigen::Vector2d;
-using vec2i = Eigen::Vector2i;
-using vec2 = vec2f;
-
-using vec3f = Eigen::Vector3f;
-using vec3d = Eigen::Vector3d;
-using vec3i = Eigen::Vector3i;
-using vec3 = vec3f;
-
-using vec4f = Eigen::Vector4f;
-using vec4d = Eigen::Vector4d;
-using vec4i = Eigen::Vector4i;
-using vec4 = vec4f;
-
-using mat3f = Eigen::AffineMatrix<float, 3>;
-using mat3d = Eigen::AffineMatrix<double, 3>;
-using mat3 = mat3f;
-
-using mat4f = Eigen::AffineMatrix<float, 4>;
-using mat4d = Eigen::AffineMatrix<double, 4>;
-using mat4 = mat4f;
-
-using quatf = Eigen::Quaternionf;
-using quatd = Eigen::Quaterniond;
-using quat = quatf;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_TYPES_H_
diff --git a/libs/vr/libdvrcommon/tests/numeric_test.cpp b/libs/vr/libdvrcommon/tests/numeric_test.cpp
deleted file mode 100644
index 1ee1447..0000000
--- a/libs/vr/libdvrcommon/tests/numeric_test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <private/dvr/numeric.h>
-
-using TestTypes = ::testing::Types<float, double, int>;
-
-using android::dvr::RandomInRange;
-
-template <typename T>
-class NumericTest : public ::testing::TestWithParam<T> {
- public:
- using FT = T;
-};
-
-TYPED_TEST_CASE(NumericTest, TestTypes);
-
-TYPED_TEST(NumericTest, RandomInRange) {
- using FT = typename TestFixture::FT;
-
- const int kNumTrials = 50;
- const FT kLowRange = static_cast<FT>(-100);
- const FT kHighRange = static_cast<FT>(100);
-
- for (int i = 0; i < kNumTrials; ++i) {
- FT value = RandomInRange(kLowRange, kHighRange);
-
- EXPECT_LE(kLowRange, value);
- EXPECT_GE(kHighRange, value);
- }
-}
-
-TEST(RandomInRange, TestIntVersion) {
- // This checks specifically that the function does not always give the lo
- // value (this was previously a bug)
-
- const int kNumTrials = 50;
- const int kLowRange = -100;
- const int kHighRange = 100;
-
- for (int i = 0; i < kNumTrials; ++i) {
- int value = RandomInRange(kLowRange, kHighRange);
-
- if (value != kLowRange) {
- SUCCEED();
- return;
- }
- }
-
- FAIL() << "Did not produce a value other than the range minimum for "
- << "integers.";
-}
-
-TEST(RandomInRange, TestVectorVersion) {
- Eigen::Vector3d lo(-3.0, -4.0, -5.0);
- Eigen::Vector3d hi(5.0, 4.0, 3.0);
-
- const int kNumTrials = 50;
-
- for (int i = 0; i < kNumTrials; ++i) {
- Eigen::Vector3d result = RandomInRange(lo, hi);
-
- for (int j = 0; j < 3; ++j) {
- EXPECT_LE(lo[j], result[j]);
- EXPECT_GE(hi[j], result[j]);
- }
- }
-}
diff --git a/libs/vr/libdvrcommon/tests/pose_test.cpp b/libs/vr/libdvrcommon/tests/pose_test.cpp
deleted file mode 100644
index aa1896d..0000000
--- a/libs/vr/libdvrcommon/tests/pose_test.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <private/dvr/eigen.h>
-#include <private/dvr/pose.h>
-#include <private/dvr/test/test_macros.h>
-
-using PoseTypes = ::testing::Types<float, double>;
-
-template <class T>
-class PoseTest : public ::testing::TestWithParam<T> {
- public:
- using FT = T;
- using Pose_t = android::dvr::Pose<FT>;
- using quat_t = Eigen::Quaternion<FT>;
- using vec3_t = Eigen::Vector3<FT>;
- using mat4_t = Eigen::AffineMatrix<FT, 4>;
-};
-
-TYPED_TEST_CASE(PoseTest, PoseTypes);
-
-// Check that the two matrix methods are inverses of each other
-TYPED_TEST(PoseTest, SelfInverse) {
- using quat_t = typename TestFixture::quat_t;
- using vec3_t = typename TestFixture::vec3_t;
- using Pose_t = typename TestFixture::Pose_t;
- using mat4_t = typename TestFixture::mat4_t;
- using FT = typename TestFixture::FT;
-
- const auto tolerance = FT(0.0001);
-
- const quat_t initial_rotation(Eigen::AngleAxis<FT>(
- FT(M_PI / 3.0), vec3_t(FT(3.0), FT(4.0), FT(5.0)).normalized()));
- const vec3_t initial_position = vec3_t(FT(2.0), FT(10.0), FT(-4.0));
- const Pose_t initial_pose(initial_rotation, initial_position);
-
- auto result_pose = initial_pose.GetReferenceFromObjectMatrix() *
- initial_pose.GetObjectFromReferenceMatrix();
-
- EXPECT_MAT4_NEAR(result_pose, mat4_t::Identity(), tolerance);
-}
-
-TYPED_TEST(PoseTest, TransformPoint) {
- using quat_t = typename TestFixture::quat_t;
- using vec3_t = typename TestFixture::vec3_t;
- using Pose_t = typename TestFixture::Pose_t;
- using FT = typename TestFixture::FT;
-
- const auto tolerance = FT(0.0001);
-
- const quat_t pose_rotation(
- Eigen::AngleAxis<FT>(FT(M_PI / 2.0), vec3_t(FT(0.0), FT(0.0), FT(1.0))));
- const auto pose_position = vec3_t(FT(1.0), FT(1.0), FT(2.0));
-
- const Pose_t test_pose(pose_rotation, pose_position);
-
- for (int axis = 0; axis < 3; ++axis) {
- vec3_t start_position = vec3_t::Zero();
- start_position[axis] = FT(1.0);
- const vec3_t expected_transformed =
- (pose_rotation * start_position) + pose_position;
- const vec3_t actual_transformed = test_pose.TransformPoint(start_position);
- EXPECT_VEC3_NEAR(expected_transformed, actual_transformed, tolerance);
- }
-}
-
-TYPED_TEST(PoseTest, TransformVector) {
- using quat_t = typename TestFixture::quat_t;
- using vec3_t = typename TestFixture::vec3_t;
- using Pose_t = typename TestFixture::Pose_t;
- using FT = typename TestFixture::FT;
-
- const auto tolerance = FT(0.0001);
-
- const quat_t pose_rotation(Eigen::AngleAxis<FT>(
- FT(M_PI / 6.0), vec3_t(FT(3.0), FT(4.0), FT(5.0)).normalized()));
-
- const auto pose_position = vec3_t(FT(500.0), FT(-500.0), FT(300.0));
-
- const Pose_t test_pose(pose_rotation, pose_position);
-
- for (int axis = 0; axis < 3; ++axis) {
- vec3_t start_position = vec3_t::Zero();
- start_position[axis] = FT(1.0);
- const vec3_t expected_rotated = pose_rotation * start_position;
- const vec3_t actual_rotated = test_pose.Transform(start_position);
- EXPECT_VEC3_NEAR(expected_rotated, actual_rotated, tolerance);
- }
-}
-
-TYPED_TEST(PoseTest, Composition) {
- using quat_t = typename TestFixture::quat_t;
- using Pose_t = typename TestFixture::Pose_t;
- using vec3_t = typename TestFixture::vec3_t;
- using FT = typename TestFixture::FT;
-
- const auto tolerance = FT(0.0001);
-
- const quat_t first_rotation(
- Eigen::AngleAxis<FT>(FT(M_PI / 2.0), vec3_t(FT(0.0), FT(0.0), FT(1.0))));
- const auto first_offset = vec3_t(FT(-3.0), FT(2.0), FT(-1.0));
- const quat_t second_rotation(Eigen::AngleAxis<FT>(
- FT(M_PI / 3.0), vec3_t(FT(1.0), FT(-1.0), FT(0.0)).normalized()));
- const auto second_offset = vec3_t(FT(6.0), FT(-7.0), FT(-8.0));
-
- const Pose_t first_pose(first_rotation, first_offset);
- const Pose_t second_pose(second_rotation, second_offset);
-
- const auto combined_pose(second_pose.Compose(first_pose));
-
- for (int axis = 0; axis < 3; ++axis) {
- vec3_t start_position = vec3_t::Zero();
- start_position[axis] = FT(1.0);
- const vec3_t expected_transformed =
- second_pose.TransformPoint(first_pose.TransformPoint(start_position));
- const vec3_t actual_transformed =
- combined_pose.TransformPoint(start_position);
- EXPECT_VEC3_NEAR(expected_transformed, actual_transformed, tolerance);
- }
-}
-
-TYPED_TEST(PoseTest, Inverse) {
- using quat_t = typename TestFixture::quat_t;
- using vec3_t = typename TestFixture::vec3_t;
- using Pose_t = typename TestFixture::Pose_t;
- using FT = typename TestFixture::FT;
-
- const auto tolerance = FT(0.0001);
-
- const quat_t pose_rotation(Eigen::AngleAxis<FT>(
- FT(M_PI / 2.0), vec3_t(FT(4.0), FT(-2.0), FT(-1.0)).normalized()));
- const auto pose_position = vec3_t(FT(-1.0), FT(2.0), FT(-4.0));
-
- Pose_t pose(pose_rotation, pose_position);
- const Pose_t pose_inverse = pose.Inverse();
-
- for (int axis = 0; axis < 3; ++axis) {
- vec3_t start_position = vec3_t::Zero();
- start_position[axis] = FT(1.0);
- const vec3_t transformed = pose.Transform(start_position);
- const vec3_t inverted = pose_inverse.Transform(transformed);
- EXPECT_VEC3_NEAR(start_position, inverted, tolerance);
- }
-
- Pose_t nullified_pose[2] = {
- pose.Compose(pose_inverse), pose_inverse.Compose(pose),
- };
-
- for (int i = 0; i < 2; ++i) {
- EXPECT_QUAT_NEAR(quat_t::Identity(), nullified_pose[i].GetRotation(),
- tolerance);
- EXPECT_VEC3_NEAR(vec3_t::Zero(), nullified_pose[i].GetPosition(),
- tolerance);
- }
-}
diff --git a/libs/vr/libpdx/Android.bp b/libs/vr/libpdx/Android.bp
deleted file mode 100644
index c95603b..0000000
--- a/libs/vr/libpdx/Android.bp
+++ /dev/null
@@ -1,85 +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_headers {
- name: "libpdx_headers",
- export_include_dirs: ["private"],
- vendor_available: true,
- min_sdk_version: "29",
-}
-
-cc_library_static {
- name: "libpdx",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-DLOG_TAG=\"libpdx\"",
- "-DTRACE=0",
- ],
- header_libs: ["libpdx_headers"],
- export_header_lib_headers: ["libpdx_headers"],
- srcs: [
- "client.cpp",
- "service.cpp",
- "service_dispatcher.cpp",
- "status.cpp",
- ],
- shared_libs: [
- "libbinder",
- "libcutils",
- "libutils",
- "liblog",
- ],
-}
-
-cc_test {
- name: "pdx_tests",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- srcs: [
- "client_tests.cpp",
- "mock_tests.cpp",
- "serialization_tests.cpp",
- "service_tests.cpp",
- "status_tests.cpp",
- "thread_local_buffer_tests.cpp",
- "variant_tests.cpp",
- ],
- static_libs: [
- "libcutils",
- "libgmock",
- "libpdx",
- "liblog",
- "libutils",
- ],
- shared_libs: [
- "libvndksupport",
- ],
-}
-
-// Code analysis target.
-cc_test {
- name: "pdx_encoder_performance_test",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-O2",
- ],
- srcs: [
- "encoder_performance_test.cpp",
- ],
- static_libs: [
- "libpdx",
- ],
-}
diff --git a/libs/vr/libpdx/client.cpp b/libs/vr/libpdx/client.cpp
deleted file mode 100644
index 3c66a40..0000000
--- a/libs/vr/libpdx/client.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-#include "pdx/client.h"
-
-#include <log/log.h>
-
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-
-void Client::EnableAutoReconnect(int64_t reconnect_timeout_ms) {
- if (channel_factory_) {
- reconnect_timeout_ms_ = reconnect_timeout_ms;
- auto_reconnect_enabled_ = true;
- }
-}
-
-void Client::DisableAutoReconnect() { auto_reconnect_enabled_ = false; }
-
-bool Client::IsConnected() const { return channel_.get() != nullptr; }
-
-Status<void> Client::CheckReconnect() {
- Status<void> ret;
- bool was_disconnected = !IsConnected();
- if (auto_reconnect_enabled_ && was_disconnected && channel_factory_) {
- auto status = channel_factory_->Connect(reconnect_timeout_ms_);
- if (!status) {
- error_ = -status.error();
- ret.SetError(status.error());
- return ret;
- }
- channel_ = status.take();
- }
-
- if (!IsConnected()) {
- ret.SetError(ESHUTDOWN);
- } else {
- // Call the subclass OnConnect handler. The subclass may choose to close the
- // connection in the handler, in which case error_ will be non-zero.
- if (was_disconnected)
- OnConnect();
- if (!IsConnected())
- ret.SetError(-error_);
- else
- ret.SetValue();
- }
-
- return ret;
-}
-
-bool Client::NeedToDisconnectChannel(int error) const {
- return error == ESHUTDOWN && auto_reconnect_enabled_;
-}
-
-void Client::CheckDisconnect(int error) {
- if (NeedToDisconnectChannel(error))
- Close(error);
-}
-
-Client::Client(std::unique_ptr<ClientChannel> channel)
- : channel_{std::move(channel)} {}
-
-Client::Client(std::unique_ptr<ClientChannelFactory> channel_factory,
- int64_t timeout_ms)
- : channel_factory_{std::move(channel_factory)} {
- auto status = channel_factory_->Connect(timeout_ms);
- if (!status) {
- ALOGE("Client::Client: Failed to connect to service because: %s",
- status.GetErrorMessage().c_str());
- error_ = -status.error();
- } else {
- channel_ = status.take();
- }
-}
-
-bool Client::IsInitialized() const {
- return IsConnected() || (channel_factory_ && auto_reconnect_enabled_);
-}
-
-void Client::OnConnect() {}
-
-int Client::error() const { return error_; }
-
-Status<void> Client::SendImpulse(int opcode) {
- PDX_TRACE_NAME("Client::SendImpulse");
-
- auto status = CheckReconnect();
- if (!status)
- return status;
-
- status = channel_->SendImpulse(opcode, nullptr, 0);
- CheckDisconnect(status);
- return status;
-}
-
-Status<void> Client::SendImpulse(int opcode, const void* buffer,
- size_t length) {
- PDX_TRACE_NAME("Client::SendImpulse");
-
- auto status = CheckReconnect();
- if (!status)
- return status;
-
- status = channel_->SendImpulse(opcode, buffer, length);
- CheckDisconnect(status);
- return status;
-}
-
-void Client::Close(int error) {
- channel_.reset();
- // Normalize error codes to negative integer space.
- error_ = error <= 0 ? error : -error;
-}
-
-int Client::event_fd() const {
- return IsConnected() ? channel_->event_fd() : -1;
-}
-
-LocalChannelHandle& Client::GetChannelHandle() {
- return channel_->GetChannelHandle();
-}
-
-const LocalChannelHandle& Client::GetChannelHandle() const {
- return channel_->GetChannelHandle();
-}
-
-///////////////////////////// Transaction implementation //////////////////////
-
-Transaction::Transaction(Client& client) : client_{client} {}
-
-Transaction::~Transaction() {
- if (state_allocated_ && client_.GetChannel())
- client_.GetChannel()->FreeTransactionState(state_);
-}
-
-bool Transaction::EnsureStateAllocated() {
- if (!state_allocated_ && client_.GetChannel()) {
- state_ = client_.GetChannel()->AllocateTransactionState();
- state_allocated_ = true;
- }
- return state_allocated_;
-}
-
-void Transaction::SendTransaction(int opcode, Status<void>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- *ret = client_.CheckReconnect();
- if (!*ret)
- return;
-
- if (!EnsureStateAllocated()) {
- ret->SetError(ESHUTDOWN);
- return;
- }
-
- auto status = client_.GetChannel()->SendWithInt(
- state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
- if (status) {
- ret->SetValue();
- } else {
- ret->SetError(status.error());
- }
- CheckDisconnect(status);
-}
-
-void Transaction::SendTransaction(int opcode, Status<int>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- auto status = client_.CheckReconnect();
- if (!status) {
- ret->SetError(status.error());
- return;
- }
-
- if (!EnsureStateAllocated()) {
- ret->SetError(ESHUTDOWN);
- return;
- }
-
- *ret = client_.GetChannel()->SendWithInt(
- state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
- CheckDisconnect(*ret);
-}
-
-void Transaction::SendTransaction(int opcode, Status<LocalHandle>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- auto status = client_.CheckReconnect();
- if (!status) {
- ret->SetError(status.error());
- return;
- }
-
- if (!EnsureStateAllocated()) {
- ret->SetError(ESHUTDOWN);
- return;
- }
-
- *ret = client_.GetChannel()->SendWithFileHandle(
- state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
- CheckDisconnect(*ret);
-}
-
-void Transaction::SendTransaction(int opcode, Status<LocalChannelHandle>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- auto status = client_.CheckReconnect();
- if (!status) {
- ret->SetError(status.error());
- return;
- }
-
- if (!EnsureStateAllocated()) {
- ret->SetError(ESHUTDOWN);
- return;
- }
-
- *ret = client_.GetChannel()->SendWithChannelHandle(
- state_, opcode, send_vector, send_count, receive_vector, receive_count);
-
- CheckDisconnect(*ret);
-}
-
-Status<FileReference> Transaction::PushFileHandle(const LocalHandle& handle) {
- if (client_.CheckReconnect() && EnsureStateAllocated())
- return client_.GetChannel()->PushFileHandle(state_, handle);
- return ErrorStatus{ESHUTDOWN};
-}
-
-Status<FileReference> Transaction::PushFileHandle(
- const BorrowedHandle& handle) {
- if (client_.CheckReconnect() && EnsureStateAllocated())
- return client_.GetChannel()->PushFileHandle(state_, handle);
- return ErrorStatus{ESHUTDOWN};
-}
-
-Status<FileReference> Transaction::PushFileHandle(const RemoteHandle& handle) {
- return handle.Get();
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
- const LocalChannelHandle& handle) {
- if (client_.CheckReconnect() && EnsureStateAllocated())
- return client_.GetChannel()->PushChannelHandle(state_, handle);
- return ErrorStatus{ESHUTDOWN};
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
- const BorrowedChannelHandle& handle) {
- if (client_.CheckReconnect() && EnsureStateAllocated())
- return client_.GetChannel()->PushChannelHandle(state_, handle);
- return ErrorStatus{ESHUTDOWN};
-}
-
-Status<ChannelReference> Transaction::PushChannelHandle(
- const RemoteChannelHandle& handle) {
- return handle.value();
-}
-
-bool Transaction::GetFileHandle(FileReference ref, LocalHandle* handle) {
- return client_.CheckReconnect() && EnsureStateAllocated() &&
- client_.GetChannel()->GetFileHandle(state_, ref, handle);
-}
-
-bool Transaction::GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) {
- return client_.CheckReconnect() && EnsureStateAllocated() &&
- client_.GetChannel()->GetChannelHandle(state_, ref, handle);
-}
-
-void Transaction::CheckDisconnect(int error) {
- if (client_.NeedToDisconnectChannel(error)) {
- if (state_allocated_) {
- if (client_.GetChannel())
- client_.GetChannel()->FreeTransactionState(state_);
- state_ = nullptr;
- state_allocated_ = false;
- }
- client_.Close(error);
- }
-}
-
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx/client_tests.cpp b/libs/vr/libpdx/client_tests.cpp
deleted file mode 100644
index 99ccc69..0000000
--- a/libs/vr/libpdx/client_tests.cpp
+++ /dev/null
@@ -1,567 +0,0 @@
-#include <pdx/client.h>
-
-#include <gmock/gmock.h>
-#include <sys/eventfd.h>
-
-#include <pdx/mock_client_channel.h>
-#include <pdx/mock_client_channel_factory.h>
-#include <pdx/rpc/remote_method.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::ClientBase;
-using android::pdx::ClientChannel;
-using android::pdx::ClientChannelFactory;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::MockClientChannel;
-using android::pdx::MockClientChannelFactory;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::rpc::Void;
-
-using testing::A;
-using testing::AnyNumber;
-using testing::ByMove;
-using testing::Invoke;
-using testing::Ne;
-using testing::Return;
-using testing::_;
-
-namespace {
-
-inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
-inline const void* IntToConstPtr(intptr_t addr) {
- return reinterpret_cast<const void*>(addr);
-}
-
-struct TestInterface final {
- // Op codes.
- enum {
- kOpAdd = 0,
- kOpSendFile,
- kOpGetFile,
- kOpPushChannel,
- };
-
- // Methods.
- PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
- PDX_REMOTE_METHOD(SendFile, kOpSendFile, void(const LocalHandle& fd));
- PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
- PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
-
- PDX_REMOTE_API(API, Add, SendFile, GetFile, PushChannel);
-};
-
-class SimpleClient : public ClientBase<SimpleClient> {
- public:
- explicit SimpleClient(std::unique_ptr<ClientChannel> channel)
- : BASE{std::move(channel)} {}
- SimpleClient(std::unique_ptr<ClientChannelFactory> channel_factory,
- int64_t timeout_ms)
- : BASE{std::move(channel_factory), timeout_ms} {
- EnableAutoReconnect(timeout_ms);
- }
-
- using BASE::SendImpulse;
- using BASE::InvokeRemoteMethod;
- using BASE::InvokeRemoteMethodInPlace;
- using BASE::Close;
- using BASE::IsConnected;
- using BASE::EnableAutoReconnect;
- using BASE::DisableAutoReconnect;
- using BASE::event_fd;
- using BASE::GetChannel;
-
- MOCK_METHOD0(OnConnect, void());
-};
-
-class FailingClient : public ClientBase<FailingClient> {
- public:
- explicit FailingClient(std::unique_ptr<ClientChannel> channel, int error_code)
- : BASE{std::move(channel)} {
- Close(error_code);
- }
-};
-
-class ClientChannelTest : public testing::Test {
- public:
- ClientChannelTest()
- : client_{SimpleClient::Create(
- std::make_unique<testing::StrictMock<MockClientChannel>>())} {}
-
- MockClientChannel* mock_channel() {
- return static_cast<MockClientChannel*>(client_->GetChannel());
- }
-
- std::unique_ptr<SimpleClient> client_;
-};
-
-class ClientChannelFactoryTest : public testing::Test {
- public:
- ClientChannelFactoryTest() {
- auto factory =
- std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
- ON_CALL(*factory, Connect(kTimeout))
- .WillByDefault(Invoke(this, &ClientChannelFactoryTest::OnConnect));
- client_ = SimpleClient::Create(std::move(factory), kTimeout);
- }
-
- MockClientChannel* mock_channel() {
- return static_cast<MockClientChannel*>(client_->GetChannel());
- }
-
- Status<std::unique_ptr<ClientChannel>> OnConnect(int64_t /*timeout_ms*/) {
- if (on_connect_error_)
- return ErrorStatus(on_connect_error_);
- std::unique_ptr<MockClientChannel> channel =
- std::make_unique<testing::StrictMock<MockClientChannel>>();
- if (on_connect_callback_)
- on_connect_callback_(channel.get());
- return Status<std::unique_ptr<ClientChannel>>{std::move(channel)};
- }
-
- void OnConnectCallback(std::function<void(MockClientChannel*)> callback) {
- on_connect_callback_ = callback;
- }
- void SetOnConnectError(int error) { on_connect_error_ = error; }
- void ResetOnConnectError() { on_connect_error_ = 0; }
-
- constexpr static int64_t kTimeout = 123;
- std::unique_ptr<SimpleClient> client_;
- std::function<void(MockClientChannel*)> on_connect_callback_;
- int on_connect_error_{0};
-};
-
-constexpr int64_t ClientChannelFactoryTest::kTimeout;
-
-class ClientTransactionTest : public ClientChannelTest {
- public:
- ClientTransactionTest() : transaction_{*client_} {}
-
- Transaction transaction_;
-};
-
-} // anonymous namespace
-
-TEST_F(ClientChannelTest, IsInitialized) {
- ASSERT_NE(client_.get(), nullptr);
- EXPECT_TRUE(client_->IsInitialized());
- EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelTest, CloseOnConstruction) {
- FailingClient failed_client1{std::make_unique<MockClientChannel>(), EACCES};
- ASSERT_FALSE(failed_client1.IsInitialized());
- EXPECT_EQ(-EACCES, failed_client1.error());
-
- FailingClient failed_client2{std::make_unique<MockClientChannel>(), -EACCES};
- ASSERT_FALSE(failed_client2.IsInitialized());
- EXPECT_EQ(-EACCES, failed_client2.error());
-
- auto failed_client3 =
- FailingClient::Create(std::make_unique<MockClientChannel>(), EIO);
- ASSERT_EQ(failed_client3.get(), nullptr);
-}
-
-TEST_F(ClientChannelTest, IsConnected) {
- EXPECT_TRUE(client_->IsConnected());
- EXPECT_EQ(0, client_->error());
- client_->Close(-EINVAL);
- EXPECT_FALSE(client_->IsConnected());
- EXPECT_EQ(-EINVAL, client_->error());
-}
-
-TEST_F(ClientChannelTest, event_fd) {
- EXPECT_CALL(*mock_channel(), event_fd()).WillOnce(Return(12));
- EXPECT_EQ(12, client_->event_fd());
-}
-
-TEST_F(ClientChannelTest, SendImpulse) {
- EXPECT_CALL(*mock_channel(), SendImpulse(123, nullptr, 0))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(client_->SendImpulse(123));
-
- EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
- .WillOnce(Return(ErrorStatus{EIO}));
- auto status = client_->SendImpulse(17);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-
- const void* const kTestPtr = IntToConstPtr(1234);
- EXPECT_CALL(*mock_channel(), SendImpulse(1, kTestPtr, 17))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(client_->SendImpulse(1, kTestPtr, 17));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodNullTransactionState) {
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(nullptr));
- EXPECT_CALL(*mock_channel(),
- SendWithInt(nullptr, TestInterface::kOpAdd, _, _, nullptr, 0))
- .WillOnce(Return(9));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
- EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::Add>(4, 5));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodAddSuccess) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(
- *mock_channel(),
- SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
- .WillOnce(Return(3));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
- ASSERT_TRUE(status);
- EXPECT_EQ(3, status.get());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodAddFailure) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(
- *mock_channel(),
- SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileSuccess) {
- void* const kTransactionState = IntToPtr(123);
- int fd = eventfd(0, 0);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(),
- SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
- _, _, nullptr, 0))
- .WillOnce(Return(ByMove(LocalHandle{fd})));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<LocalHandle> status =
- client_->InvokeRemoteMethod<TestInterface::GetFile>();
- ASSERT_TRUE(status);
- EXPECT_EQ(fd, status.get().Get());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileFailure) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(),
- SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
- _, _, nullptr, 0))
- .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<LocalHandle> status =
- client_->InvokeRemoteMethod<TestInterface::GetFile>("file", 0);
- ASSERT_FALSE(status);
- EXPECT_EQ(EACCES, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelSuccess) {
- void* const kTransactionState = IntToPtr(123);
- const int32_t kHandleValue = 17;
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(
- *mock_channel(),
- SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
- _, nullptr, 0))
- .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, kHandleValue})));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<LocalChannelHandle> status =
- client_->InvokeRemoteMethod<TestInterface::PushChannel>();
- ASSERT_TRUE(status);
- EXPECT_EQ(kHandleValue, status.get().value());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelFailure) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(
- *mock_channel(),
- SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
- _, nullptr, 0))
- .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- Status<LocalChannelHandle> status =
- client_->InvokeRemoteMethod<TestInterface::PushChannel>();
- ASSERT_FALSE(status);
- EXPECT_EQ(EACCES, status.error());
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileSuccess) {
- void* const kTransactionState = IntToPtr(123);
- LocalHandle fd{eventfd(0, 0)};
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(),
- PushFileHandle(kTransactionState, A<const LocalHandle&>()))
- .WillOnce(Return(1));
- EXPECT_CALL(*mock_channel(),
- SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
- nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
-}
-
-TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileFailure) {
- void* const kTransactionState = IntToPtr(123);
- LocalHandle fd{eventfd(0, 0)};
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(),
- PushFileHandle(kTransactionState, A<const LocalHandle&>()))
- .WillOnce(Return(1));
- EXPECT_CALL(*mock_channel(),
- SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
- nullptr, 0))
- .WillOnce(Return(ErrorStatus{EACCES}));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- EXPECT_FALSE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
-}
-
-TEST_F(ClientChannelFactoryTest, IsInitialized) {
- ASSERT_NE(client_.get(), nullptr);
- EXPECT_TRUE(client_->IsInitialized());
- EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, NotConnectedButInitialized) {
- auto factory =
- std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
- EXPECT_CALL(*factory, Connect(kTimeout))
- .WillOnce(Return(ByMove(ErrorStatus(ESHUTDOWN))))
- .WillOnce(Invoke(this, &ClientChannelFactoryTest::OnConnect));
- client_ = SimpleClient::Create(std::move(factory), kTimeout);
- ASSERT_NE(client_.get(), nullptr);
- EXPECT_TRUE(client_->IsInitialized());
- EXPECT_FALSE(client_->IsConnected());
- client_->DisableAutoReconnect();
- ASSERT_FALSE(client_->SendImpulse(17));
- EXPECT_FALSE(client_->IsConnected());
- client_->EnableAutoReconnect(kTimeout);
- EXPECT_CALL(*client_, OnConnect());
- OnConnectCallback([](auto* mock) {
- EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
- .WillOnce(Return(Status<void>{}));
- });
- ASSERT_TRUE(client_->SendImpulse(17));
- EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, CheckDisconnect) {
- EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
- .WillOnce(Return(ErrorStatus{ESHUTDOWN}));
- ASSERT_FALSE(client_->SendImpulse(17));
- EXPECT_FALSE(client_->IsConnected());
- EXPECT_EQ(-ESHUTDOWN, client_->error());
-}
-
-TEST_F(ClientChannelFactoryTest, CheckReconnect) {
- client_->Close(ESHUTDOWN);
- ASSERT_FALSE(client_->IsConnected());
-
- EXPECT_CALL(*client_, OnConnect());
- OnConnectCallback([](auto* mock) {
- EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
- .WillOnce(Return(Status<void>{}));
- });
- ASSERT_TRUE(client_->SendImpulse(17));
- EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientChannelFactoryTest, CloseOnConnect) {
- client_->Close(ESHUTDOWN);
-
- EXPECT_CALL(*client_, OnConnect()).WillOnce(Invoke([this] {
- client_->Close(EIO);
- }));
- auto status = client_->SendImpulse(17);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
- EXPECT_FALSE(client_->IsConnected());
- EXPECT_EQ(-EIO, client_->error());
-}
-
-TEST_F(ClientChannelFactoryTest, DisableAutoReconnect) {
- client_->Close(EIO);
- ASSERT_FALSE(client_->IsConnected());
- client_->DisableAutoReconnect();
- auto status = client_->SendImpulse(17);
- ASSERT_FALSE(status);
- EXPECT_EQ(ESHUTDOWN, status.error());
- EXPECT_FALSE(client_->IsConnected());
- client_->EnableAutoReconnect(kTimeout);
- EXPECT_CALL(*client_, OnConnect());
- OnConnectCallback([](auto* mock) {
- EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
- .WillOnce(Return(Status<void>{}));
- });
- ASSERT_TRUE(client_->SendImpulse(17));
- EXPECT_TRUE(client_->IsConnected());
-}
-
-TEST_F(ClientTransactionTest, SendNoData) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
- EXPECT_CALL(*mock_channel(),
- SendWithInt(kTransactionState, 1, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(1));
- EXPECT_CALL(*mock_channel(),
- SendWithFileHandle(kTransactionState, 2, nullptr, 0, nullptr, 0))
- .WillOnce(Return(ByMove(LocalHandle{-1})));
- EXPECT_TRUE(transaction_.Send<LocalHandle>(2));
- EXPECT_CALL(*mock_channel(), SendWithChannelHandle(kTransactionState, 3,
- nullptr, 0, nullptr, 0))
- .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, 1})));
- EXPECT_TRUE(transaction_.Send<LocalChannelHandle>(3));
-}
-
-TEST_F(ClientTransactionTest, SendNoState) {
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(nullptr));
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
- EXPECT_TRUE(transaction_.Send<void>(1));
-}
-
-TEST_F(ClientTransactionTest, SendBuffers) {
- const void* const kSendBuffer = IntToConstPtr(123);
- const size_t kSendSize = 12;
- void* const kReceiveBuffer = IntToPtr(456);
- const size_t kReceiveSize = 34;
-
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(nullptr));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(1, nullptr, 0, nullptr, 0));
-
- EXPECT_CALL(*mock_channel(),
- SendWithInt(nullptr, 2, Ne(nullptr), 1, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(2, kSendBuffer, kSendSize, nullptr, 0));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(3, kSendBuffer, 0, nullptr, 0));
-
- EXPECT_CALL(*mock_channel(),
- SendWithInt(nullptr, 4, nullptr, 0, Ne(nullptr), 1))
- .WillOnce(Return(0));
- EXPECT_TRUE(
- transaction_.Send<void>(4, nullptr, 0, kReceiveBuffer, kReceiveSize));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(5, nullptr, 0, kReceiveBuffer, 0));
-
- EXPECT_CALL(*mock_channel(),
- SendWithInt(nullptr, 5, Ne(nullptr), 1, Ne(nullptr), 1))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.Send<void>(5, kSendBuffer, kSendSize, kReceiveBuffer,
- kReceiveSize));
-}
-
-TEST_F(ClientTransactionTest, SendVector) {
- iovec send[3] = {};
- iovec recv[4] = {};
-
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(nullptr));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.SendVector<void>(1, nullptr, 0, nullptr, 0));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 2, send, 3, recv, 4))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.SendVector<void>(2, send, 3, recv, 4));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, send, 3, nullptr, 0))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.SendVector<void>(3, send, nullptr));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 4, nullptr, 0, recv, 4))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.SendVector<void>(4, nullptr, recv));
-
- EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, send, 3, recv, 4))
- .WillOnce(Return(0));
- EXPECT_TRUE(transaction_.SendVector<void>(5, send, recv));
-}
-
-TEST_F(ClientTransactionTest, PushHandle) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-
- EXPECT_CALL(*mock_channel(),
- PushFileHandle(kTransactionState, A<const LocalHandle&>()))
- .WillOnce(Return(1));
- EXPECT_EQ(1, transaction_.PushFileHandle(LocalHandle{-1}).get());
-
- EXPECT_CALL(*mock_channel(),
- PushFileHandle(kTransactionState, A<const BorrowedHandle&>()))
- .WillOnce(Return(2));
- EXPECT_EQ(2, transaction_.PushFileHandle(BorrowedHandle{-1}).get());
-
- EXPECT_EQ(3, transaction_.PushFileHandle(RemoteHandle{3}).get());
-
- EXPECT_CALL(
- *mock_channel(),
- PushChannelHandle(kTransactionState, A<const LocalChannelHandle&>()))
- .WillOnce(Return(11));
- EXPECT_EQ(
- 11, transaction_.PushChannelHandle(LocalChannelHandle{nullptr, 1}).get());
-
- EXPECT_CALL(
- *mock_channel(),
- PushChannelHandle(kTransactionState, A<const BorrowedChannelHandle&>()))
- .WillOnce(Return(12));
- EXPECT_EQ(12, transaction_.PushChannelHandle(BorrowedChannelHandle{2}).get());
-
- EXPECT_EQ(13, transaction_.PushChannelHandle(RemoteChannelHandle{13}).get());
-}
-
-TEST_F(ClientTransactionTest, GetHandle) {
- void* const kTransactionState = IntToPtr(123);
- EXPECT_CALL(*mock_channel(), AllocateTransactionState())
- .WillOnce(Return(kTransactionState));
- EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
-
- EXPECT_CALL(*mock_channel(), GetFileHandle(kTransactionState, 1, _))
- .WillOnce(Return(false))
- .WillOnce(Return(true));
-
- LocalHandle file_handle;
- EXPECT_FALSE(transaction_.GetFileHandle(1, &file_handle));
- EXPECT_TRUE(transaction_.GetFileHandle(1, &file_handle));
-
- EXPECT_CALL(*mock_channel(), GetChannelHandle(kTransactionState, 2, _))
- .WillOnce(Return(false))
- .WillOnce(Return(true));
-
- LocalChannelHandle channel_handle;
- EXPECT_FALSE(transaction_.GetChannelHandle(2, &channel_handle));
- EXPECT_TRUE(transaction_.GetChannelHandle(2, &channel_handle));
-}
diff --git a/libs/vr/libpdx/encoder_performance_test.cpp b/libs/vr/libpdx/encoder_performance_test.cpp
deleted file mode 100644
index 7b477c4..0000000
--- a/libs/vr/libpdx/encoder_performance_test.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <iomanip>
-#include <iostream>
-#include <vector>
-
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx::rpc;
-using namespace android::pdx;
-using std::placeholders::_1;
-using std::placeholders::_2;
-using std::placeholders::_3;
-using std::placeholders::_4;
-using std::placeholders::_5;
-using std::placeholders::_6;
-
-namespace {
-
-constexpr size_t kMaxStaticBufferSize = 20480;
-
-// Provide numpunct facet that formats numbers with ',' as thousands separators.
-class CommaNumPunct : public std::numpunct<char> {
- protected:
- char do_thousands_sep() const override { return ','; }
- std::string do_grouping() const override { return "\03"; }
-};
-
-class TestPayload : public MessagePayload<SendBuffer>,
- public MessageWriter,
- public MessageReader,
- public NoOpResourceMapper {
- public:
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override {
- const size_t section_offset = Size();
- Extend(size);
- return Data() + section_offset;
- }
-
- OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override {
- return {&*ConstCursor(), &*ConstEnd()};
- }
-
- void ConsumeReadBufferSectionData(const void* new_start) override {
- std::advance(ConstCursor(), PointerDistance(new_start, &*ConstCursor()));
- }
-
- InputResourceMapper* GetInputResourceMapper() override { return this; }
-};
-
-class StaticBuffer : public MessageWriter,
- public MessageReader,
- public NoOpResourceMapper {
- public:
- void Clear() {
- read_ptr_ = buffer_;
- write_ptr_ = 0;
- }
- void Rewind() { read_ptr_ = buffer_; }
-
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override {
- void* ptr = buffer_ + write_ptr_;
- write_ptr_ += size;
- return ptr;
- }
-
- OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override {
- return {read_ptr_, std::end(buffer_)};
- }
-
- void ConsumeReadBufferSectionData(const void* new_start) override {
- read_ptr_ = static_cast<const uint8_t*>(new_start);
- }
-
- InputResourceMapper* GetInputResourceMapper() override { return this; }
-
- private:
- uint8_t buffer_[kMaxStaticBufferSize];
- const uint8_t* read_ptr_{buffer_};
- size_t write_ptr_{0};
-};
-
-// Simple callback function to clear/reset the input/output buffers for
-// serialization. Using raw function pointer here instead of std::function to
-// minimize the overhead of invocation in the tight test loop over millions of
-// iterations.
-using ResetFunc = void(void*);
-
-// Serialization test function signature, used by the TestRunner.
-using SerializeTestSignature = std::chrono::nanoseconds(MessageWriter* writer,
- size_t iterations,
- ResetFunc* write_reset,
- void* reset_data);
-
-// Deserialization test function signature, used by the TestRunner.
-using DeserializeTestSignature = std::chrono::nanoseconds(
- MessageReader* reader, MessageWriter* writer, size_t iterations,
- ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data);
-
-// Generic serialization test runner method. Takes the |value| of type T and
-// serializes it into the output buffer represented by |writer|.
-template <typename T>
-std::chrono::nanoseconds SerializeTestRunner(MessageWriter* writer,
- size_t iterations,
- ResetFunc* write_reset,
- void* reset_data, const T& value) {
- auto start = std::chrono::high_resolution_clock::now();
- for (size_t i = 0; i < iterations; i++) {
- write_reset(reset_data);
- Serialize(value, writer);
- }
- auto stop = std::chrono::high_resolution_clock::now();
- return stop - start;
-}
-
-// Generic deserialization test runner method. Takes the |value| of type T and
-// temporarily serializes it into the output buffer, then repeatedly
-// deserializes the data back from that buffer.
-template <typename T>
-std::chrono::nanoseconds DeserializeTestRunner(
- MessageReader* reader, MessageWriter* writer, size_t iterations,
- ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data,
- const T& value) {
- write_reset(reset_data);
- Serialize(value, writer);
- T output_data;
- auto start = std::chrono::high_resolution_clock::now();
- for (size_t i = 0; i < iterations; i++) {
- read_reset(reset_data);
- Deserialize(&output_data, reader);
- }
- auto stop = std::chrono::high_resolution_clock::now();
- if (output_data != value)
- return start - stop; // Return negative value to indicate error.
- return stop - start;
-}
-
-// Special version of SerializeTestRunner that doesn't perform any serialization
-// but does all the same setup steps and moves data of size |data_size| into
-// the output buffer. Useful to determine the baseline to calculate time used
-// just for serialization layer.
-std::chrono::nanoseconds SerializeBaseTest(MessageWriter* writer,
- size_t iterations,
- ResetFunc* write_reset,
- void* reset_data, size_t data_size) {
- std::vector<uint8_t> fake_data(data_size);
- auto start = std::chrono::high_resolution_clock::now();
- for (size_t i = 0; i < iterations; i++) {
- write_reset(reset_data);
- memcpy(writer->GetNextWriteBufferSection(fake_data.size()),
- fake_data.data(), fake_data.size());
- }
- auto stop = std::chrono::high_resolution_clock::now();
- return stop - start;
-}
-
-// Special version of DeserializeTestRunner that doesn't perform any
-// deserialization but invokes Rewind on the input buffer repeatedly.
-// Useful to determine the baseline to calculate time used just for
-// deserialization layer.
-std::chrono::nanoseconds DeserializeBaseTest(
- MessageReader* reader, MessageWriter* writer, size_t iterations,
- ResetFunc* read_reset, ResetFunc* write_reset, void* reset_data,
- size_t data_size) {
- std::vector<uint8_t> fake_data(data_size);
- write_reset(reset_data);
- memcpy(writer->GetNextWriteBufferSection(fake_data.size()), fake_data.data(),
- fake_data.size());
- auto start = std::chrono::high_resolution_clock::now();
- for (size_t i = 0; i < iterations; i++) {
- read_reset(reset_data);
- auto section = reader->GetNextReadBufferSection();
- memcpy(fake_data.data(), section.first, fake_data.size());
- reader->ConsumeReadBufferSectionData(
- AdvancePointer(section.first, fake_data.size()));
- }
- auto stop = std::chrono::high_resolution_clock::now();
- return stop - start;
-}
-
-// The main class that accumulates individual tests to be executed.
-class TestRunner {
- public:
- struct BufferInfo {
- BufferInfo(const std::string& buffer_name, MessageReader* reader,
- MessageWriter* writer, ResetFunc* read_reset_func,
- ResetFunc* write_reset_func, void* reset_data)
- : name{buffer_name},
- reader{reader},
- writer{writer},
- read_reset_func{read_reset_func},
- write_reset_func{write_reset_func},
- reset_data{reset_data} {}
- std::string name;
- MessageReader* reader;
- MessageWriter* writer;
- ResetFunc* read_reset_func;
- ResetFunc* write_reset_func;
- void* reset_data;
- };
-
- void AddTestFunc(const std::string& name,
- std::function<SerializeTestSignature> serialize_test,
- std::function<DeserializeTestSignature> deserialize_test,
- size_t data_size) {
- tests_.emplace_back(name, std::move(serialize_test),
- std::move(deserialize_test), data_size);
- }
-
- template <typename T>
- void AddSerializationTest(const std::string& name, T&& value) {
- const size_t data_size = GetSerializedSize(value);
- auto serialize_test =
- std::bind(static_cast<std::chrono::nanoseconds (*)(
- MessageWriter*, size_t, ResetFunc*, void*, const T&)>(
- &SerializeTestRunner),
- _1, _2, _3, _4, std::forward<T>(value));
- tests_.emplace_back(name, std::move(serialize_test),
- std::function<DeserializeTestSignature>{}, data_size);
- }
-
- template <typename T>
- void AddDeserializationTest(const std::string& name, T&& value) {
- const size_t data_size = GetSerializedSize(value);
- auto deserialize_test =
- std::bind(static_cast<std::chrono::nanoseconds (*)(
- MessageReader*, MessageWriter*, size_t, ResetFunc*,
- ResetFunc*, void*, const T&)>(&DeserializeTestRunner),
- _1, _2, _3, _4, _5, _6, std::forward<T>(value));
- tests_.emplace_back(name, std::function<SerializeTestSignature>{},
- std::move(deserialize_test), data_size);
- }
-
- template <typename T>
- void AddTest(const std::string& name, T&& value) {
- const size_t data_size = GetSerializedSize(value);
- if (data_size > kMaxStaticBufferSize) {
- std::cerr << "Test '" << name << "' requires " << data_size
- << " bytes in the serialization buffer but only "
- << kMaxStaticBufferSize << " are available." << std::endl;
- exit(1);
- }
- auto serialize_test =
- std::bind(static_cast<std::chrono::nanoseconds (*)(
- MessageWriter*, size_t, ResetFunc*, void*, const T&)>(
- &SerializeTestRunner),
- _1, _2, _3, _4, value);
- auto deserialize_test =
- std::bind(static_cast<std::chrono::nanoseconds (*)(
- MessageReader*, MessageWriter*, size_t, ResetFunc*,
- ResetFunc*, void*, const T&)>(&DeserializeTestRunner),
- _1, _2, _3, _4, _5, _6, std::forward<T>(value));
- tests_.emplace_back(name, std::move(serialize_test),
- std::move(deserialize_test), data_size);
- }
-
- std::string CenterString(std::string text, size_t column_width) {
- if (text.size() < column_width) {
- text = std::string((column_width - text.size()) / 2, ' ') + text;
- }
- return text;
- }
-
- void RunTests(size_t iteration_count,
- const std::vector<BufferInfo>& buffers) {
- using float_seconds = std::chrono::duration<double>;
- const std::string name_column_separator = " : ";
- const std::string buffer_column_separator = " || ";
- const std::string buffer_timing_column_separator = " | ";
- const size_t data_size_column_width = 6;
- const size_t time_column_width = 9;
- const size_t qps_column_width = 18;
- const size_t buffer_column_width = time_column_width +
- buffer_timing_column_separator.size() +
- qps_column_width;
-
- auto compare_name_length = [](const TestEntry& t1, const TestEntry& t2) {
- return t1.name.size() < t2.name.size();
- };
- auto test_with_longest_name =
- std::max_element(tests_.begin(), tests_.end(), compare_name_length);
- size_t name_column_width = test_with_longest_name->name.size();
-
- size_t total_width =
- name_column_width + name_column_separator.size() +
- data_size_column_width + buffer_column_separator.size() +
- buffers.size() * (buffer_column_width + buffer_column_separator.size());
-
- const std::string dbl_separator(total_width, '=');
- const std::string separator(total_width, '-');
-
- auto print_header = [&](const std::string& header) {
- std::cout << dbl_separator << std::endl;
- std::stringstream ss;
- ss.imbue(std::locale(ss.getloc(), new CommaNumPunct));
- ss << header << " (" << iteration_count << " iterations)";
- std::cout << CenterString(ss.str(), total_width) << std::endl;
- std::cout << dbl_separator << std::endl;
- std::cout << std::setw(name_column_width) << "Test Name" << std::left
- << name_column_separator << std::setw(data_size_column_width)
- << CenterString("Size", data_size_column_width)
- << buffer_column_separator;
- for (const auto& buffer_info : buffers) {
- std::cout << std::setw(buffer_column_width)
- << CenterString(buffer_info.name, buffer_column_width)
- << buffer_column_separator;
- }
- std::cout << std::endl;
- std::cout << std::setw(name_column_width) << "" << name_column_separator
- << std::setw(data_size_column_width)
- << CenterString("bytes", data_size_column_width)
- << buffer_column_separator << std::left;
- for (size_t i = 0; i < buffers.size(); i++) {
- std::cout << std::setw(time_column_width)
- << CenterString("Time, s", time_column_width)
- << buffer_timing_column_separator
- << std::setw(qps_column_width)
- << CenterString("QPS", qps_column_width)
- << buffer_column_separator;
- }
- std::cout << std::right << std::endl;
- std::cout << separator << std::endl;
- };
-
- print_header("Serialization benchmarks");
- for (const auto& test : tests_) {
- if (test.serialize_test) {
- std::cout << std::setw(name_column_width) << test.name << " : "
- << std::setw(data_size_column_width) << test.data_size
- << buffer_column_separator;
- for (const auto& buffer_info : buffers) {
- auto seconds =
- std::chrono::duration_cast<float_seconds>(test.serialize_test(
- buffer_info.writer, iteration_count,
- buffer_info.write_reset_func, buffer_info.reset_data));
- double qps = iteration_count / seconds.count();
- std::cout << std::fixed << std::setprecision(3)
- << std::setw(time_column_width) << seconds.count()
- << buffer_timing_column_separator
- << std::setw(qps_column_width) << qps
- << buffer_column_separator;
- }
- std::cout << std::endl;
- }
- }
-
- print_header("Deserialization benchmarks");
- for (const auto& test : tests_) {
- if (test.deserialize_test) {
- std::cout << std::setw(name_column_width) << test.name << " : "
- << std::setw(data_size_column_width) << test.data_size
- << buffer_column_separator;
- for (const auto& buffer_info : buffers) {
- auto seconds =
- std::chrono::duration_cast<float_seconds>(test.deserialize_test(
- buffer_info.reader, buffer_info.writer, iteration_count,
- buffer_info.read_reset_func, buffer_info.write_reset_func,
- buffer_info.reset_data));
- double qps = iteration_count / seconds.count();
- std::cout << std::fixed << std::setprecision(3)
- << std::setw(time_column_width) << seconds.count()
- << buffer_timing_column_separator
- << std::setw(qps_column_width) << qps
- << buffer_column_separator;
- }
- std::cout << std::endl;
- }
- }
- std::cout << dbl_separator << std::endl;
- }
-
- private:
- struct TestEntry {
- TestEntry(const std::string& test_name,
- std::function<SerializeTestSignature> serialize_test,
- std::function<DeserializeTestSignature> deserialize_test,
- size_t data_size)
- : name{test_name},
- serialize_test{std::move(serialize_test)},
- deserialize_test{std::move(deserialize_test)},
- data_size{data_size} {}
- std::string name;
- std::function<SerializeTestSignature> serialize_test;
- std::function<DeserializeTestSignature> deserialize_test;
- size_t data_size;
- };
-
- std::vector<TestEntry> tests_;
-};
-
-std::string GenerateContainerName(const std::string& type, size_t count) {
- std::stringstream ss;
- ss << type << "(" << count << ")";
- return ss.str();
-}
-
-} // anonymous namespace
-
-int main(int /*argc*/, char** /*argv*/) {
- const size_t iteration_count = 10000000; // 10M iterations.
- TestRunner test_runner;
- std::cout.imbue(std::locale(std::cout.getloc(), new CommaNumPunct));
-
- // Baseline tests to figure out the overhead of buffer resizing and data
- // transfers.
- for (size_t len : {0, 1, 9, 66, 259}) {
- auto serialize_base_test =
- std::bind(&SerializeBaseTest, _1, _2, _3, _4, len);
- auto deserialize_base_test =
- std::bind(&DeserializeBaseTest, _1, _2, _3, _4, _5, _6, len);
- test_runner.AddTestFunc("--Baseline--", std::move(serialize_base_test),
- std::move(deserialize_base_test), len);
- }
-
- // Individual serialization/deserialization tests.
- test_runner.AddTest("bool", true);
- test_runner.AddTest("int32_t", 12);
-
- for (size_t len : {0, 1, 8, 64, 256}) {
- test_runner.AddTest(GenerateContainerName("string", len),
- std::string(len, '*'));
- }
- // Serialization is too slow to handle such large strings, add this test for
- // deserialization only.
- test_runner.AddDeserializationTest(GenerateContainerName("string", 10240),
- std::string(10240, '*'));
-
- for (size_t len : {0, 1, 8, 64, 256}) {
- std::vector<int32_t> int_vector(len);
- std::iota(int_vector.begin(), int_vector.end(), 0);
- test_runner.AddTest(GenerateContainerName("vector<int32_t>", len),
- std::move(int_vector));
- }
-
- std::vector<std::string> vector_of_strings = {
- "012345678901234567890123456789", "012345678901234567890123456789",
- "012345678901234567890123456789", "012345678901234567890123456789",
- "012345678901234567890123456789",
- };
- test_runner.AddTest(
- GenerateContainerName("vector<string>", vector_of_strings.size()),
- std::move(vector_of_strings));
-
- test_runner.AddTest("tuple<int, bool, string, double>",
- std::make_tuple(123, true, std::string{"foobar"}, 1.1));
-
- for (size_t len : {0, 1, 8, 64}) {
- std::map<int, std::string> test_map;
- for (size_t i = 0; i < len; i++)
- test_map.emplace(i, std::to_string(i));
- test_runner.AddTest(GenerateContainerName("map<int, string>", len),
- std::move(test_map));
- }
-
- for (size_t len : {0, 1, 8, 64}) {
- std::unordered_map<int, std::string> test_map;
- for (size_t i = 0; i < len; i++)
- test_map.emplace(i, std::to_string(i));
- test_runner.AddTest(
- GenerateContainerName("unordered_map<int, string>", len),
- std::move(test_map));
- }
-
- // BufferWrapper can't be used with deserialization tests right now because
- // it requires external buffer to be filled in, which is not available.
- std::vector<std::vector<uint8_t>> data_buffers;
- for (size_t len : {0, 1, 8, 64, 256}) {
- data_buffers.emplace_back(len);
- test_runner.AddSerializationTest(
- GenerateContainerName("BufferWrapper<uint8_t*>", len),
- BufferWrapper<uint8_t*>(data_buffers.back().data(),
- data_buffers.back().size()));
- }
-
- // Various backing buffers to run the tests on.
- std::vector<TestRunner::BufferInfo> buffers;
-
- Payload buffer;
- buffers.emplace_back("Non-TLS Buffer", &buffer, &buffer,
- [](void* ptr) { static_cast<Payload*>(ptr)->Rewind(); },
- [](void* ptr) { static_cast<Payload*>(ptr)->Clear(); },
- &buffer);
-
- TestPayload tls_buffer;
- buffers.emplace_back(
- "TLS Buffer", &tls_buffer, &tls_buffer,
- [](void* ptr) { static_cast<TestPayload*>(ptr)->Rewind(); },
- [](void* ptr) { static_cast<TestPayload*>(ptr)->Clear(); }, &tls_buffer);
-
- StaticBuffer static_buffer;
- buffers.emplace_back(
- "Static Buffer", &static_buffer, &static_buffer,
- [](void* ptr) { static_cast<StaticBuffer*>(ptr)->Rewind(); },
- [](void* ptr) { static_cast<StaticBuffer*>(ptr)->Clear(); },
- &static_buffer);
-
- // Finally, run all the tests.
- test_runner.RunTests(iteration_count, buffers);
- return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/Android.bp b/libs/vr/libpdx/fuzz/Android.bp
deleted file mode 100644
index ac831ce..0000000
--- a/libs/vr/libpdx/fuzz/Android.bp
+++ /dev/null
@@ -1,68 +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_fuzz {
- name: "libpdx_service_dispatcher_fuzzer",
- srcs: [
- "service_dispatcher_fuzzer.cpp",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- static_libs: [
- "libpdx",
- ],
- shared_libs: [
- "libutils",
- "liblog",
- "libcutils",
- ],
-}
-
-cc_fuzz {
- name: "libpdx_message_fuzzer",
- srcs: [
- "message_fuzzer.cpp",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- static_libs: [
- "libpdx",
- ],
- shared_libs: [
- "libutils",
- "liblog",
- "libcutils",
- ],
-}
-
-cc_fuzz {
- name: "libpdx_serialization_fuzzer",
- srcs: [
- "serialization_fuzzer.cpp",
- ],
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- static_libs: [
- "libpdx",
- ],
- shared_libs: [
- "libutils",
- "liblog",
- "libcutils",
- ],
-}
diff --git a/libs/vr/libpdx/fuzz/helpers.h b/libs/vr/libpdx/fuzz/helpers.h
deleted file mode 100644
index 83ec409..0000000
--- a/libs/vr/libpdx/fuzz/helpers.h
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-// brian.balling@leviathansecurity.com
-
-#ifndef LEV_FUZZERS_LIBPDX_HELPERS_H_
-#define LEV_FUZZERS_LIBPDX_HELPERS_H_
-
-#define UNUSED(expr) \
- do { \
- (void)(expr); \
- } while (0)
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <pdx/client.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <pdx/service_endpoint.h>
-#include <sys/eventfd.h>
-#include <memory>
-#include <vector>
-
-using namespace android::pdx;
-
-// Vector of operations we can call in the dispatcher.
-static const std::vector<std::function<void(
- const std::unique_ptr<ServiceDispatcher>&, FuzzedDataProvider*)>>
- dispatcher_operations = {
- [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
- FuzzedDataProvider*) -> void { dispatcher->EnterDispatchLoop(); },
- [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
- FuzzedDataProvider*) -> void { dispatcher->ReceiveAndDispatch(); },
- [](const std::unique_ptr<ServiceDispatcher>& dispatcher,
- FuzzedDataProvider* fdp) -> void {
- dispatcher->ReceiveAndDispatch(fdp->ConsumeIntegral<int>());
- }};
-
-// Most of the fuzzing occurs within the endpoint, which is derived from an
-// abstract class. So we are returning garbage data for most functions besides
-// the ones we added or need to actually use.
-class FuzzEndpoint : public Endpoint {
- public:
- explicit FuzzEndpoint(FuzzedDataProvider* fdp) {
- _fdp = fdp;
- _epoll_fd = eventfd(0, 0);
- }
-
- ~FuzzEndpoint() { close(_epoll_fd); }
-
- // Returns an fd that can be used with epoll() to wait for incoming messages
- // from this endpoint.
- int epoll_fd() const { return _epoll_fd; }
-
- // Associates a Service instance with an endpoint by setting the service
- // context pointer to the address of the Service. Only one Service may be
- // associated with a given endpoint.
- Status<void> SetService(Service* service) {
- _service = service;
- return Status<void>(0);
- }
-
- // Set the channel context for the given channel.
- Status<void> SetChannel(int channel_id, Channel* channel) {
- UNUSED(channel_id);
- _channel = std::shared_ptr<Channel>(channel);
- return Status<void>(0);
- }
-
- // Receives a message on the given endpoint file descriptor.
- // This is called by the dispatcher to determine what operations
- // to make, so we are fuzzing the response.
- Status<void> MessageReceive(Message* message) {
- // Create a randomized MessageInfo struct.
- MessageInfo info;
- eventfd_t wakeup_val = 0;
- info.pid = _fdp->ConsumeIntegral<int>();
- info.tid = _fdp->ConsumeIntegral<int>();
- info.cid = _fdp->ConsumeIntegral<int>();
- info.mid = _fdp->ConsumeIntegral<int>();
- info.euid = _fdp->ConsumeIntegral<int>();
- info.egid = _fdp->ConsumeIntegral<int>();
- info.op = _fdp->ConsumeIntegral<int32_t>();
- info.flags = _fdp->ConsumeIntegral<uint32_t>();
- info.service = _service;
- info.channel = _channel.get();
- info.send_len = _fdp->ConsumeIntegral<size_t>();
- info.recv_len = _fdp->ConsumeIntegral<size_t>();
- info.fd_count = _fdp->ConsumeIntegral<size_t>();
- if (_fdp->remaining_bytes() >= 32) {
- std::vector<uint8_t> impulse_vec = _fdp->ConsumeBytes<uint8_t>(32);
- memcpy(info.impulse, impulse_vec.data(), 32);
- }
-
- *message = Message(info);
- eventfd_read(_epoll_fd, &wakeup_val);
-
- return Status<void>();
- }
-
- // Returns a tag that uniquely identifies a specific underlying IPC
- // transport.
- uint32_t GetIpcTag() const { return 0; }
-
- // Close a channel, signaling the client file object and freeing the channel
- // id. Once closed, the client side of the channel always returns the error
- // ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
- Status<void> CloseChannel(int channel_id) {
- UNUSED(channel_id);
- return Status<void>();
- }
-
- // Update the event bits for the given channel (given by id), using the
- // given clear and set masks.
- Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask) {
- UNUSED(channel_id);
- UNUSED(clear_mask);
- UNUSED(set_mask);
- return Status<void>();
- }
-
- // Create a new channel and push it as a file descriptor to the process
- // sending the |message|. |flags| may be set to O_NONBLOCK and/or
- // O_CLOEXEC to control the initial behavior of the new file descriptor (the
- // sending process may change these later using fcntl()). The internal
- // Channel instance associated with this channel is set to |channel|,
- // which may be nullptr. The new channel id allocated for this channel is
- // returned in |channel_id|, which may also be nullptr if not needed.
- Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
- Channel* channel, int* channel_id) {
- UNUSED(message);
- UNUSED(flags);
- UNUSED(channel);
- UNUSED(channel_id);
- return Status<RemoteChannelHandle>();
- }
-
- // Check whether the |ref| is a reference to a channel to the service
- // represented by the |endpoint|. If the channel reference in question is
- // valid, the Channel object is returned in |channel| when non-nullptr and
- // the channel ID is returned through the Status object.
- Status<int> CheckChannel(const Message* message, ChannelReference ref,
- Channel** channel) {
- UNUSED(message);
- UNUSED(ref);
- UNUSED(channel);
- return Status<int>();
- }
-
- // Replies to the message with a return code.
- Status<void> MessageReply(Message* message, int return_code) {
- UNUSED(message);
- UNUSED(return_code);
- return Status<void>();
- }
-
- // Replies to the message with a file descriptor.
- Status<void> MessageReplyFd(Message* message, unsigned int push_fd) {
- UNUSED(message);
- UNUSED(push_fd);
- return Status<void>();
- }
-
- // Replies to the message with a local channel handle.
- Status<void> MessageReplyChannelHandle(Message* message,
- const LocalChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<void>();
- }
-
- // Replies to the message with a borrowed local channel handle.
- Status<void> MessageReplyChannelHandle(Message* message,
- const BorrowedChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<void>();
- }
-
- // Replies to the message with a remote channel handle.
- Status<void> MessageReplyChannelHandle(Message* message,
- const RemoteChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<void>();
- }
-
- // Reads message data into an array of memory buffers.
- Status<size_t> ReadMessageData(Message* message, const iovec* vector,
- size_t vector_length) {
- UNUSED(message);
- UNUSED(vector);
- UNUSED(vector_length);
- return Status<size_t>();
- }
-
- // Sends reply data for message.
- Status<size_t> WriteMessageData(Message* message, const iovec* vector,
- size_t vector_length) {
- UNUSED(message);
- UNUSED(vector);
- UNUSED(vector_length);
- return Status<size_t>();
- }
-
- // Records a file descriptor into the message buffer and returns the
- // remapped reference to be sent to the remote process.
- Status<FileReference> PushFileHandle(Message* message,
- const LocalHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<FileReference>();
- }
-
- Status<FileReference> PushFileHandle(Message* message,
- const BorrowedHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<FileReference>();
- }
-
- Status<FileReference> PushFileHandle(Message* message,
- const RemoteHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<FileReference>();
- }
-
- Status<ChannelReference> PushChannelHandle(Message* message,
- const LocalChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<ChannelReference>();
- }
-
- Status<ChannelReference> PushChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<ChannelReference>();
- }
-
- Status<ChannelReference> PushChannelHandle(
- Message* message, const RemoteChannelHandle& handle) {
- UNUSED(message);
- UNUSED(handle);
- return Status<ChannelReference>();
- }
-
- // Obtains a file descriptor/channel handle from a message for the given
- // reference.
- LocalHandle GetFileHandle(Message* message, FileReference ref) const {
- UNUSED(message);
- UNUSED(ref);
- return LocalHandle();
- }
-
- LocalChannelHandle GetChannelHandle(Message* message,
- ChannelReference ref) const {
- UNUSED(message);
- UNUSED(ref);
- return LocalChannelHandle();
- }
-
- // Transport-specific message state management.
- void* AllocateMessageState() { return nullptr; }
-
- void FreeMessageState(void* state) { UNUSED(state); }
-
- // Cancels the endpoint, unblocking any receiver threads waiting for a
- // message.
- Status<void> Cancel() { return Status<void>(); }
-
- private:
- FuzzedDataProvider* _fdp;
- std::shared_ptr<Channel> _channel;
- Service* _service;
- int _epoll_fd;
-};
-
-#endif // LEV_FUZZERS_LIBPDX_HELPERS_H_
diff --git a/libs/vr/libpdx/fuzz/message_fuzzer.cpp b/libs/vr/libpdx/fuzz/message_fuzzer.cpp
deleted file mode 100644
index b627045..0000000
--- a/libs/vr/libpdx/fuzz/message_fuzzer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-// brian.balling@leviathansecurity.com
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <helpers.h>
-#include <pdx/client_channel.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <thread>
-
-using namespace android::pdx;
-
-// Fuzzer for Message object functions.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
- FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
- std::shared_ptr<Service> service(
- new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
- std::shared_ptr<Channel> channel(nullptr);
-
- // Generate a random Message object to call functions in.
- MessageInfo info;
- info.pid = fdp.ConsumeIntegral<int>();
- info.tid = fdp.ConsumeIntegral<int>();
- info.cid = fdp.ConsumeIntegral<int>();
- info.mid = fdp.ConsumeIntegral<int>();
- info.euid = fdp.ConsumeIntegral<int>();
- info.egid = fdp.ConsumeIntegral<int>();
- info.op = fdp.ConsumeIntegral<int32_t>();
- info.flags = fdp.ConsumeIntegral<uint32_t>();
- info.service = service.get();
- info.channel = channel.get();
- info.send_len = fdp.ConsumeIntegral<size_t>();
- info.recv_len = fdp.ConsumeIntegral<size_t>();
- info.fd_count = fdp.ConsumeIntegral<size_t>();
- if (fdp.remaining_bytes() >= 32) {
- std::vector<uint8_t> impulse_vec = fdp.ConsumeBytes<uint8_t>(32);
- memcpy(info.impulse, impulse_vec.data(), 32);
- }
-
- Message message = Message(info);
-
- // A bunch of getters that probably won't do much, but might as well
- // get coverage, while we are here.
- message.GetProcessId();
- message.GetThreadId();
- message.GetEffectiveUserId();
- message.GetEffectiveGroupId();
- message.GetChannelId();
- message.GetMessageId();
- message.GetOp();
- message.GetFlags();
- message.GetSendLength();
- message.GetReceiveLength();
- message.GetFileDescriptorCount();
- message.ImpulseEnd();
- message.replied();
- message.IsChannelExpired();
- message.IsServiceExpired();
- message.GetState();
- message.GetState();
-
- // Some misc. functions.
- unsigned int fd = fdp.ConsumeIntegral<unsigned int>();
- int clear_mask = fdp.ConsumeIntegral<int>();
- int set_mask = fdp.ConsumeIntegral<int>();
- Status<void> status = {};
- message.ModifyChannelEvents(clear_mask, set_mask);
-
- // Fuzz the handle functions.
- LocalHandle l_handle = {};
- BorrowedHandle b_handle = {};
- RemoteHandle r_handle = {};
- LocalChannelHandle lc_handle = {};
- BorrowedChannelHandle bc_handle = {};
- RemoteChannelHandle rc_handle = {};
- FileReference f_ref = fdp.ConsumeIntegral<int32_t>();
- ChannelReference c_ref = fdp.ConsumeIntegral<int32_t>();
-
- // These don't actually modify any state in the Message or params.
- // They can be called in any order.
- message.PushFileHandle(b_handle);
- message.PushFileHandle(r_handle);
- message.PushChannelHandle(lc_handle);
- message.PushChannelHandle(bc_handle);
- message.PushChannelHandle(rc_handle);
- message.GetFileHandle(f_ref, &l_handle);
- message.GetChannelHandle(c_ref, &lc_handle);
-
- // Can only reply once, pick at random.
- switch (fdp.ConsumeIntegral<uint8_t>()) {
- case 0:
- message.ReplyFileDescriptor(fd);
- break;
- case 1:
- message.Reply(status);
- break;
- case 2:
- message.Reply(l_handle);
- break;
- case 3:
- message.Reply(b_handle);
- break;
- case 4:
- message.Reply(r_handle);
- break;
- case 5:
- message.Reply(lc_handle);
- break;
- case 6:
- message.Reply(bc_handle);
- break;
- case 7:
- message.Reply(rc_handle);
- }
-
- // Fuzz the channel functions.
- int flags = fdp.ConsumeIntegral<int>();
- int channel_id = 0;
- message.PushChannel(flags, channel, &channel_id);
- message.CheckChannel(service.get(), c_ref, &channel);
- message.CheckChannel(c_ref, &channel);
- message.PushChannel(service.get(), flags, channel, &channel_id);
- size_t iovec_size = sizeof(iovec);
- struct iovec* iovecs = nullptr;
-
- // Fuzz the read/write functions. Needs at least one iovec, plus one byte.
- if (fdp.remaining_bytes() >= iovec_size + 1) {
- std::vector<uint8_t> tmp_vec = fdp.ConsumeBytes<uint8_t>(iovec_size);
- struct iovec* vector = reinterpret_cast<struct iovec*>(tmp_vec.data());
- std::vector<uint8_t> tmp_buf =
- fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
- void* buf = reinterpret_cast<void*>(tmp_buf.data());
- size_t buf_size = fdp.ConsumeIntegral<size_t>();
-
- // Capping num_vecs to 1024 so it doesn't allocate too much memory.
- size_t num_vecs = fdp.ConsumeIntegralInRange<size_t>(0, 1024);
-
- if (num_vecs > 0)
- iovecs = new struct iovec[num_vecs];
- for (size_t i = 0; i < num_vecs; i++) {
- iovecs[i] = *vector;
- }
-
- message.ReadAll(vector, buf_size);
- message.WriteAll(buf, buf_size);
- message.ReadVectorAll(vector, num_vecs);
- message.WriteVectorAll(vector, num_vecs);
- message.ReadVector(vector, buf_size);
- message.WriteVector(vector, buf_size);
- }
-
- if (iovecs != nullptr)
- delete[] iovecs;
- return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp b/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
deleted file mode 100644
index f5c5a5a..0000000
--- a/libs/vr/libpdx/fuzz/serialization_fuzzer.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-// brian.balling@leviathansecurity.com
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-struct FuzzType {
- int a;
- float b;
- std::string c;
-
- FuzzType() {}
- FuzzType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
-
- private:
- PDX_SERIALIZABLE_MEMBERS(FuzzType, a, b, c);
-};
-
-// Fuzzer for Serialization operations, this is mostly just lifted from the
-// existing test cases to use fuzzed values as inputs.
-void FuzzSerializeDeserialize(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload result;
-
- // Currently, only fuzzing subset of types. In the future, may want
- // to add more difficult to generate types like array, map, enum, etc...
- bool b_val = fdp.ConsumeBool();
- uint8_t u8_val = fdp.ConsumeIntegral<uint8_t>();
- uint16_t u16_val = fdp.ConsumeIntegral<uint16_t>();
- uint32_t u32_val = fdp.ConsumeIntegral<uint32_t>();
- uint64_t u64_val = fdp.ConsumeIntegral<uint64_t>();
- int8_t i8_val = fdp.ConsumeIntegral<int8_t>();
- int16_t i16_val = fdp.ConsumeIntegral<uint16_t>();
- int32_t i32_val = fdp.ConsumeIntegral<uint32_t>();
- int64_t i64_val = fdp.ConsumeIntegral<uint64_t>();
- float f_val = fdp.ConsumeFloatingPoint<float>();
- double d_val = fdp.ConsumeFloatingPoint<double>();
- std::string s_val = fdp.ConsumeRandomLengthString(fdp.remaining_bytes());
- std::vector<uint8_t> vec_val =
- fdp.ConsumeBytes<uint8_t>(fdp.remaining_bytes());
- FuzzType t1_val{reinterpret_cast<int>(i32_val), f_val, s_val};
-
- // Types need to be individually fuzzed because code path changes depending
- // on which type is being serialized/deserialized.
- Serialize(b_val, &result);
- Deserialize(&b_val, &result);
- Serialize(u8_val, &result);
- Deserialize(&u8_val, &result);
- Serialize(u16_val, &result);
- Deserialize(&u16_val, &result);
- Serialize(u32_val, &result);
- Deserialize(&u32_val, &result);
- Serialize(u64_val, &result);
- Deserialize(&u64_val, &result);
- Serialize(i8_val, &result);
- Deserialize(&i8_val, &result);
- Serialize(i16_val, &result);
- Deserialize(&i16_val, &result);
- Serialize(i32_val, &result);
- Deserialize(&i32_val, &result);
- Serialize(i64_val, &result);
- Deserialize(&i64_val, &result);
- Serialize(f_val, &result);
- Deserialize(&f_val, &result);
- Serialize(d_val, &result);
- Deserialize(&d_val, &result);
- Serialize(s_val, &result);
- Deserialize(&s_val, &result);
- Serialize(WrapString(s_val), &result);
- Deserialize(&s_val, &result);
- Serialize(vec_val, &result);
- Deserialize(&vec_val, &result);
- Serialize(t1_val, &result);
- Deserialize(&t1_val, &result);
-}
-
-void FuzzDeserializeUint8(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_UINT8, fdp.ConsumeIntegral<uint8_t>()};
- std::uint8_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint16(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_UINT16, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::uint16_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint32(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_UINT32, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::uint32_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeUint64(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {
- ENCODING_TYPE_UINT64, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::uint64_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt8(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_INT8, fdp.ConsumeIntegral<uint8_t>()};
- std::int8_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt16(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_INT16, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::int16_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt32(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_INT32, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::int32_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeInt64(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_INT64,
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- std::int64_t result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFloat32(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_FLOAT32, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- float floatResult;
- Deserialize(&floatResult, &buffer);
-
- buffer.Rewind();
- double doubleResult;
- Deserialize(&doubleResult, &buffer);
-}
-
-void FuzzDeserializeFloat64(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {
- ENCODING_TYPE_FLOAT64, fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(), fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- double result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFixstr(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- std::string s_val = fdp.ConsumeRemainingBytesAsString();
- Payload buffer = {ENCODING_TYPE_FIXSTR_MAX};
- for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
- iter++) {
- buffer.Append(1, *iter);
- }
- std::string result;
- Deserialize(&result, &buffer);
-}
-
-void FuzzDeserializeFixmap(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_FIXMAP_MAX};
- // Fill the map with the fuzzed data, not attempting to
- // make a valid map
- while (fdp.remaining_bytes() > 0) {
- buffer.Append(1, fdp.ConsumeIntegral<uint8_t>());
- }
-
- std::map<std::uint32_t, std::uint32_t> result;
- Deserialize(&result, &buffer);
-
- buffer.Rewind();
- std::unordered_map<std::uint32_t, std::uint32_t> unorderedResult;
- Deserialize(&unorderedResult, &buffer);
-}
-
-void FuzzDeserializeVariant(const uint8_t* data, size_t size) {
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
- Payload buffer = {ENCODING_TYPE_INT16,
- ENCODING_TYPE_FLOAT32,
- ENCODING_TYPE_FIXSTR_MAX,
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>(),
- fdp.ConsumeIntegral<uint8_t>()};
- // Add the rest of the data as a string
- std::string s_val = fdp.ConsumeRemainingBytesAsString();
- for (std::string::iterator iter = s_val.begin(); iter != s_val.end();
- iter++) {
- buffer.Append(1, *iter);
- }
- Variant<int, float, std::string> result;
- Deserialize(&result, &buffer);
-}
-
-// Attempts to deserialize fuzzed data as various types
-void FuzzDeserialize(const uint8_t* data, size_t size) {
- FuzzDeserializeUint8(data, size);
- FuzzDeserializeUint16(data, size);
- FuzzDeserializeUint32(data, size);
- FuzzDeserializeUint64(data, size);
- FuzzDeserializeInt8(data, size);
- FuzzDeserializeInt16(data, size);
- FuzzDeserializeInt32(data, size);
- FuzzDeserializeInt64(data, size);
- FuzzDeserializeFloat32(data, size);
- FuzzDeserializeFloat64(data, size);
- FuzzDeserializeFixstr(data, size);
- FuzzDeserializeFixmap(data, size);
- FuzzDeserializeVariant(data, size);
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzSerializeDeserialize(data, size);
- FuzzDeserialize(data, size);
-
- return 0;
-}
diff --git a/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp b/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp
deleted file mode 100644
index 3a3bfd9..0000000
--- a/libs/vr/libpdx/fuzz/service_dispatcher_fuzzer.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Authors: corbin.souffrant@leviathansecurity.com
-// brian.balling@leviathansecurity.com
-
-#include <fuzzer/FuzzedDataProvider.h>
-#include <helpers.h>
-#include <pdx/client_channel.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <thread>
-
-using namespace android::pdx;
-
-// Dispatch fuzzer entry point. This fuzzer creates a ServiceDispatcher
-// and creates an endpoint that returns fuzzed messages that are passed
-// to the ReceiveAndDispatch and DispatchLoop functions.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- eventfd_t wakeup_val = 1;
- FuzzedDataProvider fdp = FuzzedDataProvider(data, size);
-
- // Endpoint is only used to be immediately wrapped as a unique_ptr,
- // so it is ok to be using a raw ptr and new here without freeing.
- FuzzEndpoint* endpoint = new FuzzEndpoint(&fdp);
- std::unique_ptr<ServiceDispatcher> dispatcher = ServiceDispatcher::Create();
- std::shared_ptr<Channel> channel(nullptr);
- std::shared_ptr<Client> client(nullptr);
- std::shared_ptr<Service> service(
- new Service("FuzzService", std::unique_ptr<Endpoint>(endpoint)));
-
- service->SetChannel(0, std::shared_ptr<Channel>(channel));
- dispatcher->AddService(service);
-
- // Dispatcher blocks, so needs to run in its own thread.
- std::thread run_dispatcher([&]() {
- uint8_t opt = 0;
-
- // Right now the only operations block, so the while loop is pointless
- // but leaving it in, just in case that ever changes.
- while (fdp.remaining_bytes() > sizeof(MessageInfo)) {
- opt = fdp.ConsumeIntegral<uint8_t>() % dispatcher_operations.size();
- dispatcher_operations[opt](dispatcher, &fdp);
- }
- });
-
- // Continuously wake up the epoll so the dispatcher can run.
- while (fdp.remaining_bytes() > sizeof(MessageInfo)) {
- eventfd_write(endpoint->epoll_fd(), wakeup_val);
- }
-
- // Cleanup the dispatcher and thread.
- dispatcher->SetCanceled(true);
- if (run_dispatcher.joinable())
- run_dispatcher.join();
- dispatcher->RemoveService(service);
-
- return 0;
-}
diff --git a/libs/vr/libpdx/mock_tests.cpp b/libs/vr/libpdx/mock_tests.cpp
deleted file mode 100644
index 4143837..0000000
--- a/libs/vr/libpdx/mock_tests.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <gtest/gtest.h>
-#include <pdx/mock_client_channel.h>
-#include <pdx/mock_client_channel_factory.h>
-#include <pdx/mock_message_reader.h>
-#include <pdx/mock_message_writer.h>
-#include <pdx/mock_service_endpoint.h>
-
-TEST(MockTypes, Instantiation) {
- // Make sure all our interfaces are mocked out properly and mock instances
- // can be created.
- android::pdx::MockClientChannel client_channel;
- android::pdx::MockClientChannelFactory client_channel_factory;
- android::pdx::MockInputResourceMapper input_resource_mapper;
- android::pdx::MockMessageReader message_reader;
- android::pdx::MockOutputResourceMapper output_resource_mapper;
- android::pdx::MockMessageWriter message_writer;
- android::pdx::MockEndpoint endpoint;
-}
diff --git a/libs/vr/libpdx/private/pdx/channel_handle.h b/libs/vr/libpdx/private/pdx/channel_handle.h
deleted file mode 100644
index bd04305..0000000
--- a/libs/vr/libpdx/private/pdx/channel_handle.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef ANDROID_PDX_CHANNEL_HANDLE_H_
-#define ANDROID_PDX_CHANNEL_HANDLE_H_
-
-#include <cstdint>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-
-enum class ChannelHandleMode {
- Local,
- Borrowed,
- Remote,
-};
-
-class ChannelManagerInterface {
- public:
- virtual void CloseHandle(std::int32_t handle) = 0;
-
- protected:
- // Nobody should be allowed to delete the instance of channel manager
- // through this interface.
- virtual ~ChannelManagerInterface() = default;
-};
-
-class ChannelHandleBase {
- public:
- ChannelHandleBase() = default;
- explicit ChannelHandleBase(const int32_t& value) : value_{value} {}
-
- ChannelHandleBase(const ChannelHandleBase&) = delete;
- ChannelHandleBase& operator=(const ChannelHandleBase&) = delete;
-
- std::int32_t value() const { return value_; }
- bool valid() const { return value_ >= 0; }
- explicit operator bool() const { return valid(); }
-
- void Close() { value_ = kEmptyHandle; }
-
- protected:
- // Must not be used by itself. Must be derived from.
- ~ChannelHandleBase() = default;
- enum : std::int32_t { kEmptyHandle = -1 };
-
- std::int32_t value_{kEmptyHandle};
-};
-
-template <ChannelHandleMode Mode>
-class ChannelHandle : public ChannelHandleBase {
- public:
- ChannelHandle() = default;
- using ChannelHandleBase::ChannelHandleBase;
- ChannelHandle(ChannelHandle&& other) noexcept : ChannelHandleBase{other.value_} {
- other.value_ = kEmptyHandle;
- }
- ~ChannelHandle() = default;
-
- ChannelHandle Duplicate() const { return ChannelHandle{value_}; }
-
- ChannelHandle& operator=(ChannelHandle&& other) noexcept {
- value_ = other.value_;
- other.value_ = kEmptyHandle;
- return *this;
- }
-};
-
-template <>
-class ChannelHandle<ChannelHandleMode::Local> : public ChannelHandleBase {
- public:
- ChannelHandle() = default;
- ChannelHandle(ChannelManagerInterface* manager, int32_t value)
- : ChannelHandleBase{value}, manager_{manager} {}
-
- ChannelHandle(const ChannelHandle&) = delete;
- ChannelHandle& operator=(const ChannelHandle&) = delete;
-
- ChannelHandle(ChannelHandle&& other) noexcept
- : ChannelHandleBase{other.value_}, manager_{other.manager_} {
- other.manager_ = nullptr;
- other.value_ = kEmptyHandle;
- }
-
- ChannelHandle& operator=(ChannelHandle&& other) noexcept {
- value_ = other.value_;
- manager_ = other.manager_;
- other.value_ = kEmptyHandle;
- other.manager_ = nullptr;
- return *this;
- }
-
- ~ChannelHandle() {
- if (manager_)
- manager_->CloseHandle(value_);
- }
-
- ChannelHandle<ChannelHandleMode::Borrowed> Borrow() const {
- return ChannelHandle<ChannelHandleMode::Borrowed>{value_};
- }
-
- void Close() {
- if (manager_)
- manager_->CloseHandle(value_);
- manager_ = nullptr;
- value_ = kEmptyHandle;
- }
-
- private:
- ChannelManagerInterface* manager_{nullptr};
-};
-
-using LocalChannelHandle = ChannelHandle<ChannelHandleMode::Local>;
-using BorrowedChannelHandle = ChannelHandle<ChannelHandleMode::Borrowed>;
-using RemoteChannelHandle = ChannelHandle<ChannelHandleMode::Remote>;
-
-// ChannelReference is a 32 bit integer used in IPC serialization to be
-// transferred across processes. You can convert this value to a local channel
-// handle by calling Transaction.GetChannelHandle().
-using ChannelReference = int32_t;
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_CHANNEL_HANDLE_H_
diff --git a/libs/vr/libpdx/private/pdx/channel_parcelable.h b/libs/vr/libpdx/private/pdx/channel_parcelable.h
deleted file mode 100644
index 59ef9d3..0000000
--- a/libs/vr/libpdx/private/pdx/channel_parcelable.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef ANDROID_PDX_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_CHANNEL_PARCELABLE_H_
-
-#include <binder/Parcelable.h>
-#include <pdx/channel_handle.h>
-
-namespace android {
-namespace pdx {
-
-/**
- * A parcelable object holds all necessary objects to recreate a ClientChannel.
- * In addition to the android::Parcelable interface, this interface exposees
- * more PDX-related interface.
- */
-class ChannelParcelable : public Parcelable {
- public:
- virtual ~ChannelParcelable() = default;
-
- // Returns whether the parcelable object holds a valid client channel.
- virtual bool IsValid() const = 0;
-
- // Returns a channel handle constructed from this parcelable object and takes
- // the ownership of all resources from the parcelable object. In another word,
- // the parcelable object will become invalid after TakeChannelHandle returns.
- virtual LocalChannelHandle TakeChannelHandle() = 0;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx/private/pdx/client.h b/libs/vr/libpdx/private/pdx/client.h
deleted file mode 100644
index 7e2d55c..0000000
--- a/libs/vr/libpdx/private/pdx/client.h
+++ /dev/null
@@ -1,302 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_H_
-#define ANDROID_PDX_CLIENT_H_
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <string>
-#include <type_traits>
-
-#include <pdx/channel_handle.h>
-#include <pdx/client_channel.h>
-#include <pdx/client_channel_factory.h>
-#include <pdx/file_handle.h>
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-#include <pdx/rpc/remote_method_type.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class Transaction;
-
-/*
- * Base class of client-side service API classes.
- */
-class Client {
- public:
- static const int64_t kInfiniteTimeout = -1;
-
- virtual ~Client() = default;
-
- /*
- * Returns true if the Client instance successfully initialized, false
- * otherwise. Subclasses that can fail to initialize must override this and
- * AND their initialization result with this base class method's result.
- *
- * This method is not intended to perform initialization, only to report
- * the status of the initialization.
- */
- virtual bool IsInitialized() const;
-
- /*
- * Returns the error code describing the Client initialization failure, or 0
- * if there was no failure.
- */
- int error() const;
-
- // Returns a reference to IPC channel handle.
- LocalChannelHandle& GetChannelHandle();
- const LocalChannelHandle& GetChannelHandle() const;
-
- protected:
- friend Transaction;
- explicit Client(std::unique_ptr<ClientChannel> channel);
- explicit Client(std::unique_ptr<ClientChannelFactory> channel_factory,
- int64_t timeout_ms = kInfiniteTimeout);
-
- /*
- * Called by Client::Connect() after successfully connecting to the service
- * endpoint. Subclasses may override this method to perform additional setup,
- * including sending messages to complete the connection process.
- *
- * Subclasses may call Client::Close() within this method to terminate the
- * connection; Client::Connect() returns the negated error passed to
- * Client::Close() when this happens.
- */
- virtual void OnConnect();
-
- enum : size_t { MAX_IMPULSE_LENGTH = sizeof(uint64_t) * 4 };
-
- Status<void> SendImpulse(int opcode);
- Status<void> SendImpulse(int opcode, const void* buffer, size_t length);
-
- /*
- * Remote method call API using pdx::rpc serialization.
- * Include pdx/rpc/remote_method.h to use these methods.
- */
- template <typename RemoteMethodType, typename... Args>
- Status<typename RemoteMethodType::Return> InvokeRemoteMethod(Args&&... args);
-
- template <typename RemoteMethodType, typename ReturnType, typename... Args>
- Status<void> InvokeRemoteMethodInPlace(ReturnType* return_value,
- Args&&... args);
-
- /*
- * Close the endpoint file descriptor and optionally indicate an error, which
- * may be retrieved through error(). Subclasses may use this in their
- * constructor to signal failure during initialization or at other times
- * during operation.
- */
- void Close(int error);
-
- /*
- * Returns true if the client is connected to the service, false otherwise.
- */
- bool IsConnected() const;
-
- /*
- * Enables auto-reconnect with the given timeout. Use kInfiniteTimeout (-1)
- * for no timeout. Auto-reconnect can only be enabled if the Client class
- * was constructed with a ClientChannelFactory.
- */
- void EnableAutoReconnect(int64_t reconnect_timeout_ms);
-
- /*
- * Disables auto-reconnect.
- */
- void DisableAutoReconnect();
-
- /*
- * Returns an fd that the client may use to check/wait for asynchronous
- * notifications to the channel. It is implementation dependent how the
- * transport backend handles this feature, however all implementations must
- * support at least POLLIN/EPOLLIN/readable.
- *
- * For uses that require more than one type of event, use
- * ClientChannel::GetEventMask() to distinguish between events.
- */
- int event_fd() const;
-
- /*
- * Returns the underlying ClientChannel object.
- */
- ClientChannel* GetChannel() const { return channel_.get(); }
- std::unique_ptr<ClientChannel>&& TakeChannel() { return std::move(channel_); }
-
- private:
- Client(const Client&) = delete;
- void operator=(const Client&) = delete;
-
- Status<void> CheckReconnect();
- bool NeedToDisconnectChannel(int error) const;
- void CheckDisconnect(int error);
-
- template <typename T>
- inline void CheckDisconnect(const Status<T>& status) {
- if (!status)
- CheckDisconnect(status.error());
- }
-
- std::unique_ptr<ClientChannel> channel_;
- int error_{0};
-
- // Reconnection state.
- std::unique_ptr<ClientChannelFactory> channel_factory_;
- int64_t reconnect_timeout_ms_{0};
- bool auto_reconnect_enabled_{false};
-};
-
-/*
- * Utility template base class for client-side service API classes. Handles
- * initialization checks during allocation and automatically cleans up on
- * failure.
- *
- * @tparam T Type of the class extending this one.
- * @tparam C Client class to wrap. Defaults to the Client class.
- */
-template <typename T, typename ParentClient = Client>
-class ClientBase : public ParentClient {
- public:
- // Type of the client this class wraps.
- using ClientType = ParentClient;
-
- static_assert(std::is_base_of<Client, ParentClient>::value,
- "The provided parent client is not a Client subclass.");
-
- /*
- * Allocates a new instance of the superclass and checks for successful
- * initialization.
- *
- * The variadic arguments must expand to match one of type T's constructors
- * and are passed through unchanged. If a timeout is desired, subclasses are
- * responsible for passing this through to the appropriate ClientBase
- * constructor.
- *
- * Returns a unique_ptr to the new instance on success, or an empty unique_ptr
- * otherwise.
- */
- template <typename... Args>
- static inline std::unique_ptr<T> Create(Args&&... args) {
- std::unique_ptr<T> client(new T(std::forward<Args>(args)...));
- if (client->IsInitialized())
- return client;
- else
- return nullptr;
- }
-
- protected:
- /*
- * Type of the base class. Useful for referencing the base class type and
- * constructor in subclasses. Subclasses with non-public constructors
- * must declare BASE a friend.
- */
- using BASE = ClientBase<T, ParentClient>;
-
- /*
- * Type of the unique_ptr deleter. Useful for friend declarations.
- */
- using deleter_type = typename std::unique_ptr<T>::deleter_type;
-
- using ParentClient::ParentClient;
-};
-
-class Transaction final : public OutputResourceMapper,
- public InputResourceMapper {
- public:
- explicit Transaction(Client& client);
- ~Transaction();
-
- template <typename T>
- Status<T> Send(int opcode) {
- return SendVector<T>(opcode, nullptr, 0, nullptr, 0);
- }
-
- template <typename T>
- Status<T> Send(int opcode, const void* send_buffer, size_t send_length,
- void* receive_buffer, size_t receive_length) {
- const bool send = (send_buffer && send_length);
- const bool receive = (receive_buffer && receive_length);
- const iovec send_vector = {const_cast<void*>(send_buffer), send_length};
- const iovec receive_vector = {receive_buffer, receive_length};
- return SendVector<T>(opcode, send ? &send_vector : nullptr, send ? 1 : 0,
- receive ? &receive_vector : nullptr, receive ? 1 : 0);
- }
-
- template <typename T>
- Status<T> SendVector(int opcode, const iovec* send_vector, size_t send_count,
- const iovec* receive_vector, size_t receive_count) {
- Status<T> ret;
- SendTransaction(opcode, &ret, send_vector, send_count, receive_vector,
- receive_count);
- return ret;
- }
-
- template <typename T, size_t send_count, size_t receive_count>
- Status<T> SendVector(int opcode, const iovec (&send_vector)[send_count],
- const iovec (&receive_vector)[receive_count]) {
- return SendVector<T>(opcode, send_vector, send_count, receive_vector,
- receive_count);
- }
-
- template <typename T, size_t send_count>
- Status<T> SendVector(int opcode, const iovec (&send_vector)[send_count],
- std::nullptr_t) {
- return SendVector<T>(opcode, send_vector, send_count, nullptr, 0);
- }
-
- template <typename T, size_t receive_count>
- Status<T> SendVector(int opcode, std::nullptr_t,
- const iovec (&receive_vector)[receive_count]) {
- return SendVector<T>(opcode, nullptr, 0, receive_vector, receive_count);
- }
-
- // OutputResourceMapper
- Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
- Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
- Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) override;
-
- // InputResourceMapper
- bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
- bool GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) override;
-
- private:
- bool EnsureStateAllocated();
- void SendTransaction(int opcode, Status<void>* ret, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector,
- size_t receive_count);
- void SendTransaction(int opcode, Status<int>* ret, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector,
- size_t receive_count);
- void SendTransaction(int opcode, Status<LocalHandle>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector, size_t receive_count);
- void SendTransaction(int opcode, Status<LocalChannelHandle>* ret,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector, size_t receive_count);
- void CheckDisconnect(int error);
-
- template <typename T>
- inline void CheckDisconnect(const Status<T>& status) {
- if (!status)
- CheckDisconnect(status.error());
- }
-
- Client& client_;
- void* state_{nullptr};
- bool state_allocated_{false};
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_CLIENT_H_
diff --git a/libs/vr/libpdx/private/pdx/client_channel.h b/libs/vr/libpdx/private/pdx/client_channel.h
deleted file mode 100644
index f33a60e..0000000
--- a/libs/vr/libpdx/private/pdx/client_channel.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_CLIENT_CHANNEL_H_
-
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/channel_parcelable.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-struct iovec;
-
-namespace android {
-namespace pdx {
-
-class ClientChannel {
- public:
- virtual ~ClientChannel() = default;
-
- // Returns a tag that uniquely identifies a specific underlying IPC transport.
- virtual uint32_t GetIpcTag() const = 0;
-
- virtual int event_fd() const = 0;
- virtual Status<int> GetEventMask(int events) = 0;
-
- struct EventSource {
- int event_fd;
- int event_mask;
- };
-
- // Returns a set of event-generating fds with and event mask for each. These
- // fds are owned by the ClientChannel and must never be closed by the caller.
- virtual std::vector<EventSource> GetEventSources() const = 0;
-
- virtual LocalChannelHandle& GetChannelHandle() = 0;
- virtual const LocalChannelHandle& GetChannelHandle() const = 0;
- virtual void* AllocateTransactionState() = 0;
- virtual void FreeTransactionState(void* state) = 0;
-
- virtual Status<void> SendImpulse(int opcode, const void* buffer,
- size_t length) = 0;
-
- virtual Status<int> SendWithInt(void* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) = 0;
- virtual Status<LocalHandle> SendWithFileHandle(
- void* transaction_state, int opcode, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector, size_t receive_count) = 0;
- virtual Status<LocalChannelHandle> SendWithChannelHandle(
- void* transaction_state, int opcode, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector, size_t receive_count) = 0;
-
- virtual FileReference PushFileHandle(void* transaction_state,
- const LocalHandle& handle) = 0;
- virtual FileReference PushFileHandle(void* transaction_state,
- const BorrowedHandle& handle) = 0;
- virtual ChannelReference PushChannelHandle(
- void* transaction_state, const LocalChannelHandle& handle) = 0;
- virtual ChannelReference PushChannelHandle(
- void* transaction_state, const BorrowedChannelHandle& handle) = 0;
- virtual bool GetFileHandle(void* transaction_state, FileReference ref,
- LocalHandle* handle) const = 0;
- virtual bool GetChannelHandle(void* transaction_state, ChannelReference ref,
- LocalChannelHandle* handle) const = 0;
-
- // Returns the internal state of the channel as a parcelable object. The
- // ClientChannel is invalidated however, the channel is kept alive by the
- // parcelable object and may be transferred to another process.
- virtual std::unique_ptr<ChannelParcelable> TakeChannelParcelable() = 0;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx/private/pdx/client_channel_factory.h b/libs/vr/libpdx/private/pdx/client_channel_factory.h
deleted file mode 100644
index a82ab70..0000000
--- a/libs/vr/libpdx/private/pdx/client_channel_factory.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
-
-#include <pdx/client_channel.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class ClientChannelFactory {
- public:
- virtual ~ClientChannelFactory() = default;
-
- virtual Status<std::unique_ptr<ClientChannel>> Connect(
- int64_t timeout_ms) const = 0;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx/private/pdx/file_handle.h b/libs/vr/libpdx/private/pdx/file_handle.h
deleted file mode 100644
index fed1529..0000000
--- a/libs/vr/libpdx/private/pdx/file_handle.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifndef ANDROID_PDX_FILE_HANDLE_H_
-#define ANDROID_PDX_FILE_HANDLE_H_
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <string>
-
-namespace android {
-namespace pdx {
-
-enum class FileHandleMode {
- Local,
- Remote,
- Borrowed,
-};
-
-// Manages ownership, sharing, and lifetime of file descriptors.
-template <FileHandleMode Mode>
-class FileHandle {
- public:
- static constexpr int kEmptyFileHandle = -1;
-
- // Constructs an empty FileHandle object.
- FileHandle() : fd_(kEmptyFileHandle) {}
-
- // Constructs a FileHandle from an integer file descriptor and takes
- // ownership.
- explicit FileHandle(int fd) : fd_(fd) {}
-
- // Constructs a FileHandle by opening |path|. The arguments follow the
- // semantics of open().
- FileHandle(const std::string& path, int flags, mode_t mode = 0) {
- fd_ = open(path.c_str(), flags, mode);
- }
-
- // Constructs a FileHandle by opening |path| relative to |dir_fd|, following
- // the semantics of openat().
- FileHandle(const int directory_fd, const std::string& path, int flags,
- mode_t mode = 0) {
- fd_ = openat(directory_fd, path.c_str(), flags, mode);
- }
-
- // Move constructor that assumes ownership of the file descriptor, leaving the
- // other FileHandle object empty.
- FileHandle(FileHandle&& other) noexcept {
- fd_ = other.fd_;
- other.fd_ = kEmptyFileHandle;
- }
-
- // Returns a FileHandle as a duplicate handle of |fd|. Borrowed handles and
- // handles in remote handle space are not duplicated.
- static FileHandle AsDuplicate(const int fd) {
- if (Mode == FileHandleMode::Local)
- return FileHandle(dup(fd));
- else
- return FileHandle(fd);
- }
-
- // Destructor closes the file descriptor when non-empty.
- ~FileHandle() { Close(); }
-
- // Move assignment operator that assumes ownership of the underlying file
- // descriptor, leaving the other FileHandle object empty.
- FileHandle& operator=(FileHandle&& other) noexcept {
- if (this != &other) {
- Reset(other.fd_);
- other.fd_ = kEmptyFileHandle;
- }
- return *this;
- }
-
- // Resets the underlying file handle to |fd|.
- void Reset(int fd) {
- Close();
- fd_ = fd;
- }
-
- // Closes the underlying file descriptor when non-empty.
- void Close() {
- if (IsValid() && Mode == FileHandleMode::Local)
- close(fd_);
- fd_ = kEmptyFileHandle;
- }
-
- // Return the internal fd, passing ownership to the caller.
- int Release() {
- int release_fd = fd_;
- fd_ = kEmptyFileHandle;
- return release_fd;
- }
-
- // Duplicates the underlying file descriptor and returns a FileHandle that
- // owns the new file descriptor. File descriptors are not duplicated when Mode
- // is Remote or Borrowed.
- FileHandle Duplicate() const {
- return FileHandle(Mode == FileHandleMode::Local ? dup(fd_) : fd_);
- }
-
- FileHandle<FileHandleMode::Borrowed> Borrow() const {
- return FileHandle<FileHandleMode::Borrowed>(Get());
- }
-
- // Gets the underlying file descriptor value.
- int Get() const { return fd_; }
- bool IsValid() const { return fd_ >= 0; }
- explicit operator bool() const { return IsValid(); }
-
- private:
- int fd_;
-
- FileHandle(const FileHandle&) = delete;
- void operator=(const FileHandle&) = delete;
-};
-
-// Alias for a file handle in the local process' handle space.
-using LocalHandle = FileHandle<FileHandleMode::Local>;
-
-// Alias for a file handle in another process' handle space. Handles returned
-// from pushing a file object or channel must be stored in this type of handle
-// class, which doesn't close the underlying file descriptor. The underlying
-// file descriptor in this wrapper should not be passed to close() because doing
-// so would close an unrelated file descriptor in the local handle space.
-using RemoteHandle = FileHandle<FileHandleMode::Remote>;
-
-// Alias for borrowed handles in the local process' handle space. A borrowed
-// file handle is not close() because this wrapper does not own the underlying
-// file descriptor. Care must be take to ensure that a borrowed file handle
-// remains valid during use.
-using BorrowedHandle = FileHandle<FileHandleMode::Borrowed>;
-
-// FileReference is a 16 bit integer used in IPC serialization to be
-// transferred across processes. You can convert this value to a local file
-// handle by calling Transaction.GetFileHandle() on client side and
-// Message.GetFileHandle() on service side.
-using FileReference = int16_t;
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_FILE_HANDLE_H_
diff --git a/libs/vr/libpdx/private/pdx/message_reader.h b/libs/vr/libpdx/private/pdx/message_reader.h
deleted file mode 100644
index bc280cf..0000000
--- a/libs/vr/libpdx/private/pdx/message_reader.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_MESSAGE_READER_H_
-#define ANDROID_PDX_MESSAGE_READER_H_
-
-#include <memory>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-
-class InputResourceMapper {
- public:
- virtual bool GetFileHandle(FileReference ref, LocalHandle* handle) = 0;
- virtual bool GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) = 0;
-
- protected:
- virtual ~InputResourceMapper() = default;
-};
-
-class MessageReader {
- public:
- // Pointers to start/end of the region in the read buffer.
- using BufferSection = std::pair<const void*, const void*>;
-
- virtual BufferSection GetNextReadBufferSection() = 0;
- virtual void ConsumeReadBufferSectionData(const void* new_start) = 0;
- virtual InputResourceMapper* GetInputResourceMapper() = 0;
-
- protected:
- virtual ~MessageReader() = default;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MESSAGE_READER_H_
diff --git a/libs/vr/libpdx/private/pdx/message_writer.h b/libs/vr/libpdx/private/pdx/message_writer.h
deleted file mode 100644
index 4a101d6..0000000
--- a/libs/vr/libpdx/private/pdx/message_writer.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_PDX_MESSAGE_WRITER_H_
-#define ANDROID_PDX_MESSAGE_WRITER_H_
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-
-class OutputResourceMapper {
- public:
- virtual Status<FileReference> PushFileHandle(const LocalHandle& handle) = 0;
- virtual Status<FileReference> PushFileHandle(
- const BorrowedHandle& handle) = 0;
- virtual Status<FileReference> PushFileHandle(const RemoteHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) = 0;
-
- protected:
- virtual ~OutputResourceMapper() = default;
-};
-
-class MessageWriter {
- public:
- virtual void* GetNextWriteBufferSection(size_t size) = 0;
- virtual OutputResourceMapper* GetOutputResourceMapper() = 0;
-
- protected:
- virtual ~MessageWriter() = default;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MESSAGE_WRITER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_client_channel.h b/libs/vr/libpdx/private/pdx/mock_client_channel.h
deleted file mode 100644
index b1a1299..0000000
--- a/libs/vr/libpdx/private/pdx/mock_client_channel.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
-
-#include <gmock/gmock.h>
-#include <pdx/client_channel.h>
-
-namespace android {
-namespace pdx {
-
-class MockClientChannel : public ClientChannel {
- public:
- MOCK_CONST_METHOD0(GetIpcTag, uint32_t());
- MOCK_CONST_METHOD0(event_fd, int());
- MOCK_CONST_METHOD0(GetEventSources, std::vector<EventSource>());
- MOCK_METHOD1(GetEventMask, Status<int>(int));
- MOCK_METHOD0(GetChannelHandle, LocalChannelHandle&());
- MOCK_CONST_METHOD0(GetChannelHandle, const LocalChannelHandle&());
- MOCK_METHOD0(AllocateTransactionState, void*());
- MOCK_METHOD1(FreeTransactionState, void(void* state));
- MOCK_METHOD3(SendImpulse,
- Status<void>(int opcode, const void* buffer, size_t length));
- MOCK_METHOD6(SendWithInt,
- Status<int>(void* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector, size_t receive_count));
- MOCK_METHOD6(SendWithFileHandle,
- Status<LocalHandle>(void* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count));
- MOCK_METHOD6(SendWithChannelHandle,
- Status<LocalChannelHandle>(void* transaction_state, int opcode,
- const iovec* send_vector,
- size_t send_count,
- const iovec* receive_vector,
- size_t receive_count));
- MOCK_METHOD2(PushFileHandle, FileReference(void* transaction_state,
- const LocalHandle& handle));
- MOCK_METHOD2(PushFileHandle, FileReference(void* transaction_state,
- const BorrowedHandle& handle));
- MOCK_METHOD2(PushChannelHandle,
- ChannelReference(void* transaction_state,
- const LocalChannelHandle& handle));
- MOCK_METHOD2(PushChannelHandle,
- ChannelReference(void* transaction_state,
- const BorrowedChannelHandle& handle));
- MOCK_CONST_METHOD3(GetFileHandle,
- bool(void* transaction_state, FileReference ref,
- LocalHandle* handle));
- MOCK_CONST_METHOD3(GetChannelHandle,
- bool(void* transaction_state, ChannelReference ref,
- LocalChannelHandle* handle));
- MOCK_METHOD0(TakeChannelParcelable, std::unique_ptr<ChannelParcelable>());
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MOCK_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h b/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h
deleted file mode 100644
index 0190f5e..0000000
--- a/libs/vr/libpdx/private/pdx/mock_client_channel_factory.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
-
-#include <gmock/gmock.h>
-#include <pdx/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-
-class MockClientChannelFactory : public ClientChannelFactory {
- public:
- MOCK_CONST_METHOD1(
- Connect, Status<std::unique_ptr<ClientChannel>>(int64_t timeout_ms));
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MOCK_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_message_reader.h b/libs/vr/libpdx/private/pdx/mock_message_reader.h
deleted file mode 100644
index 85e96ef..0000000
--- a/libs/vr/libpdx/private/pdx/mock_message_reader.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_MESSAGE_READER_H_
-#define ANDROID_PDX_MOCK_MESSAGE_READER_H_
-
-#include <gmock/gmock.h>
-#include <pdx/message_reader.h>
-
-namespace android {
-namespace pdx {
-
-class MockInputResourceMapper : public InputResourceMapper {
- public:
- MOCK_METHOD2(GetFileHandle, bool(FileReference ref, LocalHandle* handle));
- MOCK_METHOD2(GetChannelHandle,
- bool(ChannelReference ref, LocalChannelHandle* handle));
-};
-
-class MockMessageReader : public MessageReader {
- public:
- MOCK_METHOD0(GetNextReadBufferSection, BufferSection());
- MOCK_METHOD1(ConsumeReadBufferSectionData, void(const void* new_start));
- MOCK_METHOD0(GetInputResourceMapper, InputResourceMapper*());
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MOCK_MESSAGE_READER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_message_writer.h b/libs/vr/libpdx/private/pdx/mock_message_writer.h
deleted file mode 100644
index e06e5bb..0000000
--- a/libs/vr/libpdx/private/pdx/mock_message_writer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
-#define ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
-
-#include <gmock/gmock.h>
-#include <pdx/message_writer.h>
-
-namespace android {
-namespace pdx {
-
-class MockOutputResourceMapper : public OutputResourceMapper {
- public:
- MOCK_METHOD1(PushFileHandle,
- Status<FileReference>(const LocalHandle& handle));
- MOCK_METHOD1(PushFileHandle,
- Status<FileReference>(const BorrowedHandle& handle));
- MOCK_METHOD1(PushFileHandle,
- Status<FileReference>(const RemoteHandle& handle));
- MOCK_METHOD1(PushChannelHandle,
- Status<ChannelReference>(const LocalChannelHandle& handle));
- MOCK_METHOD1(PushChannelHandle,
- Status<ChannelReference>(const BorrowedChannelHandle& handle));
- MOCK_METHOD1(PushChannelHandle,
- Status<ChannelReference>(const RemoteChannelHandle& handle));
-};
-
-class MockMessageWriter : public MessageWriter {
- public:
- MOCK_METHOD1(GetNextWriteBufferSection, void*(size_t size));
- MOCK_METHOD0(GetOutputResourceMapper, OutputResourceMapper*());
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MOCK_MESSAGE_WRITER_H_
diff --git a/libs/vr/libpdx/private/pdx/mock_service_endpoint.h b/libs/vr/libpdx/private/pdx/mock_service_endpoint.h
deleted file mode 100644
index 7f829e7..0000000
--- a/libs/vr/libpdx/private/pdx/mock_service_endpoint.h
+++ /dev/null
@@ -1,75 +0,0 @@
-#ifndef ANDROID_PDX_MOCK_ENDPOINT_H_
-#define ANDROID_PDX_MOCK_ENDPOINT_H_
-
-#include <gmock/gmock.h>
-#include <pdx/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-
-class MockEndpoint : public Endpoint {
- public:
- MOCK_CONST_METHOD0(GetIpcTag, uint32_t());
- MOCK_METHOD1(SetService, Status<void>(Service* service));
- MOCK_METHOD2(SetChannel, Status<void>(int channel_id, Channel* channel));
- MOCK_METHOD1(CloseChannel, Status<void>(int channel_id));
- MOCK_METHOD3(ModifyChannelEvents,
- Status<void>(int channel_id, int clear_mask, int set_mask));
- MOCK_METHOD4(PushChannel,
- Status<RemoteChannelHandle>(Message* message, int flags,
- Channel* channel, int* channel_id));
- MOCK_METHOD3(CheckChannel,
- Status<int>(const Message* message, ChannelReference ref,
- Channel** channel));
- MOCK_METHOD1(MessageReceive, Status<void>(Message* message));
- MOCK_METHOD2(MessageReply, Status<void>(Message* message, int return_code));
- MOCK_METHOD2(MessageReplyFd,
- Status<void>(Message* message, unsigned int push_fd));
- MOCK_METHOD2(MessageReplyChannelHandle,
- Status<void>(Message* message,
- const LocalChannelHandle& handle));
- MOCK_METHOD2(MessageReplyChannelHandle,
- Status<void>(Message* message,
- const BorrowedChannelHandle& handle));
- MOCK_METHOD2(MessageReplyChannelHandle,
- Status<void>(Message* message,
- const RemoteChannelHandle& handle));
- MOCK_METHOD3(ReadMessageData,
- Status<size_t>(Message* message, const iovec* vector,
- size_t vector_length));
- MOCK_METHOD3(WriteMessageData,
- Status<size_t>(Message* message, const iovec* vector,
- size_t vector_length));
- MOCK_METHOD2(PushFileHandle,
- Status<FileReference>(Message* message,
- const LocalHandle& handle));
- MOCK_METHOD2(PushFileHandle,
- Status<FileReference>(Message* message,
- const BorrowedHandle& handle));
- MOCK_METHOD2(PushFileHandle,
- Status<FileReference>(Message* message,
- const RemoteHandle& handle));
- MOCK_METHOD2(PushChannelHandle,
- Status<ChannelReference>(Message* message,
- const LocalChannelHandle& handle));
- MOCK_METHOD2(PushChannelHandle,
- Status<ChannelReference>(Message* message,
- const BorrowedChannelHandle& handle));
- MOCK_METHOD2(PushChannelHandle,
- Status<ChannelReference>(Message* message,
- const RemoteChannelHandle& handle));
- MOCK_CONST_METHOD2(GetFileHandle,
- LocalHandle(Message* message, FileReference ref));
- MOCK_CONST_METHOD2(GetChannelHandle,
- LocalChannelHandle(Message* message,
- ChannelReference ref));
- MOCK_METHOD0(AllocateMessageState, void*());
- MOCK_METHOD1(FreeMessageState, void(void* state));
- MOCK_METHOD0(Cancel, Status<void>());
- MOCK_CONST_METHOD0(epoll_fd, int());
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_MOCK_ENDPOINT_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h b/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h
deleted file mode 100644
index e006284..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/argument_encoder.h
+++ /dev/null
@@ -1,184 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
-#define ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
-
-#include <cstdint>
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/rpc/serialization.h>
-#include <pdx/service.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Provides automatic serialization of argument lists and return
-// values by analyzing the supplied function signature types.
-// Examples:
-// ArgumentEncoder<int(int, float)> encoder(writer);
-// encoder.EncodeArguments(1, 1.0);
-
-template <typename T>
-class ArgumentEncoder;
-
-// Specialization of ArgumentEncoder for void return types.
-template <typename... Args>
-class ArgumentEncoder<void(Args...)> {
- public:
- explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
-
- // Serializes the arguments as a tuple.
- void EncodeArguments(Args... args) {
- Serialize(std::forward_as_tuple(args...), writer_);
- }
-
- private:
- MessageWriter* writer_;
-};
-
-// Specialization of ArgumentEncoder for non-void return types.
-template <typename Return, typename... Args>
-class ArgumentEncoder<Return(Args...)> {
- public:
- // Simplified types with reference and cv removed.
- using ReturnType = typename std::decay<Return>::type;
-
- explicit ArgumentEncoder(MessageWriter* writer) : writer_{writer} {}
-
- // Serializes the arguments as a tuple.
- void EncodeArguments(Args... args) {
- Serialize(std::forward_as_tuple(args...), writer_);
- }
-
- // Serializes the return value for rvalue references.
- void EncodeReturn(const ReturnType& return_value) {
- Serialize(return_value, writer_);
- }
-
- private:
- MessageWriter* writer_;
-};
-
-// Utility to build an ArgumentEncoder from a function pointer and a message
-// writer.
-template <typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
- Return (*)(Args...), MessageWriter* writer) {
- return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a method pointer and a message
-// writer.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
- Return (Class::*)(Args...), MessageWriter* writer) {
- return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a const method pointer and a
-// message writer.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentEncoder<Return(Args...)> MakeArgumentEncoder(
- Return (Class::*)(Args...) const, MessageWriter* writer) {
- return ArgumentEncoder<Return(Args...)>(writer);
-}
-
-// Utility to build an ArgumentEncoder from a function type and a message
-// writer.
-template <typename Signature>
-inline ArgumentEncoder<Signature> MakeArgumentEncoder(MessageWriter* writer) {
- return ArgumentEncoder<Signature>(writer);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Provides automatic deserialization of argument lists and return
-// values by analyzing the supplied function signature types.
-// Examples:
-// auto decoder = MakeArgumentDecoder<std::string(void)>(reader);
-// ErrorType error = decoder.DecodeReturn(&return_value);
-
-template <typename T>
-class ArgumentDecoder;
-
-// Specialization of ArgumentDecoder for void return types.
-template <typename... Args>
-class ArgumentDecoder<void(Args...)> {
- public:
- // Simplified types with reference and cv removed.
- using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
-
- explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
-
- // Deserializes arguments into a tuple.
- ArgsTupleType DecodeArguments(ErrorType* error) {
- ArgsTupleType value;
- *error = Deserialize(&value, reader_);
- return value;
- }
-
- private:
- MessageReader* reader_;
-};
-
-// Specialization of ArgumentDecoder for non-void return types.
-template <typename Return, typename... Args>
-class ArgumentDecoder<Return(Args...)> {
- public:
- // Simplified types with reference and cv removed.
- using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
- using ReturnType = typename std::decay<Return>::type;
-
- explicit ArgumentDecoder(MessageReader* reader) : reader_{reader} {}
-
- // Deserializes arguments into a tuple.
- ArgsTupleType DecodeArguments(ErrorType* error) {
- ArgsTupleType value;
- *error = Deserialize(&value, reader_);
- return value;
- }
-
- // Deserializes the return value.
- ErrorType DecodeReturn(ReturnType* value) {
- return Deserialize(value, reader_);
- }
-
- private:
- MessageReader* reader_;
-};
-
-// Utility to build an ArgumentDecoder from a function pointer and a message
-// reader.
-template <typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
- Return (*)(Args...), MessageReader* reader) {
- return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a method pointer and a message
-// reader.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
- Return (Class::*)(Args...), MessageReader* reader) {
- return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a const method pointer and a
-// message reader.
-template <typename Class, typename Return, typename... Args>
-inline ArgumentDecoder<Return(Args...)> MakeArgumentDecoder(
- Return (Class::*)(Args...) const, MessageReader* reader) {
- return ArgumentDecoder<Return(Args...)>(reader);
-}
-
-// Utility to build an ArgumentDecoder from a function type and a message
-// reader.
-template <typename Signature>
-inline ArgumentDecoder<Signature> MakeArgumentDecoder(MessageReader* reader) {
- return ArgumentDecoder<Signature>(reader);
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_ARGUMENT_ENCODER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h
deleted file mode 100644
index d835c57..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/array_wrapper.h
+++ /dev/null
@@ -1,111 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
-#define ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <vector>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for C array buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class serializes to the same
-// format as std::vector, and may be substituted for std::vector during
-// serialization and deserialization. This substitution makes handling of C
-// arrays more efficient by avoiding unnecessary copies when remote method
-// signatures specify std::vector arguments or return values.
-template <typename T>
-class ArrayWrapper {
- public:
- // Define types in the style of STL containers to support STL operators.
- typedef T value_type;
- typedef std::size_t size_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- ArrayWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
- ArrayWrapper(pointer buffer, size_type capacity, size_type size)
- : buffer_(&buffer[0]),
- capacity_(capacity),
- end_(capacity < size ? capacity : size) {}
-
- ArrayWrapper(pointer buffer, size_type size)
- : ArrayWrapper(buffer, size, size) {}
-
- ArrayWrapper(const ArrayWrapper& other) { *this = other; }
-
- ArrayWrapper(ArrayWrapper&& other) noexcept { *this = std::move(other); }
-
- ArrayWrapper& operator=(const ArrayWrapper& other) {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- }
-
- return *this;
- }
-
- ArrayWrapper& operator=(ArrayWrapper&& other) noexcept {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- other.buffer_ = nullptr;
- other.capacity_ = 0;
- other.end_ = 0;
- }
-
- return *this;
- }
-
- pointer data() { return buffer_; }
- const_pointer data() const { return buffer_; }
-
- pointer begin() { return &buffer_[0]; }
- pointer end() { return &buffer_[end_]; }
- const_pointer begin() const { return &buffer_[0]; }
- const_pointer end() const { return &buffer_[end_]; }
-
- size_type size() const { return end_; }
- size_type max_size() const { return capacity_; }
- size_type capacity() const { return capacity_; }
-
- // Moves the end marker to |size|, clamping the end marker to the max capacity
- // of the underlying array. This method does not change the size of the
- // underlying array.
- void resize(size_type size) {
- if (size <= capacity_)
- end_ = size;
- else
- end_ = capacity_;
- }
-
- reference operator[](size_type pos) { return buffer_[pos]; }
- const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
- pointer buffer_;
- size_type capacity_;
- size_type end_;
-};
-
-template <typename T, typename SizeType = std::size_t>
-ArrayWrapper<T> WrapArray(T* buffer, SizeType size) {
- return ArrayWrapper<T>(buffer, size);
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_ARRAY_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
deleted file mode 100644
index 43184dd..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/buffer_wrapper.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
-#define ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <vector>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class supports serialization of
-// buffers as raw bytes.
-template <typename T>
-class BufferWrapper;
-
-template <typename T>
-class BufferWrapper<T*> {
- public:
- // Define types in the style of STL containers to support STL operators.
- typedef T value_type;
- typedef std::size_t size_type;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T* pointer;
- typedef const T* const_pointer;
-
- BufferWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
- BufferWrapper(pointer buffer, size_type capacity, size_type size)
- : buffer_(&buffer[0]),
- capacity_(capacity),
- end_(capacity < size ? capacity : size) {}
-
- BufferWrapper(pointer buffer, size_type size)
- : BufferWrapper(buffer, size, size) {}
-
- BufferWrapper(const BufferWrapper& other) { *this = other; }
-
- BufferWrapper(BufferWrapper&& other) noexcept { *this = std::move(other); }
-
- BufferWrapper& operator=(const BufferWrapper& other) {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- }
-
- return *this;
- }
-
- BufferWrapper& operator=(BufferWrapper&& other) noexcept {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- other.buffer_ = nullptr;
- other.capacity_ = 0;
- other.end_ = 0;
- }
-
- return *this;
- }
-
- pointer data() { return buffer_; }
- const_pointer data() const { return buffer_; }
-
- pointer begin() { return &buffer_[0]; }
- pointer end() { return &buffer_[end_]; }
- const_pointer begin() const { return &buffer_[0]; }
- const_pointer end() const { return &buffer_[end_]; }
-
- size_type size() const { return end_; }
- size_type max_size() const { return capacity_; }
- size_type capacity() const { return capacity_; }
-
- void resize(size_type size) {
- if (size <= capacity_)
- end_ = size;
- else
- end_ = capacity_;
- }
-
- reference operator[](size_type pos) { return buffer_[pos]; }
- const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
- pointer buffer_;
- size_type capacity_;
- size_type end_;
-};
-
-template <typename T, typename Allocator>
-class BufferWrapper<std::vector<T, Allocator>> {
- public:
- using BufferType = typename std::vector<T, Allocator>;
- using value_type = typename BufferType::value_type;
- using size_type = typename BufferType::size_type;
- using reference = typename BufferType::reference;
- using const_reference = typename BufferType::const_reference;
- using pointer = typename BufferType::pointer;
- using const_pointer = typename BufferType::const_pointer;
- using iterator = typename BufferType::iterator;
- using const_iterator = typename BufferType::const_iterator;
-
- BufferWrapper() {}
- explicit BufferWrapper(const BufferType& buffer) : buffer_(buffer) {}
- BufferWrapper(const BufferType& buffer, const Allocator& allocator)
- : buffer_(buffer, allocator) {}
- explicit BufferWrapper(BufferType&& buffer) : buffer_(std::move(buffer)) {}
- BufferWrapper(BufferType&& buffer, const Allocator& allocator)
- : buffer_(std::move(buffer), allocator) {}
- BufferWrapper(const BufferWrapper&) = default;
- BufferWrapper(BufferWrapper&&) noexcept = default;
- BufferWrapper& operator=(const BufferWrapper&) = default;
- BufferWrapper& operator=(BufferWrapper&&) noexcept = default;
-
- pointer data() { return buffer_.data(); }
- const_pointer data() const { return buffer_.data(); }
-
- iterator begin() { return buffer_.begin(); }
- iterator end() { return buffer_.end(); }
- const_iterator begin() const { return buffer_.begin(); }
- const_iterator end() const { return buffer_.end(); }
-
- size_type size() const { return buffer_.size(); }
- size_type max_size() const { return buffer_.capacity(); }
- size_type capacity() const { return buffer_.capacity(); }
-
- void resize(size_type size) { buffer_.resize(size); }
- void reserve(size_type size) { buffer_.reserve(size); }
-
- reference operator[](size_type pos) { return buffer_[pos]; }
- const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- BufferType& buffer() { return buffer_; }
- const BufferType& buffer() const { return buffer_; }
-
- private:
- BufferType buffer_;
-};
-
-template <typename T, typename SizeType = std::size_t>
-BufferWrapper<T*> WrapBuffer(T* buffer, SizeType size) {
- return BufferWrapper<T*>(buffer, size);
-}
-
-template <typename SizeType = std::size_t>
-BufferWrapper<std::uint8_t*> WrapBuffer(void* buffer, SizeType size) {
- return BufferWrapper<std::uint8_t*>(static_cast<std::uint8_t*>(buffer), size);
-}
-
-template <typename SizeType = std::size_t>
-BufferWrapper<const std::uint8_t*> WrapBuffer(const void* buffer,
- SizeType size) {
- return BufferWrapper<const std::uint8_t*>(
- static_cast<const std::uint8_t*>(buffer), size);
-}
-
-template <typename T, typename Allocator = std::allocator<T>>
-BufferWrapper<std::vector<T, Allocator>> WrapBuffer(
- std::vector<T, Allocator>&& buffer) {
- return BufferWrapper<std::vector<T, Allocator>>(
- std::forward<std::vector<T, Allocator>>(buffer));
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_BUFFER_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h b/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h
deleted file mode 100644
index 5ce34f8..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/copy_cv_reference.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
-#define ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
-
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Copies const, void, and reference qualifiers from type T to type U, such that
-// the new type U' carries the same cv-reference qualifiers as T, with the same
-// underlying type as U.
-template <typename T, typename U>
-class CopyCVReference {
- private:
- using R = typename std::remove_reference<T>::type;
- using U1 =
- typename std::conditional<std::is_const<R>::value,
- typename std::add_const<U>::type, U>::type;
- using U2 =
- typename std::conditional<std::is_volatile<R>::value,
- typename std::add_volatile<U1>::type, U1>::type;
- using U3 =
- typename std::conditional<std::is_lvalue_reference<T>::value,
- typename std::add_lvalue_reference<U2>::type,
- U2>::type;
- using U4 =
- typename std::conditional<std::is_rvalue_reference<T>::value,
- typename std::add_rvalue_reference<U3>::type,
- U3>::type;
-
- public:
- using Type = U4;
-};
-
-template <typename T, typename U>
-using CopyCVReferenceType = typename CopyCVReference<T, U>::Type;
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_COPY_CV_REFERENCE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h b/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h
deleted file mode 100644
index b6e2980..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/default_initialization_allocator.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
-#define ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
-
-#include <memory>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Allocator adaptor that interposes construct() calls to convert value
-// initialization into default initialization. All standard containers
-// value-initialize their elements when constructed with a single size_type
-// argument or when grown by a call to resize. This allocator avoids potentially
-// costly value-initialization in these situations for value types that are
-// default constructible. As a consequence, elements of non-class types are left
-// uninitialized; this is desirable when using std::vector as a resizable
-// buffer, for example.
-template <typename T, typename Allocator = std::allocator<T>>
-class DefaultInitializationAllocator : public Allocator {
- typedef std::allocator_traits<Allocator> AllocatorTraits;
-
- public:
- template <typename U>
- struct rebind {
- using other = DefaultInitializationAllocator<
- U, typename AllocatorTraits::template rebind_alloc<U>>;
- };
-
- using Allocator::Allocator;
-
- template <typename U>
- void construct(U* pointer) noexcept(
- std::is_nothrow_default_constructible<U>::value) {
- ::new (static_cast<void*>(pointer)) U;
- }
- template <typename U, typename... Args>
- void construct(U* pointer, Args&&... args) {
- AllocatorTraits::construct(static_cast<Allocator&>(*this), pointer,
- std::forward<Args>(args)...);
- }
-};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_DEFAULT_INITIALIZATION_ALLOCATOR_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/encoding.h b/libs/vr/libpdx/private/pdx/rpc/encoding.h
deleted file mode 100644
index f51d807..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/encoding.h
+++ /dev/null
@@ -1,616 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ENCODING_H_
-#define ANDROID_PDX_RPC_ENCODING_H_
-
-#include <array>
-#include <cstdint>
-#include <cstring>
-#include <map>
-#include <numeric>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-
-#include "array_wrapper.h"
-#include "buffer_wrapper.h"
-#include "string_wrapper.h"
-#include "variant.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// This library uses a subset, or profile, of MessagePack (http://msgpack.org)
-// to encode supported data types during serialization and to verify the
-// expected data types during deserialization. One notable deviation from the
-// MessagePack specification is that little-endian byte order is used for
-// multi-byte numeric types to avoid unnecessary conversion on nearly all
-// relevant architectures.
-//
-// Some data types, integers for example, support multiple encoding strategies.
-// This library attempts to optimize for space based on the value of such types.
-// However, during decode all valid encodings for a given type are accepted.
-
-// Prefix byte for type encodings. This is the complete list of prefix bytes
-// from the MessagePack specification, even though not all types are used by
-// this library.
-enum EncodingPrefix {
- ENCODING_TYPE_POSITIVE_FIXINT = 0x00,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN = 0x00,
- ENCODING_TYPE_POSITIVE_FIXINT_MAX = 0x7f,
- ENCODING_TYPE_POSITIVE_FIXINT_MASK = 0x7f,
- ENCODING_TYPE_FIXMAP = 0x80,
- ENCODING_TYPE_FIXMAP_MIN = 0x80,
- ENCODING_TYPE_FIXMAP_MAX = 0x8f,
- ENCODING_TYPE_FIXMAP_MASK = 0x0f,
- ENCODING_TYPE_FIXARRAY = 0x90,
- ENCODING_TYPE_FIXARRAY_MIN = 0x90,
- ENCODING_TYPE_FIXARRAY_MAX = 0x9f,
- ENCODING_TYPE_FIXARRAY_MASK = 0x0f,
- ENCODING_TYPE_FIXSTR = 0xa0,
- ENCODING_TYPE_FIXSTR_MIN = 0xa0,
- ENCODING_TYPE_FIXSTR_MAX = 0xbf,
- ENCODING_TYPE_FIXSTR_MASK = 0x1f,
- ENCODING_TYPE_NIL = 0xc0,
- ENCODING_TYPE_RESERVED = 0xc1,
- ENCODING_TYPE_FALSE = 0xc2,
- ENCODING_TYPE_TRUE = 0xc3,
- ENCODING_TYPE_BIN8 = 0xc4,
- ENCODING_TYPE_BIN16 = 0xc5,
- ENCODING_TYPE_BIN32 = 0xc6,
- ENCODING_TYPE_EXT8 = 0xc7,
- ENCODING_TYPE_EXT16 = 0xc8,
- ENCODING_TYPE_EXT32 = 0xc9,
- ENCODING_TYPE_FLOAT32 = 0xca,
- ENCODING_TYPE_FLOAT64 = 0xcb,
- ENCODING_TYPE_UINT8 = 0xcc,
- ENCODING_TYPE_UINT16 = 0xcd,
- ENCODING_TYPE_UINT32 = 0xce,
- ENCODING_TYPE_UINT64 = 0xcf,
- ENCODING_TYPE_INT8 = 0xd0,
- ENCODING_TYPE_INT16 = 0xd1,
- ENCODING_TYPE_INT32 = 0xd2,
- ENCODING_TYPE_INT64 = 0xd3,
- ENCODING_TYPE_FIXEXT1 = 0xd4,
- ENCODING_TYPE_FIXEXT2 = 0xd5,
- ENCODING_TYPE_FIXEXT4 = 0xd6,
- ENCODING_TYPE_FIXEXT8 = 0xd7,
- ENCODING_TYPE_FIXEXT16 = 0xd8,
- ENCODING_TYPE_STR8 = 0xd9,
- ENCODING_TYPE_STR16 = 0xda,
- ENCODING_TYPE_STR32 = 0xdb,
- ENCODING_TYPE_ARRAY16 = 0xdc,
- ENCODING_TYPE_ARRAY32 = 0xdd,
- ENCODING_TYPE_MAP16 = 0xde,
- ENCODING_TYPE_MAP32 = 0xdf,
- ENCODING_TYPE_NEGATIVE_FIXINT = 0xe0,
- ENCODING_TYPE_NEGATIVE_FIXINT_MIN = 0xe0,
- ENCODING_TYPE_NEGATIVE_FIXINT_MAX = 0xff,
-};
-
-// Base encoding classes grouping multi-strategy encodings.
-enum EncodingClass {
- ENCODING_CLASS_BOOL,
- ENCODING_CLASS_NIL,
- ENCODING_CLASS_INT,
- ENCODING_CLASS_UINT,
- ENCODING_CLASS_FLOAT,
- ENCODING_CLASS_ARRAY,
- ENCODING_CLASS_MAP,
- ENCODING_CLASS_STRING,
- ENCODING_CLASS_BINARY,
- ENCODING_CLASS_EXTENSION,
-};
-
-// Encoding prefixes are unsigned bytes.
-typedef std::uint8_t EncodingType;
-
-// Extension encoding types defined by this library.
-enum EncodingExtType : int8_t {
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR,
- ENCODING_EXT_TYPE_CHANNEL_HANDLE,
-};
-
-// Encoding predicates. Determines whether the given encoding is of a specific
-// type.
-inline constexpr bool IsFixintEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsUnsignedFixintEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsInt8Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- case ENCODING_TYPE_INT8:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsUInt8Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_UINT8:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsInt16Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- case ENCODING_TYPE_INT8:
- case ENCODING_TYPE_INT16:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsUInt16Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_UINT8:
- case ENCODING_TYPE_UINT16:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsInt32Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- case ENCODING_TYPE_INT8:
- case ENCODING_TYPE_INT16:
- case ENCODING_TYPE_INT32:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsUInt32Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_UINT8:
- case ENCODING_TYPE_UINT16:
- case ENCODING_TYPE_UINT32:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsInt64Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- case ENCODING_TYPE_INT8:
- case ENCODING_TYPE_INT16:
- case ENCODING_TYPE_INT32:
- case ENCODING_TYPE_INT64:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsUInt64Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_UINT8:
- case ENCODING_TYPE_UINT16:
- case ENCODING_TYPE_UINT32:
- case ENCODING_TYPE_UINT64:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFixmapEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFixarrayEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFixstrEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFixextEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FIXEXT1:
- case ENCODING_TYPE_FIXEXT2:
- case ENCODING_TYPE_FIXEXT4:
- case ENCODING_TYPE_FIXEXT8:
- case ENCODING_TYPE_FIXEXT16:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFloat32Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FLOAT32:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsFloat64Encoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FLOAT32:
- case ENCODING_TYPE_FLOAT64:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr bool IsBoolEncoding(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FALSE:
- case ENCODING_TYPE_TRUE:
- return true;
- default:
- return false;
- }
-}
-
-inline constexpr std::size_t GetFixstrSize(EncodingType encoding) {
- return encoding & ENCODING_TYPE_FIXSTR_MASK;
-}
-
-inline constexpr std::size_t GetFixarraySize(EncodingType encoding) {
- return encoding & ENCODING_TYPE_FIXARRAY_MASK;
-}
-
-inline constexpr std::size_t GetFixmapSize(EncodingType encoding) {
- return encoding & ENCODING_TYPE_FIXMAP_MASK;
-}
-
-inline constexpr std::size_t GetFixextSize(EncodingType encoding) {
- switch (encoding) {
- case ENCODING_TYPE_FIXEXT1:
- return 1;
- case ENCODING_TYPE_FIXEXT2:
- return 2;
- case ENCODING_TYPE_FIXEXT4:
- return 4;
- case ENCODING_TYPE_FIXEXT8:
- return 8;
- case ENCODING_TYPE_FIXEXT16:
- return 16;
- default:
- return 0; // Invalid fixext size.
- }
-}
-
-// Gets the size of the encoding in bytes, not including external payload data.
-inline constexpr std::size_t GetEncodingSize(EncodingType encoding) {
- switch (encoding) {
- // Encoding is fully contained within the type value.
- case ENCODING_TYPE_POSITIVE_FIXINT_MIN ... ENCODING_TYPE_POSITIVE_FIXINT_MAX:
- case ENCODING_TYPE_NEGATIVE_FIXINT_MIN ... ENCODING_TYPE_NEGATIVE_FIXINT_MAX:
- case ENCODING_TYPE_FIXMAP_MIN ... ENCODING_TYPE_FIXMAP_MAX:
- case ENCODING_TYPE_FIXARRAY_MIN ... ENCODING_TYPE_FIXARRAY_MAX:
- case ENCODING_TYPE_FIXSTR_MIN ... ENCODING_TYPE_FIXSTR_MAX:
- case ENCODING_TYPE_NIL:
- case ENCODING_TYPE_RESERVED:
- case ENCODING_TYPE_FALSE:
- case ENCODING_TYPE_TRUE:
- return 1;
-
- // Encoding type followed by one-byte size or immediate value.
- case ENCODING_TYPE_BIN8:
- case ENCODING_TYPE_EXT8:
- case ENCODING_TYPE_UINT8:
- case ENCODING_TYPE_INT8:
- case ENCODING_TYPE_STR8:
- // Encoding type followed by one-byte extension type.
- case ENCODING_TYPE_FIXEXT1:
- case ENCODING_TYPE_FIXEXT2:
- case ENCODING_TYPE_FIXEXT4:
- case ENCODING_TYPE_FIXEXT8:
- case ENCODING_TYPE_FIXEXT16:
- return 2;
-
- // Encoding type followed by two-byte size or immediate value.
- case ENCODING_TYPE_BIN16:
- case ENCODING_TYPE_EXT16:
- case ENCODING_TYPE_UINT16:
- case ENCODING_TYPE_INT16:
- case ENCODING_TYPE_STR16:
- case ENCODING_TYPE_ARRAY16:
- case ENCODING_TYPE_MAP16:
- return 3;
-
- // Encoding type followed by four-byte size or immediate value.
- case ENCODING_TYPE_BIN32:
- case ENCODING_TYPE_EXT32:
- case ENCODING_TYPE_FLOAT32:
- case ENCODING_TYPE_UINT32:
- case ENCODING_TYPE_INT32:
- case ENCODING_TYPE_STR32:
- case ENCODING_TYPE_ARRAY32:
- case ENCODING_TYPE_MAP32:
- return 5;
-
- // Encoding type followed by eight-byte immediate value.
- case ENCODING_TYPE_FLOAT64:
- case ENCODING_TYPE_UINT64:
- case ENCODING_TYPE_INT64:
- return 9;
-
- default:
- return 0;
- }
-}
-
-// Encoding for standard types. Each supported data type has an associated
-// encoding or set of encodings. These functions determine the MessagePack
-// encoding based on the data type, value, and size of their arguments.
-
-inline constexpr EncodingType EncodeArrayType(std::size_t size) {
- if (size < (1U << 4))
- return ENCODING_TYPE_FIXARRAY | (size & ENCODING_TYPE_FIXARRAY_MASK);
- else if (size < (1U << 16))
- return ENCODING_TYPE_ARRAY16;
- else
- return ENCODING_TYPE_ARRAY32;
-}
-
-inline constexpr EncodingType EncodeMapType(std::size_t size) {
- if (size < (1U << 4))
- return ENCODING_TYPE_FIXMAP | (size & ENCODING_TYPE_FIXMAP_MASK);
- else if (size < (1U << 16))
- return ENCODING_TYPE_MAP16;
- else
- return ENCODING_TYPE_MAP32;
-}
-
-inline constexpr EncodingType EncodeStringType(std::size_t size) {
- if (size < (1U << 5))
- return ENCODING_TYPE_FIXSTR | (size & ENCODING_TYPE_FIXSTR_MASK);
- else if (size < (1U << 8))
- return ENCODING_TYPE_STR8;
- else if (size < (1U << 16))
- return ENCODING_TYPE_STR16;
- else
- return ENCODING_TYPE_STR32;
-}
-
-inline constexpr EncodingType EncodeBinType(std::size_t size) {
- if (size < (1U << 8))
- return ENCODING_TYPE_BIN8;
- else if (size < (1U << 16))
- return ENCODING_TYPE_BIN16;
- else
- return ENCODING_TYPE_BIN32;
-}
-
-inline EncodingType EncodeType(const EmptyVariant& /*empty*/) {
- return ENCODING_TYPE_NIL;
-}
-
-// Variant is encoded as a single-element map, with the type index as the key.
-template <typename... Types>
-inline EncodingType EncodeType(const Variant<Types...>& /*variant*/) {
- return EncodeMapType(1);
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const StringWrapper<T>& value) {
- return EncodeStringType(value.length());
-}
-
-inline constexpr EncodingType EncodeType(const std::string& value) {
- return EncodeStringType(value.length());
-}
-
-template <typename T, std::size_t Size>
-inline constexpr EncodingType EncodeType(const std::array<T, Size>& /*value*/) {
- return EncodeArrayType(Size);
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const ArrayWrapper<T>& value) {
- return EncodeArrayType(value.size());
-}
-
-template <typename T, typename Allocator>
-inline constexpr EncodingType EncodeType(
- const std::vector<T, Allocator>& value) {
- return EncodeArrayType(value.size());
-}
-
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline constexpr EncodingType EncodeType(
- const std::map<Key, T, Compare, Allocator>& value) {
- return EncodeMapType(value.size());
-}
-
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline constexpr EncodingType EncodeType(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value) {
- return EncodeMapType(value.size());
-}
-
-template <typename T>
-inline constexpr EncodingType EncodeType(const BufferWrapper<T>& value) {
- // BIN size is in bytes.
- return EncodeBinType(value.size() *
- sizeof(typename BufferWrapper<T>::value_type));
-}
-
-template <typename T, typename U>
-inline constexpr EncodingType EncodeType(const std::pair<T, U>& /*value*/) {
- return EncodeArrayType(2);
-}
-
-template <typename... T>
-inline constexpr EncodingType EncodeType(const std::tuple<T...>& /*value*/) {
- return EncodeArrayType(sizeof...(T));
-}
-
-// FileHandle is encoded as a FIXEXT2 with a type code for "FileDescriptor"
-// and a signed 16-bit index into the pushed fd array. Empty file descriptor
-// have an array index of -1.
-template <FileHandleMode Mode>
-inline constexpr EncodingType EncodeType(const FileHandle<Mode>& /*fd*/) {
- return ENCODING_TYPE_FIXEXT2;
-}
-
-// ChannelHandle is encoded as a FIXEXT4 with a type of
-// ENCODING_EXT_TYPE_CHANNEL_HANDLE and a signed 32-bit value representing
-// a client channel in a remote process. Empty handle has a value of -1.
-template <ChannelHandleMode Mode>
-inline constexpr EncodingType EncodeType(
- const ChannelHandle<Mode>& /*handle*/) {
- return ENCODING_TYPE_FIXEXT4;
-}
-
-inline constexpr EncodingType EncodeType(const bool& value) {
- return value ? ENCODING_TYPE_TRUE : ENCODING_TYPE_FALSE;
-}
-
-// Type 'char' is a little bit special in that it is distinct from 'signed char'
-// and 'unsigned char'. Treating it as an unsigned 8-bit value is safe for
-// encoding purposes and nicely handles 7-bit ASCII encodings as FIXINT.
-inline constexpr EncodingType EncodeType(const char& value) {
- if (value < static_cast<char>(1 << 7))
- return value;
- else
- return ENCODING_TYPE_UINT8;
-}
-
-inline constexpr EncodingType EncodeType(const uint8_t& value) {
- if (value < (1U << 7))
- return value;
- else
- return ENCODING_TYPE_UINT8;
-}
-inline constexpr EncodingType EncodeType(const int8_t& value) {
- if (value >= -32)
- return value;
- else
- return ENCODING_TYPE_INT8;
-}
-inline constexpr EncodingType EncodeType(const uint16_t& value) {
- if (value < (1U << 7))
- return static_cast<EncodingType>(value);
- else if (value < (1U << 8))
- return ENCODING_TYPE_UINT8;
- else
- return ENCODING_TYPE_UINT16;
-}
-inline constexpr EncodingType EncodeType(const int16_t& value) {
- if (value >= -32 && value <= 127)
- return static_cast<EncodingType>(value);
- else if (value >= -128 && value <= 127)
- return ENCODING_TYPE_INT8;
- else
- return ENCODING_TYPE_INT16;
-}
-inline constexpr EncodingType EncodeType(const uint32_t& value) {
- if (value < (1U << 7))
- return static_cast<EncodingType>(value);
- else if (value < (1U << 8))
- return ENCODING_TYPE_UINT8;
- else if (value < (1U << 16))
- return ENCODING_TYPE_UINT16;
- else
- return ENCODING_TYPE_UINT32;
-}
-inline constexpr EncodingType EncodeType(const int32_t& value) {
- if (value >= -32 && value <= 127)
- return static_cast<EncodingType>(value);
- else if (value >= -128 && value <= 127)
- return ENCODING_TYPE_INT8;
- else if (value >= -32768 && value <= 32767)
- return ENCODING_TYPE_INT16;
- else
- return ENCODING_TYPE_INT32;
-}
-inline constexpr EncodingType EncodeType(const uint64_t& value) {
- if (value < (1ULL << 7))
- return static_cast<EncodingType>(value);
- else if (value < (1ULL << 8))
- return ENCODING_TYPE_UINT8;
- else if (value < (1ULL << 16))
- return ENCODING_TYPE_UINT16;
- else if (value < (1ULL << 32))
- return ENCODING_TYPE_UINT32;
- else
- return ENCODING_TYPE_UINT64;
-}
-inline constexpr EncodingType EncodeType(const int64_t& value) {
- if (value >= -32 && value <= 127)
- return static_cast<EncodingType>(value);
- else if (value >= -128 && value <= 127) // Effectively [-128, -32).
- return ENCODING_TYPE_INT8;
- else if (value >= -32768 && value <= 32767)
- return ENCODING_TYPE_INT16;
- else if (value >= -2147483648 && value <= 2147483647)
- return ENCODING_TYPE_INT32;
- else
- return ENCODING_TYPE_INT64;
-}
-
-inline constexpr EncodingType EncodeType(const float& /*value*/) {
- return ENCODING_TYPE_FLOAT32;
-}
-
-inline constexpr EncodingType EncodeType(const double& /*value*/) {
- return ENCODING_TYPE_FLOAT64;
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_ENCODING_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/enumeration.h b/libs/vr/libpdx/private/pdx/rpc/enumeration.h
deleted file mode 100644
index 7a35d31..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/enumeration.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef ANDROID_PDX_RPC_ENUMERATION_H_
-#define ANDROID_PDX_RPC_ENUMERATION_H_
-
-#include <pdx/rpc/sequence.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility for manipulating lists of types. Provides operations to lookup an
-// element by type or index.
-
-namespace detail {
-
-// Helper type that captures type and index for each element of a type
-// enumeration.
-template <std::size_t I, typename T>
-struct IndexedElement {
- using Type = T;
- static constexpr std::size_t Index = I;
-};
-
-// Helper type that captures an IndexSequence and corresponding list of types.
-template <typename Is, typename... Ts>
-struct ElementIndexer;
-
-// Partial specialization that generates an instantiation of IndexElement<I, T>
-// for each element of a type enumeration using inheritance. Once a type
-// enumeration is instantiated this way the compiler is able to deduce either I
-// or T from the other using the method below.
-template <std::size_t... Is, typename... Ts>
-struct ElementIndexer<IndexSequence<Is...>, Ts...> : IndexedElement<Is, Ts>... {
-};
-
-// Helper function that causes the compiler to deduce an IndexedElement<I, T>
-// given T.
-template <typename T, std::size_t I>
-static IndexedElement<I, T> SelectElementByType(IndexedElement<I, T>);
-
-// Helper function that causes the compiler to deduce an IndexedElement<I, T>
-// given I.
-template <std::size_t I, typename T>
-static IndexedElement<I, T> SelectElementByIndex(IndexedElement<I, T>);
-
-} // namespace detail
-
-// Deduces the IndexedElement<I, T> given T and a type sequence Ts. This may be
-// used to determine the index of T within Ts at compile time.
-template <typename T, typename... Ts>
-using ElementForType = decltype(detail::SelectElementByType<T>(
- detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
-
-// Deduces the IndexedElement<I, T> given I and a type sequence Ts. This may be
-// used to determine the type of the element at index I within Ts at compile
-// time. Tuple operations may also be used to accomplish the same task, however
-// this implementation is provided here for symmetry.
-template <std::size_t I, typename... Ts>
-using ElementForIndex = decltype(detail::SelectElementByIndex<I>(
- detail::ElementIndexer<typename IndexSequenceFor<Ts...>::type, Ts...>{}));
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_ENUMERATION_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/find_replace.h b/libs/vr/libpdx/private/pdx/rpc/find_replace.h
deleted file mode 100644
index b4b086b..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/find_replace.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef ANDROID_PDX_RPC_FIND_REPLACE_H_
-#define ANDROID_PDX_RPC_FIND_REPLACE_H_
-
-#include <type_traits>
-
-#include <pdx/rpc/copy_cv_reference.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class to capture types to find and replace.
-template <typename Find, typename Replace>
-struct FindReplace;
-
-template <typename T, typename U>
-using IsSameBaseType = typename std::is_same<typename std::decay<T>::type,
- typename std::decay<U>::type>;
-
-// Replaces the type Subject with type Replace if type Subject is the same type
-// as type Find, excluding cv-reference qualifiers in the match.
-template <typename Find, typename Replace, typename Subject>
-using ReplaceType =
- typename std::conditional<IsSameBaseType<Find, Subject>::value,
- CopyCVReferenceType<Subject, Replace>,
- Subject>::type;
-
-// Determines whether the type Find (excluding cv-reference qualifiers) is in
-// the given parameter pack.
-template <typename Find, typename... Types>
-struct ContainsType : std::true_type {};
-
-template <typename Find, typename First, typename... Rest>
-struct ContainsType<Find, First, Rest...>
- : std::conditional<IsSameBaseType<Find, First>::value, std::true_type,
- ContainsType<Find, Rest...>>::type {};
-
-template <typename Find>
-struct ContainsType<Find> : std::false_type {};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_FIND_REPLACE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/function_traits.h b/libs/vr/libpdx/private/pdx/rpc/function_traits.h
deleted file mode 100644
index 7641b0a..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/function_traits.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
-#define ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
-
-#include <type_traits>
-
-#include <pdx/rpc/type_operators.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility type to capture return and argument types of a function signature.
-// Examples:
-// typedef SignatureType<int(int)> SignatureType;
-// using SignatureType = SignatureType<int(int)>;
-template <typename T>
-using SignatureType = T;
-
-// Utility class to extract return and argument types from function types.
-// Provides nested types for return value, arguments, and full signature. Also
-// provides accessor types for individual arguments, argument-arity, and type
-// substitution.
-template <typename T>
-struct FunctionTraits;
-
-template <typename Return_, typename... Args_>
-struct FunctionTraits<Return_(Args_...)> {
- using Return = Return_;
- using Args = std::tuple<Args_...>;
- using Signature = SignatureType<Return_(Args_...)>;
-
- enum : std::size_t { Arity = sizeof...(Args_) };
-
- template <std::size_t Index>
- using Arg = typename std::tuple_element<Index, Args>::type;
-
- template <typename... Params>
- using RewriteArgs =
- SignatureType<Return_(ConditionalRewrite<Args_, Params>...)>;
-
- template <typename ReturnType, typename... Params>
- using RewriteSignature =
- SignatureType<ConditionalRewrite<Return_, ReturnType>(
- ConditionalRewrite<Args_, Params>...)>;
-
- template <template <typename> class Wrapper, typename ReturnType,
- typename... Params>
- using RewriteSignatureWrapReturn =
- SignatureType<Wrapper<ConditionalRewrite<Return_, ReturnType>>(
- ConditionalRewrite<Args_, Params>...)>;
-
- template <typename ReturnType>
- using RewriteReturn =
- SignatureType<ConditionalRewrite<Return_, ReturnType>(Args_...)>;
-};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_FUNCTION_TRAITS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/macros.h b/libs/vr/libpdx/private/pdx/rpc/macros.h
deleted file mode 100644
index 99325b5..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/macros.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_PDX_RPC_MACROS_H_
-#define ANDROID_PDX_RPC_MACROS_H_
-
-// Macros to apply other macros over all elements in a list.
-//
-// For example, for a macro A(x) and B(x, y):
-// - FOR_EACH(A, 1, 2, 3) -> A(1) A(2) A(3).
-// - FOR_EACH_BINARY(B, z, 1, 2, 3) -> B(z, 1) B(z, 2) B(z, 3)
-// - FOR_EACH_LIST(A, 1, 2, 3) -> A(1), B(2), C(3)
-// - FOR_EACH_BINARY_LIST(B, z, 1, 2, 3) -> B(z, 1), B(z, 2), B(z, 3)
-//
-// Empty lists are supported and will produce no output.
-
-// Recursive expansion macros.
-#define _PDX_EXPAND0(...) __VA_ARGS__
-#define _PDX_EXPAND1(...) _PDX_EXPAND0(_PDX_EXPAND0(_PDX_EXPAND0(__VA_ARGS__)))
-#define _PDX_EXPAND2(...) _PDX_EXPAND1(_PDX_EXPAND1(_PDX_EXPAND1(__VA_ARGS__)))
-#define _PDX_EXPAND3(...) _PDX_EXPAND2(_PDX_EXPAND2(_PDX_EXPAND2(__VA_ARGS__)))
-#define _PDX_EXPAND4(...) _PDX_EXPAND3(_PDX_EXPAND3(_PDX_EXPAND3(__VA_ARGS__)))
-#define _PDX_EXPAND(...) _PDX_EXPAND4(_PDX_EXPAND4(_PDX_EXPAND4(__VA_ARGS__)))
-
-// Required to workaround a bug in the VC++ preprocessor.
-#define _PDX_INDIRECT_EXPAND(macro, args) macro args
-
-// Defines a step separation for macro expansion.
-#define _PDX_SEPARATOR
-
-// Clears any remaining contents wrapped in parentheses.
-#define _PDX_CLEAR(...)
-
-// Introduces a first stub argument and _PDX_CLEAR as second argument.
-#define _PDX_CLEAR_IF_LAST() _, _PDX_CLEAR
-
-// Returns the first argument of a list.
-#define _PDX_FIRST_ARG(first, ...) first
-
-// Returns the second argument of a list.
-#define _PDX_SECOND_ARG(_, second, ...) second
-
-// Expands the arguments and introduces a separator.
-#define _PDX_EXPAND_NEXT_FUNC(_, next_func, ...) \
- _PDX_INDIRECT_EXPAND(_PDX_SECOND_ARG, (_, next_func)) \
- _PDX_SEPARATOR
-
-// Returns next_func if the next element is not (), or _PDX_CLEAR
-// otherwise.
-//
-// _PDX_CLEAR_IF_LAST inserts an extra first stub argument if peek is ().
-#define _PDX_NEXT_FUNC(next_element, next_func) \
- _PDX_EXPAND_NEXT_FUNC(_PDX_CLEAR_IF_LAST next_element, next_func)
-
-// Macros for the unary version of PDX_FOR_EACH.
-
-// Applies the unary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_1(macro, head, next, ...) \
- macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_2)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_2(macro, head, next, ...) \
- macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_1)(macro, next, __VA_ARGS__)
-
-// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_1
-// otherwise.
-#define _PDX_HANDLE_EMPTY_ARGS(macro, ...) \
- _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_1) \
- (macro, __VA_ARGS__, ())
-
-// Applies a unary macro over all the elements in a list.
-#define PDX_FOR_EACH(macro, ...) \
- _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS(macro, __VA_ARGS__))
-
-// Applies the unary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_LIST_1(macro, head, next, ...) \
- , macro(head) \
- _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_2)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_LIST_2(macro, head, next, ...) \
- , macro(head) \
- _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
-
-// Applies the unary macro at the start of a list.
-#define _PDX_APPLY_LIST_0(macro, head, next, ...) \
- macro(head) _PDX_NEXT_FUNC(next, _PDX_APPLY_LIST_1)(macro, next, __VA_ARGS__)
-
-// Stops expansion if __VA_ARGS__ is empty, calling _PDX_APPLY_LIST_0
-// otherwise.
-#define _PDX_HANDLE_EMPTY_LIST(macro, ...) \
- _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_LIST_0) \
- (macro, __VA_ARGS__, ())
-
-// Applies a unary macro over all the elements in a list.
-#define PDX_FOR_EACH_LIST(macro, ...) \
- _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST(macro, __VA_ARGS__))
-
-// Macros for the binary version of PDX_FOR_EACH.
-
-// Applies the binary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_BINARY_1(macro, arg, head, next, ...) \
- macro(arg, head) \
- _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_2)(macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro. Duplicated for macro recursive expansion.
-#define _PDX_APPLY_BINARY_2(macro, arg, head, next, ...) \
- macro(arg, head) \
- _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_1)(macro, arg, next, __VA_ARGS__)
-
-// Version of _PDX_HANDLE_EMPTY_ARGS that takes 1 fixed argument for a
-// binary macro.
-#define _PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, ...) \
- _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_1) \
- (macro, arg, __VA_ARGS__, ())
-
-// Applies a binary macro over all the elements in a list and a given argument.
-#define PDX_FOR_EACH_BINARY(macro, arg, ...) \
- _PDX_EXPAND(_PDX_HANDLE_EMPTY_ARGS_BINARY(macro, arg, __VA_ARGS__))
-
-// Applies the binary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_BINARY_LIST_1(macro, arg, head, next, ...) \
- , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_2)( \
- macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro at the end of a list. Duplicated for macro recursive
-// expansion.
-#define _PDX_APPLY_BINARY_LIST_2(macro, arg, head, next, ...) \
- , macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
- macro, arg, next, __VA_ARGS__)
-
-// Applies the binary macro at the start of a list. Duplicated for macro
-// recursive expansion.
-#define _PDX_APPLY_BINARY_LIST_0(macro, arg, head, next, ...) \
- macro(arg, head) _PDX_NEXT_FUNC(next, _PDX_APPLY_BINARY_LIST_1)( \
- macro, arg, next, __VA_ARGS__)
-
-// Version of _PDX_HANDLE_EMPTY_LIST that takes 1 fixed argument for a
-// binary macro.
-#define _PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, ...) \
- _PDX_NEXT_FUNC(_PDX_FIRST_ARG(__VA_ARGS__()), _PDX_APPLY_BINARY_LIST_0) \
- (macro, arg, __VA_ARGS__, ())
-
-// Applies a binary macro over all the elements in a list and a given argument.
-#define PDX_FOR_EACH_BINARY_LIST(macro, arg, ...) \
- _PDX_EXPAND(_PDX_HANDLE_EMPTY_LIST_BINARY(macro, arg, __VA_ARGS__))
-
-#endif // ANDROID_PDX_RPC_MACROS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/message_buffer.h b/libs/vr/libpdx/private/pdx/rpc/message_buffer.h
deleted file mode 100644
index ba4e86e..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/message_buffer.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
-#define ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
-
-#include <pdx/rpc/thread_local_buffer.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility type for thread-local buffers, providing suitable defaults for most
-// situations. Independent thread-local buffers may be created by using
-// different types for Slot -- ThreadLocalSlot, ThreadLocalTypedSlot and
-// ThreadLocalIndexedSlot provide utilities for building these types.
-template <typename Slot, std::size_t Capacity = 4096, typename T = std::uint8_t,
- typename Allocator = DefaultInitializationAllocator<T>>
-using MessageBuffer = ThreadLocalBuffer<T, Allocator, Capacity, Slot>;
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_MESSAGE_BUFFER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/payload.h b/libs/vr/libpdx/private/pdx/rpc/payload.h
deleted file mode 100644
index d2df14f..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/payload.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef ANDROID_PDX_RPC_PAYLOAD_H_
-#define ANDROID_PDX_RPC_PAYLOAD_H_
-
-#include <iterator>
-
-#include <pdx/client.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/service.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Implements the payload interface, required by Serialize/Deserialize, on top
-// of a thread-local MessageBuffer.
-template <typename Slot>
-class MessagePayload {
- public:
- using BufferType = typename MessageBuffer<Slot>::BufferType;
- using ValueType = typename MessageBuffer<Slot>::ValueType;
-
- // Constructs a MessagePayload with an empty TLS buffer.
- MessagePayload()
- : buffer_(MessageBuffer<Slot>::GetEmptyBuffer()),
- cursor_(buffer_.begin()),
- const_cursor_(buffer_.cbegin()) {}
-
- // Returns a reference to the cursor iterator to be used during serialization
- // into the underlying MessageBuffer.
- typename BufferType::iterator& Cursor() { return cursor_; }
-
- // Returns a reference to the const cursor iterator at the beginning of the
- // underlying MessageBuffer.
- typename BufferType::const_iterator& ConstCursor() { return const_cursor_; }
-
- // Returns a const iterator marking the end of the underlying MessageBuffer.
- typename BufferType::const_iterator ConstEnd() { return buffer_.cend(); }
-
- // Resizes the underlying MessageBuffer and sets the cursor to the beginning.
- void Resize(std::size_t size) {
- buffer_.resize(size);
- cursor_ = buffer_.begin();
- const_cursor_ = buffer_.cbegin();
- }
-
- // Resets the read cursor so that data can be read from the buffer again.
- void Rewind() { const_cursor_ = buffer_.cbegin(); }
-
- // Adds |size| bytes to the size of the underlying MessageBuffer and positions
- // the cursor at the beginning of the extended region.
- void Extend(std::size_t size) {
- const std::size_t offset = buffer_.size();
- buffer_.resize(offset + size);
- cursor_ = buffer_.begin() + offset;
- const_cursor_ = buffer_.cbegin() + offset;
- }
-
- // Clears the underlying MessageBuffer and sets the cursor to the beginning.
- void Clear() {
- buffer_.clear();
- cursor_ = buffer_.begin();
- const_cursor_ = buffer_.cbegin();
- }
-
- ValueType* Data() { return buffer_.data(); }
- const ValueType* Data() const { return buffer_.data(); }
- std::size_t Size() const { return buffer_.size(); }
- std::size_t Capacity() const { return buffer_.capacity(); }
-
- private:
- BufferType& buffer_;
- typename BufferType::iterator cursor_;
- typename BufferType::const_iterator const_cursor_;
-
- MessagePayload(const MessagePayload<Slot>&) = delete;
- void operator=(const MessagePayload<Slot>&) = delete;
-};
-
-// Implements the payload interface for service-side RPCs. Handles translating
-// between remote and local handle spaces automatically.
-template <typename Slot>
-class ServicePayload : public MessagePayload<Slot>,
- public MessageWriter,
- public MessageReader {
- public:
- explicit ServicePayload(Message& message) : message_(message) {}
-
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override {
- this->Extend(size);
- return &*this->Cursor();
- }
-
- OutputResourceMapper* GetOutputResourceMapper() override { return &message_; }
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override {
- return {&*this->ConstCursor(), &*this->ConstEnd()};
- }
-
- void ConsumeReadBufferSectionData(const void* new_start) override {
- std::advance(this->ConstCursor(),
- PointerDistance(new_start, &*this->ConstCursor()));
- }
-
- InputResourceMapper* GetInputResourceMapper() override { return &message_; }
-
- private:
- Message& message_;
-};
-
-// Implements the payload interface for client-side RPCs. Handles gathering file
-// handles to be sent over IPC automatically.
-template <typename Slot>
-class ClientPayload : public MessagePayload<Slot>,
- public MessageWriter,
- public MessageReader {
- public:
- using ContainerType =
- MessageBuffer<ThreadLocalTypeSlot<ClientPayload<Slot>>, 1024u, int>;
- using BufferType = typename ContainerType::BufferType;
-
- explicit ClientPayload(Transaction& transaction)
- : transaction_{transaction} {}
-
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override {
- this->Extend(size);
- return &*this->Cursor();
- }
-
- OutputResourceMapper* GetOutputResourceMapper() override {
- return &transaction_;
- }
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override {
- return {&*this->ConstCursor(), &*this->ConstEnd()};
- }
-
- void ConsumeReadBufferSectionData(const void* new_start) override {
- std::advance(this->ConstCursor(),
- PointerDistance(new_start, &*this->ConstCursor()));
- }
-
- InputResourceMapper* GetInputResourceMapper() override {
- return &transaction_;
- }
-
- private:
- Transaction& transaction_;
-};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_PAYLOAD_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
deleted file mode 100644
index 88868fe..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/pointer_wrapper.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_RPC_POINTER_WRAPPER_H_
-#define ANDROID_PDX_RPC_POINTER_WRAPPER_H_
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for pointers to any serializable type. This class is used by
-// serialization/deserialization to handle pointers to objects that are to be
-// serialized or deserialized.
-template <typename T>
-class PointerWrapper {
- public:
- using BaseType = T;
-
- explicit PointerWrapper(T* pointer) : pointer_(pointer) {}
- PointerWrapper(const PointerWrapper&) = default;
- PointerWrapper(PointerWrapper&&) noexcept = default;
- PointerWrapper& operator=(const PointerWrapper&) = default;
- PointerWrapper& operator=(PointerWrapper&&) noexcept = default;
-
- T& Dereference() { return *pointer_; }
- const T& Dereference() const { return *pointer_; }
-
- private:
- T* pointer_;
-};
-
-template <typename T>
-PointerWrapper<T> WrapPointer(T* pointer) {
- return PointerWrapper<T>(pointer);
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_POINTER_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method.h b/libs/vr/libpdx/private/pdx/rpc/remote_method.h
deleted file mode 100644
index 505c63b..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method.h
+++ /dev/null
@@ -1,473 +0,0 @@
-#ifndef ANDROID_PDX_RPC_REMOTE_METHOD_H_
-#define ANDROID_PDX_RPC_REMOTE_METHOD_H_
-
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/client.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/remote_method_type.h>
-#include <pdx/service.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-#ifdef __clang__
-// Stand-in type to avoid Clang compiler bug. Clang currently has a bug where
-// performing parameter pack expansion for arguments with empty packs causes a
-// compiler crash. Provide a substitute void type and specializations/overloads
-// of CheckArgumentTypes and DispatchRemoteMethod to work around this problem.
-struct Void {};
-
-// Evaluates to true if the method type is <any>(Void), false otherwise.
-template <typename RemoteMethodType>
-using IsVoidMethod = typename std::integral_constant<
- bool, RemoteMethodType::Traits::Arity == 1 &&
- std::is_same<typename RemoteMethodType::Traits::template Arg<0>,
- Void>::value>;
-
-// Utility to determine if a method is of type <any>(Void).
-template <typename RemoteMethodType>
-using EnableIfVoidMethod =
- typename std::enable_if<IsVoidMethod<RemoteMethodType>::value>::type;
-
-// Utility to determine if a method is not of type <any>(Void).
-template <typename RemoteMethodType>
-using EnableIfNotVoidMethod =
- typename std::enable_if<!IsVoidMethod<RemoteMethodType>::value>::type;
-
-#else
-// GCC works fine with void argument types, always enable the regular
-// implementation of DispatchRemoteMethod.
-using Void = void;
-template <typename RemoteMethodType>
-using EnableIfVoidMethod = void;
-template <typename RemoteMethodType>
-using EnableIfNotVoidMethod = void;
-#endif
-
-// Helper type trait to specialize InvokeRemoteMethods for return types that
-// can be obtained directly from Transaction::Send<T>() without deserializing
-// reply payload.
-template <typename T>
-struct IsDirectReturn : std::false_type {};
-
-template <>
-struct IsDirectReturn<void> : std::true_type {};
-
-template <>
-struct IsDirectReturn<int> : std::true_type {};
-
-template <>
-struct IsDirectReturn<LocalHandle> : std::true_type {};
-
-template <>
-struct IsDirectReturn<LocalChannelHandle> : std::true_type {};
-
-template <typename Return, typename Type = void>
-using EnableIfDirectReturn =
- typename std::enable_if<IsDirectReturn<Return>::value, Type>::type;
-
-template <typename Return, typename Type = void>
-using EnableIfNotDirectReturn =
- typename std::enable_if<!IsDirectReturn<Return>::value, Type>::type;
-
-// Utility class to invoke a method with arguments packed in a tuple.
-template <typename Class, typename T>
-class UnpackArguments;
-
-// Utility class to invoke a method with arguments packed in a tuple.
-template <typename Class, typename Return, typename... Args>
-class UnpackArguments<Class, Return(Args...)> {
- public:
- using ArgsTupleType = std::tuple<typename std::decay<Args>::type...>;
- using MethodType = Return (Class::*)(Message&, Args...);
-
- UnpackArguments(Class& instance, MethodType method, Message& message,
- ArgsTupleType& parameters)
- : instance_(instance),
- method_(method),
- message_(message),
- parameters_(parameters) {}
-
- // Invokes method_ on intance_ with the packed arguments from parameters_.
- Return Invoke() {
- constexpr auto Arity = sizeof...(Args);
- return static_cast<Return>(InvokeHelper(MakeIndexSequence<Arity>{}));
- }
-
- private:
- Class& instance_;
- MethodType method_;
- Message& message_;
- ArgsTupleType& parameters_;
-
- template <std::size_t... Index>
- Return InvokeHelper(IndexSequence<Index...>) {
- return static_cast<Return>((instance_.*method_)(
- message_,
- std::get<Index>(std::forward<ArgsTupleType>(parameters_))...));
- }
-
- UnpackArguments(const UnpackArguments&) = delete;
- void operator=(const UnpackArguments&) = delete;
-};
-
-// Returns an error code from a remote method to the client. May be called
-// either during dispatch of the remote method handler or at a later time if the
-// message is moved for delayed response.
-inline void RemoteMethodError(Message& message, int error_code) {
- const auto status = message.ReplyError(error_code);
- ALOGE_IF(!status, "RemoteMethodError: Failed to reply to message: %s",
- status.GetErrorMessage().c_str());
-}
-
-// Returns a value from a remote method to the client. The usual method to
-// return a value during dispatch of a remote method is to simply use a return
-// statement in the handler. If the message is moved however, these methods may
-// be used to return a value at a later time, outside of initial dispatch.
-
-// Overload for direct return types.
-template <typename RemoteMethodType, typename Return>
-EnableIfDirectReturn<typename RemoteMethodType::Return> RemoteMethodReturn(
- Message& message, const Return& return_value) {
- const auto status = message.Reply(return_value);
- ALOGE_IF(!status, "RemoteMethodReturn: Failed to reply to message: %s",
- status.GetErrorMessage().c_str());
-}
-
-// Overload for non-direct return types.
-template <typename RemoteMethodType, typename Return>
-EnableIfNotDirectReturn<typename RemoteMethodType::Return> RemoteMethodReturn(
- Message& message, const Return& return_value) {
- using Signature = typename RemoteMethodType::template RewriteReturn<Return>;
- rpc::ServicePayload<ReplyBuffer> payload(message);
- MakeArgumentEncoder<Signature>(&payload).EncodeReturn(return_value);
-
- auto ret = message.WriteAll(payload.Data(), payload.Size());
- auto status = message.Reply(ret);
- ALOGE_IF(!status, "RemoteMethodReturn: Failed to reply to message: %s",
- status.GetErrorMessage().c_str());
-}
-
-// Overload for Status<void> return types.
-template <typename RemoteMethodType>
-void RemoteMethodReturn(Message& message, const Status<void>& return_value) {
- if (return_value)
- RemoteMethodReturn<RemoteMethodType>(message, 0);
- else
- RemoteMethodError(message, return_value.error());
-}
-
-// Overload for Status<T> return types. This overload forwards the underlying
-// value or error within the Status<T>.
-template <typename RemoteMethodType, typename Return>
-void RemoteMethodReturn(Message& message, const Status<Return>& return_value) {
- if (return_value)
- RemoteMethodReturn<RemoteMethodType, Return>(message, return_value.get());
- else
- RemoteMethodError(message, return_value.error());
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface check. Overload for void return types.
-template <typename RemoteMethodType, typename Class, typename... Args,
- typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
- void (Class::*method)(Message&, Args...),
- Message& message,
- std::size_t max_capacity = InitialBufferCapacity) {
- using Signature = typename RemoteMethodType::template RewriteArgs<Args...>;
- rpc::ServicePayload<ReceiveBuffer> payload(message);
- payload.Resize(max_capacity);
-
- Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
- if (!read_status) {
- RemoteMethodError(message, read_status.error());
- return;
- }
-
- payload.Resize(read_status.get());
-
- ErrorType error;
- auto decoder = MakeArgumentDecoder<Signature>(&payload);
- auto arguments = decoder.DecodeArguments(&error);
- if (error) {
- RemoteMethodError(message, EIO);
- return;
- }
-
- UnpackArguments<Class, Signature>(instance, method, message, arguments)
- .Invoke();
- // Return to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, 0);
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface signature check. Overload for generic return types.
-template <typename RemoteMethodType, typename Class, typename Return,
- typename... Args, typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
- Return (Class::*method)(Message&, Args...),
- Message& message,
- std::size_t max_capacity = InitialBufferCapacity) {
- using Signature =
- typename RemoteMethodType::template RewriteSignature<Return, Args...>;
- rpc::ServicePayload<ReceiveBuffer> payload(message);
- payload.Resize(max_capacity);
-
- Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
- if (!read_status) {
- RemoteMethodError(message, read_status.error());
- return;
- }
-
- payload.Resize(read_status.get());
-
- ErrorType error;
- auto decoder = MakeArgumentDecoder<Signature>(&payload);
- auto arguments = decoder.DecodeArguments(&error);
- if (error) {
- RemoteMethodError(message, EIO);
- return;
- }
-
- auto return_value =
- UnpackArguments<Class, Signature>(instance, method, message, arguments)
- .Invoke();
- // Return the value to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-// Dispatches a method by deserializing arguments from the given Message, with
-// compile-time interface signature check. Overload for Status<T> return types.
-template <typename RemoteMethodType, typename Class, typename Return,
- typename... Args, typename = EnableIfNotVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
- Status<Return> (Class::*method)(Message&, Args...),
- Message& message,
- std::size_t max_capacity = InitialBufferCapacity) {
- using Signature =
- typename RemoteMethodType::template RewriteSignature<Return, Args...>;
- using InvokeSignature =
- typename RemoteMethodType::template RewriteSignatureWrapReturn<
- Status, Return, Args...>;
- rpc::ServicePayload<ReceiveBuffer> payload(message);
- payload.Resize(max_capacity);
-
- Status<size_t> read_status = message.Read(payload.Data(), payload.Size());
- if (!read_status) {
- RemoteMethodError(message, read_status.error());
- return;
- }
-
- payload.Resize(read_status.get());
-
- ErrorType error;
- auto decoder = MakeArgumentDecoder<Signature>(&payload);
- auto arguments = decoder.DecodeArguments(&error);
- if (error) {
- RemoteMethodError(message, EIO);
- return;
- }
-
- auto return_value = UnpackArguments<Class, InvokeSignature>(
- instance, method, message, arguments)
- .Invoke();
- // Return the value to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-#ifdef __clang__
-// Overloads to handle Void argument type without exploding clang.
-
-// Overload for void return type.
-template <typename RemoteMethodType, typename Class,
- typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance, void (Class::*method)(Message&),
- Message& message) {
- (instance.*method)(message);
- // Return to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, 0);
-}
-
-// Overload for generic return type.
-template <typename RemoteMethodType, typename Class, typename Return,
- typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance, Return (Class::*method)(Message&),
- Message& message) {
- auto return_value = (instance.*method)(message);
- // Return the value to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-
-// Overload for Status<T> return type.
-template <typename RemoteMethodType, typename Class, typename Return,
- typename = EnableIfVoidMethod<RemoteMethodType>>
-void DispatchRemoteMethod(Class& instance,
- Status<Return> (Class::*method)(Message&),
- Message& message) {
- auto return_value = (instance.*method)(message);
- // Return the value to the caller unless the message was moved.
- if (message)
- RemoteMethodReturn<RemoteMethodType>(message, return_value);
-}
-#endif
-
-} // namespace rpc
-
-// Definitions for template methods declared in pdx/client.h.
-
-template <int Opcode, typename T>
-struct CheckArgumentTypes;
-
-template <int Opcode, typename Return, typename... Args>
-struct CheckArgumentTypes<Opcode, Return(Args...)> {
- template <typename R>
- static typename rpc::EnableIfDirectReturn<R, Status<R>> Invoke(Client& client,
- Args... args) {
- Transaction trans{client};
- rpc::ClientPayload<rpc::SendBuffer> payload{trans};
- rpc::MakeArgumentEncoder<Return(Args...)>(&payload).EncodeArguments(
- std::forward<Args>(args)...);
- return trans.Send<R>(Opcode, payload.Data(), payload.Size(), nullptr, 0);
- }
-
- template <typename R>
- static typename rpc::EnableIfNotDirectReturn<R, Status<R>> Invoke(
- Client& client, Args... args) {
- Transaction trans{client};
-
- rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
- rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
- .EncodeArguments(std::forward<Args>(args)...);
-
- rpc::ClientPayload<rpc::ReplyBuffer> reply_payload{trans};
- reply_payload.Resize(reply_payload.Capacity());
-
- Status<R> result;
- auto status =
- trans.Send<void>(Opcode, send_payload.Data(), send_payload.Size(),
- reply_payload.Data(), reply_payload.Size());
- if (!status) {
- result.SetError(status.error());
- } else {
- R return_value;
- rpc::ErrorType error =
- rpc::MakeArgumentDecoder<Return(Args...)>(&reply_payload)
- .DecodeReturn(&return_value);
-
- switch (error.error_code()) {
- case rpc::ErrorCode::NO_ERROR:
- result.SetValue(std::move(return_value));
- break;
-
- // This error is returned when ArrayWrapper/StringWrapper is too
- // small to receive the payload.
- case rpc::ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
- result.SetError(ENOBUFS);
- break;
-
- default:
- result.SetError(EIO);
- break;
- }
- }
- return result;
- }
-
- template <typename R>
- static typename rpc::EnableIfDirectReturn<R, Status<void>> InvokeInPlace(
- Client& client, R* return_value, Args... args) {
- Transaction trans{client};
-
- rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
- rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
- .EncodeArguments(std::forward<Args>(args)...);
-
- Status<void> result;
- auto status = trans.Send<R>(Opcode, send_payload.Data(),
- send_payload.Size(), nullptr, 0);
- if (status) {
- *return_value = status.take();
- result.SetValue();
- } else {
- result.SetError(status.error());
- }
- return result;
- }
-
- template <typename R>
- static typename rpc::EnableIfNotDirectReturn<R, Status<void>> InvokeInPlace(
- Client& client, R* return_value, Args... args) {
- Transaction trans{client};
-
- rpc::ClientPayload<rpc::SendBuffer> send_payload{trans};
- rpc::MakeArgumentEncoder<Return(Args...)>(&send_payload)
- .EncodeArguments(std::forward<Args>(args)...);
-
- rpc::ClientPayload<rpc::ReplyBuffer> reply_payload{trans};
- reply_payload.Resize(reply_payload.Capacity());
-
- auto result =
- trans.Send<void>(Opcode, send_payload.Data(), send_payload.Size(),
- reply_payload.Data(), reply_payload.Size());
- if (result) {
- rpc::ErrorType error =
- rpc::MakeArgumentDecoder<Return(Args...)>(&reply_payload)
- .DecodeReturn(return_value);
-
- switch (error.error_code()) {
- case rpc::ErrorCode::NO_ERROR:
- result.SetValue();
- break;
-
- // This error is returned when ArrayWrapper/StringWrapper is too
- // small to receive the payload.
- case rpc::ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
- result.SetError(ENOBUFS);
- break;
-
- default:
- result.SetError(EIO);
- break;
- }
- }
- return result;
- }
-};
-
-// Invokes the remote method with opcode and signature described by
-// |RemoteMethodType|.
-template <typename RemoteMethodType, typename... Args>
-Status<typename RemoteMethodType::Return> Client::InvokeRemoteMethod(
- Args&&... args) {
- return CheckArgumentTypes<
- RemoteMethodType::Opcode,
- typename RemoteMethodType::template RewriteArgs<Args...>>::
- template Invoke<typename RemoteMethodType::Return>(
- *this, std::forward<Args>(args)...);
-}
-
-template <typename RemoteMethodType, typename Return, typename... Args>
-Status<void> Client::InvokeRemoteMethodInPlace(Return* return_value,
- Args&&... args) {
- return CheckArgumentTypes<
- RemoteMethodType::Opcode,
- typename RemoteMethodType::template RewriteSignature<Return, Args...>>::
- template InvokeInPlace(*this, return_value, std::forward<Args>(args)...);
-}
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_REMOTE_METHOD_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h b/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
deleted file mode 100644
index cf9a189..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/remote_method_type.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
-#define ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
-
-#include <cstddef>
-#include <tuple>
-#include <type_traits>
-
-#include <pdx/rpc/enumeration.h>
-#include <pdx/rpc/function_traits.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class binding a remote method opcode to its function signature.
-// Describes the interface between RPC clients and services for a single method.
-template <int Opcode_, typename Signature_>
-struct RemoteMethodType {
- typedef FunctionTraits<Signature_> Traits;
-
- enum : int { Opcode = Opcode_ };
-
- typedef typename Traits::Signature Signature;
- typedef typename Traits::Return Return;
- typedef typename Traits::Args Args;
-
- template <typename... Params>
- using RewriteArgs = typename Traits::template RewriteArgs<Params...>;
-
- template <typename ReturnType, typename... Params>
- using RewriteSignature =
- typename Traits::template RewriteSignature<ReturnType, Params...>;
-
- template <template <typename> class Wrapper, typename ReturnType,
- typename... Params>
- using RewriteSignatureWrapReturn =
- typename Traits::template RewriteSignatureWrapReturn<Wrapper, ReturnType,
- Params...>;
-
- template <typename ReturnType>
- using RewriteReturn = typename Traits::template RewriteReturn<ReturnType>;
-};
-
-// Utility class representing a set of related RemoteMethodTypes. Describes the
-// interface between RPC clients and services as a set of methods.
-template <typename... MethodTypes>
-struct RemoteAPI {
- typedef std::tuple<MethodTypes...> Methods;
- enum : std::size_t { Length = sizeof...(MethodTypes) };
-
- template <std::size_t Index>
- using Method = typename std::tuple_element<Index, Methods>::type;
-
- template <typename MethodType>
- static constexpr std::size_t MethodIndex() {
- return ElementForType<MethodType, MethodTypes...>::Index;
- }
-};
-
-// Macro to simplify defining remote method signatures. Remote method signatures
-// are specified by defining a RemoteMethodType for each remote method.
-#define PDX_REMOTE_METHOD(name, opcode, ... /*signature*/) \
- using name = ::android::pdx::rpc::RemoteMethodType<opcode, __VA_ARGS__>
-
-// Macro to simplify defining a set of remote method signatures.
-#define PDX_REMOTE_API(name, ... /*methods*/) \
- using name = ::android::pdx::rpc::RemoteAPI<__VA_ARGS__>
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_REMOTE_METHOD_TYPE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/sequence.h b/libs/vr/libpdx/private/pdx/rpc/sequence.h
deleted file mode 100644
index 5fd898a..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/sequence.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SEQUENCE_H_
-#define ANDROID_PDX_RPC_SEQUENCE_H_
-
-#include <cstdint>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Provides a C++11 implementation of C++14 index_sequence and
-// make_index_sequence for compatibility with common compilers. This
-// implementation may be conditionally replaced with compiler-provided versions
-// when C++14 support is available.
-
-// Utility to capture a sequence of unsigned indices.
-template <std::size_t... I>
-struct IndexSequence {
- using type = IndexSequence;
- using value_type = std::size_t;
- static constexpr std::size_t size() { return sizeof...(I); }
-};
-
-namespace detail {
-
-// Helper class to merge and renumber sequence parts in log N instantiations.
-template <typename S1, typename S2>
-struct MergeSequencesAndRenumber;
-
-template <std::size_t... I1, std::size_t... I2>
-struct MergeSequencesAndRenumber<IndexSequence<I1...>, IndexSequence<I2...>>
- : IndexSequence<I1..., (sizeof...(I1) + I2)...> {};
-
-} // namespace detail
-
-// Utility to build an IndexSequence with N indices.
-template <std::size_t N>
-struct MakeIndexSequence : detail::MergeSequencesAndRenumber<
- typename MakeIndexSequence<N / 2>::type,
- typename MakeIndexSequence<N - N / 2>::type> {};
-
-// Identity sequences.
-template <>
-struct MakeIndexSequence<0> : IndexSequence<> {};
-template <>
-struct MakeIndexSequence<1> : IndexSequence<0> {};
-
-// Utility to build an IndexSequence with indices for each element of a
-// parameter pack.
-template <typename... T>
-using IndexSequenceFor = MakeIndexSequence<sizeof...(T)>;
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_SEQUENCE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/serializable.h b/libs/vr/libpdx/private/pdx/rpc/serializable.h
deleted file mode 100644
index 04a4352..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/serializable.h
+++ /dev/null
@@ -1,150 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SERIALIZABLE_H_
-#define ANDROID_PDX_RPC_SERIALIZABLE_H_
-
-#include <cstddef>
-#include <string>
-#include <tuple>
-
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-
-#include "macros.h"
-#include "serialization.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// This file provides utilities to define serializable types for communication
-// between clients and services. Supporting efficient, typed communication
-// protocols is the primary goal, NOT providing a general-purpose solution for
-// all your C++ serialization needs. Features that are not aligned to the goals
-// are not supported, such as static/const member serialization and serializable
-// types with virtual methods (requiring a virtual destructor).
-
-// Captures the type and value of a pointer to member. Pointer to members are
-// essentially compile-time constant offsets that can be stored in the type
-// system without adding to the size of the structures they describe. This
-// library uses this property to implement a limited form of reflection for
-// serialization/deserialization functions.
-template <typename T, T>
-struct MemberPointer;
-
-template <typename Type, typename Class, Type Class::*Pointer>
-struct MemberPointer<Type Class::*, Pointer> {
- // Type of the member pointer this type represents.
- using PointerType = Type Class::*;
-
- // Resolves a pointer to member with the given instance, yielding a
- // reference to the member in that instance.
- static Type& Resolve(Class& instance) { return (instance.*Pointer); }
- static const Type& Resolve(const Class& instance) {
- return (instance.*Pointer);
- }
-};
-
-// Describes a set of members to be serialized/deserialized by this library. The
-// parameter pack MemberPointers takes a list of MemberPointer types that
-// describe each member to participate in serialization/deserialization.
-template <typename T, typename... MemberPointers>
-struct SerializableMembersType {
- using Type = T;
-
- // The number of member pointers described by this type.
- enum : std::size_t { MemberCount = sizeof...(MemberPointers) };
-
- // The member pointers described by this type.
- using Members = std::tuple<MemberPointers...>;
-
- // Accessor for individual member pointer types.
- template <std::size_t Index>
- using At = typename std::tuple_element<Index, Members>::type;
-};
-
-// Classes must do the following to correctly define a serializable type:
-// 1. Define a type called "SerializableMembers" as a template instantiation
-// of SerializableMembersType, describing the members of the class to
-// participate in serialization (presumably all of them). Use the macro
-// PDX_SERIALIZABLE_MEMBERS(...) below to aid the correct type
-// definition. This type should be private to prevent leaking member
-// access information.
-// 2. Make SerializableTraits and HasSerilizableMembers types a friend of
-// the class. The macro PDX_SERIALIZABLE_MEMEBRS(...) takes care of
-// this automatically.
-// 3. Define a public default constructor, if necessary. Deserialization
-// requires instances to be default-constructible.
-//
-// Example usage:
-// class MySerializableType : public AnotherBaseType {
-// public:
-// MySerializableType();
-// ...
-// private:
-// int a;
-// string b;
-// PDX_SERIALIZABLE_MEMBERS(MySerializableType, a, b);
-// };
-//
-// Note that const and static member serialization is not supported.
-
-template <typename T>
-class SerializableTraits {
- public:
- // Gets the serialized size of type T.
- static std::size_t GetSerializedSize(const T& value) {
- return GetEncodingSize(EncodeArrayType(SerializableMembers::MemberCount)) +
- GetMembersSize<SerializableMembers>(value);
- }
-
- // Serializes type T.
- static void SerializeObject(const T& value, MessageWriter* writer,
- void*& buffer) {
- SerializeArrayEncoding(EncodeArrayType(SerializableMembers::MemberCount),
- SerializableMembers::MemberCount, buffer);
- SerializeMembers<SerializableMembers>(value, writer, buffer);
- }
-
- // Deserializes type T.
- static ErrorType DeserializeObject(T* value, MessageReader* reader,
- const void*& start, const void* end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end)) {
- return error;
- } else if (size != SerializableMembers::MemberCount) {
- return ErrorCode::UNEXPECTED_TYPE_SIZE;
- } else {
- return DeserializeMembers<SerializableMembers>(value, reader, start, end);
- }
- }
-
- private:
- using SerializableMembers = typename T::SerializableMembers;
-};
-
-// Utility macro to define a MemberPointer type for a member name.
-#define PDX_MEMBER_POINTER(type, member) \
- ::android::pdx::rpc::MemberPointer<decltype(&type::member), &type::member>
-
-// Defines a list of MemberPointer types given a list of member names.
-#define PDX_MEMBERS(type, ... /*members*/) \
- PDX_FOR_EACH_BINARY_LIST(PDX_MEMBER_POINTER, type, __VA_ARGS__)
-
-// Defines the serializable members of a type given a list of member names and
-// befriends SerializableTraits and HasSerializableMembers for the class. This
-// macro handles requirements #1 and #2 above.
-#define PDX_SERIALIZABLE_MEMBERS(type, ... /*members*/) \
- template <typename T> \
- friend class ::android::pdx::rpc::SerializableTraits; \
- template <typename, typename> \
- friend struct ::android::pdx::rpc::HasSerializableMembers; \
- using SerializableMembers = ::android::pdx::rpc::SerializableMembersType< \
- type, PDX_MEMBERS(type, __VA_ARGS__)>
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_SERIALIZABLE_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/serialization.h b/libs/vr/libpdx/private/pdx/rpc/serialization.h
deleted file mode 100644
index 914ea66..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/serialization.h
+++ /dev/null
@@ -1,2000 +0,0 @@
-#ifndef ANDROID_PDX_RPC_SERIALIZATION_H_
-#define ANDROID_PDX_RPC_SERIALIZATION_H_
-
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-#include <map>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <tuple>
-#include <type_traits>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/message_reader.h>
-#include <pdx/message_writer.h>
-#include <pdx/trace.h>
-#include <pdx/utility.h>
-
-#include "array_wrapper.h"
-#include "default_initialization_allocator.h"
-#include "encoding.h"
-#include "pointer_wrapper.h"
-#include "string_wrapper.h"
-#include "variant.h"
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Automatic serialization/deserialization library based on MessagePack
-// (http://msgpack.org). This library provides top level Serialize() and
-// Deserialize() functions to encode/decode a variety of data types.
-//
-// The following data types are supported:
-// * Standard signed integer types: int8_t, int16_t, int32_t, and int64_t.
-// * Regular signed integer types equivalent to the standard types:
-// signed char, short, int, long, and long long.
-// * Standard unsigned integer types: uint8_t, uint16_t, uint32_t, and
-// uint64_t.
-// * Regular unsigned integer types equivalent to the standard types:
-// unsigned char, unsigned short, unsigned int, unsigned long,
-// and unsigned long long.
-// * char without signed/unsigned qualifiers.
-// * bool.
-// * std::vector with value type of any supported type, including nesting.
-// * std::string.
-// * std::tuple with elements of any supported type, including nesting.
-// * std::pair with elements of any supported type, including nesting.
-// * std::map with keys and values of any supported type, including nesting.
-// * std::unordered_map with keys and values of any supported type, including
-// nesting.
-// * std::array with values of any supported type, including nesting.
-// * ArrayWrapper of any supported basic type.
-// * BufferWrapper of any POD type.
-// * StringWrapper of any supported char type.
-// * User types with correctly defined SerializableMembers member type.
-//
-// Planned support for:
-// * std::basic_string with all supported char types.
-
-// Counting template for managing template recursion.
-template <std::size_t N>
-struct Index {};
-
-// Forward declaration of traits type to access types with a SerializedMembers
-// member type.
-template <typename T>
-class SerializableTraits;
-
-template <typename T, typename... MemberPointers>
-struct SerializableMembersType;
-
-// Utility to deduce the template type from a derived type.
-template <template <typename...> class TT, typename... Ts>
-std::true_type DeduceTemplateType(const TT<Ts...>*);
-template <template <typename...> class TT>
-std::false_type DeduceTemplateType(...);
-
-// Utility determining whether template type TT<...> is a base of type T.
-template <template <typename...> class TT, typename T>
-using IsTemplateBaseOf = decltype(DeduceTemplateType<TT>(std::declval<T*>()));
-
-// Utility type for SFINAE in HasHasSerializableMembers.
-template <typename... Ts>
-using TrySerializableMembersType = void;
-
-// Determines whether type T has a member type named SerializableMembers of
-// template type SerializableMembersType.
-template <typename, typename = void>
-struct HasSerializableMembers : std::false_type {};
-template <typename T>
-struct HasSerializableMembers<
- T, TrySerializableMembersType<typename T::SerializableMembers>>
- : std::integral_constant<
- bool, IsTemplateBaseOf<SerializableMembersType,
- typename T::SerializableMembers>::value> {};
-
-// Utility to simplify overload enable expressions for types with correctly
-// defined SerializableMembers.
-template <typename T>
-using EnableIfHasSerializableMembers =
- typename std::enable_if<HasSerializableMembers<T>::value>::type;
-
-// Utility to simplify overload enable expressions for enum types.
-template <typename T, typename ReturnType = void>
-using EnableIfEnum =
- typename std::enable_if<std::is_enum<T>::value, ReturnType>::type;
-
-///////////////////////////////////////////////////////////////////////////////
-// Error Reporting //
-///////////////////////////////////////////////////////////////////////////////
-
-// Error codes returned by the deserialization code.
-enum class ErrorCode {
- NO_ERROR = 0,
- UNEXPECTED_ENCODING,
- UNEXPECTED_TYPE_SIZE,
- INSUFFICIENT_BUFFER,
- INSUFFICIENT_DESTINATION_SIZE,
- GET_FILE_DESCRIPTOR_FAILED,
- GET_CHANNEL_HANDLE_FAILED,
- INVALID_VARIANT_ELEMENT,
-};
-
-// Type for errors returned by the deserialization code.
-class ErrorType {
- public:
- ErrorType() : error_code_(ErrorCode::NO_ERROR) {}
-
- // ErrorType constructor for generic error codes. Explicitly not explicit,
- // implicit conversion from ErrorCode to ErrorType is desirable behavior.
- // NOLINTNEXTLINE(google-explicit-constructor)
- ErrorType(ErrorCode error_code) : error_code_(error_code) {}
-
- // ErrorType constructor for encoding type errors.
- ErrorType(ErrorCode error_code, EncodingClass encoding_class,
- EncodingType encoding_type)
- : error_code_(error_code) {
- unexpected_encoding_.encoding_class = encoding_class;
- unexpected_encoding_.encoding_type = encoding_type;
- }
-
- // Evaluates to true if the ErrorType represents an error.
- explicit operator bool() const { return error_code_ != ErrorCode::NO_ERROR; }
-
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator ErrorCode() const { return error_code_; }
- ErrorCode error_code() const { return error_code_; }
-
- // Accessors for extra info about unexpected encoding errors.
- EncodingClass encoding_class() const {
- return unexpected_encoding_.encoding_class;
- }
- EncodingType encoding_type() const {
- return unexpected_encoding_.encoding_type;
- }
-
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator std::string() const {
- std::ostringstream stream;
-
- switch (error_code_) {
- case ErrorCode::NO_ERROR:
- return "NO_ERROR";
- case ErrorCode::UNEXPECTED_ENCODING:
- stream << "UNEXPECTED_ENCODING: " << static_cast<int>(encoding_class())
- << ", " << static_cast<int>(encoding_type());
- return stream.str();
- case ErrorCode::UNEXPECTED_TYPE_SIZE:
- return "UNEXPECTED_TYPE_SIZE";
- case ErrorCode::INSUFFICIENT_BUFFER:
- return "INSUFFICIENT_BUFFER";
- case ErrorCode::INSUFFICIENT_DESTINATION_SIZE:
- return "INSUFFICIENT_DESTINATION_SIZE";
- default:
- return "[Unknown Error]";
- }
- }
-
- private:
- ErrorCode error_code_;
-
- // Union of extra information for different error code types.
- union {
- // UNEXPECTED_ENCODING.
- struct {
- EncodingClass encoding_class;
- EncodingType encoding_type;
- } unexpected_encoding_;
- };
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Size //
-///////////////////////////////////////////////////////////////////////////////
-
-inline constexpr std::size_t GetSerializedSize(const bool& b) {
- return GetEncodingSize(EncodeType(b));
-}
-
-// Overloads of GetSerializedSize() for standard integer types.
-inline constexpr std::size_t GetSerializedSize(const char& c) {
- return GetEncodingSize(EncodeType(c));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint8_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int8_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint16_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int16_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint32_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int32_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::uint64_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-inline constexpr std::size_t GetSerializedSize(const std::int64_t& i) {
- return GetEncodingSize(EncodeType(i));
-}
-
-inline constexpr std::size_t GetSerializedSize(const float& f) {
- return GetEncodingSize(EncodeType(f));
-}
-inline constexpr std::size_t GetSerializedSize(const double& d) {
- return GetEncodingSize(EncodeType(d));
-}
-
-// Overload for enum types.
-template <typename T>
-inline EnableIfEnum<T, std::size_t> GetSerializedSize(T v) {
- return GetSerializedSize(static_cast<std::underlying_type_t<T>>(v));
-}
-
-// Forward declaration for nested definitions.
-inline std::size_t GetSerializedSize(const EmptyVariant&);
-template <typename... Types>
-inline std::size_t GetSerializedSize(const Variant<Types...>&);
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline constexpr std::size_t GetSerializedSize(const T&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>&);
-inline constexpr std::size_t GetSerializedSize(const std::string&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>&);
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>&);
-template <FileHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>&);
-template <ChannelHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const ChannelHandle<Mode>&);
-template <typename T, typename Allocator>
-inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline std::size_t GetSerializedSize(
- const std::map<Key, T, Compare, Allocator>& m);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline std::size_t GetSerializedSize(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&);
-template <typename T>
-inline std::size_t GetSerializedSize(const ArrayWrapper<T>&);
-template <typename T, std::size_t Size>
-inline std::size_t GetSerializedSize(const std::array<T, Size>& v);
-template <typename T, typename U>
-inline std::size_t GetSerializedSize(const std::pair<T, U>& p);
-template <typename... T>
-inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple);
-
-// Overload for empty variant type.
-inline std::size_t GetSerializedSize(const EmptyVariant& empty) {
- return GetEncodingSize(EncodeType(empty));
-}
-
-// Overload for Variant types.
-template <typename... Types>
-inline std::size_t GetSerializedSize(const Variant<Types...>& variant) {
- return GetEncodingSize(EncodeType(variant)) +
- GetSerializedSize(variant.index()) +
- variant.Visit(
- [](const auto& value) { return GetSerializedSize(value); });
-}
-
-// Overload for structs/classes with SerializableMembers defined.
-template <typename T, typename Enabled>
-inline constexpr std::size_t GetSerializedSize(const T& value) {
- return SerializableTraits<T>::GetSerializedSize(value);
-}
-
-// Overload for PointerWrapper.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const PointerWrapper<T>& p) {
- return GetSerializedSize(p.Dereference());
-}
-
-// Overload for std::string.
-inline constexpr std::size_t GetSerializedSize(const std::string& s) {
- return GetEncodingSize(EncodeType(s)) +
- s.length() * sizeof(std::string::value_type);
-}
-
-// Overload for StringWrapper.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const StringWrapper<T>& s) {
- return GetEncodingSize(EncodeType(s)) +
- s.length() * sizeof(typename StringWrapper<T>::value_type);
-}
-
-// Overload for BufferWrapper types.
-template <typename T>
-inline constexpr std::size_t GetSerializedSize(const BufferWrapper<T>& b) {
- return GetEncodingSize(EncodeType(b)) +
- b.size() * sizeof(typename BufferWrapper<T>::value_type);
-}
-
-// Overload for FileHandle. FileHandle is encoded as a FIXEXT2, with a type code
-// of "FileHandle" and a signed 16-bit offset into the pushed fd array. Empty
-// FileHandles are encoded with an array index of -1.
-template <FileHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(const FileHandle<Mode>& fd) {
- return GetEncodingSize(EncodeType(fd)) + sizeof(std::int16_t);
-}
-
-// Overload for ChannelHandle. ChannelHandle is encoded as a FIXEXT4, with a
-// type code of "ChannelHandle" and a signed 32-bit offset into the pushed
-// channel array. Empty ChannelHandles are encoded with an array index of -1.
-template <ChannelHandleMode Mode>
-inline constexpr std::size_t GetSerializedSize(
- const ChannelHandle<Mode>& channel_handle) {
- return GetEncodingSize(EncodeType(channel_handle)) + sizeof(std::int32_t);
-}
-
-// Overload for standard vector types.
-template <typename T, typename Allocator>
-inline std::size_t GetSerializedSize(const std::vector<T, Allocator>& v) {
- return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
- [](const std::size_t& sum, const T& object) {
- return sum + GetSerializedSize(object);
- });
-}
-
-// Overload for standard map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline std::size_t GetSerializedSize(
- const std::map<Key, T, Compare, Allocator>& v) {
- return std::accumulate(
- v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
- [](const std::size_t& sum, const std::pair<Key, T>& object) {
- return sum + GetSerializedSize(object.first) +
- GetSerializedSize(object.second);
- });
-}
-
-// Overload for standard unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline std::size_t GetSerializedSize(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v) {
- return std::accumulate(
- v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
- [](const std::size_t& sum, const std::pair<Key, T>& object) {
- return sum + GetSerializedSize(object.first) +
- GetSerializedSize(object.second);
- });
-}
-
-// Overload for ArrayWrapper types.
-template <typename T>
-inline std::size_t GetSerializedSize(const ArrayWrapper<T>& v) {
- return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
- [](const std::size_t& sum, const T& object) {
- return sum + GetSerializedSize(object);
- });
-}
-
-// Overload for std::array types.
-template <typename T, std::size_t Size>
-inline std::size_t GetSerializedSize(const std::array<T, Size>& v) {
- return std::accumulate(v.begin(), v.end(), GetEncodingSize(EncodeType(v)),
- [](const std::size_t& sum, const T& object) {
- return sum + GetSerializedSize(object);
- });
-}
-
-// Overload for std::pair.
-template <typename T, typename U>
-inline std::size_t GetSerializedSize(const std::pair<T, U>& p) {
- return GetEncodingSize(EncodeType(p)) + GetSerializedSize(p.first) +
- GetSerializedSize(p.second);
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline std::size_t GetTupleSize(const std::tuple<T...>&, Index<0>) {
- return 0;
-}
-
-// Gets the size of each element in a tuple recursively.
-template <typename... T, std::size_t index>
-inline std::size_t GetTupleSize(const std::tuple<T...>& tuple, Index<index>) {
- return GetTupleSize(tuple, Index<index - 1>()) +
- GetSerializedSize(std::get<index - 1>(tuple));
-}
-
-// Overload for tuple types. Gets the size of the tuple, recursing
-// through the elements.
-template <typename... T>
-inline std::size_t GetSerializedSize(const std::tuple<T...>& tuple) {
- return GetEncodingSize(EncodeType(tuple)) +
- GetTupleSize(tuple, Index<sizeof...(T)>());
-}
-
-// Stops template recursion when the last member of a Serializable
-// type is reached.
-template <typename Members, typename T>
-inline std::size_t GetMemberSize(const T&, Index<0>) {
- return 0;
-}
-
-// Gets the size of each member of a Serializable type recursively.
-template <typename Members, typename T, std::size_t index>
-inline std::size_t GetMemberSize(const T& object, Index<index>) {
- return GetMemberSize<Members>(object, Index<index - 1>()) +
- GetSerializedSize(Members::template At<index - 1>::Resolve(object));
-}
-
-// Gets the size of a type using the given SerializableMembersType
-// type.
-template <typename Members, typename T>
-inline std::size_t GetMembersSize(const T& object) {
- return GetMemberSize<Members>(object, Index<Members::MemberCount>());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Serialization //
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// SerializeRaw() converts a primitive array or type into a raw byte string.
-// These functions are named differently from SerializeObject() expressly to
-// avoid catch-all specialization of that template, which can be difficult to
-// detect otherwise.
-//
-
-inline void WriteRawData(void*& dest, const void* src, size_t size) {
- memcpy(dest, src, size);
- dest = static_cast<uint8_t*>(dest) + size;
-}
-
-// Serializes a primitive array into a raw byte string.
-template <typename T,
- typename = typename std::enable_if<std::is_pod<T>::value>::type>
-inline void SerializeRaw(const T& value, void*& buffer) {
- WriteRawData(buffer, &value, sizeof(value));
-}
-
-inline void SerializeEncoding(EncodingType encoding, void*& buffer) {
- SerializeRaw(encoding, buffer);
-}
-
-inline void SerializeType(const bool& value, void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
-}
-
-// Serializes the type code, extended type code, and size for
-// extension types.
-inline void SerializeExtEncoding(EncodingType encoding,
- EncodingExtType ext_type, std::size_t size,
- void*& buffer) {
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_EXT8) {
- std::uint8_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_EXT16) {
- std::uint16_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_EXT32) {
- std::uint32_t length = size;
- SerializeRaw(length, buffer);
- } else /* if (IsFixextEncoding(encoding) */ {
- // Encoding byte contains the fixext length, nothing else to do.
- }
- SerializeRaw(ext_type, buffer);
-}
-
-// Serializes the type code for file descriptor types.
-template <FileHandleMode Mode>
-inline void SerializeType(const FileHandle<Mode>& value, void*& buffer) {
- SerializeExtEncoding(EncodeType(value), ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 2,
- buffer);
-}
-
-// Serializes the type code for channel handle types.
-template <ChannelHandleMode Mode>
-inline void SerializeType(const ChannelHandle<Mode>& handle, void*& buffer) {
- SerializeExtEncoding(EncodeType(handle), ENCODING_EXT_TYPE_CHANNEL_HANDLE, 4,
- buffer);
-}
-
-// Serializes type code for variant types.
-template <typename... Types>
-inline void SerializeType(const Variant<Types...>& value, void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
-}
-
-// Serializes the type code for string types.
-template <typename StringType>
-inline void SerializeStringType(const StringType& value, void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_STR8) {
- std::uint8_t length = value.length();
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_STR16) {
- std::uint16_t length = value.length();
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_STR32) {
- std::uint32_t length = value.length();
- SerializeRaw(length, buffer);
- } else /* if (IsFixstrEncoding(encoding) */ {
- // Encoding byte contains the fixstr length, nothing else to do.
- }
-}
-
-// Serializes the type code for std::string and StringWrapper. These types are
-// interchangeable and must serialize to the same format.
-inline void SerializeType(const std::string& value, void*& buffer) {
- SerializeStringType(value, buffer);
-}
-template <typename T>
-inline void SerializeType(const StringWrapper<T>& value, void*& buffer) {
- SerializeStringType(value, buffer);
-}
-
-// Serializes the type code for bin types.
-inline void SerializeBinEncoding(EncodingType encoding, std::size_t size,
- void*& buffer) {
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_BIN8) {
- std::uint8_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_BIN16) {
- std::uint16_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_BIN32) {
- std::uint32_t length = size;
- SerializeRaw(length, buffer);
- } else {
- // Invalid encoding for BIN type.
- }
-}
-
-// Serializes the type code for BufferWrapper types.
-template <typename T>
-inline void SerializeType(const BufferWrapper<T>& value, void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeBinEncoding(
- encoding, value.size() * sizeof(typename BufferWrapper<T>::value_type),
- buffer);
-}
-
-// Serializes the array encoding type and length.
-inline void SerializeArrayEncoding(EncodingType encoding, std::size_t size,
- void*& buffer) {
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_ARRAY16) {
- std::uint16_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_ARRAY32) {
- std::uint32_t length = size;
- SerializeRaw(length, buffer);
- } else /* if (IsFixarrayEncoding(encoding) */ {
- // Encoding byte contains the fixarray length, nothing else to do.
- }
-}
-
-// Serializes the map encoding type and length.
-inline void SerializeMapEncoding(EncodingType encoding, std::size_t size,
- void*& buffer) {
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_MAP16) {
- std::uint16_t length = size;
- SerializeRaw(length, buffer);
- } else if (encoding == ENCODING_TYPE_MAP32) {
- std::uint32_t length = size;
- SerializeRaw(length, buffer);
- } else /* if (IsFixmapEncoding(encoding) */ {
- // Encoding byte contains the fixmap length, nothing else to do.
- }
-}
-
-// Serializes the type code for array types.
-template <typename ArrayType>
-inline void SerializeArrayType(const ArrayType& value, std::size_t size,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeArrayEncoding(encoding, size, buffer);
-}
-
-// Serializes the type code for map types.
-template <typename MapType>
-inline void SerializeMapType(const MapType& value, std::size_t size,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeMapEncoding(encoding, size, buffer);
-}
-
-// Serializes the type code for std::vector and ArrayWrapper. These types are
-// interchangeable and must serialize to the same format.
-template <typename T, typename Allocator>
-inline void SerializeType(const std::vector<T, Allocator>& value,
- void*& buffer) {
- SerializeArrayType(value, value.size(), buffer);
-}
-template <typename T>
-inline void SerializeType(const ArrayWrapper<T>& value, void*& buffer) {
- SerializeArrayType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::array. This type serializes to the same
-// format as std::vector and ArrayWrapper and is interchangeable in certain
-// situations.
-template <typename T, std::size_t Size>
-inline void SerializeType(const std::array<T, Size>& value, void*& buffer) {
- SerializeArrayType(value, Size, buffer);
-}
-
-// Serializes the type code for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeType(const std::map<Key, T, Compare, Allocator>& value,
- void*& buffer) {
- SerializeMapType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline void SerializeType(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& value,
- void*& buffer) {
- SerializeMapType(value, value.size(), buffer);
-}
-
-// Serializes the type code for std::pair types.
-template <typename T, typename U>
-inline void SerializeType(const std::pair<T, U>& value, void*& buffer) {
- SerializeArrayType(value, 2, buffer);
-}
-
-// Serializes the type code for std::tuple types.
-template <typename... T>
-inline void SerializeType(const std::tuple<T...>& value, void*& buffer) {
- SerializeArrayType(value, sizeof...(T), buffer);
-}
-
-// Specialization of SerializeObject for boolean type.
-inline void SerializeObject(const bool& value, MessageWriter* /*writer*/,
- void*& buffer) {
- SerializeType(value, buffer);
- // Encoding contains the boolean value, nothing else to do.
-}
-
-// Overloads of SerializeObject for float and double types.
-inline void SerializeObject(const float& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- SerializeRaw(value, buffer);
-}
-
-inline void SerializeObject(const double& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- SerializeRaw(value, buffer);
-}
-
-// Overloads of SerializeObject() for standard integer types.
-inline void SerializeObject(const char& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_UINT8) {
- SerializeRaw(value, buffer);
- } else /* if (IsUnsignedFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const int8_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_INT8) {
- SerializeRaw(value, buffer);
- } else /* if (IsFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const uint8_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_UINT8) {
- SerializeRaw(value, buffer);
- } else /* if (IsUnsignedFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const int16_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_INT8) {
- const int8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_INT16) {
- SerializeRaw(value, buffer);
- } else /* if (IsFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const uint16_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_UINT8) {
- const uint8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_UINT16) {
- SerializeRaw(value, buffer);
- } else /* if (IsUnsignedFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const int32_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_INT8) {
- const int8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_INT16) {
- const int16_t half = value;
- SerializeRaw(half, buffer);
- } else if (encoding == ENCODING_TYPE_INT32) {
- SerializeRaw(value, buffer);
- } else /* if (IsFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const uint32_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_UINT8) {
- const uint8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_UINT16) {
- const uint16_t half = value;
- SerializeRaw(half, buffer);
- } else if (encoding == ENCODING_TYPE_UINT32) {
- SerializeRaw(value, buffer);
- } else /* if (IsUnsignedFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const int64_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_INT8) {
- const int8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_INT16) {
- const int16_t half = value;
- SerializeRaw(half, buffer);
- } else if (encoding == ENCODING_TYPE_INT32) {
- const int32_t word = value;
- SerializeRaw(word, buffer);
- } else if (encoding == ENCODING_TYPE_INT64) {
- SerializeRaw(value, buffer);
- } else /* if (IsFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-inline void SerializeObject(const uint64_t& value, MessageWriter* /*writer*/,
- void*& buffer) {
- const EncodingType encoding = EncodeType(value);
- SerializeEncoding(encoding, buffer);
- if (encoding == ENCODING_TYPE_UINT8) {
- const uint8_t byte = value;
- SerializeRaw(byte, buffer);
- } else if (encoding == ENCODING_TYPE_UINT16) {
- const uint16_t half = value;
- SerializeRaw(half, buffer);
- } else if (encoding == ENCODING_TYPE_UINT32) {
- const uint32_t word = value;
- SerializeRaw(word, buffer);
- } else if (encoding == ENCODING_TYPE_UINT64) {
- SerializeRaw(value, buffer);
- } else /* if (IsUnsignedFixintEncoding(encoding) */ {
- // Encoding byte contains the value, nothing else to do.
- }
-}
-
-// Serialize enum types.
-template <typename T>
-inline EnableIfEnum<T> SerializeObject(const T& value, MessageWriter* writer,
- void*& buffer) {
- SerializeObject(static_cast<std::underlying_type_t<T>>(value), writer,
- buffer);
-}
-
-// Forward declaration for nested definitions.
-inline void SerializeObject(const EmptyVariant&, MessageWriter*, void*&);
-template <typename... Types>
-inline void SerializeObject(const Variant<Types...>&, MessageWriter*, void*&);
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline void SerializeObject(const T&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const PointerWrapper<T>&, MessageWriter*, void*&);
-template <FileHandleMode Mode>
-inline void SerializeObject(const FileHandle<Mode>&, MessageWriter*, void*&);
-template <ChannelHandleMode Mode>
-inline void SerializeObject(const ChannelHandle<Mode>&, MessageWriter*, void*&);
-template <typename T, typename Allocator>
-inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const BufferWrapper<T*>&, MessageWriter*, void*&);
-inline void SerializeObject(const std::string&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const StringWrapper<T>&, MessageWriter*, void*&);
-template <typename T, typename Allocator>
-inline void SerializeObject(const std::vector<T, Allocator>&, MessageWriter*, void*&);
-template <typename T>
-inline void SerializeObject(const ArrayWrapper<T>&, MessageWriter*, void*&);
-template <typename T, std::size_t Size>
-inline void SerializeObject(const std::array<T, Size>&, MessageWriter*, void*&);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeObject(const std::map<Key, T, Compare, Allocator>&, MessageWriter*, void*&);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline void SerializeObject(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>&, MessageWriter*, void*&);
-template <typename T, typename U>
-inline void SerializeObject(const std::pair<T, U>&, MessageWriter*, void*&);
-template <typename... T>
-inline void SerializeObject(const std::tuple<T...>&, MessageWriter*, void*&);
-
-// Overload for empty variant type.
-inline void SerializeObject(const EmptyVariant& empty,
- MessageWriter* /*writer*/, void*& buffer) {
- const EncodingType encoding = EncodeType(empty);
- SerializeEncoding(encoding, buffer);
-}
-
-// Overload for Variant types.
-template <typename... Types>
-inline void SerializeObject(const Variant<Types...>& variant,
- MessageWriter* writer, void*& buffer) {
- SerializeType(variant, buffer);
- SerializeObject(variant.index(), writer, buffer);
- return variant.Visit([writer, &buffer](const auto& value) {
- return SerializeObject(value, writer, buffer);
- });
-}
-
-// Overload for serializable structure/class types.
-template <typename T, typename Enabled>
-inline void SerializeObject(const T& value, MessageWriter* writer,
- void*& buffer) {
- SerializableTraits<T>::SerializeObject(value, writer, buffer);
-}
-
-// Serializes the payload of a PointerWrapper.
-template <typename T>
-inline void SerializeObject(const PointerWrapper<T>& pointer,
- MessageWriter* writer, void*& buffer) {
- SerializeObject(pointer.Dereference(), writer, buffer);
-}
-
-// Serializes the payload of file descriptor types.
-template <FileHandleMode Mode>
-inline void SerializeObject(const FileHandle<Mode>& fd, MessageWriter* writer,
- void*& buffer) {
- SerializeType(fd, buffer);
- const Status<FileReference> status =
- writer->GetOutputResourceMapper()->PushFileHandle(fd);
- FileReference value = status ? status.get() : -status.error();
- SerializeRaw(value, buffer);
-}
-
-// Serializes the payload of channel handle types.
-template <ChannelHandleMode Mode>
-inline void SerializeObject(const ChannelHandle<Mode>& handle,
- MessageWriter* writer, void*& buffer) {
- SerializeType(handle, buffer);
- const Status<ChannelReference> status =
- writer->GetOutputResourceMapper()->PushChannelHandle(handle);
- ChannelReference value = status ? status.get() : -status.error();
- SerializeRaw(value, buffer);
-}
-
-// Serializes the payload of BufferWrapper types.
-template <typename T, typename Allocator>
-inline void SerializeObject(const BufferWrapper<std::vector<T, Allocator>>& b,
- MessageWriter* /*writer*/, void*& buffer) {
- const auto value_type_size =
- sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
- SerializeType(b, buffer);
- WriteRawData(buffer, b.data(), b.size() * value_type_size);
-}
-template <typename T>
-inline void SerializeObject(const BufferWrapper<T*>& b,
- MessageWriter* /*writer*/, void*& buffer) {
- const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
- SerializeType(b, buffer);
- WriteRawData(buffer, b.data(), b.size() * value_type_size);
-}
-
-// Serializes the payload of string types.
-template <typename StringType>
-inline void SerializeString(const StringType& s, void*& buffer) {
- const auto value_type_size = sizeof(typename StringType::value_type);
- SerializeType(s, buffer);
- WriteRawData(buffer, s.data(), s.length() * value_type_size);
-}
-
-// Overload of SerializeObject() for std::string and StringWrapper. These types
-// are interchangeable and must serialize to the same format.
-inline void SerializeObject(const std::string& s, MessageWriter* /*writer*/,
- void*& buffer) {
- SerializeString(s, buffer);
-}
-template <typename T>
-inline void SerializeObject(const StringWrapper<T>& s,
- MessageWriter* /*writer*/, void*& buffer) {
- SerializeString(s, buffer);
-}
-
-// Serializes the payload of array types.
-template <typename ArrayType>
-inline void SerializeArray(const ArrayType& v, MessageWriter* writer,
- void*& buffer) {
- SerializeType(v, buffer);
- for (const auto& element : v)
- SerializeObject(element, writer, buffer);
-}
-
-// Serializes the payload for map types.
-template <typename MapType>
-inline void SerializeMap(const MapType& v, MessageWriter* writer,
- void*& buffer) {
- SerializeType(v, buffer);
- for (const auto& element : v) {
- SerializeObject(element.first, writer, buffer);
- SerializeObject(element.second, writer, buffer);
- }
-}
-
-// Overload of SerializeObject() for std::vector and ArrayWrapper types. These
-// types are interchangeable and must serialize to the same format.
-template <typename T, typename Allocator>
-inline void SerializeObject(const std::vector<T, Allocator>& v,
- MessageWriter* writer, void*& buffer) {
- SerializeArray(v, writer, buffer);
-}
-template <typename T>
-inline void SerializeObject(const ArrayWrapper<T>& v, MessageWriter* writer,
- void*& buffer) {
- SerializeArray(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::array types. These types serialize to
-// the same format at std::vector and ArrayWrapper and are interchangeable in
-// certain situations.
-template <typename T, std::size_t Size>
-inline void SerializeObject(const std::array<T, Size>& v, MessageWriter* writer,
- void*& buffer) {
- SerializeArray(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline void SerializeObject(const std::map<Key, T, Compare, Allocator>& v,
- MessageWriter* writer, void*& buffer) {
- SerializeMap(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline void SerializeObject(
- const std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& v,
- MessageWriter* writer, void*& buffer) {
- SerializeMap(v, writer, buffer);
-}
-
-// Overload of SerializeObject() for std:pair types.
-template <typename T, typename U>
-inline void SerializeObject(const std::pair<T, U>& pair, MessageWriter* writer,
- void*& buffer) {
- SerializeType(pair, buffer);
- SerializeObject(pair.first, writer, buffer);
- SerializeObject(pair.second, writer, buffer);
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline void SerializeTuple(const std::tuple<T...>&, MessageWriter*, void*&,
- Index<0>) {}
-
-// Serializes each element of a tuple recursively.
-template <typename... T, std::size_t index>
-inline void SerializeTuple(const std::tuple<T...>& tuple, MessageWriter* writer,
- void*& buffer, Index<index>) {
- SerializeTuple(tuple, writer, buffer, Index<index - 1>());
- SerializeObject(std::get<index - 1>(tuple), writer, buffer);
-}
-
-// Overload of SerializeObject() for tuple types.
-template <typename... T>
-inline void SerializeObject(const std::tuple<T...>& tuple,
- MessageWriter* writer, void*& buffer) {
- SerializeType(tuple, buffer);
- SerializeTuple(tuple, writer, buffer, Index<sizeof...(T)>());
-}
-
-// Stops template recursion when the last member pointer is reached.
-template <typename Members, typename T>
-inline void SerializeMember(const T&, MessageWriter*, void*&, Index<0>) {}
-
-// Serializes each member pointer recursively.
-template <typename Members, typename T, std::size_t index>
-inline void SerializeMember(const T& object, MessageWriter* writer,
- void*& buffer, Index<index>) {
- SerializeMember<Members>(object, writer, buffer, Index<index - 1>());
- SerializeObject(Members::template At<index - 1>::Resolve(object), writer,
- buffer);
-}
-
-// Serializes the members of a type using the given SerializableMembersType
-// type.
-template <typename Members, typename T>
-inline void SerializeMembers(const T& object, MessageWriter* writer,
- void*& buffer) {
- SerializeMember<Members>(object, writer, buffer,
- Index<Members::MemberCount>());
-}
-
-// Top level serialization function that replaces the buffer's contents.
-template <typename T>
-inline void Serialize(const T& object, MessageWriter* writer) {
- PDX_TRACE_NAME("Serialize");
- const std::size_t size = GetSerializedSize(object);
-
- // Reserve the space needed for the object(s).
- void* buffer = writer->GetNextWriteBufferSection(size);
- SerializeObject(object, writer, buffer);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Object Deserialization //
-///////////////////////////////////////////////////////////////////////////////
-
-inline ErrorType ReadRawDataFromNextSection(void* dest, MessageReader* reader,
- const void*& start,
- const void*& end, size_t size) {
- while (AdvancePointer(start, size) > end) {
- auto remaining_size = PointerDistance(end, start);
- if (remaining_size > 0) {
- memcpy(dest, start, remaining_size);
- dest = AdvancePointer(dest, remaining_size);
- size -= remaining_size;
- }
- reader->ConsumeReadBufferSectionData(AdvancePointer(start, remaining_size));
- std::tie(start, end) = reader->GetNextReadBufferSection();
- if (start == end)
- return ErrorCode::INSUFFICIENT_BUFFER;
- }
- memcpy(dest, start, size);
- start = AdvancePointer(start, size);
- return ErrorCode::NO_ERROR;
-}
-
-inline ErrorType ReadRawData(void* dest, MessageReader* /*reader*/,
- const void*& start, const void*& end,
- size_t size) {
- if (PDX_UNLIKELY(AdvancePointer(start, size) > end)) {
- // TODO(avakulenko): Enabling reading from next sections of input buffer
- // (using ReadRawDataFromNextSection) screws up clang compiler optimizations
- // (probably inefficient inlining) making the whole deserialization
- // code path about twice as slow. Investigate and enable more generic
- // deserialization code, but right now we don't really need/support this
- // scenario, so I keep this commented out for the time being...
-
- // return ReadRawDataFromNextSection(dest, reader, start, end, size);
- return ErrorCode::INSUFFICIENT_BUFFER;
- }
- memcpy(dest, start, size);
- start = AdvancePointer(start, size);
- return ErrorCode::NO_ERROR;
-}
-
-// Deserializes a primitive object from raw bytes.
-template <typename T,
- typename = typename std::enable_if<std::is_pod<T>::value>::type>
-inline ErrorType DeserializeRaw(T* value, MessageReader* reader,
- const void*& start, const void*& end) {
- return ReadRawData(value, reader, start, end, sizeof(T));
-}
-
-// Utility to deserialize POD types when the serialized type is different
-// (smaller) than the target real type. This happens when values are serialized
-// into more compact encodings.
-template <typename SerializedType, typename RealType>
-ErrorType DeserializeValue(RealType* real_value, MessageReader* reader,
- const void*& start, const void*& end) {
- SerializedType serialized_value;
- if (const auto error =
- DeserializeRaw(&serialized_value, reader, start, end)) {
- return error;
- } else {
- *real_value = serialized_value;
- return ErrorCode::NO_ERROR;
- }
-}
-
-inline ErrorType DeserializeEncoding(EncodingType* encoding,
- MessageReader* reader, const void*& start,
- const void*& end) {
- return DeserializeRaw(encoding, reader, start, end);
-}
-
-// Overload to deserialize bool type.
-inline ErrorType DeserializeObject(bool* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsBoolEncoding(encoding)) {
- *value = (encoding == ENCODING_TYPE_TRUE);
- return ErrorCode::NO_ERROR;
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BOOL,
- encoding);
- }
-}
-
-// Specializations to deserialize float and double types.
-inline ErrorType DeserializeObject(float* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFloat32Encoding(encoding)) {
- return DeserializeValue<float>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(double* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFloat32Encoding(encoding)) {
- return DeserializeValue<float>(value, reader, start, end);
- } else if (IsFloat64Encoding(encoding)) {
- return DeserializeValue<double>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_FLOAT,
- encoding);
- }
-}
-
-// Specializations to deserialize standard integer types.
-inline ErrorType DeserializeObject(char* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsUnsignedFixintEncoding(encoding)) {
- *value = static_cast<char>(encoding);
- return ErrorCode::NO_ERROR;
- } else if (IsUInt8Encoding(encoding)) {
- return DeserializeValue<char>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::int8_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFixintEncoding(encoding)) {
- *value = static_cast<std::int8_t>(encoding);
- return ErrorCode::NO_ERROR;
- } else if (IsInt8Encoding(encoding)) {
- return DeserializeValue<std::int8_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::uint8_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsUnsignedFixintEncoding(encoding)) {
- *value = encoding;
- return ErrorCode::NO_ERROR;
- } else if (IsUInt8Encoding(encoding)) {
- return DeserializeValue<std::uint8_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::int16_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFixintEncoding(encoding)) {
- *value = static_cast<std::int8_t>(encoding);
- return ErrorCode::NO_ERROR;
- } else if (IsInt8Encoding(encoding)) {
- return DeserializeValue<std::int8_t>(value, reader, start, end);
- } else if (IsInt16Encoding(encoding)) {
- return DeserializeValue<std::int16_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::uint16_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsUnsignedFixintEncoding(encoding)) {
- *value = encoding;
- return ErrorCode::NO_ERROR;
- } else if (IsUInt8Encoding(encoding)) {
- return DeserializeValue<std::uint8_t>(value, reader, start, end);
- } else if (IsUInt16Encoding(encoding)) {
- return DeserializeValue<std::uint16_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::int32_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFixintEncoding(encoding)) {
- *value = static_cast<std::int8_t>(encoding);
- return ErrorCode::NO_ERROR;
- } else if (IsInt8Encoding(encoding)) {
- return DeserializeValue<std::int8_t>(value, reader, start, end);
- } else if (IsInt16Encoding(encoding)) {
- return DeserializeValue<std::int16_t>(value, reader, start, end);
- } else if (IsInt32Encoding(encoding)) {
- return DeserializeValue<std::int32_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::uint32_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsUnsignedFixintEncoding(encoding)) {
- *value = encoding;
- return ErrorCode::NO_ERROR;
- } else if (IsUInt8Encoding(encoding)) {
- return DeserializeValue<std::uint8_t>(value, reader, start, end);
- } else if (IsUInt16Encoding(encoding)) {
- return DeserializeValue<std::uint16_t>(value, reader, start, end);
- } else if (IsUInt32Encoding(encoding)) {
- return DeserializeValue<std::uint32_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::int64_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsFixintEncoding(encoding)) {
- *value = static_cast<std::int8_t>(encoding);
- return ErrorCode::NO_ERROR;
- } else if (IsInt8Encoding(encoding)) {
- return DeserializeValue<std::int8_t>(value, reader, start, end);
- } else if (IsInt16Encoding(encoding)) {
- return DeserializeValue<std::int16_t>(value, reader, start, end);
- } else if (IsInt32Encoding(encoding)) {
- return DeserializeValue<std::int32_t>(value, reader, start, end);
- } else if (IsInt64Encoding(encoding)) {
- return DeserializeValue<std::int64_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_INT,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(std::uint64_t* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (IsUnsignedFixintEncoding(encoding)) {
- *value = encoding;
- return ErrorCode::NO_ERROR;
- } else if (IsUInt8Encoding(encoding)) {
- return DeserializeValue<std::uint8_t>(value, reader, start, end);
- } else if (IsUInt16Encoding(encoding)) {
- return DeserializeValue<std::uint16_t>(value, reader, start, end);
- } else if (IsUInt32Encoding(encoding)) {
- return DeserializeValue<std::uint32_t>(value, reader, start, end);
- } else if (IsUInt64Encoding(encoding)) {
- return DeserializeValue<std::uint64_t>(value, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_UINT,
- encoding);
- }
-}
-
-template <typename T>
-inline EnableIfEnum<T, ErrorType> DeserializeObject(T* value,
- MessageReader* reader,
- const void*& start,
- const void*& end) {
- std::underlying_type_t<T> enum_value;
- ErrorType error = DeserializeObject(&enum_value, reader, start, end);
- if (!error)
- *value = static_cast<T>(enum_value);
- return error;
-}
-
-// Forward declarations for nested definitions.
-template <typename T, typename Enabled = EnableIfHasSerializableMembers<T>>
-inline ErrorType DeserializeObject(T*, MessageReader*, const void*&,
- const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(PointerWrapper<T>*, MessageReader*,
- const void*&, const void*&);
-inline ErrorType DeserializeObject(LocalHandle*, MessageReader*, const void*&,
- const void*&);
-inline ErrorType DeserializeObject(LocalChannelHandle*, MessageReader*,
- const void*&, const void*&);
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(BufferWrapper<std::vector<T, Allocator>>*,
- MessageReader*, const void*&, const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(BufferWrapper<T*>*, MessageReader*,
- const void*&, const void*&);
-inline ErrorType DeserializeObject(std::string*, MessageReader*, const void*&,
- const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(StringWrapper<T>*, MessageReader*,
- const void*&, const void*&);
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
- const void*&, const void*&);
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
- const void*&, const void*&);
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(std::vector<T, Allocator>*, MessageReader*,
- const void*&, const void*&);
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>*,
- MessageReader*, const void*&, const void*&);
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline ErrorType DeserializeObject(
- std::unordered_map<Key, T, Hash, KeyEqual, Allocator>*, MessageReader*,
- const void*&, const void*&);
-template <typename T>
-inline ErrorType DeserializeObject(ArrayWrapper<T>*, MessageReader*,
- const void*&, const void*&);
-template <typename T, std::size_t Size>
-inline ErrorType DeserializeObject(std::array<T, Size>*, MessageReader*,
- const void*&, const void*&);
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>*, MessageReader*,
- const void*&, const void*&);
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>*, MessageReader*,
- const void*&, const void*&);
-inline ErrorType DeserializeObject(EmptyVariant*,
- MessageReader*, const void*&,
- const void*&);
-template <typename... Types>
-inline ErrorType DeserializeObject(Variant<Types...>*,
- MessageReader*, const void*&,
- const void*&);
-
-// Deserializes a Serializable type.
-template <typename T, typename Enable>
-inline ErrorType DeserializeObject(T* value, MessageReader* reader,
- const void*& start, const void*& end) {
- return SerializableTraits<T>::DeserializeObject(value, reader, start, end);
-}
-
-// Deserializes a PointerWrapper.
-template <typename T>
-inline ErrorType DeserializeObject(PointerWrapper<T>* pointer,
- MessageReader* reader, const void*& start,
- const void*& end) {
- return DeserializeObject(&pointer->Dereference(), reader, start, end);
-}
-
-// Deserializes the type code and size for extension types.
-inline ErrorType DeserializeExtType(EncodingType* encoding,
- EncodingExtType* type, std::size_t* size,
- MessageReader* reader, const void*& start,
- const void*& end) {
- if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
- return error;
- } else if (IsFixextEncoding(*encoding)) {
- *size = GetFixextSize(*encoding);
- } else if (*encoding == ENCODING_TYPE_EXT8) {
- if (const auto error =
- DeserializeValue<std::uint8_t>(size, reader, start, end))
- return error;
- } else if (*encoding == ENCODING_TYPE_EXT16) {
- if (const auto error =
- DeserializeValue<std::uint16_t>(size, reader, start, end))
- return error;
- } else if (*encoding == ENCODING_TYPE_EXT32) {
- if (const auto error =
- DeserializeValue<std::uint32_t>(size, reader, start, end))
- return error;
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
- *encoding);
- }
-
- // The extension type code follows the encoding and size.
- return DeserializeRaw(type, reader, start, end);
-}
-
-// Deserializes a file handle and performs handle space translation, if
-// required.
-inline ErrorType DeserializeObject(LocalHandle* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- EncodingExtType type;
- std::size_t size;
-
- if (const auto error =
- DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
- return error;
- } else if (size != 2) {
- return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
- encoding);
- } else if (type == ENCODING_EXT_TYPE_FILE_DESCRIPTOR) {
- // Read the encoded file descriptor value.
- FileReference ref;
- if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
- return error;
- }
-
- return reader->GetInputResourceMapper()->GetFileHandle(ref, value)
- ? ErrorCode::NO_ERROR
- : ErrorCode::GET_FILE_DESCRIPTOR_FAILED;
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
- encoding);
- }
-}
-
-inline ErrorType DeserializeObject(LocalChannelHandle* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- EncodingExtType type;
- std::size_t size;
-
- if (const auto error =
- DeserializeExtType(&encoding, &type, &size, reader, start, end)) {
- return error;
- } else if (size != 4) {
- return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_EXTENSION,
- encoding);
- } else if (type == ENCODING_EXT_TYPE_CHANNEL_HANDLE) {
- // Read the encoded channel handle value.
- ChannelReference ref;
- if (const auto error = DeserializeRaw(&ref, reader, start, end)) {
- return error;
- }
- return reader->GetInputResourceMapper()->GetChannelHandle(ref, value)
- ? ErrorCode::NO_ERROR
- : ErrorCode::GET_CHANNEL_HANDLE_FAILED;
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_EXTENSION,
- encoding);
- }
-}
-
-// Deserializes the type code and size for bin types.
-inline ErrorType DeserializeBinType(EncodingType* encoding, std::size_t* size,
- MessageReader* reader, const void*& start,
- const void*& end) {
- if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
- return error;
- } else if (*encoding == ENCODING_TYPE_BIN8) {
- return DeserializeValue<std::uint8_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_BIN16) {
- return DeserializeValue<std::uint16_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_BIN32) {
- return DeserializeValue<std::uint32_t>(size, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_BINARY,
- *encoding);
- }
-}
-
-// Overload of DeserializeObject() for BufferWrapper types.
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(
- BufferWrapper<std::vector<T, Allocator>>* value, MessageReader* reader,
- const void*& start, const void*& end) {
- const auto value_type_size =
- sizeof(typename BufferWrapper<std::vector<T, Allocator>>::value_type);
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeBinType(&encoding, &size, reader, start, end))
- return error;
-
- // Try to resize the BufferWrapper to the size of the payload.
- value->resize(size / value_type_size);
-
- if (size > value->size() * value_type_size || size % value_type_size != 0) {
- return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
- } else if (size == 0U) {
- return ErrorCode::NO_ERROR;
- } else {
- return ReadRawData(value->data(), reader, start, end, size);
- }
-}
-template <typename T>
-inline ErrorType DeserializeObject(BufferWrapper<T*>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- const auto value_type_size = sizeof(typename BufferWrapper<T*>::value_type);
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeBinType(&encoding, &size, reader, start, end))
- return error;
-
- // Try to resize the BufferWrapper to the size of the payload.
- value->resize(size / value_type_size);
-
- if (size > value->size() * value_type_size || size % value_type_size != 0) {
- return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
- } else if (size == 0U) {
- return ErrorCode::NO_ERROR;
- } else {
- return ReadRawData(value->data(), reader, start, end, size);
- }
-}
-
-// Deserializes the type code and size for string types.
-inline ErrorType DeserializeStringType(EncodingType* encoding,
- std::size_t* size, MessageReader* reader,
- const void*& start, const void*& end) {
- if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
- return error;
- } else if (IsFixstrEncoding(*encoding)) {
- *size = GetFixstrSize(*encoding);
- return ErrorCode::NO_ERROR;
- } else if (*encoding == ENCODING_TYPE_STR8) {
- return DeserializeValue<std::uint8_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_STR16) {
- return DeserializeValue<std::uint16_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_STR32) {
- return DeserializeValue<std::uint32_t>(size, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_STRING,
- *encoding);
- }
-}
-
-// Overload of DeserializeObject() for std::string types.
-inline ErrorType DeserializeObject(std::string* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeStringType(&encoding, &size, reader, start, end)) {
- return error;
- } else if (size == 0U) {
- value->clear();
- return ErrorCode::NO_ERROR;
- } else {
- value->resize(size);
- return ReadRawData(&(*value)[0], reader, start, end, size);
- }
-}
-
-// Overload of DeserializeObject() for StringWrapper types.
-template <typename T>
-inline ErrorType DeserializeObject(StringWrapper<T>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- const auto value_type_size = sizeof(typename StringWrapper<T>::value_type);
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeStringType(&encoding, &size, reader, start, end))
- return error;
-
- // Try to resize the StringWrapper to the size of the payload
- // string.
- value->resize(size / value_type_size);
-
- if (size > value->length() * value_type_size || size % value_type_size != 0) {
- return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
- } else if (size == 0U) {
- return ErrorCode::NO_ERROR;
- } else {
- return ReadRawData(value->data(), reader, start, end, size);
- }
-}
-
-// Deserializes the type code and size of array types.
-inline ErrorType DeserializeArrayType(EncodingType* encoding, std::size_t* size,
- MessageReader* reader, const void*& start,
- const void*& end) {
- if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
- return error;
- } else if (IsFixarrayEncoding(*encoding)) {
- *size = GetFixarraySize(*encoding);
- return ErrorCode::NO_ERROR;
- } else if (*encoding == ENCODING_TYPE_ARRAY16) {
- return DeserializeValue<std::uint16_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_ARRAY32) {
- return DeserializeValue<std::uint32_t>(size, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_ARRAY,
- *encoding);
- }
-}
-
-// Deserializes the type code and size of map types.
-inline ErrorType DeserializeMapType(EncodingType* encoding, std::size_t* size,
- MessageReader* reader, const void*& start,
- const void*& end) {
- if (const auto error = DeserializeEncoding(encoding, reader, start, end)) {
- return error;
- } else if (IsFixmapEncoding(*encoding)) {
- *size = GetFixmapSize(*encoding);
- return ErrorCode::NO_ERROR;
- } else if (*encoding == ENCODING_TYPE_MAP16) {
- return DeserializeValue<std::uint16_t>(size, reader, start, end);
- } else if (*encoding == ENCODING_TYPE_MAP32) {
- return DeserializeValue<std::uint32_t>(size, reader, start, end);
- } else {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
- *encoding);
- }
-}
-
-// Overload for std::vector types.
-template <typename T, typename Allocator>
-inline ErrorType DeserializeObject(std::vector<T, Allocator>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end))
- return error;
-
- std::vector<T, Allocator> result(size);
- for (std::size_t i = 0; i < size; i++) {
- if (const auto error = DeserializeObject(&result[i], reader, start, end))
- return error;
- }
-
- *value = std::move(result);
- return ErrorCode::NO_ERROR;
-
-// TODO(eieio): Consider the benefits and trade offs of this alternative.
-#if 0
- value->resize(size);
- for (std::size_t i = 0; i < size; i++) {
- if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
- return error;
- }
- return ErrorCode::NO_ERROR;
-#endif
-}
-
-// Deserializes an EmptyVariant value.
-inline ErrorType DeserializeObject(EmptyVariant* /*empty*/,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
-
- if (const auto error = DeserializeEncoding(&encoding, reader, start, end)) {
- return error;
- } else if (encoding != ENCODING_TYPE_NIL) {
- return ErrorType(ErrorCode::UNEXPECTED_ENCODING, ENCODING_CLASS_MAP,
- encoding);
- } else {
- return ErrorCode::NO_ERROR;
- }
-}
-
-// Deserializes a Variant type.
-template <typename... Types>
-inline ErrorType DeserializeObject(Variant<Types...>* variant,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeMapType(&encoding, &size, reader, start, end)) {
- return error;
- }
-
- if (size != 1)
- return ErrorType(ErrorCode::UNEXPECTED_TYPE_SIZE, ENCODING_CLASS_MAP,
- encoding);
-
- std::int32_t type;
- if (const auto error = DeserializeObject(&type, reader, start, end)) {
- return error;
- } else if (type < Variant<Types...>::kEmptyIndex ||
- type >= static_cast<std::int32_t>(sizeof...(Types))) {
- return ErrorCode::INVALID_VARIANT_ELEMENT;
- } else {
- variant->Become(type);
- return variant->Visit([reader, &start, &end](auto&& value) {
- return DeserializeObject(&value, reader, start, end);
- });
- }
-}
-
-// Deserializes map types.
-template <typename MapType>
-inline ErrorType DeserializeMap(MapType* value, MessageReader* reader,
- const void*& start, const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeMapType(&encoding, &size, reader, start, end))
- return error;
-
- MapType result;
- for (std::size_t i = 0; i < size; i++) {
- std::pair<typename MapType::key_type, typename MapType::mapped_type>
- element;
- if (const auto error =
- DeserializeObject(&element.first, reader, start, end))
- return error;
- if (const auto error =
- DeserializeObject(&element.second, reader, start, end))
- return error;
- result.emplace(std::move(element));
- }
-
- *value = std::move(result);
- return ErrorCode::NO_ERROR;
-}
-
-// Overload for std::map types.
-template <typename Key, typename T, typename Compare, typename Allocator>
-inline ErrorType DeserializeObject(std::map<Key, T, Compare, Allocator>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- return DeserializeMap(value, reader, start, end);
-}
-
-// Overload for std::unordered_map types.
-template <typename Key, typename T, typename Hash, typename KeyEqual,
- typename Allocator>
-inline ErrorType DeserializeObject(
- std::unordered_map<Key, T, Hash, KeyEqual, Allocator>* value,
- MessageReader* reader, const void*& start, const void*& end) {
- return DeserializeMap(value, reader, start, end);
-}
-
-// Overload for ArrayWrapper types.
-template <typename T>
-inline ErrorType DeserializeObject(ArrayWrapper<T>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end)) {
- return error;
- }
-
- // Try to resize the wrapper.
- value->resize(size);
-
- // Make sure there is enough space in the ArrayWrapper for the
- // payload.
- if (size > value->capacity())
- return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-
- for (std::size_t i = 0; i < size; i++) {
- if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
- return error;
- }
-
- return ErrorCode::NO_ERROR;
-}
-
-// Overload for std::array types.
-template <typename T, std::size_t Size>
-inline ErrorType DeserializeObject(std::array<T, Size>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end)) {
- return error;
- }
-
- if (size != Size)
- return ErrorCode::INSUFFICIENT_DESTINATION_SIZE;
-
- for (std::size_t i = 0; i < size; i++) {
- if (const auto error = DeserializeObject(&(*value)[i], reader, start, end))
- return error;
- }
-
- return ErrorCode::NO_ERROR;
-}
-
-// Deserializes std::pair types.
-template <typename T, typename U>
-inline ErrorType DeserializeObject(std::pair<T, U>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end)) {
- return error;
- } else if (size != 2) {
- return ErrorCode::UNEXPECTED_TYPE_SIZE;
- } else if (const auto error =
- DeserializeObject(&value->first, reader, start, end)) {
- return error;
- } else if (const auto error =
- DeserializeObject(&value->second, reader, start, end)) {
- return error;
- } else {
- return ErrorCode::NO_ERROR;
- }
-}
-
-// Stops template recursion when the last tuple element is reached.
-template <typename... T>
-inline ErrorType DeserializeTuple(std::tuple<T...>*, MessageReader*,
- const void*&, const void*, Index<0>) {
- return ErrorCode::NO_ERROR;
-}
-
-// Deserializes each element of a tuple recursively.
-template <typename... T, std::size_t index>
-inline ErrorType DeserializeTuple(std::tuple<T...>* tuple,
- MessageReader* reader, const void*& start,
- const void*& end, Index<index>) {
- if (const auto error =
- DeserializeTuple(tuple, reader, start, end, Index<index - 1>()))
- return error;
- else
- return DeserializeObject(&std::get<index - 1>(*tuple), reader, start, end);
-}
-
-// Overload for standard tuple types.
-template <typename... T>
-inline ErrorType DeserializeObject(std::tuple<T...>* value,
- MessageReader* reader, const void*& start,
- const void*& end) {
- EncodingType encoding;
- std::size_t size;
-
- if (const auto error =
- DeserializeArrayType(&encoding, &size, reader, start, end)) {
- return error;
- } else if (size != sizeof...(T)) {
- return ErrorCode::UNEXPECTED_TYPE_SIZE;
- } else {
- return DeserializeTuple(value, reader, start, end, Index<sizeof...(T)>());
- }
-}
-
-// Stops template recursion when the last member of a Serializable type is
-// reached.
-template <typename Members, typename T>
-inline ErrorType DeserializeMember(T*, MessageReader*, const void*&,
- const void*, Index<0>) {
- return ErrorCode::NO_ERROR;
-}
-
-// Deserializes each member of a Serializable type recursively.
-template <typename Members, typename T, std::size_t index>
-inline ErrorType DeserializeMember(T* value, MessageReader* reader,
- const void*& start, const void*& end,
- Index<index>) {
- if (const auto error = DeserializeMember<Members>(value, reader, start, end,
- Index<index - 1>()))
- return error;
- else
- return DeserializeObject(&Members::template At<index - 1>::Resolve(*value),
- reader, start, end);
-}
-
-// Deserializes the members of a Serializable type using the given
-// SerializableMembersType type.
-template <typename Members, typename T>
-inline ErrorType DeserializeMembers(T* value, MessageReader* reader,
- const void*& start, const void*& end) {
- return DeserializeMember<Members>(value, reader, start, end,
- Index<Members::MemberCount>());
-}
-
-// Top level deserialization function.
-template <typename T>
-inline ErrorType Deserialize(T* value, MessageReader* reader) {
- PDX_TRACE_NAME("Deserialize");
- MessageReader::BufferSection section = reader->GetNextReadBufferSection();
- if (section.first == section.second)
- return ErrorCode::INSUFFICIENT_BUFFER;
- ErrorType error =
- DeserializeObject(value, reader, section.first, section.second);
- reader->ConsumeReadBufferSectionData(section.first);
- return error;
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_SERIALIZATION_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h b/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
deleted file mode 100644
index 371ed89..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/string_wrapper.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef ANDROID_PDX_RPC_STRING_WRAPPER_H_
-#define ANDROID_PDX_RPC_STRING_WRAPPER_H_
-
-#include <cstddef>
-#include <cstring>
-#include <string>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Wrapper class for C string buffers, providing an interface suitable for
-// SerializeObject and DeserializeObject. This class serializes to the same
-// format as std::basic_string, and may be substituted for std::basic_string
-// during serialization and deserialization. This substitution makes handling of
-// C strings more efficient by avoiding unnecessary copies when remote method
-// signatures specify std::basic_string arguments or return values.
-template <typename CharT = std::string::value_type,
- typename Traits = std::char_traits<std::remove_cv_t<CharT>>>
-class StringWrapper {
- public:
- // Define types in the style of STL strings to support STL operators.
- typedef Traits traits_type;
- typedef CharT value_type;
- typedef std::size_t size_type;
- typedef value_type& reference;
- typedef const value_type& const_reference;
- typedef value_type* pointer;
- typedef const value_type* const_pointer;
-
- StringWrapper() : buffer_(nullptr), capacity_(0), end_(0) {}
-
- StringWrapper(pointer buffer, size_type capacity, size_type size)
- : buffer_(&buffer[0]),
- capacity_(capacity),
- end_(capacity < size ? capacity : size) {}
-
- StringWrapper(pointer buffer, size_type size)
- : StringWrapper(buffer, size, size) {}
-
- explicit StringWrapper(pointer buffer)
- : StringWrapper(buffer, std::strlen(buffer)) {}
-
- StringWrapper(const StringWrapper& other) { *this = other; }
-
- StringWrapper(StringWrapper&& other) noexcept { *this = std::move(other); }
-
- StringWrapper& operator=(const StringWrapper& other) {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- }
-
- return *this;
- }
-
- StringWrapper& operator=(StringWrapper&& other) noexcept {
- if (&other == this) {
- return *this;
- } else {
- buffer_ = other.buffer_;
- capacity_ = other.capacity_;
- end_ = other.end_;
- other.buffer_ = nullptr;
- other.capacity_ = 0;
- other.end_ = 0;
- }
-
- return *this;
- }
-
- pointer data() { return buffer_; }
- const_pointer data() const { return buffer_; }
-
- pointer begin() { return &buffer_[0]; }
- pointer end() { return &buffer_[end_]; }
- const_pointer begin() const { return &buffer_[0]; }
- const_pointer end() const { return &buffer_[end_]; }
-
- size_type size() const { return end_; }
- size_type length() const { return end_; }
- size_type max_size() const { return capacity_; }
- size_type capacity() const { return capacity_; }
-
- void resize(size_type size) {
- if (size <= capacity_)
- end_ = size;
- else
- end_ = capacity_;
- }
-
- reference operator[](size_type pos) { return buffer_[pos]; }
- const_reference operator[](size_type pos) const { return buffer_[pos]; }
-
- private:
- pointer buffer_;
- size_type capacity_;
- size_type end_;
-};
-
-// Utility functions that infer the underlying type of the string, simplifying
-// the wrapper interface.
-
-// TODO(eieio): Wrapping std::basic_string is here for completeness, but is it
-// useful?
-template <typename T, typename... Any>
-StringWrapper<const T> WrapString(const std::basic_string<T, Any...>& s) {
- return StringWrapper<const T>(s.c_str(), s.length());
-}
-
-template <typename T, typename SizeType = std::size_t>
-StringWrapper<T> WrapString(T* s, SizeType size) {
- return StringWrapper<T>(s, size);
-}
-
-template <typename T>
-StringWrapper<T> WrapString(T* s) {
- return StringWrapper<T>(s);
-}
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_STRING_WRAPPER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h b/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h
deleted file mode 100644
index e5ef2aa..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/thread_local_buffer.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
-#define ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
-
-#include <cstdint>
-#include <memory>
-#include <vector>
-
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Utility class to distinguish between different thread local entries or
-// "slots" in the thread local variable table. Each slot is uniquely identified
-// by (T,Index) and is independent of any other slot.
-template <typename T, std::size_t Index>
-struct ThreadLocalSlot;
-
-// Utility class to specify thread local slots using only a type.
-template <typename T>
-struct ThreadLocalTypeSlot;
-
-// Utility class to specify thread local slots using only an index.
-template <std::size_t Index>
-struct ThreadLocalIndexSlot;
-
-// Initial capacity of thread local buffer, unless otherwise specified.
-constexpr std::size_t InitialBufferCapacity = 4096;
-
-// Thread local slots for buffers used by this library to send, receive, and
-// reply to messages.
-using SendBuffer = ThreadLocalIndexSlot<0>;
-using ReceiveBuffer = ThreadLocalIndexSlot<1>;
-using ReplyBuffer = ThreadLocalIndexSlot<2>;
-
-// Provides a simple interface to thread local buffers for large IPC messages.
-// Slot provides multiple thread local slots for a given T, Allocator, Capacity
-// combination.
-template <typename T, typename Allocator = DefaultInitializationAllocator<T>,
- std::size_t Capacity = InitialBufferCapacity,
- typename Slot = ThreadLocalSlot<void, 0>>
-class ThreadLocalBuffer {
- public:
- using BufferType = std::vector<T, Allocator>;
- using ValueType = T;
-
- // Reserves |capacity| number of elements of capacity in the underlying
- // buffer. Call this during startup to avoid allocation during use.
- static void Reserve(std::size_t capacity) {
- PDX_TRACE_NAME("ThreadLocalBuffer::Reserve");
- InitializeBuffer(capacity);
- buffer_->reserve(capacity);
- }
-
- // Resizes the buffer to |size| elements.
- static void Resize(std::size_t size) {
- PDX_TRACE_NAME("ThreadLocalBuffer::Resize");
- InitializeBuffer(size);
- buffer_->resize(size);
- }
-
- // Gets a reference to the underlying buffer after reserving |capacity|
- // elements. The current size of the buffer is left intact. The returned
- // reference is valid until FreeBuffer() is called.
- static BufferType& GetBuffer(std::size_t capacity = Capacity) {
- PDX_TRACE_NAME("ThreadLocalBuffer::GetBuffer");
- Reserve(capacity);
- return *buffer_;
- }
-
- // Gets a reference to the underlying buffer after reserving |Capacity|
- // elements. The current size of the buffer is set to zero. The returned
- // reference is valid until FreeBuffer() is called.
- static BufferType& GetEmptyBuffer() {
- PDX_TRACE_NAME("ThreadLocalBuffer::GetEmptyBuffer");
- Reserve(Capacity);
- buffer_->clear();
- return *buffer_;
- }
-
- // Gets a reference to the underlying buffer after resizing it to |size|
- // elements. The returned reference is valid until FreeBuffer() is called.
- static BufferType& GetSizedBuffer(std::size_t size = Capacity) {
- PDX_TRACE_NAME("ThreadLocalBuffer::GetSizedBuffer");
- Resize(size);
- return *buffer_;
- }
-
- // Frees the underlying buffer. The buffer will be reallocated if any of the
- // methods above are called.
- static void FreeBuffer() {
- if (buffer_) {
- GetBufferGuard().reset(buffer_ = nullptr);
- }
- }
-
- private:
- friend class ThreadLocalBufferTest;
-
- static void InitializeBuffer(std::size_t capacity) {
- if (!buffer_) {
- GetBufferGuard().reset(buffer_ = new BufferType(capacity));
- }
- }
-
- // Work around performance issues with thread-local dynamic initialization
- // semantics by using a normal pointer in parallel with a std::unique_ptr. The
- // std::unique_ptr is never dereferenced, only assigned, to avoid the high
- // cost of dynamic initialization checks, while still providing automatic
- // cleanup. The normal pointer provides fast access to the buffer object.
- // Never dereference buffer_guard or performance could be severely impacted
- // by slow implementations of TLS dynamic initialization.
- static thread_local BufferType* buffer_;
-
- static std::unique_ptr<BufferType>& GetBufferGuard() {
- PDX_TRACE_NAME("ThreadLocalBuffer::GetBufferGuard");
- static thread_local std::unique_ptr<BufferType> buffer_guard;
- return buffer_guard;
- }
-};
-
-// Instantiation of the static ThreadLocalBuffer::buffer_ member.
-template <typename T, typename Allocator, std::size_t Capacity, typename Slot>
-thread_local
- typename ThreadLocalBuffer<T, Allocator, Capacity, Slot>::BufferType*
- ThreadLocalBuffer<T, Allocator, Capacity, Slot>::buffer_;
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_THREAD_LOCAL_BUFFER_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/type_operators.h b/libs/vr/libpdx/private/pdx/rpc/type_operators.h
deleted file mode 100644
index 811bd87..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/type_operators.h
+++ /dev/null
@@ -1,195 +0,0 @@
-#ifndef ANDROID_PDX_RPC_TYPE_OPERATORS_H_
-#define ANDROID_PDX_RPC_TYPE_OPERATORS_H_
-
-#include <array>
-#include <map>
-#include <type_traits>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <pdx/rpc/copy_cv_reference.h>
-#include <pdx/rpc/pointer_wrapper.h>
-#include <pdx/rpc/string_wrapper.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Simplifies type expressions.
-template <typename T>
-using Decay = typename std::decay<T>::type;
-
-// Compares the underlying type of A and B.
-template <typename A, typename B>
-using IsEquivalent = typename std::is_same<Decay<A>, Decay<B>>::type;
-
-// Logical AND over template parameter pack.
-template <typename... T>
-struct And : std::false_type {};
-template <typename A, typename B>
-struct And<A, B> : std::integral_constant<bool, A::value && B::value> {};
-template <typename A, typename B, typename... Rest>
-struct And<A, B, Rest...> : And<A, And<B, Rest...>> {};
-
-// Determines whether A is convertible to B (serializes to the same format)
-// using these rules:
-// 1. std:vector<T, Any...> is convertible to ArrayWrapper<T>.
-// 2. ArrayWrapper<T> is convertible to std:vector<T, Any...>.
-// 3. std::basic_string<T, Any...> is convertible to StringWrapper<T>.
-// 4. StringWrapper<T> is convertible to std::basic_string<T, Any...>.
-// 5. BufferWrapper<T*> is convertible to BufferWrapper<std::vector<T,
-// Any...>>.
-// 6. BufferWrapper<std::vector<T, ...>> is convertible to BufferWrapper<T*>.
-// 7. The value type T of A and B must match.
-
-// Compares A and B for convertibility. This base type determines convertibility
-// by equivalence of the underlying types of A and B. Specializations of this
-// type handle the rules for which complex types are convertible.
-template <typename A, typename B>
-struct IsConvertible : IsEquivalent<A, B> {};
-
-// Compares TT<A, ...> and TT<B, ...>; these are convertible if A and B are
-// convertible.
-template <template <typename, typename...> class TT, typename A, typename B,
- typename... AnyA, typename... AnyB>
-struct IsConvertible<TT<A, AnyA...>, TT<B, AnyB...>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-
-// Compares TT<KeyA, ValueA, ...> and TT<KeyB, ValueB, ...>; these are
-// convertible if KeyA and KeyB are
-// convertible and ValueA and ValueB are convertible.
-template <template <typename, typename, typename...> class TT, typename KeyA,
- typename ValueA, typename KeyB, typename ValueB, typename... AnyA,
- typename... AnyB>
-struct IsConvertible<TT<KeyA, ValueA, AnyA...>, TT<KeyB, ValueB, AnyB...>>
- : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
- IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-
-// Compares two std::pairs to see if the corresponding elements are convertible.
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::pair<A, B>, std::pair<C, D>>
- : And<IsConvertible<Decay<A>, Decay<C>>,
- IsConvertible<Decay<B>, Decay<D>>> {};
-
-// Compares std::pair with a two-element std::tuple to see if the corresponding
-// elements are convertible.
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::pair<A, B>, std::tuple<C, D>>
- : And<IsConvertible<Decay<A>, Decay<C>>,
- IsConvertible<Decay<B>, Decay<D>>> {};
-template <typename A, typename B, typename C, typename D>
-struct IsConvertible<std::tuple<A, B>, std::pair<C, D>>
- : And<IsConvertible<Decay<A>, Decay<C>>,
- IsConvertible<Decay<B>, Decay<D>>> {};
-
-// Compares two std::tuples to see if the corresponding elements are
-// convertible.
-template <typename... A, typename... B>
-struct IsConvertible<std::tuple<A...>, std::tuple<B...>>
- : And<IsConvertible<Decay<A>, Decay<B>>...> {};
-
-// Compares std::vector, std::array, and ArrayWrapper; these are convertible if
-// the value types are convertible.
-template <typename A, typename B, typename... Any>
-struct IsConvertible<std::vector<A, Any...>, ArrayWrapper<B>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any>
-struct IsConvertible<ArrayWrapper<A>, std::vector<B, Any...>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any, std::size_t Size>
-struct IsConvertible<std::vector<A, Any...>, std::array<B, Size>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, typename... Any, std::size_t Size>
-struct IsConvertible<std::array<A, Size>, std::vector<B, Any...>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, std::size_t Size>
-struct IsConvertible<ArrayWrapper<A>, std::array<B, Size>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-template <typename A, typename B, std::size_t Size>
-struct IsConvertible<std::array<A, Size>, ArrayWrapper<B>>
- : IsConvertible<Decay<A>, Decay<B>> {};
-
-// Compares std::map and std::unordered_map; these are convertible if the keys
-// are convertible and the values are convertible.
-template <typename KeyA, typename ValueA, typename KeyB, typename ValueB,
- typename... AnyA, typename... AnyB>
-struct IsConvertible<std::map<KeyA, ValueA, AnyA...>,
- std::unordered_map<KeyB, ValueB, AnyB...>>
- : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
- IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-template <typename KeyA, typename ValueA, typename KeyB, typename ValueB,
- typename... AnyA, typename... AnyB>
-struct IsConvertible<std::unordered_map<KeyA, ValueA, AnyA...>,
- std::map<KeyB, ValueB, AnyB...>>
- : And<IsConvertible<Decay<KeyA>, Decay<KeyB>>,
- IsConvertible<Decay<ValueA>, Decay<ValueB>>> {};
-
-// Compares BufferWrapper<A*> and BufferWrapper<std::vector<B>>; these are
-// convertible if A and B are equivalent. Allocator types are not relevant to
-// convertibility.
-template <typename A, typename B, typename Allocator>
-struct IsConvertible<BufferWrapper<A*>,
- BufferWrapper<std::vector<B, Allocator>>>
- : IsEquivalent<A, B> {};
-template <typename A, typename B, typename Allocator>
-struct IsConvertible<BufferWrapper<std::vector<A, Allocator>>,
- BufferWrapper<B*>> : IsEquivalent<A, B> {};
-template <typename A, typename B, typename AllocatorA, typename AllocatorB>
-struct IsConvertible<BufferWrapper<std::vector<A, AllocatorA>>,
- BufferWrapper<std::vector<B, AllocatorB>>>
- : IsEquivalent<A, B> {};
-template <typename A, typename B>
-struct IsConvertible<BufferWrapper<A*>, BufferWrapper<B*>>
- : IsEquivalent<A, B> {};
-
-// Compares std::basic_string<A, ...> and StringWrapper<B>; these are
-// convertible if A and B are equivalent.
-template <typename A, typename B, typename... Any>
-struct IsConvertible<std::basic_string<A, Any...>, StringWrapper<B>>
- : IsEquivalent<A, B> {};
-template <typename A, typename B, typename... Any>
-struct IsConvertible<StringWrapper<A>, std::basic_string<B, Any...>>
- : IsEquivalent<A, B> {};
-
-// Compares PointerWrapper<A> and B; these are convertible if A and B are
-// convertible.
-template <typename A, typename B>
-struct IsConvertible<PointerWrapper<A>, B> : IsConvertible<Decay<A>, Decay<B>> {
-};
-template <typename A, typename B>
-struct IsConvertible<A, PointerWrapper<B>> : IsConvertible<Decay<A>, Decay<B>> {
-};
-
-// LocalHandle is convertible to RemoteHandle on the service side. This means
-// that a RemoteHandle may be supplied by a service when the protocol calls for
-// a LocalHandle return value. The other way around is not safe and can leak
-// file descriptors. The ServicePayload class enforces this policy by only
-// supporting RemoteHandle for pushed handles.
-template <>
-struct IsConvertible<LocalHandle, RemoteHandle> : std::true_type {};
-template <>
-struct IsConvertible<LocalHandle, BorrowedHandle> : std::true_type {};
-
-template <>
-struct IsConvertible<LocalChannelHandle, RemoteChannelHandle> : std::true_type {
-};
-template <>
-struct IsConvertible<LocalChannelHandle, BorrowedChannelHandle>
- : std::true_type {};
-
-// Conditionally "rewrites" type A as type B, including cv-reference qualifiers,
-// iff A is convertible to B.
-template <typename A, typename B>
-using ConditionalRewrite =
- typename std::conditional<IsConvertible<Decay<A>, Decay<B>>::value,
- CopyCVReferenceType<A, B>, A>::type;
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_RPC_TYPE_OPERATORS_H_
diff --git a/libs/vr/libpdx/private/pdx/rpc/variant.h b/libs/vr/libpdx/private/pdx/rpc/variant.h
deleted file mode 100644
index a1292b0..0000000
--- a/libs/vr/libpdx/private/pdx/rpc/variant.h
+++ /dev/null
@@ -1,760 +0,0 @@
-#ifndef ANDROID_PDX_RPC_VARIANT_H_
-#define ANDROID_PDX_RPC_VARIANT_H_
-
-#include <cstdint>
-#include <tuple>
-#include <type_traits>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-// Type tag denoting an empty variant.
-struct EmptyVariant {};
-
-namespace detail {
-
-// Type for matching tagged overloads.
-template <typename T>
-struct TypeTag {};
-
-// Determines the type of the I-th element of Types....
-template <std::size_t I, typename... Types>
-using TypeForIndex = std::tuple_element_t<I, std::tuple<Types...>>;
-
-// Determines the type tag for the I-th element of Types....
-template <std::size_t I, typename... Types>
-using TypeTagForIndex = TypeTag<TypeForIndex<I, Types...>>;
-
-// Similar to std::is_constructible except that it evaluates to false for bool
-// construction from pointer types: this helps prevent subtle to bugs caused by
-// assigning values that decay to pointers to Variants with bool elements.
-//
-// Here is an example of the problematic situation this trait avoids:
-//
-// Variant<int, bool> v;
-// const int array[3] = {1, 2, 3};
-// v = array; // This is allowed by regular std::is_constructible.
-//
-template <typename...>
-struct IsConstructible;
-template <typename T, typename U>
-struct IsConstructible<T, U>
- : std::integral_constant<bool,
- std::is_constructible<T, U>::value &&
- !(std::is_same<std::decay_t<T>, bool>::value &&
- std::is_pointer<std::decay_t<U>>::value)> {};
-template <typename T, typename... Args>
-struct IsConstructible<T, Args...> : std::is_constructible<T, Args...> {};
-
-// Enable if T(Args...) is well formed.
-template <typename R, typename T, typename... Args>
-using EnableIfConstructible =
- typename std::enable_if<IsConstructible<T, Args...>::value, R>::type;
-// Enable if T(Args...) is not well formed.
-template <typename R, typename T, typename... Args>
-using EnableIfNotConstructible =
- typename std::enable_if<!IsConstructible<T, Args...>::value, R>::type;
-
-// Determines whether T is an element of Types...;
-template <typename... Types>
-struct HasType : std::false_type {};
-template <typename T, typename U>
-struct HasType<T, U> : std::is_same<std::decay_t<T>, std::decay_t<U>> {};
-template <typename T, typename First, typename... Rest>
-struct HasType<T, First, Rest...>
- : std::integral_constant<bool, HasType<T, First>::value ||
- HasType<T, Rest...>::value> {};
-
-// Defines set operations on a set of Types...
-template <typename... Types>
-struct Set {
- // Default specialization catches the empty set, which is always a subset.
- template <typename...>
- struct IsSubset : std::true_type {};
- template <typename T>
- struct IsSubset<T> : HasType<T, Types...> {};
- template <typename First, typename... Rest>
- struct IsSubset<First, Rest...>
- : std::integral_constant<bool, IsSubset<First>::value &&
- IsSubset<Rest...>::value> {};
-};
-
-// Determines the number of elements of Types... that are constructible from
-// From.
-template <typename... Types>
-struct ConstructibleCount;
-template <typename From, typename To>
-struct ConstructibleCount<From, To>
- : std::integral_constant<std::size_t, IsConstructible<To, From>::value> {};
-template <typename From, typename First, typename... Rest>
-struct ConstructibleCount<From, First, Rest...>
- : std::integral_constant<std::size_t,
- IsConstructible<First, From>::value +
- ConstructibleCount<From, Rest...>::value> {};
-
-// Enable if T is an element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfElement =
- typename std::enable_if<HasType<T, Types...>::value, R>::type;
-// Enable if T is not an element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfNotElement =
- typename std::enable_if<!HasType<T, Types...>::value, R>::type;
-
-// Enable if T is convertible to an element of Types... T is considered
-// convertible IIF a single element of Types... is assignable from T and T is
-// not a direct element of Types...
-template <typename R, typename T, typename... Types>
-using EnableIfConvertible =
- typename std::enable_if<!HasType<T, Types...>::value &&
- ConstructibleCount<T, Types...>::value == 1,
- R>::type;
-
-// Enable if T is assignable to an element of Types... T is considered
-// assignable IFF a single element of Types... is constructible from T or T is a
-// direct element of Types.... Note that T is REQUIRED to be an element of
-// Types... when multiple elements are constructible from T to prevent ambiguity
-// in conversion.
-template <typename R, typename T, typename... Types>
-using EnableIfAssignable =
- typename std::enable_if<HasType<T, Types...>::value ||
- ConstructibleCount<T, Types...>::value == 1,
- R>::type;
-
-// Selects a type for SFINAE constructor selection.
-template <bool CondA, typename SelectA, typename SelectB>
-using Select = std::conditional_t<CondA, SelectA, SelectB>;
-
-// Recursive union type.
-template <typename... Types>
-union Union;
-
-// Specialization handling a singular type, terminating template recursion.
-template <typename Type>
-union Union<Type> {
- Union() {}
- ~Union() {}
-
- template <typename T>
- Union(std::int32_t index, std::int32_t* index_out, TypeTag<Type>, T&& value)
- : first_(std::forward<T>(value)) {
- *index_out = index;
- }
- template <typename T, typename = EnableIfAssignable<void, T, Type>>
- Union(std::int32_t index, std::int32_t* index_out, T&& value)
- : first_(std::forward<T>(value)) {
- *index_out = index;
- }
- Union(const Union& other, std::int32_t index) {
- if (index == 0)
- new (&first_) Type(other.first_);
- }
- Union(Union&& other, std::int32_t index) {
- if (index == 0)
- new (&first_) Type(std::move(other.first_));
- }
- Union(const Union&) = delete;
- Union(Union&&) = delete;
- void operator=(const Union&) = delete;
- void operator=(Union&&) = delete;
-
- Type& get(TypeTag<Type>) { return first_; }
- const Type& get(TypeTag<Type>) const { return first_; }
- EmptyVariant get(TypeTag<EmptyVariant>) const { return {}; }
- constexpr std::int32_t index(TypeTag<Type>) const { return 0; }
-
- template <typename... Args>
- std::int32_t Construct(TypeTag<Type>, Args&&... args) {
- new (&first_) Type(std::forward<Args>(args)...);
- return 0;
- }
- template <typename... Args>
- EnableIfConstructible<std::int32_t, Type, Args...> Construct(Args&&... args) {
- new (&first_) Type(std::forward<Args>(args)...);
- return 0;
- }
-
- void Destruct(std::int32_t target_index) {
- if (target_index == index(TypeTag<Type>{})) {
- (&get(TypeTag<Type>{}))->~Type();
- }
- }
-
- template <typename T>
- bool Assign(TypeTag<Type>, std::int32_t target_index, T&& value) {
- if (target_index == 0) {
- first_ = std::forward<T>(value);
- return true;
- } else {
- return false;
- }
- }
- template <typename T>
- EnableIfConstructible<bool, Type, T> Assign(std::int32_t target_index,
- T&& value) {
- if (target_index == 0) {
- first_ = std::forward<T>(value);
- return true;
- } else {
- return false;
- }
- }
- template <typename T>
- EnableIfNotConstructible<bool, Type, T> Assign(std::int32_t /*target_index*/,
- T&& /*value*/) {
- return false;
- }
-
- template <typename Op>
- decltype(auto) Visit(std::int32_t target_index, Op&& op) {
- if (target_index == index(TypeTag<Type>{}))
- return std::forward<Op>(op)(get(TypeTag<Type>{}));
- else
- return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
- }
- template <typename Op>
- decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
- if (target_index == index(TypeTag<Type>{}))
- return std::forward<Op>(op)(get(TypeTag<Type>{}));
- else
- return std::forward<Op>(op)(get(TypeTag<EmptyVariant>{}));
- }
-
- template <typename... Args>
- bool Become(std::int32_t target_index, Args&&... args) {
- if (target_index == index(TypeTag<Type>{})) {
- Construct(TypeTag<Type>{}, std::forward<Args>(args)...);
- return true;
- } else {
- return false;
- }
- }
-
- private:
- Type first_;
-};
-
-// Specialization that recursively unions types from the paramater pack.
-template <typename First, typename... Rest>
-union Union<First, Rest...> {
- Union() {}
- ~Union() {}
-
- template <typename T>
- Union(std::int32_t index, std::int32_t* index_out, TypeTag<First>, T&& value)
- : first_(std::forward<T>(value)) {
- *index_out = index;
- }
- template <typename T, typename U>
- Union(std::int32_t index, std::int32_t* index_out, TypeTag<T>, U&& value)
- : rest_(index + 1, index_out, TypeTag<T>{}, std::forward<U>(value)) {}
- Union(const Union& other, std::int32_t index) {
- if (index == 0)
- new (&first_) First(other.first_);
- else
- new (&rest_) Union<Rest...>(other.rest_, index - 1);
- }
- Union(Union&& other, std::int32_t index) {
- if (index == 0)
- new (&first_) First(std::move(other.first_));
- else
- new (&rest_) Union<Rest...>(std::move(other.rest_), index - 1);
- }
- Union(const Union&) = delete;
- Union(Union&&) = delete;
- void operator=(const Union&) = delete;
- void operator=(Union&&) = delete;
-
- struct FirstType {};
- struct RestType {};
- template <typename T>
- using SelectConstructor =
- Select<ConstructibleCount<T, First>::value == 1, FirstType, RestType>;
-
- template <typename T>
- Union(std::int32_t index, std::int32_t* index_out, T&& value)
- : Union(index, index_out, std::forward<T>(value),
- SelectConstructor<T>{}) {}
-
- template <typename T>
- Union(std::int32_t index, std::int32_t* index_out, T&& value, FirstType)
- : first_(std::forward<T>(value)) {
- *index_out = index;
- }
- template <typename T>
- Union(std::int32_t index, std::int32_t* index_out, T&& value, RestType)
- : rest_(index + 1, index_out, std::forward<T>(value)) {}
-
- First& get(TypeTag<First>) { return first_; }
- const First& get(TypeTag<First>) const { return first_; }
- constexpr std::int32_t index(TypeTag<First>) const { return 0; }
-
- template <typename T>
- T& get(TypeTag<T>) {
- return rest_.get(TypeTag<T>{});
- }
- template <typename T>
- const T& get(TypeTag<T>) const {
- return rest_.template get(TypeTag<T>{});
- }
- template <typename T>
- constexpr std::int32_t index(TypeTag<T>) const {
- return 1 + rest_.index(TypeTag<T>{});
- }
-
- template <typename... Args>
- std::int32_t Construct(TypeTag<First>, Args&&... args) {
- new (&first_) First(std::forward<Args>(args)...);
- return 0;
- }
- template <typename T, typename... Args>
- std::int32_t Construct(TypeTag<T>, Args&&... args) {
- return 1 +
- rest_.template Construct(TypeTag<T>{}, std::forward<Args>(args)...);
- }
-
- template <typename... Args>
- EnableIfConstructible<std::int32_t, First, Args...> Construct(
- Args&&... args) {
- new (&first_) First(std::forward<Args>(args)...);
- return 0;
- }
- template <typename... Args>
- EnableIfNotConstructible<std::int32_t, First, Args...> Construct(
- Args&&... args) {
- return 1 + rest_.template Construct(std::forward<Args>(args)...);
- }
-
- void Destruct(std::int32_t target_index) {
- if (target_index == index(TypeTag<First>{})) {
- (get(TypeTag<First>{})).~First();
- } else {
- rest_.Destruct(target_index - 1);
- }
- }
-
- template <typename T>
- bool Assign(TypeTag<First>, std::int32_t target_index, T&& value) {
- if (target_index == 0) {
- first_ = std::forward<T>(value);
- return true;
- } else {
- return false;
- }
- }
- template <typename T, typename U>
- bool Assign(TypeTag<T>, std::int32_t target_index, U&& value) {
- return rest_.Assign(TypeTag<T>{}, target_index - 1, std::forward<U>(value));
- }
- template <typename T>
- EnableIfConstructible<bool, First, T> Assign(std::int32_t target_index,
- T&& value) {
- if (target_index == 0) {
- first_ = std::forward<T>(value);
- return true;
- } else {
- return rest_.Assign(target_index - 1, std::forward<T>(value));
- }
- }
- template <typename T>
- EnableIfNotConstructible<bool, First, T> Assign(std::int32_t target_index,
- T&& value) {
- return rest_.Assign(target_index - 1, std::forward<T>(value));
- }
-
- // Recursively traverses the union and calls Op on the active value when the
- // active type is found. If the union is empty Op is called on EmptyVariant.
- // TODO(eieio): This could be refactored into an array or jump table. It's
- // unclear whether this would be more efficient for practical variant arity.
- template <typename Op>
- decltype(auto) Visit(std::int32_t target_index, Op&& op) {
- if (target_index == index(TypeTag<First>{}))
- return std::forward<Op>(op)(get(TypeTag<First>{}));
- else
- return rest_.Visit(target_index - 1, std::forward<Op>(op));
- }
- template <typename Op>
- decltype(auto) Visit(std::int32_t target_index, Op&& op) const {
- if (target_index == index(TypeTag<First>{}))
- return std::forward<Op>(op)(get(TypeTag<First>{}));
- else
- return rest_.Visit(target_index - 1, std::forward<Op>(op));
- }
-
- template <typename... Args>
- bool Become(std::int32_t target_index, Args&&... args) {
- if (target_index == index(TypeTag<First>{})) {
- Construct(TypeTag<First>{}, std::forward<Args>(args)...);
- return true;
- } else {
- return rest_.Become(target_index - 1, std::forward<Args>(args)...);
- }
- }
-
- private:
- First first_;
- Union<Rest...> rest_;
-};
-
-} // namespace detail
-
-// Variant is a type safe union that can store values of any of its element
-// types. A Variant is different than std::tuple in that it only stores one type
-// at a time or a special empty type. Variants are always default constructible
-// to empty, even when none of the element types are default constructible.
-template <typename... Types>
-class Variant {
- private:
- // Convenience types.
- template <typename T>
- using TypeTag = detail::TypeTag<T>;
- template <typename T>
- using DecayedTypeTag = TypeTag<std::decay_t<T>>;
- template <std::size_t I>
- using TypeForIndex = detail::TypeForIndex<I, Types...>;
- template <std::size_t I>
- using TypeTagForIndex = detail::TypeTagForIndex<I, Types...>;
- template <typename T>
- using HasType = detail::HasType<T, Types...>;
- template <typename R, typename T>
- using EnableIfElement = detail::EnableIfElement<R, T, Types...>;
- template <typename R, typename T>
- using EnableIfConvertible = detail::EnableIfConvertible<R, T, Types...>;
- template <typename R, typename T>
- using EnableIfAssignable = detail::EnableIfAssignable<R, T, Types...>;
-
- struct Direct {};
- struct Convert {};
- template <typename T>
- using SelectConstructor = detail::Select<HasType<T>::value, Direct, Convert>;
-
- // Constructs by type tag when T is an direct element of Types...
- template <typename T>
- explicit Variant(T&& value, Direct)
- : value_(0, &index_, DecayedTypeTag<T>{}, std::forward<T>(value)) {}
- // Conversion constructor when T is not a direct element of Types...
- template <typename T>
- explicit Variant(T&& value, Convert)
- : value_(0, &index_, std::forward<T>(value)) {}
-
- public:
- // Variants are default construcible, regardless of whether the elements are
- // default constructible. Default consruction yields an empty Variant.
- Variant() {}
- explicit Variant(EmptyVariant) {}
- ~Variant() { Destruct(); }
-
- Variant(const Variant& other)
- : index_{other.index_}, value_{other.value_, other.index_} {}
- Variant(Variant&& other) noexcept
- : index_{other.index_}, value_{std::move(other.value_), other.index_} {}
-
-// Recent Clang versions has a regression that produces bogus
-// unused-lambda-capture warning. Suppress the warning as a temporary
-// workaround. http://b/71356631
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-lambda-capture"
- // Copy and move construction from Variant types. Each element of OtherTypes
- // must be convertible to an element of Types.
- template <typename... OtherTypes>
- explicit Variant(const Variant<OtherTypes...>& other) {
- other.Visit([this](const auto& value) { Construct(value); });
- }
-#pragma clang diagnostic pop
-
- template <typename... OtherTypes>
- explicit Variant(Variant<OtherTypes...>&& other) {
- other.Visit([this](auto&& value) { Construct(std::move(value)); });
- }
-
- Variant& operator=(const Variant& other) {
- other.Visit([this](const auto& value) { *this = value; });
- return *this;
- }
- Variant& operator=(Variant&& other) noexcept {
- other.Visit([this](auto&& value) { *this = std::move(value); });
- return *this;
- }
-
- // Construction from non-Variant types.
- template <typename T, typename = EnableIfAssignable<void, T>>
- explicit Variant(T&& value)
- : Variant(std::forward<T>(value), SelectConstructor<T>{}) {}
-
- // Performs assignment from type T belonging to Types. This overload takes
- // priority to prevent implicit conversion in cases where T is implicitly
- // convertible to multiple elements of Types.
- template <typename T>
- EnableIfElement<Variant&, T> operator=(T&& value) {
- Assign(DecayedTypeTag<T>{}, std::forward<T>(value));
- return *this;
- }
-
- // Performs assignment from type T not belonging to Types. This overload
- // matches in cases where conversion is the only viable option.
- template <typename T>
- EnableIfConvertible<Variant&, T> operator=(T&& value) {
- Assign(std::forward<T>(value));
- return *this;
- }
-
- // Handles assignment from the empty type. This overload supports assignment
- // in visitors using generic lambdas.
- Variant& operator=(EmptyVariant) {
- Destruct();
- return *this;
- }
-
- // Assignment from Variant types. Each element of OtherTypes must be
- // convertible to an element of Types. Forwards through non-Variant assignment
- // operators to apply conversion checks.
- template <typename... OtherTypes>
- Variant& operator=(const Variant<OtherTypes...>& other) {
- other.Visit([this](const auto& value) { *this = value; });
- return *this;
- }
- template <typename... OtherTypes>
- Variant& operator=(Variant<OtherTypes...>&& other) {
- other.Visit([this](auto&& value) { *this = std::move(value); });
- return *this;
- }
-
- // Becomes the target type, constructing a new element from the given
- // arguments if necessary. No action is taken if the active element is already
- // the target type. Otherwise the active element is destroyed and replaced by
- // constructing an element of the new type using |Args|. An invalid target
- // type index results in an empty Variant.
- template <typename... Args>
- void Become(std::int32_t target_index, Args&&... args) {
- if (target_index != index()) {
- Destruct();
- index_ = value_.Become(target_index, std::forward<Args>(args)...)
- ? target_index
- : kEmptyIndex;
- }
- }
-
- // Invokes |Op| on the active element. If the Variant is empty |Op| is invoked
- // on EmptyVariant.
- template <typename Op>
- decltype(auto) Visit(Op&& op) {
- return value_.Visit(index_, std::forward<Op>(op));
- }
- template <typename Op>
- decltype(auto) Visit(Op&& op) const {
- return value_.Visit(index_, std::forward<Op>(op));
- }
-
- // Index returned when the Variant is empty.
- enum : std::int32_t { kEmptyIndex = -1 };
-
- // Returns the index of the given type.
- template <typename T>
- constexpr std::int32_t index_of() const {
- static_assert(HasType<T>::value, "T is not an element type of Variant.");
- return value_.index(DecayedTypeTag<T>{});
- }
-
- // Returns the index of the active type. If the Variant is empty -1 is
- // returned.
- std::int32_t index() const { return index_; }
-
- // Returns true if the given type is active, false otherwise.
- template <typename T>
- bool is() const {
- static_assert(HasType<T>::value, "T is not an element type of Variant.");
- return index() == index_of<T>();
- }
-
- // Returns true if the Variant is empty, false otherwise.
- bool empty() const { return index() == kEmptyIndex; }
-
- // Element accessors. Returns a pointer to the active value if the given
- // type/index is active, otherwise nullptr is returned.
- template <typename T>
- T* get() {
- if (is<T>())
- return &value_.get(DecayedTypeTag<T>{});
- else
- return nullptr;
- }
- template <typename T>
- const T* get() const {
- if (is<T>())
- return &value_.template get(DecayedTypeTag<T>{});
- else
- return nullptr;
- }
- template <std::size_t I>
- TypeForIndex<I>* get() {
- if (is<TypeForIndex<I>>())
- return &value_.get(TypeTagForIndex<I>{});
- else
- return nullptr;
- }
- template <std::size_t I>
- const TypeForIndex<I>* get() const {
- if (is<TypeForIndex<I>>())
- return &value_.template get(TypeTagForIndex<I>{});
- else
- return nullptr;
- }
-
- private:
- std::int32_t index_ = kEmptyIndex;
- detail::Union<std::decay_t<Types>...> value_;
-
- // Constructs an element from the given arguments and sets the Variant to the
- // resulting type.
- template <typename... Args>
- void Construct(Args&&... args) {
- index_ = value_.template Construct(std::forward<Args>(args)...);
- }
- void Construct(EmptyVariant) {}
-
- // Destroys the active element of the Variant.
- void Destruct() {
- value_.Destruct(index_);
- index_ = kEmptyIndex;
- }
-
- // Assigns the Variant when non-empty and the current type matches the target
- // type, otherwise destroys the current value and constructs a element of the
- // new type. Tagged assignment is used when T is an element of the Variant to
- // prevent implicit conversion in cases where T is implicitly convertible to
- // multiple element types.
- template <typename T, typename U>
- void Assign(TypeTag<T>, U&& value) {
- if (!value_.template Assign(TypeTag<T>{}, index_, std::forward<U>(value))) {
- Destruct();
- Construct(TypeTag<T>{}, std::forward<U>(value));
- }
- }
- template <typename T>
- void Assign(T&& value) {
- if (!value_.template Assign(index_, std::forward<T>(value))) {
- Destruct();
- Construct(std::forward<T>(value));
- }
- }
-};
-
-// Utility type to extract/convert values from a variant. This class simplifies
-// conditional logic to get/move/swap/action values from a variant when one or
-// more elements are compatible with the destination type.
-//
-// Example:
-// Variant<int, bool, std::string> v(10);
-// bool bool_value;
-// if (IfAnyOf<int, bool>::Get(v, &bool_value)) {
-// DoSomething(bool_value);
-// } else {
-// HandleInvalidType();
-// }
-// IfAnyOf<int>::Call(v, [](const auto& value) { DoSomething(value); });
-//
-template <typename... ValidTypes>
-struct IfAnyOf {
- // Calls Op on the underlying value of the variant and returns true when the
- // variant is a valid type, otherwise does nothing and returns false.
- template <typename Op, typename... Types>
- static bool Call(Variant<Types...>* variant, Op&& op) {
- static_assert(
- detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
- "ValidTypes may only contain element types from the Variant.");
- return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
- }
- template <typename Op, typename... Types>
- static bool Call(const Variant<Types...>* variant, Op&& op) {
- static_assert(
- detail::Set<Types...>::template IsSubset<ValidTypes...>::value,
- "ValidTypes may only contain element types from the Variant.");
- return variant->Visit(CallOp<Op>{std::forward<Op>(op)});
- }
-
- // Gets/converts the underlying value of the variant to type T and returns
- // true when the variant is a valid type, otherwise does nothing and returns
- // false.
- template <typename T, typename... Types>
- static bool Get(const Variant<Types...>* variant, T* value_out) {
- return Call(variant,
- [value_out](const auto& value) { *value_out = value; });
- }
-
- // Moves the underlying value of the variant and returns true when the variant
- // is a valid type, otherwise does nothing and returns false.
- template <typename T, typename... Types>
- static bool Take(Variant<Types...>* variant, T* value_out) {
- return Call(variant,
- [value_out](auto&& value) { *value_out = std::move(value); });
- }
-
- // Swaps the underlying value of the variant with |*value_out| and returns
- // true when the variant is a valid type, otherwise does nothing and returns
- // false.
- template <typename T, typename... Types>
- static bool Swap(Variant<Types...>* variant, T* value_out) {
- return Call(variant,
- [value_out](auto&& value) { std::swap(*value_out, value); });
- }
-
- private:
- template <typename Op>
- struct CallOp {
- Op&& op;
- template <typename U>
- detail::EnableIfNotElement<bool, U, ValidTypes...> operator()(U&&) {
- return false;
- }
- template <typename U>
- detail::EnableIfElement<bool, U, ValidTypes...> operator()(const U& value) {
- std::forward<Op>(op)(value);
- return true;
- }
- template <typename U>
- detail::EnableIfElement<bool, U, ValidTypes...> operator()(U&& value) {
- std::forward<Op>(op)(std::forward<U>(value));
- return true;
- }
- };
-};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-// Overloads of std::get<T> and std::get<I> for android::pdx::rpc::Variant.
-namespace std {
-
-template <typename T, typename... Types>
-inline T& get(::android::pdx::rpc::Variant<Types...>& v) {
- return *v.template get<T>();
-}
-template <typename T, typename... Types>
-inline T&& get(::android::pdx::rpc::Variant<Types...>&& v) {
- return std::move(*v.template get<T>());
-}
-template <typename T, typename... Types>
-inline const T& get(const ::android::pdx::rpc::Variant<Types...>& v) {
- return *v.template get<T>();
-}
-template <std::size_t I, typename... Types>
-inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
- ::android::pdx::rpc::Variant<Types...>& v) {
- return *v.template get<I>();
-}
-template <std::size_t I, typename... Types>
-inline ::android::pdx::rpc::detail::TypeForIndex<I, Types...>&& get(
- ::android::pdx::rpc::Variant<Types...>&& v) {
- return std::move(*v.template get<I>());
-}
-template <std::size_t I, typename... Types>
-inline const ::android::pdx::rpc::detail::TypeForIndex<I, Types...>& get(
- const ::android::pdx::rpc::Variant<Types...>& v) {
- return *v.template get<I>();
-}
-
-} // namespace std
-
-#endif // ANDROID_PDX_RPC_VARIANT_H_
diff --git a/libs/vr/libpdx/private/pdx/service.h b/libs/vr/libpdx/private/pdx/service.h
deleted file mode 100644
index f5a2d5e..0000000
--- a/libs/vr/libpdx/private/pdx/service.h
+++ /dev/null
@@ -1,759 +0,0 @@
-#ifndef ANDROID_PDX_SERVICE_H_
-#define ANDROID_PDX_SERVICE_H_
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "pdx/channel_handle.h"
-#include "pdx/file_handle.h"
-#include "pdx/message_reader.h"
-#include "pdx/message_writer.h"
-#include "pdx/service_endpoint.h"
-
-namespace android {
-namespace pdx {
-
-class Service;
-
-namespace opcodes {
-
-/*
- * Reserved message opcodes used by libpdx. The reserved opcodes start at the
- * max positive signed integer for the system and go down.
- * In contrast, service opcodes start at zero and go up. This scheme leaves
- * most of the positive integer space for services, a tiny fraction of the
- * positive integer space for the framework, and the entire negative integer
- * space for the kernel.
- */
-#define PDX_OPCODE(name, n) name = ((-1U >> 1) - (n)) // 0x7fff..ffff - n
-
-enum {
- // System message sent when a new client channel is open.
- CHANNEL_OPEN = -1,
- // System message sent when a channel is closed.
- CHANNEL_CLOSE = -2,
- // Request the service to reload system properties.
- PDX_OPCODE(REPORT_SYSPROP_CHANGE, 0),
- // Request the service to dump state and return it in a text buffer.
- PDX_OPCODE(DUMP_STATE, 1),
-};
-
-} // namespace opcodes
-
-/*
- * Base class of service-side per-channel context classes.
- */
-class Channel : public std::enable_shared_from_this<Channel> {
- public:
- Channel() {}
- virtual ~Channel() {}
-
- /*
- * Accessors to the pid of the last active client.
- */
- pid_t GetActiveProcessId() const { return client_pid_; }
- void SetActiveProcessId(pid_t pid) { client_pid_ = pid; }
-
- /*
- * Utility to get a shared_ptr reference from the channel context pointer.
- */
- static std::shared_ptr<Channel> GetFromMessageInfo(const MessageInfo& info);
-
- private:
- pid_t client_pid_ = 0;
-};
-
-/*
- * Message class represents an RPC message, and implicitly the blocked sender
- * waiting for a response. Every message should get a reply, at some point
- * (unless the endpoint is closed), to prevent clients from blocking
- * indefinitely. In order to enforce this and prevent leaking message ids,
- * Message automatically replies with an error to the client on destruction,
- * unless one of two things happens:
- *
- * 1. The service calls one of the reply methods before the Message is
- * destroyed.
- * 2. The responsibility for the message is moved to another instance of
- * Message, using either move construction or move assignment.
- *
- * The second case is useful for services that need to delay responding to a
- * sender until a later time. In this situation the service can move the
- * Message to another instance in a suitable data structure for later use. The
- * moved-to Message then takes on the same behavior and responsibilities
- * described above.
- */
-class Message : public OutputResourceMapper, public InputResourceMapper {
- public:
- Message();
- explicit Message(const MessageInfo& info);
- ~Message();
-
- /*
- * Message objects support move construction and assignment.
- */
- Message(Message&& other) noexcept;
- Message& operator=(Message&& other) noexcept;
-
- /*
- * Read/write payload, in either single buffer or iovec form.
- */
- Status<size_t> ReadVector(const iovec* vector, size_t vector_length);
- Status<size_t> Read(void* buffer, size_t length);
- Status<size_t> WriteVector(const iovec* vector, size_t vector_length);
- Status<size_t> Write(const void* buffer, size_t length);
-
- template <size_t N>
- inline Status<size_t> ReadVector(const iovec (&vector)[N]) {
- return ReadVector(vector, N);
- }
-
- template <size_t N>
- inline Status<size_t> WriteVector(const iovec (&vector)[N]) {
- return WriteVector(vector, N);
- }
-
- // Helper functions to read/write all requested bytes, and return EIO if not
- // all were read/written.
- Status<void> ReadVectorAll(const iovec* vector, size_t vector_length);
- Status<void> WriteVectorAll(const iovec* vector, size_t vector_length);
-
- inline Status<void> ReadAll(void* buffer, size_t length) {
- Status<size_t> status = Read(buffer, length);
- if (status && status.get() < length)
- status.SetError(EIO);
- Status<void> ret;
- ret.PropagateError(status);
- return ret;
- }
- inline Status<void> WriteAll(const void* buffer, size_t length) {
- Status<size_t> status = Write(buffer, length);
- if (status && status.get() < length)
- status.SetError(EIO);
- Status<void> ret;
- ret.PropagateError(status);
- return ret;
- }
-
- template <size_t N>
- inline Status<void> ReadVectorAll(const iovec (&vector)[N]) {
- return ReadVectorAll(vector, N);
- }
-
- template <size_t N>
- inline Status<void> WriteVectorAll(const iovec (&vector)[N]) {
- return WriteVectorAll(vector, N);
- }
-
- // OutputResourceMapper
- Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
- Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
- Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) override;
-
- // InputResourceMapper
- bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
- bool GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) override;
-
- /*
- * Various ways to reply to a message.
- */
- Status<void> Reply(int return_code);
- Status<void> ReplyError(unsigned int error);
- Status<void> ReplyFileDescriptor(unsigned int fd);
- Status<void> Reply(const LocalHandle& handle);
- Status<void> Reply(const BorrowedHandle& handle);
- Status<void> Reply(const RemoteHandle& handle);
- Status<void> Reply(const LocalChannelHandle& handle);
- Status<void> Reply(const BorrowedChannelHandle& handle);
- Status<void> Reply(const RemoteChannelHandle& handle);
-
- template <typename T>
- inline Status<void> Reply(const Status<T>& status) {
- return status ? Reply(status.get()) : ReplyError(status.error());
- }
-
- inline Status<void> Reply(const Status<void>& status) {
- return status ? Reply(0) : ReplyError(status.error());
- }
-
- /*
- * Update the channel event bits with the given clear and set masks.
- */
- Status<void> ModifyChannelEvents(int clear_mask, int set_mask);
-
- /*
- * Create a new channel and push it as a file descriptor to the client. See
- * Service::PushChannel() for a detail description of this method's operation.
- */
- Status<RemoteChannelHandle> PushChannel(
- int flags, const std::shared_ptr<Channel>& channel, int* channel_id);
-
- /*
- * Create a new channel and push it as a file descriptor to the client. See
- * Service::PushChannel() for a detail description of this method's operation.
- */
- Status<RemoteChannelHandle> PushChannel(
- Service* service, int flags, const std::shared_ptr<Channel>& channel,
- int* channel_id);
-
- /*
- * Check whether the |ref| is a reference to channel to this service.
- * If the channel reference in question is valid, the Channel object is
- * returned in |channel| when non-nullptr.
- *
- * Return values:
- * channel_id - id of the channel if the |ref| is a valid reference to
- * this service's channel.
- * Errors:
- * EOPNOTSUPP - the file descriptor is not a channel or is a channel to
- * another service.
- * EBADF - the file descriptor is invalid.
- * FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
- * memory addresses.
- * EINVAL - the value of |ref| is invalid or the message id for this
- * message is no longer valid.
- */
- Status<int> CheckChannel(ChannelReference ref,
- std::shared_ptr<Channel>* channel) const;
-
- /*
- * Overload of CheckChannel() that checks whether the channel reference is for
- * a channel to the service |service|.
- */
- Status<int> CheckChannel(const Service* service, ChannelReference ref,
- std::shared_ptr<Channel>* channel) const;
-
- /*
- * Overload of CheckChannel() that automatically converts to shared pointers
- * to types derived from Channel.
- */
- template <class C>
- Status<int> CheckChannel(ChannelReference ref,
- std::shared_ptr<C>* channel) const {
- std::shared_ptr<Channel> base_pointer;
- const Status<int> ret =
- CheckChannel(ref, channel ? &base_pointer : nullptr);
- if (channel)
- *channel = std::static_pointer_cast<C>(base_pointer);
- return ret;
- }
-
- template <class C>
- Status<int> CheckChannel(const Service* service, ChannelReference ref,
- std::shared_ptr<C>* channel) const {
- std::shared_ptr<Channel> base_pointer;
- const Status<int> ret =
- CheckChannel(service, ref, channel ? &base_pointer : nullptr);
- if (channel)
- *channel = std::static_pointer_cast<C>(base_pointer);
- return ret;
- }
-
- /*
- * MessageInfo accessors.
- */
- pid_t GetProcessId() const;
- pid_t GetThreadId() const;
- uid_t GetEffectiveUserId() const;
- gid_t GetEffectiveGroupId() const;
- int GetChannelId() const;
- int GetMessageId() const;
- int GetOp() const;
- int GetFlags() const;
- size_t GetSendLength() const;
- size_t GetReceiveLength() const;
- size_t GetFileDescriptorCount() const;
-
- /*
- * Impulses are asynchronous and cannot be replied to. All impulses have this
- * invalid message id.
- */
- enum { IMPULSE_MESSAGE_ID = -1 };
-
- /*
- * Returns true if this Message describes an asynchronous "impulse" message.
- */
- bool IsImpulse() const { return GetMessageId() == IMPULSE_MESSAGE_ID; }
-
- /*
- * Returns a pointer to the impulse payload. Impulses are a maximum of 32
- * bytes in size and the start of the impulse payload is guaranteed to be
- * 8-byte aligned. Use GetSendLength() to determine the payload size.
- */
- const std::uint8_t* ImpulseBegin() const;
-
- /*
- * Returns one byte past the end of the impulse payload, as conventional for
- * STL iterators.
- */
- const std::uint8_t* ImpulseEnd() const;
-
- /*
- * Get/set the Channel object for the channel associated
- * with this message. It is up to the caller to synchronize
- * these in multi-threaded services.
- */
- std::shared_ptr<Channel> GetChannel() const;
- Status<void> SetChannel(const std::shared_ptr<Channel>& channnel);
-
- /*
- * Get the Channel object for the channel associated with this message,
- * automatically converted to the desired subclass of Channel.
- */
- template <class C>
- std::shared_ptr<C> GetChannel() const {
- return std::static_pointer_cast<C>(GetChannel());
- }
-
- /*
- * Gets the service this message was received on. Returns nullptr if the
- * service was destroyed.
- */
- std::shared_ptr<Service> GetService() const;
-
- /*
- * Raw access to the MessageInfo for this message.
- */
- const MessageInfo& GetInfo() const;
-
- bool replied() const { return replied_; }
- bool IsChannelExpired() const { return channel_.expired(); }
- bool IsServiceExpired() const { return service_.expired(); }
-
- /*
- * Returns true if the message is non-empty; that is the message can be
- * replied to using this instance.
- */
- explicit operator bool() const { return !replied_; }
-
- const void* GetState() const { return state_; }
- void* GetState() { return state_; }
-
- private:
- friend class Service;
-
- Message(const Message&) = delete;
- void operator=(const Message&) = delete;
- void Destroy();
-
- std::weak_ptr<Service> service_;
- std::weak_ptr<Channel> channel_;
- MessageInfo info_;
- void* state_{nullptr};
- bool replied_;
-};
-
-// Base class for RPC services.
-class Service : public std::enable_shared_from_this<Service> {
- public:
- Service(const std::string& name, std::unique_ptr<Endpoint> endpoint);
- virtual ~Service();
-
- /*
- * Utility to get a shared_ptr reference from the service context pointer.
- */
- static std::shared_ptr<Service> GetFromMessageInfo(const MessageInfo& info);
-
- /*
- * Returns whether initialization was successful. Subclasses that override
- * this must call this base method and AND the results with their own. This
- * method is not intended to do any initialization work itself, only to
- * signal success or failure.
- */
- virtual bool IsInitialized() const;
-
- /*
- * Called by defaultHandleMessage in response to a CHANNEL_OPEN message.
- * This gives subclasses of Service a convenient hook to create per-channel
- * context in the form of a Channel subclass.
- *
- * The Channel instance returned by this is used to set the channel context
- * pointer for the channel that was just opened.
- */
- virtual std::shared_ptr<Channel> OnChannelOpen(Message& message);
-
- /*
- * Called by defaultHandleMessage in response to a CHANNEL_CLOSE message.
- * This give subclasses of Service a convenient hook to clean up per-channel
- * context.
- */
- virtual void OnChannelClose(Message& message,
- const std::shared_ptr<Channel>& channel);
-
- /*
- * Set the channel context for the given channel. This keeps a reference to
- * the Channel object until the channel is closed or another call replaces
- * the current value.
- */
- Status<void> SetChannel(int channel_id,
- const std::shared_ptr<Channel>& channel);
-
- /*
- * Get the channel context for the given channel id. This method should be
- * used sparingly because of the performance characteristics of the underlying
- * map; it is intended for limited, non-critical path access from outside of
- * message dispatch. In most cases lookup by id should be unnecessary in a
- * properly designed service; Message::GetChannel() should be used instead
- * whenever an operation is in the context of a message.
- *
- * Again, if you lookup a channel context object for a service by id in a
- * message handling path for the same service, you're probably doing something
- * wrong.
- */
- std::shared_ptr<Channel> GetChannel(int channel_id) const;
-
- /*
- * Get a snapshot of the active channels for this service. This is the
- * preferred way to access the set of channels because it avoids potential
- * deadlocks and race conditions that may occur when operating on the channel
- * map directly. However, it is more expensive than direct iteration because
- * of dynamic memory allocation and shared pointer reference costs.
- *
- * Automatically converts returned items to shared pointers of the type
- * std::shared_ptr<C>, where C is the subclass of Channel used by the service.
- */
- template <class C>
- std::vector<std::shared_ptr<C>> GetChannels() const {
- std::lock_guard<std::mutex> autolock(channels_mutex_);
- std::vector<std::shared_ptr<C>> items;
- items.reserve(channels_.size());
-
- for (const auto& pair : channels_) {
- items.push_back(std::static_pointer_cast<C>(pair.second));
- }
-
- return items;
- }
-
- /*
- * Close a channel, signaling the client file object and freeing the channel
- * id. Once closed, the client side of the channel always returns the error
- * ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
- *
- * The internal reference to the Channel instance associated with the channel
- * is removed, which may result in the Channel object being freed.
- *
- * OnChannelClosed is not called in response to this method call.
- */
- Status<void> CloseChannel(int channel_id);
-
- /*
- * Update the event bits for the given channel (given by id), using the
- * given clear and set masks.
- *
- * This is useful for asynchronously signaling events that clients may be
- * waiting for using select/poll/epoll.
- */
- Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask);
-
- /*
- * Create a new channel and push it as a file descriptor to the process
- * sending the |message|. |flags| may be set to O_NONBLOCK and/or
- * O_CLOEXEC to control the initial behavior of the new file descriptor (the
- * sending process may change these later using fcntl()). The internal Channel
- * instance associated with this channel is set to |channel|, which may be
- * nullptr. The new channel id allocated for this channel is returned in
- * |channel_id|, which may also be nullptr if not needed.
- *
- * On success, returns the remote channel handle for the new channel in the
- * sending process' handle space. This MUST be returned to the sender via
- * Message::Reply(), Message::Write(), or Message::WriteVector().
- *
- * On error, returns an errno code describing the cause of the error.
- *
- * Service::OnChannelCreate() is not called in response to the creation of the
- * new channel.
- */
- Status<RemoteChannelHandle> PushChannel(
- Message* message, int flags, const std::shared_ptr<Channel>& channel,
- int* channel_id);
-
- /*
- * Check whether the |ref| is a reference to a channel to this service.
- * If the channel reference in question is valid, the Channel object is
- * returned in |channel| when non-nullptr.
- *
- * Return values:
- * channel_id - id of the channel if the channel reference.
- * Errors:
- * EOPNOTSUPP - the file descriptor is not a channel or is a channel to
- * another service.
- * EBADF - the file descriptor is invalid.
- * FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
- * memory addresses.
- * EINVAL - the value of |ref| is invalid or the message id for this
- * message is no longer valid.
- */
- Status<int> CheckChannel(const Message* message, ChannelReference ref,
- std::shared_ptr<Channel>* channel) const;
-
- /*
- * Overload of CheckChannel() that automatically converts to shared pointers
- * of types derived from Channel.
- */
- template <class C>
- Status<int> CheckChannel(const Message* message, ChannelReference ref,
- std::shared_ptr<C>* channel) const {
- std::shared_ptr<Channel> base_pointer;
- const Status<int> ret =
- CheckChannel(message, ref, channel ? &base_pointer : nullptr);
- if (channel)
- *channel = std::static_pointer_cast<C>(base_pointer);
- return ret;
- }
-
- /*
- * Handle a message. Subclasses override this to receive messages and decide
- * how to dispatch them.
- *
- * The default implementation simply calls defaultHandleMessage().
- * Subclasses should call the same for any unrecognized message opcodes.
- */
- virtual Status<void> HandleMessage(Message& message);
-
- /*
- * Handle an asynchronous message. Subclasses override this to receive
- * asynchronous "impulse" messages. Impulses have a limited-size payload that
- * is transferred upfront with the message description.
- */
- virtual void HandleImpulse(Message& impulse);
-
- /*
- * The default message handler. It is important that all messages
- * (eventually) get a reply. This method should be called by subclasses for
- * any unrecognized opcodes or otherwise unhandled messages to prevent
- * erroneous requests from blocking indefinitely.
- *
- * Provides default handling of CHANNEL_OPEN and CHANNEL_CLOSE, calling
- * OnChannelOpen() and OnChannelClose(), respectively.
- *
- * For all other message opcodes, this method replies with ENOTSUP.
- */
- Status<void> DefaultHandleMessage(Message& message);
-
- /*
- * Called when system properties have changed. Subclasses should implement
- * this method if they need to handle when system properties change.
- */
- virtual void OnSysPropChange();
-
- /*
- * Get the endpoint for the service.
- */
- Endpoint* endpoint() const { return endpoint_.get(); }
-
- /*
- * Cancels the endpoint, unblocking any receiver threads waiting in
- * ReceiveAndDispatch().
- */
- Status<void> Cancel();
-
- /*
- * Iterator type for Channel map iterators.
- */
- using ChannelIterator =
- std::unordered_map<int, std::shared_ptr<Channel>>::iterator;
-
- /*
- * Iterates over the Channel map and performs the action given by |action| on
- * each channel map item (const ChannelIterator::value_type).
- * |channels_mutex_| is not held; it is the responsibility of the caller to
- * ensure serialization between threads that modify or iterate over the
- * Channel map.
- */
- template <class A>
- void ForEachChannelUnlocked(A action) const {
- std::for_each(channels_.begin(), channels_.end(), action);
- }
-
- /*
- * Iterates over the Channel map and performs the action given by |action| on
- * each channel map item (const ChannelIterator::value_type).
- * |channels_mutex_| is held to serialize access to the map; care must be
- * taken to avoid recursively acquiring the mutex, for example, by calling
- * Service::{GetChannel,SetChannel,CloseChannel,PushChannel}() or
- * Message::SetChannel() in the action.
- */
- template <class A>
- void ForEachChannel(A action) const {
- std::lock_guard<std::mutex> autolock(channels_mutex_);
- ForEachChannelUnlocked(action);
- }
-
- /*
- * Return true if a channel with the given ID exists in the Channel map.
- */
- bool HasChannelId(int channel_id) const {
- std::lock_guard<std::mutex> autolock(channels_mutex_);
- return channels_.find(channel_id) != channels_.end();
- }
-
- /*
- * Subclasses of Service may override this method to provide a text string
- * describing the state of the service. This method is called by
- * HandleSystemMessage in response to the standard
- * DUMP_STATE message. The string returned to the dump state client is
- * truncated to |max_length| and reflects the maximum size the client can
- * handle.
- */
- virtual std::string DumpState(size_t max_length);
-
- /*
- * Receives a message on this Service instance's endpoint and dispatches it.
- * If the endpoint is in blocking mode this call blocks until a message is
- * received, a signal is delivered to this thread, or the service is canceled.
- * If the endpoint is in non-blocking mode and a message is not pending this
- * call returns immediately with ETIMEDOUT.
- */
- Status<void> ReceiveAndDispatch();
-
- private:
- friend class Message;
-
- Status<void> HandleSystemMessage(Message& message);
-
- Service(const Service&);
- void operator=(const Service&) = delete;
-
- const std::string name_;
- std::unique_ptr<Endpoint> endpoint_;
-
- /*
- * Maintains references to active channels.
- */
- mutable std::mutex channels_mutex_;
- std::unordered_map<int, std::shared_ptr<Channel>> channels_;
-};
-
-/*
- * Utility base class for services. This template handles allocation and
- * initialization checks, reducing boiler plate code.
- */
-template <typename TYPE>
-class ServiceBase : public Service {
- public:
- /*
- * Static service allocation method that check for initialization errors.
- * If errors are encountered these automatically clean up and return
- * nullptr.
- */
- template <typename... Args>
- static inline std::shared_ptr<TYPE> Create(Args&&... args) {
- std::shared_ptr<TYPE> service(new TYPE(std::forward<Args>(args)...));
- if (service->IsInitialized())
- return service;
- else
- return nullptr;
- }
-
- protected:
- /*
- * Shorthand for subclasses to refer to this base, particularly
- * to call the base class constructor.
- */
- typedef ServiceBase<TYPE> BASE;
-
- ServiceBase(const std::string& name, std::unique_ptr<Endpoint> endpoint)
- : Service(name, std::move(endpoint)) {}
-};
-
-#ifndef STRINGIFY
-#define STRINGIFY2(s) #s
-#define STRINGIFY(s) STRINGIFY2(s)
-#endif
-
-#define PDX_ERROR_PREFIX "[" __FILE__ ":" STRINGIFY(__LINE__) "]"
-
-/*
- * Macros for replying to messages. Error handling can be tedious;
- * these macros make things a little cleaner.
- */
-#define CHECK_ERROR(cond, error, fmt, ...) \
- do { \
- if ((cond)) { \
- ALOGE(fmt, ##__VA_ARGS__); \
- goto error; \
- } \
- } while (0)
-
-#define REPLY_ERROR(message, error, error_label) \
- do { \
- auto __status = message.ReplyError(error); \
- CHECK_ERROR(!__status, error_label, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
- __status.GetErrorMessage().c_str()); \
- goto error_label; \
- } while (0)
-
-#define REPLY_ERROR_RETURN(message, error, ...) \
- do { \
- auto __status = message.ReplyError(error); \
- ALOGE_IF(!__status, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
- __status.GetErrorMessage().c_str()); \
- return __VA_ARGS__; \
- } while (0)
-
-#define REPLY_MESSAGE(message, message_return_code, error_label) \
- do { \
- auto __status = message.Reply(message_return_code); \
- CHECK_ERROR(!__status, error_label, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
- __status.GetErrorMessage().c_str()); \
- goto error_label; \
- } while (0)
-
-#define REPLY_SUCCESS(message, message_return_code, error_label) \
- REPLY_MESSAGE(message, message_return_code, error_label)
-
-#define REPLY_MESSAGE_RETURN(message, message_return_code, ...) \
- do { \
- auto __status = message.Reply(message_return_code); \
- ALOGE_IF(!__status, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
- __status.GetErrorMessage().c_str()); \
- return __VA_ARGS__; \
- } while (0)
-
-#define REPLY_SUCCESS_RETURN(message, message_return_code, ...) \
- REPLY_MESSAGE_RETURN(message, message_return_code, __VA_ARGS__)
-
-#define REPLY_FD(message, push_fd, error_label) \
- do { \
- auto __status = message.ReplyFileDescriptor(push_fd); \
- CHECK_ERROR(!__status, error_label, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
- __status.GetErrorMessage().c_str()); \
- goto error_label; \
- } while (0)
-
-#define REPLY_FD_RETURN(message, push_fd, ...) \
- do { \
- auto __status = message.ReplyFileDescriptor(push_fd); \
- ALOGE_IF(__status < 0, \
- PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
- __status.GetErrorMessage().c_str()); \
- return __VA_ARGS__; \
- } while (0)
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_SERVICE_H_
diff --git a/libs/vr/libpdx/private/pdx/service_dispatcher.h b/libs/vr/libpdx/private/pdx/service_dispatcher.h
deleted file mode 100644
index bd27000..0000000
--- a/libs/vr/libpdx/private/pdx/service_dispatcher.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef ANDROID_PDX_SERVICE_DISPATCHER_H_
-#define ANDROID_PDX_SERVICE_DISPATCHER_H_
-
-#include <memory>
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-
-class Service;
-
-/*
- * ServiceDispatcher manages a list of Service instances and handles message
- * reception and dispatch to the services. This makes repetitive dispatch tasks
- * easier to implement.
- */
-class ServiceDispatcher {
- public:
- // Get a new instance of ServiceDispatcher, or return nullptr if init failed.
- static std::unique_ptr<ServiceDispatcher> Create();
-
- ~ServiceDispatcher();
-
- /*
- * Adds a service to the list of services handled by this dispatcher. This
- * will fail if any threads are blocked waiting for messages in this
- * dispatcher.
- *
- * Returns 0 on success; -EEXIST if the service was already added.
- */
- int AddService(const std::shared_ptr<Service>& service);
-
- /*
- * Removes a service from this dispatcher. This will fail if any threads are
- * blocked waiting for messages in this dispatcher.
- *
- * Returns 0 on success; -ENOENT if the service was not previously added;
- * -EBUSY if there are threads in the dispatcher.
- */
- int RemoveService(const std::shared_ptr<Service>& service);
-
- /*
- * Receive and dispatch one set of messages. Multiple threads may enter this
- * method to create an implicit thread pool, as described for
- * enterDispatchLoop() below, however this method exits after one dispatch
- * cycle, requiring an external loop. This is useful when other work needs
- * to be done in the service dispatch loop.
- */
- int ReceiveAndDispatch();
-
- /*
- * Same as above with timeout in milliseconds. A negative value means
- * infinite timeout, while a value of 0 means return immediately if no
- * messages are available to receive.
- */
- int ReceiveAndDispatch(int timeout);
-
- /*
- * Receive and dispatch messages until canceled. When more than one thread
- * enters this method it creates an implicit thread pool to dispatch messages.
- * Explicit thread pools may be created by using a single dispatch thread that
- * hands Message instances (via move assignment) over to a queue of threads
- * (or perhaps one of several) to handle.
- */
- int EnterDispatchLoop();
-
- /*
- * Sets the canceled state of the dispatcher. When canceled is true, any
- * threads blocked waiting for messages will return. This method waits until
- * all dispatch threads have exited the dispatcher.
- */
- void SetCanceled(bool cancel);
-
- /*
- * Gets the canceled state of the dispatcher.
- */
- bool IsCanceled() const;
-
- private:
- ServiceDispatcher();
-
- // Internal thread accounting.
- int ThreadEnter();
- void ThreadExit();
-
- std::mutex mutex_;
- std::condition_variable condition_;
- std::atomic<bool> canceled_{false};
-
- std::vector<std::shared_ptr<Service>> services_;
-
- int thread_count_ = 0;
- LocalHandle event_fd_;
- LocalHandle epoll_fd_;
-
- ServiceDispatcher(const ServiceDispatcher&) = delete;
- void operator=(const ServiceDispatcher&) = delete;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_SERVICE_DISPATCHER_H_
diff --git a/libs/vr/libpdx/private/pdx/service_endpoint.h b/libs/vr/libpdx/private/pdx/service_endpoint.h
deleted file mode 100644
index d581894..0000000
--- a/libs/vr/libpdx/private/pdx/service_endpoint.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_PDX_ENDPOINT_H_
-#define ANDROID_PDX_ENDPOINT_H_
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-struct iovec;
-
-namespace android {
-namespace pdx {
-
-class Service;
-class Channel;
-class Message;
-
-struct MessageInfo {
- int pid{0};
- int tid{0};
- int cid{0};
- int mid{0};
- int euid{0};
- int egid{0};
- int32_t op{0};
- uint32_t flags{0};
- Service* service{nullptr};
- Channel* channel{nullptr};
- size_t send_len{0};
- size_t recv_len{0};
- size_t fd_count{0};
- uint64_t impulse[4] = {};
-};
-
-// Wrapper around transport endpoint. Abstracts the underlying transport APIs in
-// a way, that the underlying IPC can be substituted for another technology
-// without changing the Service, Client and Message classes of this library.
-class Endpoint {
- public:
- virtual ~Endpoint() = default;
-
- // Returns a tag that uniquely identifies a specific underlying IPC transport.
- virtual uint32_t GetIpcTag() const = 0;
-
- // Associates a Service instance with an endpoint by setting the service
- // context pointer to the address of the Service. Only one Service may be
- // associated with a given endpoint.
- virtual Status<void> SetService(Service* service) = 0;
-
- // Set the channel context for the given channel.
- virtual Status<void> SetChannel(int channel_id, Channel* channel) = 0;
-
- // Close a channel, signaling the client file object and freeing the channel
- // id. Once closed, the client side of the channel always returns the error
- // ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
- virtual Status<void> CloseChannel(int channel_id) = 0;
-
- // Update the event bits for the given channel (given by id), using the
- // given clear and set masks.
- virtual Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask) = 0;
-
- // Create a new channel and push it as a file descriptor to the process
- // sending the |message|. |flags| may be set to O_NONBLOCK and/or
- // O_CLOEXEC to control the initial behavior of the new file descriptor (the
- // sending process may change these later using fcntl()). The internal Channel
- // instance associated with this channel is set to |channel|, which may be
- // nullptr. The new channel id allocated for this channel is returned in
- // |channel_id|, which may also be nullptr if not needed.
- virtual Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
- Channel* channel,
- int* channel_id) = 0;
-
- // Check whether the |ref| is a reference to a channel to the service
- // represented by the |endpoint|. If the channel reference in question is
- // valid, the Channel object is returned in |channel| when non-nullptr and
- // the channel ID is returned through the Status object.
- virtual Status<int> CheckChannel(const Message* message, ChannelReference ref,
- Channel** channel) = 0;
-
- // Receives a message on the given endpoint file descriptor.
- virtual Status<void> MessageReceive(Message* message) = 0;
-
- // Replies to the message with a return code.
- virtual Status<void> MessageReply(Message* message, int return_code) = 0;
-
- // Replies to the message with a file descriptor.
- virtual Status<void> MessageReplyFd(Message* message,
- unsigned int push_fd) = 0;
-
- // Replies to the message with a local channel handle.
- virtual Status<void> MessageReplyChannelHandle(
- Message* message, const LocalChannelHandle& handle) = 0;
-
- // Replies to the message with a borrowed local channel handle.
- virtual Status<void> MessageReplyChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) = 0;
-
- // Replies to the message with a remote channel handle.
- virtual Status<void> MessageReplyChannelHandle(
- Message* message, const RemoteChannelHandle& handle) = 0;
-
- // Reads message data into an array of memory buffers.
- virtual Status<size_t> ReadMessageData(Message* message, const iovec* vector,
- size_t vector_length) = 0;
-
- // Sends reply data for message.
- virtual Status<size_t> WriteMessageData(Message* message, const iovec* vector,
- size_t vector_length) = 0;
-
- // Records a file descriptor into the message buffer and returns the remapped
- // reference to be sent to the remote process.
- virtual Status<FileReference> PushFileHandle(Message* message,
- const LocalHandle& handle) = 0;
- virtual Status<FileReference> PushFileHandle(
- Message* message, const BorrowedHandle& handle) = 0;
- virtual Status<FileReference> PushFileHandle(Message* message,
- const RemoteHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- Message* message, const LocalChannelHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) = 0;
- virtual Status<ChannelReference> PushChannelHandle(
- Message* message, const RemoteChannelHandle& handle) = 0;
-
- // Obtains a file descriptor/channel handle from a message for the given
- // reference.
- virtual LocalHandle GetFileHandle(Message* message,
- FileReference ref) const = 0;
- virtual LocalChannelHandle GetChannelHandle(Message* message,
- ChannelReference ref) const = 0;
-
- // Transport-specific message state management.
- virtual void* AllocateMessageState() = 0;
- virtual void FreeMessageState(void* state) = 0;
-
- // Cancels the endpoint, unblocking any receiver threads waiting for a
- // message.
- virtual Status<void> Cancel() = 0;
-
- // Returns an fd that can be used with epoll() to wait for incoming messages
- // from this endpoint.
- virtual int epoll_fd() const = 0;
-};
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_ENDPOINT_H_
diff --git a/libs/vr/libpdx/private/pdx/status.h b/libs/vr/libpdx/private/pdx/status.h
deleted file mode 100644
index 498dd6d..0000000
--- a/libs/vr/libpdx/private/pdx/status.h
+++ /dev/null
@@ -1,183 +0,0 @@
-#ifndef ANDROID_PDX_STATUS_H_
-#define ANDROID_PDX_STATUS_H_
-
-#include <algorithm>
-#include <memory>
-#include <string>
-
-namespace android {
-namespace pdx {
-
-// This is a helper class for constructing Status<T> with an error code.
-struct ErrorStatus {
- public:
- // NOLINTNEXTLINE(google-explicit-constructor)
- ErrorStatus(int error) : error_{error} {}
- int error() const { return error_; }
-
- static std::string ErrorToString(int error_code);
-
- private:
- int error_;
-};
-
-// Status<T> is a container class that can be used to return a value of type T
-// or error code to the caller.
-template <typename T>
-class Status {
- public:
- // Default constructor so an empty Status object can be created.
- Status() : error_{-1} {}
-
- // Value copy/move constructors. These are intentionally not marked as
- // explicit to allow direct value returns from functions without having
- // to explicitly wrap them into Status<T>().
- // NOLINTNEXTLINE(google-explicit-constructor)
- Status(const T& value) : value_{value} {}
- // NOLINTNEXTLINE(google-explicit-constructor)
- Status(T&& value) : value_{std::move(value)} {}
-
- // Constructor for storing an error code inside the Status object.
- // NOLINTNEXTLINE(google-explicit-constructor)
- Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
-
- // Copy/move constructors. Move constructor leaves |other| object in empty
- // state.
- Status(const Status& other) = default;
- Status(Status&& other) noexcept
- : value_{std::move(other.value_)}, error_{other.error_} {
- other.error_ = -1;
- }
-
- // Assignment operators.
- Status& operator=(const Status& other) = default;
- Status& operator=(Status&& other) noexcept {
- error_ = other.error_;
- value_ = std::move(other.value_);
- other.error_ = -1;
- T empty;
- std::swap(other.value_, empty);
- return *this;
- }
-
- // Change the value/error code of the status object directly.
- void SetValue(T value) {
- error_ = 0;
- value_ = std::move(value);
- }
- void SetError(int error) {
- error_ = error;
- T empty;
- std::swap(value_, empty);
- }
-
- // If |other| is in error state, copy the error code to this object.
- // Returns true if error was propagated
- template<typename U>
- bool PropagateError(const Status<U>& other) {
- if (!other.ok() && !other.empty()) {
- SetError(other.error());
- return true;
- }
- return false;
- }
-
- // Returns true if the status object contains valid value for type T.
- // This means, the object is not empty and does not contain an error code.
- bool ok() const { return error_ == 0; }
-
- // Checks if the object is empty (doesn't contain a valid value nor an error).
- bool empty() const { return error_ < 0; }
-
- // Explicit bool conversion, equivalent to invoking ok().
- explicit operator bool() const { return ok(); }
-
- // Accessors for the value stored in Status. Calling when ok() is false leads
- // to undefined behavior.
- const T& get() const { return value_; }
- T&& take() {
- error_ = -1;
- return std::move(value_);
- }
-
- // Returns the error code stored in the object. These codes are positive
- // non-zero values.
- // Can be called only when an error is actually stored (that is, the object
- // is not empty nor containing a valid value).
- int error() const { return std::max(error_, 0); }
-
- // Returns the error code as ErrorStatus object. This is a helper method
- // to aid in propagation of error codes between Status<T> of different types
- // as in the following example:
- // Status<int> foo() {
- // Status<void> status = bar();
- // if(!status)
- // return status.error_status();
- // return 12;
- // }
- inline ErrorStatus error_status() const { return ErrorStatus{error()}; }
-
- // Returns the error message associated with error code stored in the object.
- // The message is the same as the string returned by strerror(status.error()).
- // Can be called only when an error is actually stored (that is, the object
- // is not empty nor containing a valid value).
- std::string GetErrorMessage() const {
- std::string message;
- if (error_ > 0)
- message = ErrorStatus::ErrorToString(error_);
- return message;
- }
-
- private:
- T value_{};
- int error_{0};
-};
-
-// Specialization for status containing no other value but the error code.
-template <>
-class Status<void> {
- public:
- Status() = default;
- // NOLINTNEXTLINE(google-explicit-constructor)
- Status(const ErrorStatus& error_status) : error_{error_status.error()} {}
- void SetValue() { error_ = 0; }
- void SetError(int error) { error_ = error; }
-
- template<typename U>
- bool PropagateError(const Status<U>& other) {
- if (!other.ok() && !other.empty()) {
- SetError(other.error());
- return true;
- }
- return false;
- }
-
- bool ok() const { return error_ == 0; }
- bool empty() const { return false; }
- explicit operator bool() const { return ok(); }
- int error() const { return std::max(error_, 0); }
- inline ErrorStatus error_status() const { return ErrorStatus{error()}; }
- std::string GetErrorMessage() const {
- std::string message;
- if (error_ > 0)
- message = ErrorStatus::ErrorToString(error_);
- return message;
- }
-
- private:
- int error_{0};
-};
-
-// TODO(avakulenko): Remove these function once all callers of it are gone.
-inline int ReturnStatusOrError(const Status<void>& status) {
- return status ? 0 : -status.error();
-}
-
-inline int ReturnStatusOrError(const Status<int>& status) {
- return status ? status.get() : -status.error();
-}
-
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_STATUS_H_
diff --git a/libs/vr/libpdx/private/pdx/trace.h b/libs/vr/libpdx/private/pdx/trace.h
deleted file mode 100644
index c687fd6..0000000
--- a/libs/vr/libpdx/private/pdx/trace.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_PDX_TRACE_H_
-#define ANDROID_PDX_TRACE_H_
-
-#include <array>
-
-#include <utils/Trace.h>
-
-// Enables internal tracing in libpdx. This is disabled by default to avoid
-// spamming the trace buffers during normal trace activities. libpdx must be
-// built with this set to true to enable internal tracing.
-#ifndef PDX_LIB_TRACE_ENABLED
-#define PDX_LIB_TRACE_ENABLED false
-#endif
-
-namespace android {
-namespace pdx {
-
-// Utility to generate scoped tracers with arguments.
-class ScopedTraceArgs {
- public:
- template <typename... Args>
- ScopedTraceArgs(uint64_t tag, const char* format, Args&&... args)
- : tag_{tag} {
- if (atrace_is_tag_enabled(tag_)) {
- std::array<char, 1024> buffer;
- snprintf(buffer.data(), buffer.size(), format,
- std::forward<Args>(args)...);
- atrace_begin(tag_, buffer.data());
- }
- }
-
- ~ScopedTraceArgs() { atrace_end(tag_); }
-
- private:
- uint64_t tag_;
-
- ScopedTraceArgs(const ScopedTraceArgs&) = delete;
- void operator=(const ScopedTraceArgs&) = delete;
-};
-
-// Utility to generate scoped tracers.
-class ScopedTrace {
- public:
- template <typename... Args>
- ScopedTrace(uint64_t tag, bool enabled, const char* name)
- : tag_{tag}, enabled_{enabled} {
- if (enabled_)
- atrace_begin(tag_, name);
- }
-
- ~ScopedTrace() {
- if (enabled_)
- atrace_end(tag_);
- }
-
- private:
- uint64_t tag_;
- bool enabled_;
-
- ScopedTrace(const ScopedTrace&) = delete;
- void operator=(const ScopedTrace&) = delete;
-};
-
-} // namespace pdx
-} // namespace android
-
-// Macro to define a scoped tracer with arguments. Uses PASTE(x, y) macro
-// defined in utils/Trace.h.
-#define PDX_TRACE_FORMAT(format, ...) \
- ::android::pdx::ScopedTraceArgs PASTE(__tracer, __LINE__) { \
- ATRACE_TAG, format, ##__VA_ARGS__ \
- }
-
-// TODO(eieio): Rename this to PDX_LIB_TRACE_NAME() for internal use by libpdx
-// and rename internal uses inside the library. This version is only enabled
-// when PDX_LIB_TRACE_ENABLED is true.
-#define PDX_TRACE_NAME(name) \
- ::android::pdx::ScopedTrace PASTE(__tracer, __LINE__) { \
- ATRACE_TAG, PDX_LIB_TRACE_ENABLED, name \
- }
-
-#endif // ANDROID_PDX_TRACE_H_
diff --git a/libs/vr/libpdx/private/pdx/utility.h b/libs/vr/libpdx/private/pdx/utility.h
deleted file mode 100644
index c9a0c21..0000000
--- a/libs/vr/libpdx/private/pdx/utility.h
+++ /dev/null
@@ -1,369 +0,0 @@
-#ifndef ANDROID_PDX_UTILITY_H_
-#define ANDROID_PDX_UTILITY_H_
-
-#include <cstdint>
-#include <cstdlib>
-#include <iterator>
-
-#include <pdx/rpc/sequence.h>
-
-// Utilities for testing object serialization.
-
-namespace android {
-namespace pdx {
-
-class ByteBuffer {
- public:
- using iterator = uint8_t*;
- using const_iterator = const uint8_t*;
- using size_type = size_t;
-
- ByteBuffer() = default;
- ByteBuffer(const ByteBuffer& other) {
- resize(other.size());
- if (other.size())
- memcpy(data_, other.data(), other.size());
- }
- ~ByteBuffer() { std::free(data_); }
-
- ByteBuffer& operator=(const ByteBuffer& other) {
- resize(other.size());
- if (other.size())
- memcpy(data_, other.data(), other.size());
- return *this;
- }
-
- ByteBuffer& operator=(ByteBuffer&& other) noexcept {
- std::swap(data_, other.data_);
- std::swap(size_, other.size_);
- std::swap(capacity_, other.capacity_);
- other.clear();
- return *this;
- }
-
- inline const uint8_t* data() const { return data_; }
- inline uint8_t* data() { return data_; }
- inline size_t size() const { return size_; }
- inline size_t capacity() const { return capacity_; }
-
- iterator begin() { return data_; }
- const_iterator begin() const { return data_; }
- iterator end() { return data_ + size_; }
- const_iterator end() const { return data_ + size_; }
-
- inline bool operator==(const ByteBuffer& other) const {
- return size_ == other.size_ &&
- (size_ == 0 || memcmp(data_, other.data_, size_) == 0);
- }
-
- inline bool operator!=(const ByteBuffer& other) const {
- return !operator==(other);
- }
-
- inline void reserve(size_t size) {
- if (size <= capacity_)
- return;
- // Find next power of 2 (assuming the size is 32 bits for now).
- size--;
- size |= size >> 1;
- size |= size >> 2;
- size |= size >> 4;
- size |= size >> 8;
- size |= size >> 16;
- size++;
- void* new_data = data_ ? std::realloc(data_, size) : std::malloc(size);
- // TODO(avakulenko): Check for allocation failures.
- data_ = static_cast<uint8_t*>(new_data);
- capacity_ = size;
- }
-
- inline void resize(size_t size) {
- reserve(size);
- size_ = size;
- }
-
- inline uint8_t* grow_by(size_t size_delta) {
- size_t old_size = size_;
- resize(old_size + size_delta);
- return data_ + old_size;
- }
-
- inline void clear() { size_ = 0; }
-
- private:
- uint8_t* data_{nullptr};
- size_t size_{0};
- size_t capacity_{0};
-};
-
-// Utility functions to increment/decrement void pointers to data buffers.
-template <typename OFFSET_T>
-inline const void* AdvancePointer(const void* ptr, OFFSET_T offset) {
- return static_cast<const uint8_t*>(ptr) + offset;
-}
-
-template <typename OFFSET_T>
-inline void* AdvancePointer(void* ptr, OFFSET_T offset) {
- return static_cast<uint8_t*>(ptr) + offset;
-}
-
-inline ptrdiff_t PointerDistance(const void* end, const void* begin) {
- return static_cast<const uint8_t*>(end) - static_cast<const uint8_t*>(begin);
-}
-
-// Utility to build sequences of types.
-template <typename, typename>
-struct AppendTypeSequence;
-
-template <typename T, typename... S, template <typename...> class TT>
-struct AppendTypeSequence<T, TT<S...>> {
- using type = TT<S..., T>;
-};
-
-// Utility to generate repeated types.
-template <typename T, std::size_t N, template <typename...> class TT>
-struct RepeatedType {
- using type = typename AppendTypeSequence<
- T, typename RepeatedType<T, N - 1, TT>::type>::type;
-};
-
-template <typename T, template <typename...> class TT>
-struct RepeatedType<T, 0, TT> {
- using type = TT<>;
-};
-
-template <typename V, typename S>
-inline V ReturnValueHelper(V value, S /*ignore*/) {
- return value;
-}
-
-template <typename R, typename V, size_t... S>
-inline R GetNTupleHelper(V value, rpc::IndexSequence<S...>) {
- return std::make_tuple(ReturnValueHelper(value, S)...);
-}
-
-// Returns an N-tuple of type std::tuple<T,...T> containing |value| in each
-// element.
-template <size_t N, typename T,
- typename R = typename RepeatedType<T, N, std::tuple>::type>
-inline R GetNTuple(T value) {
- return GetNTupleHelper<R>(value, rpc::MakeIndexSequence<N>{});
-}
-
-class NoOpOutputResourceMapper : public OutputResourceMapper {
- public:
- Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
- return handle.Get();
- }
-
- Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
- return handle.Get();
- }
-
- Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
- return handle.Get();
- }
-
- Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) override {
- return handle.value();
- }
-
- Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) override {
- return handle.value();
- }
-
- Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) override {
- return handle.value();
- }
-};
-
-class NoOpInputResourceMapper : public InputResourceMapper {
- public:
- bool GetFileHandle(FileReference ref, LocalHandle* handle) override {
- *handle = LocalHandle{ref};
- return true;
- }
-
- bool GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) override {
- *handle = LocalChannelHandle{nullptr, ref};
- return true;
- }
-};
-
-class NoOpResourceMapper : public NoOpOutputResourceMapper,
- public NoOpInputResourceMapper {};
-
-// Simple implementation of the payload interface, required by
-// Serialize/Deserialize. This is intended for test cases, where compatibility
-// with std::vector is helpful.
-class Payload : public MessageWriter,
- public MessageReader,
- public OutputResourceMapper {
- public:
- using BaseType = ByteBuffer;
- using iterator = typename BaseType::iterator;
- using const_iterator = typename BaseType::const_iterator;
- using size_type = typename BaseType::size_type;
-
- Payload() = default;
- explicit Payload(size_type count, uint8_t value = 0) { Append(count, value); }
- Payload(const Payload& other) : buffer_(other.buffer_) {}
- Payload(const std::initializer_list<uint8_t>& initializer) {
- buffer_.resize(initializer.size());
- std::copy(initializer.begin(), initializer.end(), buffer_.begin());
- }
-
- Payload& operator=(const Payload& other) {
- buffer_ = other.buffer_;
- read_pos_ = 0;
- return *this;
- }
- Payload& operator=(const std::initializer_list<uint8_t>& initializer) {
- buffer_.resize(initializer.size());
- std::copy(initializer.begin(), initializer.end(), buffer_.begin());
- read_pos_ = 0;
- return *this;
- }
-
- // Compares Payload with Payload.
- bool operator==(const Payload& other) const {
- return buffer_ == other.buffer_;
- }
- bool operator!=(const Payload& other) const {
- return buffer_ != other.buffer_;
- }
-
- // Compares Payload with std::vector.
- template <typename Type, typename AllocatorType>
- typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
- operator==(const std::vector<Type, AllocatorType>& other) const {
- return buffer_.size() == other.size() &&
- memcmp(buffer_.data(), other.data(), other.size()) == 0;
- }
- template <typename Type, typename AllocatorType>
- typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
- operator!=(const std::vector<Type, AllocatorType>& other) const {
- return !operator!=(other);
- }
-
- iterator begin() { return buffer_.begin(); }
- const_iterator begin() const { return buffer_.begin(); }
- iterator end() { return buffer_.end(); }
- const_iterator end() const { return buffer_.end(); }
-
- void Append(size_type count, uint8_t value) {
- auto* data = buffer_.grow_by(count);
- std::fill(data, data + count, value);
- }
-
- void Clear() {
- buffer_.clear();
- file_handles_.clear();
- read_pos_ = 0;
- }
-
- void Rewind() { read_pos_ = 0; }
-
- uint8_t* Data() { return buffer_.data(); }
- const uint8_t* Data() const { return buffer_.data(); }
- size_type Size() const { return buffer_.size(); }
-
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override {
- return buffer_.grow_by(size);
- }
-
- OutputResourceMapper* GetOutputResourceMapper() override { return this; }
-
- // OutputResourceMapper
- Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.Get());
- return ref;
- } else {
- return handle.Get();
- }
- }
-
- Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.Get());
- return ref;
- } else {
- return handle.Get();
- }
- }
-
- Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
- return handle.Get();
- }
-
- Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) override {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.value());
- return ref;
- } else {
- return handle.value();
- }
- }
-
- Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) override {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.value());
- return ref;
- } else {
- return handle.value();
- }
- }
-
- Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) override {
- return handle.value();
- }
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override {
- return {buffer_.data() + read_pos_, &*buffer_.end()};
- }
-
- void ConsumeReadBufferSectionData(const void* new_start) override {
- read_pos_ = PointerDistance(new_start, buffer_.data());
- }
-
- InputResourceMapper* GetInputResourceMapper() override {
- return &input_resource_mapper_;
- }
-
- const int* FdArray() const { return file_handles_.data(); }
- std::size_t FdCount() const { return file_handles_.size(); }
-
- private:
- NoOpInputResourceMapper input_resource_mapper_;
- ByteBuffer buffer_;
- std::vector<int> file_handles_;
- size_t read_pos_{0};
-};
-
-} // namespace pdx
-} // namespace android
-
-// Helper macros for branch prediction hinting.
-#ifdef __GNUC__
-#define PDX_LIKELY(x) __builtin_expect(!!(x), true)
-#define PDX_UNLIKELY(x) __builtin_expect(!!(x), false)
-#else
-#define PDX_LIKELY(x) (x)
-#define PDX_UNLIKELY(x) (x)
-#endif
-
-#endif // ANDROID_PDX_UTILITY_H_
diff --git a/libs/vr/libpdx/serialization_tests.cpp b/libs/vr/libpdx/serialization_tests.cpp
deleted file mode 100644
index ee800f6..0000000
--- a/libs/vr/libpdx/serialization_tests.cpp
+++ /dev/null
@@ -1,2505 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/array_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/payload.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <pdx/utility.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-// Tests the serialization/deserialization of all supported types, verifying all
-// reasonable boundary conditions for types with multiple encodings.
-//
-// NOTE: Sometimes this file uses the construct "var = decltype(var)({...})"
-// instead of the equivalent "var = {...}" to construct vectors. This is to
-// prevent clang-format from producing annoyingly vertical code from long
-// initializers.
-
-// TODO(eieio): Automatically generate some of these tests?
-
-namespace {
-
-// Test data for serialization/deserialization of floats.
-const float kZeroFloat = 0.0f;
-const float kOneFloat = 1.0f;
-const auto kZeroFloatBytes = reinterpret_cast<const std::uint8_t*>(&kZeroFloat);
-const auto kOneFloatBytes = reinterpret_cast<const std::uint8_t*>(&kOneFloat);
-const double kZeroDouble = 0.0;
-const double kOneDouble = 1.0;
-const auto kZeroDoubleBytes =
- reinterpret_cast<const std::uint8_t*>(&kZeroDouble);
-const auto kOneDoubleBytes = reinterpret_cast<const std::uint8_t*>(&kOneDouble);
-
-struct TestType {
- enum class Foo { kFoo, kBar, kBaz };
-
- int a;
- float b;
- std::string c;
- Foo d;
-
- TestType() {}
- TestType(int a, float b, const std::string& c, Foo d)
- : a(a), b(b), c(c), d(d) {}
-
- // Make gtest expressions simpler by defining equality operator. This is not
- // needed for serialization.
- bool operator==(const TestType& other) const {
- return a == other.a && b == other.b && c == other.c && d == other.d;
- }
-
- private:
- PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c, d);
-};
-
-template <typename FileHandleType>
-struct TestTemplateType {
- FileHandleType fd;
-
- TestTemplateType() {}
- explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
-
- bool operator==(const TestTemplateType& other) const {
- return fd.Get() == other.fd.Get();
- }
-
- private:
- PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
-};
-
-// Utilities to generate test maps and payloads.
-template <typename MapType>
-MapType MakeMap(std::size_t size) {
- MapType result;
- for (std::size_t i = 0; i < size; i++) {
- result.emplace(i, i);
- }
- return result;
-}
-
-template <typename MapType>
-void InsertKeyValue(MessageWriter* writer, std::size_t size) {
- MapType map;
- for (std::size_t i = 0; i < size; i++) {
- map.emplace(i, i);
- }
- for (const auto& element : map) {
- Serialize(element.first, writer);
- Serialize(element.second, writer);
- }
-}
-
-} // anonymous namespace
-
-TEST(SerializableTypes, Constructor) {
- TestType tt(1, 2.0, "three", TestType::Foo::kBar);
- EXPECT_EQ(1, tt.a);
- EXPECT_EQ(2.0, tt.b);
- EXPECT_EQ("three", tt.c);
- EXPECT_EQ(TestType::Foo::kBar, tt.d);
-}
-
-TEST(SerializationTest, bool) {
- Payload result;
- Payload expected;
- bool value;
-
- // True.
- value = true;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_TRUE};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // False.
- value = false;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FALSE};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, uint8_t) {
- Payload result;
- Payload expected;
- uint8_t value;
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = (1 << 7) - 1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT8.
- value = (1 << 7);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, (1 << 7)};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT8.
- value = 0xff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, uint16_t) {
- Payload result;
- Payload expected;
- uint16_t value;
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = (1 << 7) - 1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT8.
- value = (1 << 7);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, (1 << 7)};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT8.
- value = 0xff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT16.
- value = (1 << 8);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0, 1};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT16.
- value = 0xffff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, uint32_t) {
- Payload result;
- Payload expected;
- uint32_t value;
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = (1 << 7) - 1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT8.
- value = (1 << 7);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, (1 << 7)};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT8.
- value = 0xff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT16.
- value = (1 << 8);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0, 1};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT16.
- value = 0xffff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT32.
- value = (1 << 16);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT32.
- value = 0xffffffff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, uint64_t) {
- Payload result;
- Payload expected;
- uint64_t value;
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = (1 << 7) - 1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT8.
- value = (1 << 7);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, (1 << 7)};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT8.
- value = 0xff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT8, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT16.
- value = (1 << 8);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0, 1};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT16.
- value = 0xffff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT32.
- value = (1 << 16);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT32, 0, 0, 1, 0};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT32.
- value = 0xffffffff;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min UINT64.
- value = (1ULL << 32);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_UINT64, 0, 0, 0, 0, 1, 0, 0, 0};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max UINT64.
- value = 0xffffffffffffffffULL;
- Serialize(value, &result);
- expected = {
- ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, int8_t) {
- Payload result;
- Payload expected;
- int8_t value;
-
- // Min NEGATIVE FIXINT.
- value = -32;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max NEGATIVE FIXINT.
- value = -1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = 127;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT8.
- value = -128;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT8.
- value = -33;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0xdf};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, int16_t) {
- Payload result;
- Payload expected;
- int16_t value;
-
- // Min NEGATIVE FIXINT.
- value = -32;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max NEGATIVE FIXINT.
- value = -1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = 127;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT8.
- value = -128;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT8.
- value = -33;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0xdf};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT16.
- value = -32768;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT16.
- value = 32767;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, int32_t) {
- Payload result;
- Payload expected;
- int32_t value;
-
- // Min NEGATIVE FIXINT.
- value = -32;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max NEGATIVE FIXINT.
- value = -1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = 127;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT8.
- value = -128;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT8.
- value = -33;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0xdf};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT16.
- value = -32768;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT16.
- value = 32767;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT32.
- value = -2147483648;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT32.
- value = 2147483647;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, int64_t) {
- Payload result;
- Payload expected;
- int64_t value;
-
- // Min NEGATIVE FIXINT.
- value = -32;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max NEGATIVE FIXINT.
- value = -1;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min FIXINT.
- value = 0;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXINT.
- value = 127;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT8.
- value = -128;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT8.
- value = -33;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT8, 0xdf};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT16.
- value = -32768;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT16.
- value = 32767;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT32.
- value = -2147483648;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT32.
- value = 2147483647;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min INT64.
- value = -9223372036854775808ULL;
- Serialize(value, &result);
- expected = {
- ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max INT64.
- value = 9223372036854775807ULL;
- Serialize(value, &result);
- expected = {
- ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, float) {
- Payload result;
- Payload expected;
- float value;
-
- value = 0.0f;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
- kZeroFloatBytes[2], kZeroFloatBytes[3]};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- value = 1.0f;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
- kOneFloatBytes[2], kOneFloatBytes[3]};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, double) {
- Payload result;
- Payload expected;
- double value;
-
- value = 0.0f;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1],
- kZeroDoubleBytes[2], kZeroDoubleBytes[3], kZeroDoubleBytes[4],
- kZeroDoubleBytes[5], kZeroDoubleBytes[6], kZeroDoubleBytes[7]};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- value = 1.0f;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1],
- kOneDoubleBytes[2], kOneDoubleBytes[3], kOneDoubleBytes[4],
- kOneDoubleBytes[5], kOneDoubleBytes[6], kOneDoubleBytes[7]};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, Enum) {
- Payload result;
- Payload expected;
-
- enum Foo { kFoo, kBar, kBaz };
- Foo value = kBar;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, EnumClass) {
- Payload result;
- Payload expected;
-
- enum class Foo { kFoo, kBar, kBaz };
- Foo value = Foo::kBaz;
- Serialize(value, &result);
- expected = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2};
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, LocalHandle) {
- Payload result;
- Payload expected;
- LocalHandle fd1;
- LocalHandle fd2;
-
- fd1 = LocalHandle(100);
- Serialize(fd1, &result);
- expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0};
- EXPECT_EQ(expected, result);
- EXPECT_EQ(1u, result.FdCount());
- EXPECT_EQ(100, result.FdArray()[0]);
- result.Clear();
-
- fd2 = LocalHandle(200);
- Serialize(std::forward_as_tuple(fd1, fd2), &result);
- expected = decltype(expected)(
- {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0});
- EXPECT_EQ(expected, result);
- EXPECT_EQ(2u, result.FdCount());
- EXPECT_EQ(100, result.FdArray()[0]);
- EXPECT_EQ(200, result.FdArray()[1]);
- result.Clear();
-
- fd1.Release(); // Don't try to close fd 100.
- fd2.Release(); // Don't try to close fd 200.
-
- fd1 = LocalHandle(-2);
- Serialize(fd1, &result);
- expected = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe,
- 0xff};
- EXPECT_EQ(expected, result);
- EXPECT_EQ(0u, result.FdCount());
- result.Clear();
-}
-
-TEST(SerializationTest, string) {
- Payload result;
- Payload expected;
- std::string value;
-
- // Min FIXSTR.
- value = "";
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXSTR_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXSTR.
- value = std::string((1 << 5) - 1, 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXSTR_MAX};
- expected.Append((1 << 5) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR8.
- value = std::string((1 << 5), 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_STR8, (1 << 5)};
- expected.Append((1 << 5), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max STR8.
- value = std::string((1 << 8) - 1, 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_STR8, (1 << 8) - 1};
- expected.Append((1 << 8) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR16.
- value = std::string((1 << 8), 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_STR16, 0x00, 0x01};
- expected.Append((1 << 8), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max STR16.
- value = std::string((1 << 16) - 1, 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_STR16, 0xff, 0xff};
- expected.Append((1 << 16) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR32.
- value = std::string((1 << 16), 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, StringWrapper) {
- Payload result;
- Payload expected;
- std::string value;
-
- // Min FIXSTR.
- value = "";
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_FIXSTR_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXSTR.
- value = std::string((1 << 5) - 1, 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_FIXSTR_MAX};
- expected.Append((1 << 5) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR8.
- value = std::string((1 << 5), 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_STR8, (1 << 5)};
- expected.Append((1 << 5), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max STR8.
- value = std::string((1 << 8) - 1, 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_STR8, (1 << 8) - 1};
- expected.Append((1 << 8) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR16.
- value = std::string((1 << 8), 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_STR16, 0x00, 0x01};
- expected.Append((1 << 8), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max STR16.
- value = std::string((1 << 16) - 1, 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_STR16, 0xff, 0xff};
- expected.Append((1 << 16) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min STR32.
- value = std::string((1 << 16), 'x');
- Serialize(WrapString(value), &result);
- expected = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, vector) {
- Payload result;
- Payload expected;
- std::vector<uint8_t> value;
-
- // Min FIXARRAY.
- value = {};
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXARRAY.
- value = decltype(value)((1 << 4) - 1, 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MAX};
- expected.Append((1 << 4) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY16.
- value = decltype(value)((1 << 4), 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
- expected.Append((1 << 4), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max ARRAY16.
- value = decltype(value)((1 << 16) - 1, 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- expected.Append((1 << 16) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY32.
- value = decltype(value)((1 << 16), 'x');
- Serialize(value, &result);
- expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, map) {
- Payload result;
- Payload expected;
- std::map<std::uint32_t, std::uint32_t> value;
-
- // Min FIXMAP.
- value = {};
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXMAP.
- value = MakeMap<decltype(value)>((1 << 4) - 1);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXMAP_MAX};
- InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min MAP16.
- value = MakeMap<decltype(value)>((1 << 4));
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
- InsertKeyValue<decltype(value)>(&expected, (1 << 4));
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max MAP16.
- value = MakeMap<decltype(value)>((1 << 16) - 1);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
- InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min MAP32.
- value = MakeMap<decltype(value)>((1 << 16));
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
- InsertKeyValue<decltype(value)>(&expected, (1 << 16));
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, unordered_map) {
- Payload result;
- Payload expected;
- std::unordered_map<std::uint32_t, std::uint32_t> value;
-
- // Min FIXMAP.
- value = {};
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXMAP.
- value = MakeMap<decltype(value)>((1 << 4) - 1);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_FIXMAP_MAX};
- InsertKeyValue<decltype(value)>(&expected, (1 << 4) - 1);
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min MAP16.
- value = MakeMap<decltype(value)>((1 << 4));
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP16, 0x10, 0x00};
- InsertKeyValue<decltype(value)>(&expected, (1 << 4));
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max MAP16.
- value = MakeMap<decltype(value)>((1 << 16) - 1);
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP16, 0xff, 0xff};
- InsertKeyValue<decltype(value)>(&expected, (1 << 16) - 1);
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min MAP32.
- value = MakeMap<decltype(value)>((1 << 16));
- Serialize(value, &result);
- expected = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
- InsertKeyValue<decltype(value)>(&expected, (1 << 16));
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, array) {
- Payload result;
- Payload expected;
-
- // Min FIXARRAY.
- std::array<std::uint8_t, 0> a0;
- Serialize(a0, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXARRAY.
- std::array<std::uint8_t, (1 << 4) - 1> a1;
- for (auto& element : a1)
- element = 'x';
- Serialize(a1, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MAX};
- expected.Append((1 << 4) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY16.
- std::array<std::uint8_t, (1 << 4)> a2;
- for (auto& element : a2)
- element = 'x';
- Serialize(a2, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
- expected.Append((1 << 4), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max ARRAY16.
- std::array<std::uint8_t, (1 << 16) - 1> a3;
- for (auto& element : a3)
- element = 'x';
- Serialize(a3, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- expected.Append((1 << 16) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY32.
- std::array<std::uint8_t, (1 << 16)> a4;
- for (auto& element : a4)
- element = 'x';
- Serialize(a4, &result);
- expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, ArrayWrapper) {
- Payload result;
- Payload expected;
- std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>> value;
- ArrayWrapper<std::uint8_t> wrapper;
-
- // Min FIXARRAY.
- value = {};
- Serialize(wrapper, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXARRAY.
- value = decltype(value)((1 << 4) - 1, 'x');
- wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
- Serialize(wrapper, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MAX};
- expected.Append((1 << 4) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY16.
- value = decltype(value)((1 << 4), 'x');
- wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
- Serialize(wrapper, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
- expected.Append((1 << 4), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max ARRAY16.
- value = decltype(value)((1 << 16) - 1, 'x');
- wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
- Serialize(wrapper, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- expected.Append((1 << 16) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY32.
- value = decltype(value)((1 << 16), 'x');
- wrapper = decltype(wrapper)(value.data(), value.capacity(), value.size());
- Serialize(wrapper, &result);
- expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, pair) {
- Payload result;
- Payload expected;
-
- auto p1 = std::make_pair(1, 2);
- Serialize(p1, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- auto p2 = std::make_pair('x', std::string("12345"));
- Serialize(p2, &result);
- expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x',
- ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3',
- '4', '5'});
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, tuple) {
- Payload result;
- Payload expected;
-
- // Min FIXARRAY.
- auto t1 = std::make_tuple();
- Serialize(t1, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MIN};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Max FIXARRAY.
- auto t2 = GetNTuple<15>('x');
- Serialize(t2, &result);
- expected = {ENCODING_TYPE_FIXARRAY_MAX};
- expected.Append((1 << 4) - 1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY16.
- auto t3 = GetNTuple<(1 << 4)>('x');
- Serialize(t3, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
- expected.Append((1 << 4), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
-// Template instantiation depth is an issue for these tests. They are commented
-// out to document the expected behavior, even though tuples of this order are
-// not expected in practice.
-#if 0
- // Max ARRAY16.
- auto t4 = GetNTuple<(1 << 16)-1>('x');
- Serialize(t4, &result);
- expected = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- expected.Append((1 << 16)-1, 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // Min ARRAY32.
- auto t5 = GetNTuple<(1 << 16)>('x');
- Serialize(t5, &result);
- expected = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- expected.Append((1 << 16), 'x');
- EXPECT_EQ(expected, result);
- result.Clear();
-#endif
-}
-
-// TODO(eieio): More exhaustive testing of type nesting.
-TEST(SerializationTest, NestedTuple) {
- Payload result;
- Payload expected;
-
- auto t1 = std::make_tuple('x', std::make_tuple<int, int>(1, 2));
- Serialize(t1, &result);
- expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 2, 'x',
- ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2});
- EXPECT_EQ(expected, result);
- result.Clear();
-
- auto t2 = std::make_tuple('x', std::make_tuple<int, int>(1, 2),
- std::string("0123456789"));
- Serialize(t2, &result);
- expected = decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 3, 'x',
- ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2,
- ENCODING_TYPE_FIXSTR | 10, '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9'});
- EXPECT_EQ(expected, result);
- result.Clear();
-
- auto t3 = std::make_tuple(0.0f, std::uint64_t(10ULL),
- std::vector<char>{'a', 'b', 'c'});
- Serialize(t3, &result);
- expected = decltype(expected)(
- {ENCODING_TYPE_FIXARRAY_MIN + 3, ENCODING_TYPE_FLOAT32,
- kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
- kZeroFloatBytes[3], ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10,
- ENCODING_TYPE_FIXARRAY_MIN + 3, 'a', 'b', 'c'});
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, NestedMap) {
- Payload result;
- Payload expected;
-
- std::map<int, std::pair<std::string, int>> m1 = {{0, {"a", 2}},
- {1, {"b", 10}}};
- Serialize(m1, &result);
- expected = decltype(expected)(
- {ENCODING_TYPE_FIXMAP_MIN + 2, 0, ENCODING_TYPE_FIXARRAY_MIN + 2,
- ENCODING_TYPE_FIXSTR_MIN + 1, 'a', 2, 1, ENCODING_TYPE_FIXARRAY_MIN + 2,
- ENCODING_TYPE_FIXSTR_MIN + 1, 'b', 10});
- EXPECT_EQ(expected, result);
- result.Clear();
-}
-
-TEST(SerializationTest, Serializable) {
- Payload result;
- Payload expected;
-
- TestType t1{10, 0.0, "12345", TestType::Foo::kBaz};
- Serialize(t1, &result);
- expected = decltype(expected)(
- {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32,
- kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
- kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4',
- '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2});
- EXPECT_EQ(expected, result);
- result.Clear();
-
- TestTemplateType<LocalHandle> tt{LocalHandle(-1)};
- Serialize(tt, &result);
- expected =
- decltype(expected)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff});
- EXPECT_EQ(expected, result);
-}
-
-TEST(SerializationTest, Variant) {
- Payload result;
- Payload expected;
-
- Variant<int, bool, float> v;
-
- // Empty variant.
- Serialize(v, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX,
- ENCODING_TYPE_NIL};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- v = 10;
- Serialize(v, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- v = true;
- Serialize(v, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_TRUE};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- v = false;
- Serialize(v, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1, ENCODING_TYPE_FALSE};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- v = 1.0f;
- Serialize(v, &result);
- expected = {ENCODING_TYPE_FIXMAP_MIN + 1,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2,
- ENCODING_TYPE_FLOAT32,
- kOneFloatBytes[0],
- kOneFloatBytes[1],
- kOneFloatBytes[2],
- kOneFloatBytes[3]};
- EXPECT_EQ(expected, result);
- result.Clear();
-
- // TODO(eieio): Add more serialization tests for Variant.
-}
-
-TEST(DeserializationTest, bool) {
- Payload buffer;
- bool result = false;
- ErrorType error;
-
- // True.
- buffer = {ENCODING_TYPE_TRUE};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(1, result); // Gtest generates warning from bool literals.
-
- // False.
- buffer = {ENCODING_TYPE_FALSE};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result); // Gtest generates warning from bool literals.
-}
-
-TEST(DeserializationTest, uint8_t) {
- Payload buffer;
- std::uint8_t result = 0;
- ErrorType error;
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127U, result);
-
- // Min UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffU, result);
-
- // UINT16 out of range.
- buffer = {ENCODING_TYPE_UINT16};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT16, error.encoding_type());
-
- // UINT32 out of range.
- buffer = {ENCODING_TYPE_UINT32};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type());
-
- // UINT64 out of range.
- buffer = {ENCODING_TYPE_UINT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint16_t) {
- Payload buffer;
- std::uint16_t result = 0;
- ErrorType error;
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127U, result);
-
- // Min UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffU, result);
-
- // Min UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffU, result);
-
- // UINT32 out of range.
- buffer = {ENCODING_TYPE_UINT32};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT32, error.encoding_type());
-
- // UINT64 out of range.
- buffer = {ENCODING_TYPE_UINT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint32_t) {
- Payload buffer;
- std::uint32_t result = 0;
- ErrorType error;
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127U, result);
-
- // Min UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffU, result);
-
- // Min UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffU, result);
-
- // Min UINT32.
- buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT32.
- buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffffffU, result);
-
- // UINT64 out of range.
- buffer = {ENCODING_TYPE_UINT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_UINT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, uint64_t) {
- Payload buffer;
- std::uint64_t result = 0;
- ErrorType error;
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127U, result);
-
- // Min UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT8.
- buffer = {ENCODING_TYPE_UINT8, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffU, result);
-
- // Min UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT16.
- buffer = {ENCODING_TYPE_UINT16, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffU, result);
-
- // Min UINT32.
- buffer = {ENCODING_TYPE_UINT32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT32.
- buffer = {ENCODING_TYPE_UINT32, 0xff, 0xff, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffffffU, result);
-
- // Min UINT64.
- buffer = {
- ENCODING_TYPE_UINT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0U, result);
-
- // Max UINT64.
- buffer = {
- ENCODING_TYPE_UINT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0xffffffffffffffffUL, result);
-}
-
-TEST(DeserializationTest, int8_t) {
- Payload buffer;
- std::int8_t result = 0;
- ErrorType error;
-
- // Min NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32, result);
-
- // Max NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-1, result);
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT8.
- buffer = {ENCODING_TYPE_INT8, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-128, result);
-
- // Max INT8.
- buffer = {ENCODING_TYPE_INT8, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // INT16 out of range.
- buffer = {ENCODING_TYPE_INT16};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT16, error.encoding_type());
-
- // INT32 out of range.
- buffer = {ENCODING_TYPE_INT32};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type());
-
- // INT64 out of range.
- buffer = {ENCODING_TYPE_INT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int16_t) {
- Payload buffer;
- std::int16_t result = 0;
- ErrorType error;
-
- // Min NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32, result);
-
- // Max NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-1, result);
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT8.
- buffer = {ENCODING_TYPE_INT8, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-128, result);
-
- // Max INT8.
- buffer = {ENCODING_TYPE_INT8, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT16.
- buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32768, result);
-
- // Max INT16.
- buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(32767, result);
-
- // INT32 out of range.
- buffer = {ENCODING_TYPE_INT32};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT32, error.encoding_type());
-
- // INT64 out of range.
- buffer = {ENCODING_TYPE_INT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int32_t) {
- Payload buffer;
- std::int32_t result = 0;
- ErrorType error;
-
- // Min NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32, result);
-
- // Max NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-1, result);
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT8.
- buffer = {ENCODING_TYPE_INT8, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-128, result);
-
- // Max INT8.
- buffer = {ENCODING_TYPE_INT8, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT16.
- buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32768, result);
-
- // Max INT16.
- buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(32767, result);
-
- // Min INT32.
- buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-2147483648, result);
-
- // Max INT32.
- buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(2147483647, result);
-
- // INT64 out of range.
- buffer = {ENCODING_TYPE_INT64};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_INT64, error.encoding_type());
-}
-
-TEST(DeserializationTest, int64_t) {
- Payload buffer;
- std::int64_t result = 0;
- ErrorType error;
-
- // Min NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32, result);
-
- // Max NEGATIVE FIXINT.
- buffer = {ENCODING_TYPE_NEGATIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-1, result);
-
- // Min FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result);
-
- // Max FIXINT.
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MAX};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT8.
- buffer = {ENCODING_TYPE_INT8, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-128, result);
-
- // Max INT8.
- buffer = {ENCODING_TYPE_INT8, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(127, result);
-
- // Min INT16.
- buffer = {ENCODING_TYPE_INT16, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-32768, result);
-
- // Max INT16.
- buffer = {ENCODING_TYPE_INT16, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(32767, result);
-
- // Min INT32.
- buffer = {ENCODING_TYPE_INT32, 0x00, 0x00, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-2147483648, result);
-
- // Max INT32.
- buffer = {ENCODING_TYPE_INT32, 0xff, 0xff, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(2147483647, result);
-
- // Min INT64.
- buffer = {
- ENCODING_TYPE_INT64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- // Believe it or not, this is actually the correct way to specify the most
- // negative signed long long.
- EXPECT_EQ(-9223372036854775807LL - 1, result);
-
- // Max INT64.
- buffer = {
- ENCODING_TYPE_INT64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(9223372036854775807LL, result);
-}
-
-TEST(DeserializationTest, float) {
- Payload buffer;
- float result;
- ErrorType error;
-
- // FLOAT32.
- buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
- kZeroFloatBytes[2], kZeroFloatBytes[3]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kZeroFloat, result);
-
- // FLOAT32.
- buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
- kOneFloatBytes[2], kOneFloatBytes[3]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kOneFloat, result);
-}
-
-TEST(DeserializationTest, double) {
- Payload buffer;
- double result;
- ErrorType error;
-
- // FLOAT32.
- buffer = {ENCODING_TYPE_FLOAT32, kZeroFloatBytes[0], kZeroFloatBytes[1],
- kZeroFloatBytes[2], kZeroFloatBytes[3]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kZeroDouble, result);
-
- // FLOAT64.
- buffer = {ENCODING_TYPE_FLOAT64, kZeroDoubleBytes[0], kZeroDoubleBytes[1],
- kZeroDoubleBytes[2], kZeroDoubleBytes[3], kZeroDoubleBytes[4],
- kZeroDoubleBytes[5], kZeroDoubleBytes[6], kZeroDoubleBytes[7]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kZeroDouble, result);
-
- // FLOAT32.
- buffer = {ENCODING_TYPE_FLOAT32, kOneFloatBytes[0], kOneFloatBytes[1],
- kOneFloatBytes[2], kOneFloatBytes[3]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kOneDouble, result);
-
- // FLOAT64.
- buffer = {ENCODING_TYPE_FLOAT64, kOneDoubleBytes[0], kOneDoubleBytes[1],
- kOneDoubleBytes[2], kOneDoubleBytes[3], kOneDoubleBytes[4],
- kOneDoubleBytes[5], kOneDoubleBytes[6], kOneDoubleBytes[7]};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kOneDouble, result);
-}
-
-TEST(DeserializationTest, Enum) {
- Payload buffer;
- enum Foo { kFoo, kBar, kBaz } result;
- ErrorType error;
-
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(kBar, result);
-}
-
-TEST(DeserializationTest, EnumClass) {
- Payload buffer;
- enum Foo { kFoo, kBar, kBaz } result;
- ErrorType error;
-
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(Foo::kBaz, result);
-}
-
-TEST(DeserializationTest, LocalHandle) {
- Payload buffer;
- LocalHandle result1;
- LocalHandle result2;
- ErrorType error;
-
- buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0};
- error = Deserialize(&result1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result1.Get());
- result1.Release(); // Don't close fd 0.
-
- std::tuple<LocalHandle&, LocalHandle&> t1(result1, result2);
- buffer = decltype(buffer)(
- {ENCODING_TYPE_FIXARRAY_MIN + 2, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0, 0, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 1, 0});
- error = Deserialize(&t1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(0, result1.Get());
- EXPECT_EQ(1, result2.Get());
- result1.Release(); // Don't close fd 0.
- result2.Release(); // Don't close fd 1.
-
- buffer = {ENCODING_TYPE_FIXEXT2, ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xfe,
- 0xff};
- error = Deserialize(&result1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(-2, result1.Get());
-}
-
-TEST(DeserializationTest, string) {
- Payload buffer;
- std::string result = "";
- ErrorType error;
-
- // Min FIXSTR.
- buffer = {ENCODING_TYPE_FIXSTR_MIN};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ("", result);
-
- // Max FIXSTR.
- buffer = {ENCODING_TYPE_FIXSTR_MAX};
- buffer.Append((1 << 5) - 1, 'x');
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::string((1 << 5) - 1, 'x'), result);
-
- // Min STR8.
- buffer = {ENCODING_TYPE_STR8, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ("", result);
-
- // Max STR8.
- buffer = {ENCODING_TYPE_STR8, 0xff};
- buffer.Append(0xff, 'x');
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::string(0xff, 'x'), result);
-
- // Min STR16.
- buffer = {ENCODING_TYPE_STR16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ("", result);
-
- // Max STR16.
- buffer = {ENCODING_TYPE_STR16, 0xff, 0xff};
- buffer.Append(0xffff, 'x');
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::string(0xffff, 'x'), result);
-
- // Min STR32.
- buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ("", result);
-
- // Test STR32 with max STR16 + 1 bytes. It's not practical to test max
- // STR32.
- buffer = {ENCODING_TYPE_STR32, 0x00, 0x00, 0x01, 0x00};
- buffer.Append(0x10000, 'x');
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::string(0x10000, 'x'), result);
-}
-
-TEST(DeserializationTest, vector) {
- Payload buffer;
- std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
- result;
- Payload expected;
- ErrorType error;
-
- // Min FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MIN};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MAX};
- buffer.Append((1 << 4) - 1, 1);
- error = Deserialize(&result, &buffer);
- expected = decltype(expected)((1 << 4) - 1, 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- buffer.Append(0xffff, 1);
- error = Deserialize(&result, &buffer);
- expected = decltype(expected)(0xffff, 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- buffer.Append(0x10000, 1);
- error = Deserialize(&result, &buffer);
- expected = decltype(expected)(0x10000, 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, map) {
- Payload buffer;
- std::map<std::uint32_t, std::uint32_t> result;
- std::map<std::uint32_t, std::uint32_t> expected;
- ErrorType error;
-
- // Min FIXMAP.
- buffer = {ENCODING_TYPE_FIXMAP_MIN};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Size mismatch.
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error);
-
- // Max FIXMAP.
- buffer = {ENCODING_TYPE_FIXMAP_MAX};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 4) - 1);
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 4) - 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error) << std::string(error);
- EXPECT_EQ(expected, result);
-
- // Min MAP16.
- buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max MAP16.
- buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 16) - 1);
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 16) - 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min MAP32.
- buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // MAP32 with max MAP16 + 1. It's not practical to test max MAP32.
- buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 16));
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 16));
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, unordered_map) {
- Payload buffer;
- std::unordered_map<std::uint32_t, std::uint32_t> result;
- std::unordered_map<std::uint32_t, std::uint32_t> expected;
- ErrorType error;
-
- // Min FIXMAP.
- buffer = {ENCODING_TYPE_FIXMAP_MIN};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Size mismatch.
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1};
- error = Deserialize(&result, &buffer);
- EXPECT_EQ(ErrorCode::INSUFFICIENT_BUFFER, error);
-
- // Max FIXMAP.
- buffer = {ENCODING_TYPE_FIXMAP_MAX};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 4) - 1);
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 4) - 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min MAP16.
- buffer = {ENCODING_TYPE_MAP16, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max MAP16.
- buffer = {ENCODING_TYPE_MAP16, 0xff, 0xff};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 16) - 1);
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 16) - 1);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min MAP32.
- buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&result, &buffer);
- expected = {};
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // MAP32 with max MAP16 + 1. It's not practical to test max MAP32.
- buffer = {ENCODING_TYPE_MAP32, 0x00, 0x00, 0x01, 0x00};
- InsertKeyValue<decltype(result)>(&buffer, (1 << 16));
- error = Deserialize(&result, &buffer);
- expected = MakeMap<decltype(expected)>((1 << 16));
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, array) {
- Payload buffer;
- ErrorType error;
-
- // Min FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MIN};
- std::array<std::uint8_t, 0> a0;
- error = Deserialize(&a0, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
- // Size mismatch.
- buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1};
- error = Deserialize(&a0, &buffer);
- EXPECT_EQ(ErrorCode::INSUFFICIENT_DESTINATION_SIZE, error);
-
- // Max FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MAX};
- buffer.Append((1 << 4) - 1, 'x');
- std::array<std::uint8_t, (1 << 4) - 1> a1, expected1;
- for (auto& element : expected1)
- element = 'x';
- error = Deserialize(&a1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected1, a1);
-
- // Min ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
- error = Deserialize(&a0, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
- // Max ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- buffer.Append((1 << 16) - 1, 'x');
- std::array<std::uint8_t, (1 << 16) - 1> a3, expected3;
- for (auto& element : expected3)
- element = 'x';
- error = Deserialize(&a3, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected3, a3);
-
- // Min ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&a0, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
-
- // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- buffer.Append((1 << 16), 'x');
- std::array<std::uint8_t, (1 << 16)> a4, expected4;
- for (auto& element : expected4)
- element = 'x';
- error = Deserialize(&a4, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected4, a4);
-}
-
-TEST(DeserializationTest, ArrayWrapper) {
- Payload buffer;
- std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
- result;
- std::vector<std::uint8_t, DefaultInitializationAllocator<std::uint8_t>>
- expected;
- ErrorType error;
-
- result.reserve(0x10000);
- ArrayWrapper<std::uint8_t> wrapper(result.data(), result.capacity());
-
- // Min FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MIN};
- error = Deserialize(&wrapper, &buffer);
- expected = {};
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max FIXARRAY.
- buffer = {ENCODING_TYPE_FIXARRAY_MAX};
- buffer.Append((1 << 4) - 1, 1);
- error = Deserialize(&wrapper, &buffer);
- expected = decltype(expected)((1 << 4) - 1, 1);
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
- error = Deserialize(&wrapper, &buffer);
- expected = {};
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Max ARRAY16.
- buffer = {ENCODING_TYPE_ARRAY16, 0xff, 0xff};
- buffer.Append(0xffff, 1);
- error = Deserialize(&wrapper, &buffer);
- expected = decltype(expected)(0xffff, 1);
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // Min ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&wrapper, &buffer);
- expected = {};
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-
- // ARRAY32 with max ARRAY16 + 1. It's not practical to test max ARRAY32.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x01, 0x00};
- buffer.Append(0x10000, 1);
- error = Deserialize(&wrapper, &buffer);
- expected = decltype(expected)(0x10000, 1);
- result.resize(wrapper.size());
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(expected, result);
-}
-
-TEST(DeserializationTest, pair) {
- Payload buffer;
- ErrorType error;
-
- std::pair<int, int> p1;
- buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 1, 2};
- error = Deserialize(&p1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::make_pair(1, 2), p1);
-}
-
-TEST(DeserializationTest, tuple) {
- Payload buffer;
- ErrorType error;
-
- // Min FIXARRAY.
- std::tuple<> t1;
- buffer = {ENCODING_TYPE_FIXARRAY_MIN};
- error = Deserialize(&t1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::make_tuple(), t1); // Superfluous.
-
- // Max FIXARRAY.
- auto t2 = GetNTuple<15, int>(0);
- buffer = {ENCODING_TYPE_FIXARRAY_MAX};
- buffer.Append((1 << 4) - 1, 1);
- error = Deserialize(&t2, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ((GetNTuple<15, int>(1)), t2);
-
- // Min ARRAY16.
- // Using t1 above.
- buffer = {ENCODING_TYPE_ARRAY16, 0x00, 0x00};
- error = Deserialize(&t1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::make_tuple(), t1);
-
- // ARRAY16 at Max FIXARRAY + 1
- auto t3 = GetNTuple<(1 << 4), int>(0);
- buffer = {ENCODING_TYPE_ARRAY16, 0x10, 0x00};
- buffer.Append((1 << 4), 1);
- error = Deserialize(&t3, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t3);
-
- // Min ARRAY32.
- // Using t1 from above.
- buffer = {ENCODING_TYPE_ARRAY32, 0x00, 0x00, 0x00, 0x00};
- error = Deserialize(&t1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(std::make_tuple(), t1);
-
- // ARRAY32 at Max FIXARRAY + 1
- auto t4 = GetNTuple<(1 << 4), int>(0);
- buffer = {ENCODING_TYPE_ARRAY32, 0x10, 0x00, 0x00, 0x00};
- buffer.Append((1 << 4), 1);
- error = Deserialize(&t4, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ((GetNTuple<(1 << 4), int>(1)), t4);
-
- // Template instantiation depth is an issue for tuples with large numbers of
- // elements. As these are not expected in practice, the limits of ARRAY16
- // and ARRAY32 are not tested.
-}
-
-TEST(DeserializationTest, Serializable) {
- Payload buffer;
- ErrorType error;
-
- buffer = decltype(buffer)(
- {ENCODING_TYPE_FIXARRAY_MIN + 4, 10, ENCODING_TYPE_FLOAT32,
- kZeroFloatBytes[0], kZeroFloatBytes[1], kZeroFloatBytes[2],
- kZeroFloatBytes[3], ENCODING_TYPE_FIXSTR_MIN + 5, '1', '2', '3', '4',
- '5', ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1});
- TestType t1;
- error = Deserialize(&t1, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(TestType(10, 0.f, "12345", TestType::Foo::kBar), t1);
-
- buffer =
- decltype(buffer)({ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_FIXEXT2,
- ENCODING_EXT_TYPE_FILE_DESCRIPTOR, 0xff, 0xff});
- TestTemplateType<LocalHandle> tt;
- error = Deserialize(&tt, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_EQ(TestTemplateType<LocalHandle>(LocalHandle(-1)), tt);
-}
-
-TEST(DeserializationTest, Variant) {
- Payload buffer;
- ErrorType error;
-
- Variant<int, bool, float> v;
-
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_NEGATIVE_FIXINT_MAX,
- ENCODING_TYPE_NIL};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- EXPECT_TRUE(v.empty());
-
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 0,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 10};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- ASSERT_TRUE(v.is<int>());
- EXPECT_EQ(10, std::get<int>(v));
-
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1,
- ENCODING_TYPE_TRUE};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- ASSERT_TRUE(v.is<bool>());
- EXPECT_EQ(true, std::get<bool>(v));
-
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1, ENCODING_TYPE_POSITIVE_FIXINT_MIN + 1,
- ENCODING_TYPE_FALSE};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- ASSERT_TRUE(v.is<bool>());
- EXPECT_EQ(false, std::get<bool>(v));
-
- buffer = {ENCODING_TYPE_FIXMAP_MIN + 1,
- ENCODING_TYPE_POSITIVE_FIXINT_MIN + 2,
- ENCODING_TYPE_FLOAT32,
- kOneFloatBytes[0],
- kOneFloatBytes[1],
- kOneFloatBytes[2],
- kOneFloatBytes[3]};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::NO_ERROR, error);
- ASSERT_TRUE(v.is<float>());
- EXPECT_FLOAT_EQ(1.0, std::get<float>(v));
-
- // TODO(eieio): Add more deserialization tests for Variant.
-}
-
-TEST(DeserializationTest, ErrorType) {
- Payload buffer;
- ErrorType error;
-
- std::uint8_t u8;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&u8, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::uint16_t u16;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&u16, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::uint32_t u32;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&u32, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::uint64_t u64;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&u64, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::int8_t i8;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&i8, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::int16_t i16;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&i16, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::int32_t i32;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&i32, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::int64_t i64;
- buffer = {ENCODING_TYPE_STR8};
- error = Deserialize(&i64, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_INT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- std::string s;
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT};
- error = Deserialize(&s, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_STRING, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type());
-
- std::vector<std::uint8_t> v;
- buffer = {ENCODING_TYPE_POSITIVE_FIXINT};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_ARRAY, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_POSITIVE_FIXINT, error.encoding_type());
-
- buffer = {ENCODING_TYPE_FIXARRAY_MIN + 1, ENCODING_TYPE_STR8};
- error = Deserialize(&v, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_ENCODING, error);
- EXPECT_EQ(ENCODING_CLASS_UINT, error.encoding_class());
- EXPECT_EQ(ENCODING_TYPE_STR8, error.encoding_type());
-
- buffer = {ENCODING_TYPE_FIXARRAY_MIN + 2, 0, 1};
- std::tuple<int> t;
- error = Deserialize(&t, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
-
- buffer = {ENCODING_TYPE_FIXARRAY_MIN + 3, 0, 1, 2};
- std::pair<int, int> p;
- error = Deserialize(&p, &buffer);
- EXPECT_EQ(ErrorCode::UNEXPECTED_TYPE_SIZE, error);
-}
diff --git a/libs/vr/libpdx/service.cpp b/libs/vr/libpdx/service.cpp
deleted file mode 100644
index 3769162..0000000
--- a/libs/vr/libpdx/service.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-#include "pdx/service.h"
-
-#include <fcntl.h>
-#include <log/log.h>
-#include <utils/misc.h>
-
-#include <algorithm>
-#include <cstdint>
-
-#include <pdx/trace.h>
-
-namespace android {
-namespace pdx {
-
-std::shared_ptr<Channel> Channel::GetFromMessageInfo(const MessageInfo& info) {
- return info.channel ? info.channel->shared_from_this()
- : std::shared_ptr<Channel>();
-}
-
-Message::Message() : replied_(true) {}
-
-Message::Message(const MessageInfo& info)
- : service_{Service::GetFromMessageInfo(info)},
- channel_{Channel::GetFromMessageInfo(info)},
- info_{info},
- replied_{IsImpulse()} {
- auto svc = service_.lock();
- if (svc)
- state_ = svc->endpoint()->AllocateMessageState();
-}
-
-// C++11 specifies the move semantics for shared_ptr but not weak_ptr. This
-// means we have to manually implement the desired move semantics for Message.
-Message::Message(Message&& other) noexcept { *this = std::move(other); }
-
-Message& Message::operator=(Message&& other) noexcept {
- Destroy();
- auto base = reinterpret_cast<std::uint8_t*>(&info_);
- std::fill(&base[0], &base[sizeof(info_)], 0);
- replied_ = true;
- std::swap(service_, other.service_);
- std::swap(channel_, other.channel_);
- std::swap(info_, other.info_);
- std::swap(state_, other.state_);
- std::swap(replied_, other.replied_);
- return *this;
-}
-
-Message::~Message() { Destroy(); }
-
-void Message::Destroy() {
- auto svc = service_.lock();
- if (svc) {
- if (!replied_) {
- ALOGE(
- "ERROR: Service \"%s\" failed to reply to message: op=%d pid=%d "
- "cid=%d\n",
- svc->name_.c_str(), info_.op, info_.pid, info_.cid);
- svc->DefaultHandleMessage(*this);
- }
- svc->endpoint()->FreeMessageState(state_);
- }
- state_ = nullptr;
- service_.reset();
- channel_.reset();
-}
-
-const std::uint8_t* Message::ImpulseBegin() const {
- return reinterpret_cast<const std::uint8_t*>(info_.impulse);
-}
-
-const std::uint8_t* Message::ImpulseEnd() const {
- return ImpulseBegin() + (IsImpulse() ? GetSendLength() : 0);
-}
-
-Status<size_t> Message::ReadVector(const struct iovec* vector,
- size_t vector_length) {
- PDX_TRACE_NAME("Message::ReadVector");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->ReadMessageData(this, vector, vector_length);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<void> Message::ReadVectorAll(const struct iovec* vector,
- size_t vector_length) {
- PDX_TRACE_NAME("Message::ReadVectorAll");
- if (auto svc = service_.lock()) {
- const auto status =
- svc->endpoint()->ReadMessageData(this, vector, vector_length);
- if (!status)
- return status.error_status();
- size_t size_to_read = 0;
- for (size_t i = 0; i < vector_length; i++)
- size_to_read += vector[i].iov_len;
- if (status.get() < size_to_read)
- return ErrorStatus{EIO};
- return {};
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<size_t> Message::Read(void* buffer, size_t length) {
- PDX_TRACE_NAME("Message::Read");
- if (auto svc = service_.lock()) {
- const struct iovec vector = {buffer, length};
- return svc->endpoint()->ReadMessageData(this, &vector, 1);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<size_t> Message::WriteVector(const struct iovec* vector,
- size_t vector_length) {
- PDX_TRACE_NAME("Message::WriteVector");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->WriteMessageData(this, vector, vector_length);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<void> Message::WriteVectorAll(const struct iovec* vector,
- size_t vector_length) {
- PDX_TRACE_NAME("Message::WriteVector");
- if (auto svc = service_.lock()) {
- const auto status =
- svc->endpoint()->WriteMessageData(this, vector, vector_length);
- if (!status)
- return status.error_status();
- size_t size_to_write = 0;
- for (size_t i = 0; i < vector_length; i++)
- size_to_write += vector[i].iov_len;
- if (status.get() < size_to_write)
- return ErrorStatus{EIO};
- return {};
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<size_t> Message::Write(const void* buffer, size_t length) {
- PDX_TRACE_NAME("Message::Write");
- if (auto svc = service_.lock()) {
- const struct iovec vector = {const_cast<void*>(buffer), length};
- return svc->endpoint()->WriteMessageData(this, &vector, 1);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<FileReference> Message::PushFileHandle(const LocalHandle& handle) {
- PDX_TRACE_NAME("Message::PushFileHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushFileHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<FileReference> Message::PushFileHandle(const BorrowedHandle& handle) {
- PDX_TRACE_NAME("Message::PushFileHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushFileHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<FileReference> Message::PushFileHandle(const RemoteHandle& handle) {
- PDX_TRACE_NAME("Message::PushFileHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushFileHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
- const LocalChannelHandle& handle) {
- PDX_TRACE_NAME("Message::PushChannelHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushChannelHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
- const BorrowedChannelHandle& handle) {
- PDX_TRACE_NAME("Message::PushChannelHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushChannelHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<ChannelReference> Message::PushChannelHandle(
- const RemoteChannelHandle& handle) {
- PDX_TRACE_NAME("Message::PushChannelHandle");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->PushChannelHandle(this, handle);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-bool Message::GetFileHandle(FileReference ref, LocalHandle* handle) {
- PDX_TRACE_NAME("Message::GetFileHandle");
- auto svc = service_.lock();
- if (!svc)
- return false;
-
- if (ref >= 0) {
- *handle = svc->endpoint()->GetFileHandle(this, ref);
- if (!handle->IsValid())
- return false;
- } else {
- *handle = LocalHandle{ref};
- }
- return true;
-}
-
-bool Message::GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) {
- PDX_TRACE_NAME("Message::GetChannelHandle");
- auto svc = service_.lock();
- if (!svc)
- return false;
-
- if (ref >= 0) {
- *handle = svc->endpoint()->GetChannelHandle(this, ref);
- if (!handle->valid())
- return false;
- } else {
- *handle = LocalChannelHandle{nullptr, ref};
- }
- return true;
-}
-
-Status<void> Message::Reply(int return_code) {
- PDX_TRACE_NAME("Message::Reply");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret = svc->endpoint()->MessageReply(this, return_code);
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::ReplyFileDescriptor(unsigned int fd) {
- PDX_TRACE_NAME("Message::ReplyFileDescriptor");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret = svc->endpoint()->MessageReplyFd(this, fd);
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::ReplyError(unsigned int error) {
- PDX_TRACE_NAME("Message::ReplyError");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret =
- svc->endpoint()->MessageReply(this, -static_cast<int>(error));
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const LocalHandle& handle) {
- PDX_TRACE_NAME("Message::ReplyFileHandle");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- Status<void> ret;
-
- if (handle)
- ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
- else
- ret = svc->endpoint()->MessageReply(this, handle.Get());
-
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const BorrowedHandle& handle) {
- PDX_TRACE_NAME("Message::ReplyFileHandle");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- Status<void> ret;
-
- if (handle)
- ret = svc->endpoint()->MessageReplyFd(this, handle.Get());
- else
- ret = svc->endpoint()->MessageReply(this, handle.Get());
-
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const RemoteHandle& handle) {
- PDX_TRACE_NAME("Message::ReplyFileHandle");
- auto svc = service_.lock();
- if (!replied_ && svc) {
- Status<void> ret = svc->endpoint()->MessageReply(this, handle.Get());
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const LocalChannelHandle& handle) {
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const BorrowedChannelHandle& handle) {
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::Reply(const RemoteChannelHandle& handle) {
- auto svc = service_.lock();
- if (!replied_ && svc) {
- const auto ret = svc->endpoint()->MessageReplyChannelHandle(this, handle);
- replied_ = ret.ok();
- return ret;
- } else {
- return ErrorStatus{EINVAL};
- }
-}
-
-Status<void> Message::ModifyChannelEvents(int clear_mask, int set_mask) {
- PDX_TRACE_NAME("Message::ModifyChannelEvents");
- if (auto svc = service_.lock()) {
- return svc->endpoint()->ModifyChannelEvents(info_.cid, clear_mask,
- set_mask);
- } else {
- return ErrorStatus{ESHUTDOWN};
- }
-}
-
-Status<RemoteChannelHandle> Message::PushChannel(
- int flags, const std::shared_ptr<Channel>& channel, int* channel_id) {
- PDX_TRACE_NAME("Message::PushChannel");
- if (auto svc = service_.lock()) {
- return svc->PushChannel(this, flags, channel, channel_id);
- } else {
- return ErrorStatus(ESHUTDOWN);
- }
-}
-
-Status<RemoteChannelHandle> Message::PushChannel(
- Service* service, int flags, const std::shared_ptr<Channel>& channel,
- int* channel_id) {
- PDX_TRACE_NAME("Message::PushChannel");
- return service->PushChannel(this, flags, channel, channel_id);
-}
-
-Status<int> Message::CheckChannel(ChannelReference ref,
- std::shared_ptr<Channel>* channel) const {
- PDX_TRACE_NAME("Message::CheckChannel");
- if (auto svc = service_.lock()) {
- return svc->CheckChannel(this, ref, channel);
- } else {
- return ErrorStatus(ESHUTDOWN);
- }
-}
-
-Status<int> Message::CheckChannel(const Service* service, ChannelReference ref,
- std::shared_ptr<Channel>* channel) const {
- PDX_TRACE_NAME("Message::CheckChannel");
- return service->CheckChannel(this, ref, channel);
-}
-
-pid_t Message::GetProcessId() const { return info_.pid; }
-
-pid_t Message::GetThreadId() const { return info_.tid; }
-
-uid_t Message::GetEffectiveUserId() const { return info_.euid; }
-
-gid_t Message::GetEffectiveGroupId() const { return info_.egid; }
-
-int Message::GetChannelId() const { return info_.cid; }
-
-int Message::GetMessageId() const { return info_.mid; }
-
-int Message::GetOp() const { return info_.op; }
-
-int Message::GetFlags() const { return info_.flags; }
-
-size_t Message::GetSendLength() const { return info_.send_len; }
-
-size_t Message::GetReceiveLength() const { return info_.recv_len; }
-
-size_t Message::GetFileDescriptorCount() const { return info_.fd_count; }
-
-std::shared_ptr<Channel> Message::GetChannel() const { return channel_.lock(); }
-
-Status<void> Message::SetChannel(const std::shared_ptr<Channel>& chan) {
- channel_ = chan;
- Status<void> status;
- if (auto svc = service_.lock())
- status = svc->SetChannel(info_.cid, chan);
- return status;
-}
-
-std::shared_ptr<Service> Message::GetService() const { return service_.lock(); }
-
-const MessageInfo& Message::GetInfo() const { return info_; }
-
-Service::Service(const std::string& name, std::unique_ptr<Endpoint> endpoint)
- : name_(name), endpoint_{std::move(endpoint)} {
- if (!endpoint_)
- return;
-
- const auto status = endpoint_->SetService(this);
- ALOGE_IF(!status, "Failed to set service context because: %s",
- status.GetErrorMessage().c_str());
-}
-
-Service::~Service() {
- if (endpoint_) {
- const auto status = endpoint_->SetService(nullptr);
- ALOGE_IF(!status, "Failed to clear service context because: %s",
- status.GetErrorMessage().c_str());
- }
-}
-
-std::shared_ptr<Service> Service::GetFromMessageInfo(const MessageInfo& info) {
- return info.service ? info.service->shared_from_this()
- : std::shared_ptr<Service>();
-}
-
-bool Service::IsInitialized() const { return endpoint_.get() != nullptr; }
-
-std::shared_ptr<Channel> Service::OnChannelOpen(Message& /*message*/) {
- return nullptr;
-}
-
-void Service::OnChannelClose(Message& /*message*/,
- const std::shared_ptr<Channel>& /*channel*/) {}
-
-Status<void> Service::SetChannel(int channel_id,
- const std::shared_ptr<Channel>& channel) {
- PDX_TRACE_NAME("Service::SetChannel");
- std::lock_guard<std::mutex> autolock(channels_mutex_);
-
- const auto status = endpoint_->SetChannel(channel_id, channel.get());
- if (!status) {
- ALOGE("%s::SetChannel: Failed to set channel context: %s\n", name_.c_str(),
- status.GetErrorMessage().c_str());
-
- // It's possible someone mucked with things behind our back by calling the C
- // API directly. Since we know the channel id isn't valid, make sure we
- // don't have it in the channels map.
- if (status.error() == ENOENT)
- channels_.erase(channel_id);
- } else {
- if (channel != nullptr)
- channels_[channel_id] = channel;
- else
- channels_.erase(channel_id);
- }
- return status;
-}
-
-std::shared_ptr<Channel> Service::GetChannel(int channel_id) const {
- PDX_TRACE_NAME("Service::GetChannel");
- std::lock_guard<std::mutex> autolock(channels_mutex_);
-
- auto search = channels_.find(channel_id);
- if (search != channels_.end())
- return search->second;
- else
- return nullptr;
-}
-
-Status<void> Service::CloseChannel(int channel_id) {
- PDX_TRACE_NAME("Service::CloseChannel");
- std::lock_guard<std::mutex> autolock(channels_mutex_);
-
- const auto status = endpoint_->CloseChannel(channel_id);
-
- // Always erase the map entry, in case someone mucked with things behind our
- // back using the C API directly.
- channels_.erase(channel_id);
-
- return status;
-}
-
-Status<void> Service::ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask) {
- PDX_TRACE_NAME("Service::ModifyChannelEvents");
- return endpoint_->ModifyChannelEvents(channel_id, clear_mask, set_mask);
-}
-
-Status<RemoteChannelHandle> Service::PushChannel(
- Message* message, int flags, const std::shared_ptr<Channel>& channel,
- int* channel_id) {
- PDX_TRACE_NAME("Service::PushChannel");
-
- std::lock_guard<std::mutex> autolock(channels_mutex_);
-
- int channel_id_temp = -1;
- Status<RemoteChannelHandle> ret =
- endpoint_->PushChannel(message, flags, channel.get(), &channel_id_temp);
- ALOGE_IF(!ret.ok(), "%s::PushChannel: Failed to push channel: %s",
- name_.c_str(), strerror(ret.error()));
-
- if (channel && channel_id_temp != -1)
- channels_[channel_id_temp] = channel;
- if (channel_id)
- *channel_id = channel_id_temp;
-
- return ret;
-}
-
-Status<int> Service::CheckChannel(const Message* message, ChannelReference ref,
- std::shared_ptr<Channel>* channel) const {
- PDX_TRACE_NAME("Service::CheckChannel");
-
- // Synchronization to maintain consistency between the kernel's channel
- // context pointer and the userspace channels_ map. Other threads may attempt
- // to modify the map at the same time, which could cause the channel context
- // pointer returned by the kernel to be invalid.
- std::lock_guard<std::mutex> autolock(channels_mutex_);
-
- Channel* channel_context = nullptr;
- Status<int> ret = endpoint_->CheckChannel(
- message, ref, channel ? &channel_context : nullptr);
- if (ret && channel) {
- if (channel_context)
- *channel = channel_context->shared_from_this();
- else
- *channel = nullptr;
- }
-
- return ret;
-}
-
-std::string Service::DumpState(size_t /*max_length*/) { return ""; }
-
-Status<void> Service::HandleMessage(Message& message) {
- return DefaultHandleMessage(message);
-}
-
-void Service::HandleImpulse(Message& /*impulse*/) {}
-
-Status<void> Service::HandleSystemMessage(Message& message) {
- const MessageInfo& info = message.GetInfo();
-
- switch (info.op) {
- case opcodes::CHANNEL_OPEN: {
- ALOGD("%s::OnChannelOpen: pid=%d cid=%d\n", name_.c_str(), info.pid,
- info.cid);
- message.SetChannel(OnChannelOpen(message));
- return message.Reply(0);
- }
-
- case opcodes::CHANNEL_CLOSE: {
- ALOGD("%s::OnChannelClose: pid=%d cid=%d\n", name_.c_str(), info.pid,
- info.cid);
- OnChannelClose(message, Channel::GetFromMessageInfo(info));
- message.SetChannel(nullptr);
- return message.Reply(0);
- }
-
- case opcodes::REPORT_SYSPROP_CHANGE:
- ALOGD("%s:REPORT_SYSPROP_CHANGE: pid=%d cid=%d\n", name_.c_str(),
- info.pid, info.cid);
- OnSysPropChange();
- android::report_sysprop_change();
- return message.Reply(0);
-
- case opcodes::DUMP_STATE: {
- ALOGD("%s:DUMP_STATE: pid=%d cid=%d\n", name_.c_str(), info.pid,
- info.cid);
- auto response = DumpState(message.GetReceiveLength());
- const size_t response_size = response.size() < message.GetReceiveLength()
- ? response.size()
- : message.GetReceiveLength();
- const Status<size_t> status =
- message.Write(response.data(), response_size);
- if (status && status.get() < response_size)
- return message.ReplyError(EIO);
- else
- return message.Reply(status);
- }
-
- default:
- return ErrorStatus{EOPNOTSUPP};
- }
-}
-
-Status<void> Service::DefaultHandleMessage(Message& message) {
- const MessageInfo& info = message.GetInfo();
-
- ALOGD_IF(TRACE, "Service::DefaultHandleMessage: pid=%d cid=%d op=%d\n",
- info.pid, info.cid, info.op);
-
- switch (info.op) {
- case opcodes::CHANNEL_OPEN:
- case opcodes::CHANNEL_CLOSE:
- case opcodes::REPORT_SYSPROP_CHANGE:
- case opcodes::DUMP_STATE:
- return HandleSystemMessage(message);
-
- default:
- return message.ReplyError(EOPNOTSUPP);
- }
-}
-
-void Service::OnSysPropChange() {}
-
-Status<void> Service::ReceiveAndDispatch() {
- Message message;
- const auto status = endpoint_->MessageReceive(&message);
- if (!status) {
- ALOGE("Failed to receive message: %s\n", status.GetErrorMessage().c_str());
- return status;
- }
-
- std::shared_ptr<Service> service = message.GetService();
-
- if (!service) {
- ALOGE("Service::ReceiveAndDispatch: service context is NULL!!!\n");
- // Don't block the sender indefinitely in this error case.
- endpoint_->MessageReply(&message, -EINVAL);
- return ErrorStatus{EINVAL};
- }
-
- if (message.IsImpulse()) {
- service->HandleImpulse(message);
- return {};
- } else if (service->HandleSystemMessage(message)) {
- return {};
- } else {
- return service->HandleMessage(message);
- }
-}
-
-Status<void> Service::Cancel() { return endpoint_->Cancel(); }
-
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx/service_dispatcher.cpp b/libs/vr/libpdx/service_dispatcher.cpp
deleted file mode 100644
index ba0d69c..0000000
--- a/libs/vr/libpdx/service_dispatcher.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-#include <pdx/service_dispatcher.h>
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <pdx/service.h>
-#include <pdx/service_endpoint.h>
-
-static const int kMaxEventsPerLoop = 128;
-
-namespace android {
-namespace pdx {
-
-std::unique_ptr<ServiceDispatcher> ServiceDispatcher::Create() {
- std::unique_ptr<ServiceDispatcher> dispatcher{new ServiceDispatcher()};
- if (!dispatcher->epoll_fd_ || !dispatcher->event_fd_) {
- dispatcher.reset();
- }
-
- return dispatcher;
-}
-
-ServiceDispatcher::ServiceDispatcher() {
- event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
- if (!event_fd_) {
- ALOGE("Failed to create event fd because: %s\n", strerror(errno));
- return;
- }
-
- epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
- if (!epoll_fd_) {
- ALOGE("Failed to create epoll fd because: %s\n", strerror(errno));
- return;
- }
-
- // Use "this" as a unique pointer to distinguish the event fd from all
- // the other entries that point to instances of Service.
- epoll_event event;
- event.events = EPOLLIN;
- event.data.ptr = this;
-
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, event_fd_.Get(), &event) < 0) {
- ALOGE("Failed to add event fd to epoll fd because: %s\n", strerror(errno));
-
- // Close the fds here and signal failure to the factory method.
- event_fd_.Close();
- epoll_fd_.Close();
- }
-}
-
-ServiceDispatcher::~ServiceDispatcher() { SetCanceled(true); }
-
-int ServiceDispatcher::ThreadEnter() {
- std::lock_guard<std::mutex> autolock(mutex_);
-
- if (canceled_)
- return -EBUSY;
-
- thread_count_++;
- return 0;
-}
-
-void ServiceDispatcher::ThreadExit() {
- std::lock_guard<std::mutex> autolock(mutex_);
- thread_count_--;
- condition_.notify_one();
-}
-
-int ServiceDispatcher::AddService(const std::shared_ptr<Service>& service) {
- std::lock_guard<std::mutex> autolock(mutex_);
-
- epoll_event event;
- event.events = EPOLLIN;
- event.data.ptr = service.get();
-
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, service->endpoint()->epoll_fd(),
- &event) < 0) {
- ALOGE("Failed to add service to dispatcher because: %s\n", strerror(errno));
- return -errno;
- }
-
- services_.push_back(service);
- return 0;
-}
-
-int ServiceDispatcher::RemoveService(const std::shared_ptr<Service>& service) {
- std::lock_guard<std::mutex> autolock(mutex_);
-
- // It's dangerous to remove a service while other threads may be using it.
- if (thread_count_ > 0)
- return -EBUSY;
-
- epoll_event ee; // See BUGS in man 2 epoll_ctl.
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, service->endpoint()->epoll_fd(),
- &ee) < 0) {
- ALOGE("Failed to remove service from dispatcher because: %s\n",
- strerror(errno));
- return -errno;
- }
-
- services_.erase(std::remove(services_.begin(), services_.end(), service),
- services_.end());
- return 0;
-}
-
-int ServiceDispatcher::ReceiveAndDispatch() { return ReceiveAndDispatch(-1); }
-
-int ServiceDispatcher::ReceiveAndDispatch(int timeout) {
- int ret = ThreadEnter();
- if (ret < 0)
- return ret;
-
- epoll_event events[kMaxEventsPerLoop];
-
- int count = epoll_wait(epoll_fd_.Get(), events, kMaxEventsPerLoop, timeout);
- if (count <= 0) {
- ALOGE_IF(count < 0, "Failed to wait for epoll events because: %s\n",
- strerror(errno));
- ThreadExit();
- return count < 0 ? -errno : -ETIMEDOUT;
- }
-
- for (int i = 0; i < count; i++) {
- if (events[i].data.ptr == this) {
- ThreadExit();
- return -EBUSY;
- } else {
- Service* service = static_cast<Service*>(events[i].data.ptr);
-
- ALOGI_IF(TRACE, "Dispatching message: fd=%d\n",
- service->endpoint()->epoll_fd());
- service->ReceiveAndDispatch();
- }
- }
-
- ThreadExit();
- return 0;
-}
-
-int ServiceDispatcher::EnterDispatchLoop() {
- int ret = ThreadEnter();
- if (ret < 0)
- return ret;
-
- epoll_event events[kMaxEventsPerLoop];
-
- while (!IsCanceled()) {
- int count = epoll_wait(epoll_fd_.Get(), events, kMaxEventsPerLoop, -1);
- if (count < 0 && errno != EINTR) {
- ALOGE("Failed to wait for epoll events because: %s\n", strerror(errno));
- ThreadExit();
- return -errno;
- }
-
- for (int i = 0; i < count; i++) {
- if (events[i].data.ptr == this) {
- ThreadExit();
- return -EBUSY;
- } else {
- Service* service = static_cast<Service*>(events[i].data.ptr);
-
- ALOGI_IF(TRACE, "Dispatching message: fd=%d\n",
- service->endpoint()->epoll_fd());
- service->ReceiveAndDispatch();
- }
- }
- }
-
- ThreadExit();
- return 0;
-}
-
-void ServiceDispatcher::SetCanceled(bool cancel) {
- std::unique_lock<std::mutex> lock(mutex_);
- canceled_ = cancel;
-
- if (canceled_ && thread_count_ > 0) {
- eventfd_write(event_fd_.Get(), 1); // Signal threads to quit.
-
- condition_.wait(lock, [this] { return !(canceled_ && thread_count_ > 0); });
-
- eventfd_t value;
- eventfd_read(event_fd_.Get(), &value); // Unsignal.
- }
-}
-
-bool ServiceDispatcher::IsCanceled() const { return canceled_; }
-
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx/service_tests.cpp b/libs/vr/libpdx/service_tests.cpp
deleted file mode 100644
index 938d737..0000000
--- a/libs/vr/libpdx/service_tests.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-#include <pdx/service.h>
-
-#include <memory>
-#include <string>
-
-#include <gmock/gmock.h>
-#include <pdx/mock_service_endpoint.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ChannelReference;
-using android::pdx::ErrorStatus;
-using android::pdx::FileReference;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::MessageInfo;
-using android::pdx::MockEndpoint;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::Service;
-using android::pdx::Status;
-
-using testing::A;
-using testing::ByMove;
-using testing::DoAll;
-using testing::Invoke;
-using testing::Matcher;
-using testing::Ref;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::WithArg;
-using testing::WithoutArgs;
-using testing::_;
-
-namespace {
-
-// Helper functions to construct fake void pointers for tests.
-inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
-
-// Helper matchers for working with iovec structures in tests.
-// Simple matcher for one element iovec array:
-// EXPECT_CALL(mock, method(IoVecMatcher(ptr, size)));
-MATCHER_P2(IoVecMatcher, ptr, size, "") {
- return arg->iov_base == ptr && arg->iov_len == size;
-}
-
-// Matcher for an array of iovecs:
-// EXPECT_CALL(mock,
-// method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}})));
-using IoVecArray = std::vector<iovec>;
-MATCHER_P(IoVecMatcher, iovec_array, "") {
- auto local_arg = arg;
- for (const iovec& item : iovec_array) {
- if (local_arg->iov_base != item.iov_base || local_arg->iov_len != item.iov_len)
- return false;
- local_arg++;
- }
- return true;
-}
-
-using IoVecData = std::vector<std::string>;
-MATCHER_P(IoVecDataMatcher, iovec_data, "") {
- auto local_arg = arg;
- for (const std::string& item : iovec_data) {
- std::string data{reinterpret_cast<const char*>(local_arg->iov_base),
- local_arg->iov_len};
- if (data != item)
- return false;
- local_arg++;
- }
- return true;
-}
-
-MATCHER_P(FileHandleMatcher, value, "") { return arg.Get() == value; }
-MATCHER_P(ChannelHandleMatcher, value, "") { return arg.value() == value; }
-
-enum : int {
- kTestPid = 1,
- kTestTid,
- kTestCid,
- kTestMid,
- kTestEuid,
- kTestEgid,
- kTestOp,
-};
-
-class MockService : public Service {
- public:
- using Service::Service;
- MOCK_METHOD1(OnChannelOpen, std::shared_ptr<Channel>(Message& message));
- MOCK_METHOD2(OnChannelClose,
- void(Message& message, const std::shared_ptr<Channel>& channel));
- MOCK_METHOD1(HandleMessage, Status<void>(Message& message));
- MOCK_METHOD1(HandleImpulse, void(Message& impulse));
- MOCK_METHOD0(OnSysPropChange, void());
- MOCK_METHOD1(DumpState, std::string(size_t max_length));
-};
-
-class ServiceTest : public testing::Test {
- public:
- ServiceTest() {
- auto endpoint = std::make_unique<testing::StrictMock<MockEndpoint>>();
- EXPECT_CALL(*endpoint, SetService(_))
- .Times(2)
- .WillRepeatedly(Return(Status<void>{}));
- service_ = std::make_shared<MockService>("MockSvc", std::move(endpoint));
- }
-
- MockEndpoint* endpoint() {
- return static_cast<MockEndpoint*>(service_->endpoint());
- }
-
- void SetupMessageInfo(MessageInfo* info, int32_t op, bool impulse = false) {
- info->pid = kTestPid;
- info->tid = kTestTid;
- info->cid = kTestCid;
- info->mid = impulse ? Message::IMPULSE_MESSAGE_ID : kTestMid;
- info->euid = kTestEuid;
- info->egid = kTestEgid;
- info->op = op;
- info->flags = 0;
- info->service = service_.get();
- info->channel = nullptr;
- info->send_len = 0;
- info->recv_len = 0;
- info->fd_count = 0;
- memset(info->impulse, 0, sizeof(info->impulse));
- }
-
- void SetupMessageInfoAndDefaultExpectations(MessageInfo* info, int32_t op,
- bool impulse = false) {
- SetupMessageInfo(info, op, impulse);
- EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
- EXPECT_CALL(*endpoint(), FreeMessageState(kState));
- }
-
- void ExpectDefaultHandleMessage() {
- EXPECT_CALL(*endpoint(), MessageReply(_, -EOPNOTSUPP))
- .WillOnce(Return(Status<void>{}));
- }
-
- std::shared_ptr<MockService> service_;
- void* kState = IntToPtr(123456);
-};
-
-class ServiceMessageTest : public ServiceTest {
- public:
- ServiceMessageTest() {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
- message_ = std::make_unique<Message>(info);
- }
-
- std::unique_ptr<Message> message_;
-};
-
-} // anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////
-// Service class tests
-///////////////////////////////////////////////////////////////////////////////
-
-TEST_F(ServiceTest, IsInitialized) {
- EXPECT_TRUE(service_->IsInitialized());
- service_ = std::make_shared<MockService>("MockSvc2", nullptr);
- EXPECT_FALSE(service_->IsInitialized());
-}
-
-TEST_F(ServiceTest, ConstructMessage) {
- MessageInfo info;
- SetupMessageInfo(&info, kTestOp);
- auto test_channel = std::make_shared<Channel>();
- info.channel = test_channel.get();
- EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
-
- Message message{info};
-
- EXPECT_FALSE(message.IsImpulse());
- EXPECT_EQ(kTestPid, message.GetProcessId());
- EXPECT_EQ(kTestTid, message.GetThreadId());
- EXPECT_EQ(kTestCid, message.GetChannelId());
- EXPECT_EQ(kTestMid, message.GetMessageId());
- EXPECT_EQ((unsigned) kTestEuid, message.GetEffectiveUserId());
- EXPECT_EQ((unsigned) kTestEgid, message.GetEffectiveGroupId());
- EXPECT_EQ(kTestOp, message.GetOp());
- EXPECT_EQ(service_, message.GetService());
- EXPECT_EQ(test_channel, message.GetChannel());
- EXPECT_FALSE(message.replied());
- EXPECT_FALSE(message.IsChannelExpired());
- EXPECT_FALSE(message.IsServiceExpired());
- EXPECT_EQ(kState, message.GetState());
-
- ExpectDefaultHandleMessage();
- EXPECT_CALL(*endpoint(), FreeMessageState(kState));
-}
-
-TEST_F(ServiceTest, ConstructImpulseMessage) {
- MessageInfo info;
- SetupMessageInfo(&info, kTestOp, true);
- auto test_channel = std::make_shared<Channel>();
- info.channel = test_channel.get();
- EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
-
- Message message{info};
-
- EXPECT_TRUE(message.IsImpulse());
- EXPECT_EQ(kTestOp, message.GetOp());
- EXPECT_EQ(service_, message.GetService());
- EXPECT_EQ(test_channel, message.GetChannel());
- EXPECT_TRUE(message.replied());
- EXPECT_FALSE(message.IsChannelExpired());
- EXPECT_FALSE(message.IsServiceExpired());
-
- // DefaultHandleMessage should not be called here.
- EXPECT_CALL(*endpoint(), FreeMessageState(nullptr));
-}
-
-TEST_F(ServiceTest, HandleMessageChannelOpen) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info,
- android::pdx::opcodes::CHANNEL_OPEN);
- Message message{info};
-
- auto channel = std::make_shared<Channel>();
- EXPECT_CALL(*service_, OnChannelOpen(Ref(message))).WillOnce(Return(channel));
- EXPECT_CALL(*endpoint(), SetChannel(kTestCid, channel.get()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageChannelClose) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info,
- android::pdx::opcodes::CHANNEL_CLOSE);
- auto channel = std::make_shared<Channel>();
- info.channel = channel.get();
- Message message{info};
-
- EXPECT_CALL(*service_, OnChannelClose(Ref(message), channel));
- EXPECT_CALL(*endpoint(), SetChannel(kTestCid, nullptr))
- .WillOnce(Return(Status<void>{}));
- EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnSysPropChange) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(
- &info, android::pdx::opcodes::REPORT_SYSPROP_CHANGE);
- Message message{info};
-
- EXPECT_CALL(*service_, OnSysPropChange());
- EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpState) {
- const size_t kRecvBufSize = 1000;
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info,
- android::pdx::opcodes::DUMP_STATE);
- info.recv_len = kRecvBufSize;
- Message message{info};
-
- const std::string kReply = "foo";
- EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
- EXPECT_CALL(
- *endpoint(),
- WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
- .WillOnce(Return(kReply.size()));
- EXPECT_CALL(*endpoint(), MessageReply(&message, kReply.size()))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpStateTooLarge) {
- const size_t kRecvBufSize = 3;
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info,
- android::pdx::opcodes::DUMP_STATE);
- info.recv_len = kRecvBufSize;
- Message message{info};
-
- const std::string kReply = "0123456789";
- const std::string kActualReply = kReply.substr(0, kRecvBufSize);
- EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
- EXPECT_CALL(
- *endpoint(),
- WriteMessageData(&message, IoVecDataMatcher(IoVecData{kActualReply}), 1))
- .WillOnce(Return(kActualReply.size()));
- EXPECT_CALL(*endpoint(), MessageReply(&message, kActualReply.size()))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageOnDumpStateFail) {
- const size_t kRecvBufSize = 1000;
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info,
- android::pdx::opcodes::DUMP_STATE);
- info.recv_len = kRecvBufSize;
- Message message{info};
-
- const std::string kReply = "foo";
- EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
- EXPECT_CALL(
- *endpoint(),
- WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
- .WillOnce(Return(1));
- EXPECT_CALL(*endpoint(), MessageReply(&message, -EIO))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, HandleMessageCustom) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
- Message message{info};
-
- EXPECT_CALL(*endpoint(), MessageReply(&message, -EOPNOTSUPP))
- .WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->Service::HandleMessage(message));
-}
-
-TEST_F(ServiceTest, ReplyMessageWithoutService) {
- MessageInfo info;
- SetupMessageInfo(&info, kTestOp);
- EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
-
- Message message{info};
-
- EXPECT_FALSE(message.IsServiceExpired());
- service_.reset();
- EXPECT_TRUE(message.IsServiceExpired());
-
- EXPECT_EQ(EINVAL, message.Reply(12).error());
-}
-
-TEST_F(ServiceTest, ReceiveAndDispatchMessage) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
- ExpectDefaultHandleMessage();
-
- auto on_receive = [&info](Message* message) -> Status<void> {
- *message = Message{info};
- return {};
- };
- EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
- EXPECT_CALL(*service_, HandleMessage(_)).WillOnce(Return(Status<void>{}));
-
- EXPECT_TRUE(service_->ReceiveAndDispatch());
-}
-
-TEST_F(ServiceTest, ReceiveAndDispatchImpulse) {
- MessageInfo info;
- SetupMessageInfoAndDefaultExpectations(&info, kTestOp, true);
-
- auto on_receive = [&info](Message* message) -> Status<void> {
- *message = Message{info};
- return {};
- };
- EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
- EXPECT_CALL(*service_, HandleImpulse(_));
-
- EXPECT_TRUE(service_->ReceiveAndDispatch());
-}
-
-TEST_F(ServiceTest, Cancel) {
- EXPECT_CALL(*endpoint(), Cancel()).WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(service_->Cancel());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Message class tests
-///////////////////////////////////////////////////////////////////////////////
-
-TEST_F(ServiceMessageTest, Reply) {
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
- .WillOnce(Return(Status<void>{}));
- EXPECT_FALSE(message_->replied());
- EXPECT_TRUE(message_->Reply(12));
- EXPECT_TRUE(message_->replied());
-
- EXPECT_EQ(EINVAL, message_->Reply(12).error()); // Already replied.
-}
-
-TEST_F(ServiceMessageTest, ReplyFail) {
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(EIO, message_->Reply(12).error());
-
- ExpectDefaultHandleMessage();
-}
-
-TEST_F(ServiceMessageTest, ReplyError) {
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -12))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->ReplyError(12));
-}
-
-TEST_F(ServiceMessageTest, ReplyFileDescriptor) {
- EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), 5))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->ReplyFileDescriptor(5));
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalFileHandle) {
- const int kFakeFd = 12345;
- LocalHandle handle{kFakeFd};
- EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
- handle.Release(); // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalFileHandleError) {
- LocalHandle handle{-EINVAL};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EINVAL))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedFileHandle) {
- const int kFakeFd = 12345;
- BorrowedHandle handle{kFakeFd};
- EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedFileHandleError) {
- BorrowedHandle handle{-EACCES};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EACCES))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteFileHandle) {
- RemoteHandle handle{123};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), handle.Get()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteFileHandleError) {
- RemoteHandle handle{-EIO};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EIO))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyLocalChannelHandle) {
- LocalChannelHandle handle{nullptr, 12345};
- EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
- message_.get(), A<const LocalChannelHandle&>()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyBorrowedChannelHandle) {
- BorrowedChannelHandle handle{12345};
- EXPECT_CALL(*endpoint(),
- MessageReplyChannelHandle(message_.get(),
- A<const BorrowedChannelHandle&>()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyRemoteChannelHandle) {
- RemoteChannelHandle handle{12345};
- EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
- message_.get(), A<const RemoteChannelHandle&>()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(handle));
-}
-
-TEST_F(ServiceMessageTest, ReplyStatusInt) {
- Status<int> status{123};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), status.get()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(status));
-}
-
-TEST_F(ServiceMessageTest, ReplyStatusError) {
- Status<int> status{ErrorStatus{EIO}};
- EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -status.error()))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->Reply(status));
-}
-
-TEST_F(ServiceMessageTest, Read) {
- ExpectDefaultHandleMessage();
- void* const kDataBuffer = IntToPtr(12345);
- const size_t kDataSize = 100;
- EXPECT_CALL(
- *endpoint(),
- ReadMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
- .WillOnce(Return(50))
- .WillOnce(Return(ErrorStatus{EACCES}));
- EXPECT_EQ(50u, message_->Read(kDataBuffer, kDataSize).get());
- EXPECT_EQ(EACCES, message_->Read(kDataBuffer, kDataSize).error());
-}
-
-TEST_F(ServiceMessageTest, ReadVector) {
- ExpectDefaultHandleMessage();
- char buffer1[10];
- char buffer2[20];
- iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
- EXPECT_CALL(*endpoint(),
- ReadMessageData(
- message_.get(),
- IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
- .WillOnce(Return(30))
- .WillOnce(Return(15))
- .WillOnce(Return(ErrorStatus{EBADF}));
- EXPECT_EQ(30u, message_->ReadVector(vec, 2).get());
- EXPECT_EQ(15u, message_->ReadVector(vec).get());
- EXPECT_EQ(EBADF, message_->ReadVector(vec).error());
-}
-
-TEST_F(ServiceMessageTest, Write) {
- ExpectDefaultHandleMessage();
- void* const kDataBuffer = IntToPtr(12345);
- const size_t kDataSize = 100;
- EXPECT_CALL(
- *endpoint(),
- WriteMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
- .WillOnce(Return(50))
- .WillOnce(Return(ErrorStatus{EBADMSG}));
- EXPECT_EQ(50u, message_->Write(kDataBuffer, kDataSize).get());
- EXPECT_EQ(EBADMSG, message_->Write(kDataBuffer, kDataSize).error());
-}
-
-TEST_F(ServiceMessageTest, WriteVector) {
- ExpectDefaultHandleMessage();
- char buffer1[10];
- char buffer2[20];
- iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
- EXPECT_CALL(*endpoint(),
- WriteMessageData(
- message_.get(),
- IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
- .WillOnce(Return(30))
- .WillOnce(Return(15))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(30u, message_->WriteVector(vec, 2).get());
- EXPECT_EQ(15u, message_->WriteVector(vec).get());
- EXPECT_EQ(EIO, message_->WriteVector(vec, 2).error());
-}
-
-TEST_F(ServiceMessageTest, PushLocalFileHandle) {
- ExpectDefaultHandleMessage();
- const int kFakeFd = 12345;
- LocalHandle handle{kFakeFd};
- EXPECT_CALL(*endpoint(),
- PushFileHandle(message_.get(), Matcher<const LocalHandle&>(
- FileHandleMatcher(kFakeFd))))
- .WillOnce(Return(12))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(12, message_->PushFileHandle(handle).get());
- EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
- handle.Release(); // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, PushBorrowedFileHandle) {
- ExpectDefaultHandleMessage();
- const int kFakeFd = 12345;
- BorrowedHandle handle{kFakeFd};
- EXPECT_CALL(*endpoint(),
- PushFileHandle(message_.get(), Matcher<const BorrowedHandle&>(
- FileHandleMatcher(kFakeFd))))
- .WillOnce(Return(13))
- .WillOnce(Return(ErrorStatus{EACCES}));
- EXPECT_EQ(13, message_->PushFileHandle(handle).get());
- EXPECT_EQ(EACCES, message_->PushFileHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushRemoteFileHandle) {
- ExpectDefaultHandleMessage();
- const int kFakeFd = 12345;
- RemoteHandle handle{kFakeFd};
- EXPECT_CALL(*endpoint(),
- PushFileHandle(message_.get(), Matcher<const RemoteHandle&>(
- FileHandleMatcher(kFakeFd))))
- .WillOnce(Return(kFakeFd))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(kFakeFd, message_->PushFileHandle(handle).get());
- EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushLocalChannelHandle) {
- ExpectDefaultHandleMessage();
- int32_t kValue = 12345;
- LocalChannelHandle handle{nullptr, kValue};
- EXPECT_CALL(*endpoint(), PushChannelHandle(message_.get(),
- Matcher<const LocalChannelHandle&>(
- ChannelHandleMatcher(kValue))))
- .WillOnce(Return(7))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(7, message_->PushChannelHandle(handle).get());
- EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushBorrowedChannelHandle) {
- ExpectDefaultHandleMessage();
- int32_t kValue = 12345;
- BorrowedChannelHandle handle{kValue};
- EXPECT_CALL(
- *endpoint(),
- PushChannelHandle(message_.get(), Matcher<const BorrowedChannelHandle&>(
- ChannelHandleMatcher(kValue))))
- .WillOnce(Return(8))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(8, message_->PushChannelHandle(handle).get());
- EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, PushRemoteChannelHandle) {
- ExpectDefaultHandleMessage();
- int32_t kValue = 12345;
- RemoteChannelHandle handle{kValue};
- EXPECT_CALL(
- *endpoint(),
- PushChannelHandle(message_.get(), Matcher<const RemoteChannelHandle&>(
- ChannelHandleMatcher(kValue))))
- .WillOnce(Return(kValue))
- .WillOnce(Return(ErrorStatus{EIO}));
- EXPECT_EQ(kValue, message_->PushChannelHandle(handle).get());
- EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
-}
-
-TEST_F(ServiceMessageTest, GetFileHandle) {
- ExpectDefaultHandleMessage();
- auto make_file_handle = [](FileReference ref) { return LocalHandle{ref}; };
- EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
- .WillOnce(WithArg<1>(Invoke(make_file_handle)));
- LocalHandle handle;
- FileReference kRef = 12345;
- EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
- EXPECT_EQ(kRef, handle.Get());
- handle.Release(); // Make sure we do not close the fake file descriptor.
-}
-
-TEST_F(ServiceMessageTest, GetFileHandleInvalid) {
- ExpectDefaultHandleMessage();
- LocalHandle handle;
- FileReference kRef = -12;
- EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
- EXPECT_EQ(kRef, handle.Get());
-}
-
-TEST_F(ServiceMessageTest, GetFileHandleError) {
- ExpectDefaultHandleMessage();
- EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
- .WillOnce(WithoutArgs(Invoke([] { return LocalHandle{-EIO}; })));
- LocalHandle handle;
- FileReference kRef = 12345;
- EXPECT_FALSE(message_->GetFileHandle(kRef, &handle));
- EXPECT_EQ(-EIO, handle.Get());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandle) {
- ExpectDefaultHandleMessage();
- auto make_channel_handle = [](ChannelReference ref) {
- return LocalChannelHandle{nullptr, ref};
- };
- EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
- .WillOnce(WithArg<1>(Invoke(make_channel_handle)));
- LocalChannelHandle handle;
- ChannelReference kRef = 12345;
- EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
- EXPECT_EQ(kRef, handle.value());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandleInvalid) {
- ExpectDefaultHandleMessage();
- LocalChannelHandle handle;
- ChannelReference kRef = -12;
- EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
- EXPECT_EQ(-12, handle.value());
-}
-
-TEST_F(ServiceMessageTest, GetChannelHandleError) {
- ExpectDefaultHandleMessage();
- EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
- .WillOnce(WithoutArgs(Invoke([] {
- return LocalChannelHandle{nullptr, -EIO};
- })));
- LocalChannelHandle handle;
- ChannelReference kRef = 12345;
- EXPECT_FALSE(message_->GetChannelHandle(kRef, &handle));
- EXPECT_EQ(-EIO, handle.value());
-}
-
-TEST_F(ServiceMessageTest, ModifyChannelEvents) {
- ExpectDefaultHandleMessage();
- int kClearMask = 1;
- int kSetMask = 2;
- EXPECT_CALL(*endpoint(), ModifyChannelEvents(kTestCid, kClearMask, kSetMask))
- .WillOnce(Return(Status<void>{}));
- EXPECT_TRUE(message_->ModifyChannelEvents(kClearMask, kSetMask));
-}
-
-TEST_F(ServiceMessageTest, PushChannelSameService) {
- ExpectDefaultHandleMessage();
- int kFlags = 123;
- int32_t kValue = 12;
- EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
- .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
- Return(ByMove(RemoteChannelHandle{kValue}))));
- int channel_id = -1;
- auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
- ASSERT_TRUE(status);
- EXPECT_EQ(kValue, status.get().value());
- EXPECT_EQ(kTestCid, channel_id);
-}
-
-TEST_F(ServiceMessageTest, PushChannelFailure) {
- ExpectDefaultHandleMessage();
- int kFlags = 123;
- EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
- .WillOnce(Return(ByMove(ErrorStatus{EIO})));
- int channel_id = -1;
- auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(ServiceMessageTest, PushChannelDifferentService) {
- ExpectDefaultHandleMessage();
- auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
- EXPECT_CALL(*endpoint2, SetService(_))
- .Times(2)
- .WillRepeatedly(Return(Status<void>{}));
- auto service2 =
- std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
-
- int kFlags = 123;
- int32_t kValue = 12;
- EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
- PushChannel(message_.get(), kFlags, nullptr, _))
- .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
- Return(ByMove(RemoteChannelHandle{kValue}))));
- int channel_id = -1;
- auto status =
- message_->PushChannel(service2.get(), kFlags, nullptr, &channel_id);
- ASSERT_TRUE(status);
- EXPECT_EQ(kValue, status.get().value());
- EXPECT_EQ(kTestCid, channel_id);
-}
-
-TEST_F(ServiceMessageTest, CheckChannelSameService) {
- ExpectDefaultHandleMessage();
-
- auto test_channel = std::make_shared<Channel>();
- ChannelReference kRef = 123;
- EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
- .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
- std::shared_ptr<Channel> channel;
- auto status = message_->CheckChannel(kRef, &channel);
- ASSERT_TRUE(status);
- EXPECT_EQ(kTestCid, status.get());
- EXPECT_EQ(test_channel, channel);
-}
-
-TEST_F(ServiceMessageTest, CheckChannelFailure) {
- ExpectDefaultHandleMessage();
- ChannelReference kRef = 123;
- EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
- .WillOnce(Return(ByMove(ErrorStatus{EOPNOTSUPP})));
- std::shared_ptr<Channel> channel;
- auto status = message_->CheckChannel(kRef, &channel);
- ASSERT_FALSE(status);
- EXPECT_EQ(EOPNOTSUPP, status.error());
-}
-
-TEST_F(ServiceMessageTest, CheckChannelDifferentService) {
- ExpectDefaultHandleMessage();
- auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
- EXPECT_CALL(*endpoint2, SetService(_))
- .Times(2)
- .WillRepeatedly(Return(Status<void>{}));
- auto service2 =
- std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
-
- auto test_channel = std::make_shared<Channel>();
- ChannelReference kRef = 123;
- EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
- CheckChannel(message_.get(), kRef, _))
- .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
- std::shared_ptr<Channel> channel;
- auto status = message_->CheckChannel(service2.get(), kRef, &channel);
- ASSERT_TRUE(status);
- EXPECT_EQ(kTestCid, status.get());
- EXPECT_EQ(test_channel, channel);
-}
diff --git a/libs/vr/libpdx/status.cpp b/libs/vr/libpdx/status.cpp
deleted file mode 100644
index c275daf..0000000
--- a/libs/vr/libpdx/status.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "pdx/status.h"
-
-#include <pdx/rpc/serialization.h>
-#include <string.h>
-
-namespace android {
-namespace pdx {
-
-std::string ErrorStatus::ErrorToString(int error_code) {
- char message[1024] = {};
- return strerror_r(error_code, message, sizeof(message));
-}
-
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx/status_tests.cpp b/libs/vr/libpdx/status_tests.cpp
deleted file mode 100644
index 772c529..0000000
--- a/libs/vr/libpdx/status_tests.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include <pdx/status.h>
-
-#include <gtest/gtest.h>
-
-#include <memory>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-TEST(Status, DefaultInit) {
- Status<int> status;
- EXPECT_FALSE(status.ok());
- EXPECT_TRUE(status.empty());
- EXPECT_EQ(0, status.get());
- EXPECT_EQ(0, status.error());
-}
-
-TEST(Status, InitalizeSuccess) {
- Status<int> status_int{0};
- EXPECT_FALSE(status_int.empty());
- EXPECT_TRUE(status_int.ok());
- EXPECT_EQ(0, status_int.get());
- status_int = Status<int>(3);
- EXPECT_FALSE(status_int.empty());
- EXPECT_TRUE(status_int.ok());
- EXPECT_EQ(3, status_int.get());
- status_int = Status<int>(-3);
- EXPECT_FALSE(status_int.empty());
- EXPECT_TRUE(status_int.ok());
- EXPECT_EQ(-3, status_int.get());
-
- Status<std::string> status_str{"foo"};
- EXPECT_FALSE(status_str.empty());
- EXPECT_TRUE(status_str.ok());
- EXPECT_EQ("foo", status_str.get());
-}
-
-TEST(Status, InitalizeError) {
- Status<int> status_int = ErrorStatus(12);
- EXPECT_FALSE(status_int.empty());
- EXPECT_FALSE(status_int.ok());
- EXPECT_EQ(0, status_int.get());
- EXPECT_EQ(12, status_int.error());
-
- Status<std::string> status_str = ErrorStatus(EIO);
- EXPECT_FALSE(status_str.empty());
- EXPECT_FALSE(status_str.ok());
- EXPECT_EQ(EIO, status_str.error());
-}
-
-TEST(Status, ErrorMessage) {
- Status<int> status = ErrorStatus(EIO);
- EXPECT_EQ(status.GetErrorMessage(), strerror(EIO));
-
- status = ErrorStatus(EINVAL);
- EXPECT_EQ(status.GetErrorMessage(), strerror(EINVAL));
-}
-
-TEST(Status, Copy) {
- Status<int> status1;
- Status<int> status2;
-
- status1 = Status<int>{12};
- status2 = ErrorStatus(13);
- EXPECT_FALSE(status1.empty());
- EXPECT_FALSE(status2.empty());
- EXPECT_TRUE(status1.ok());
- EXPECT_FALSE(status2.ok());
- EXPECT_EQ(12, status1.get());
- EXPECT_EQ(0, status1.error());
- EXPECT_EQ(0, status2.get());
- EXPECT_EQ(13, status2.error());
-
- status1 = status2;
- EXPECT_FALSE(status1.empty());
- EXPECT_FALSE(status2.empty());
- EXPECT_FALSE(status1.ok());
- EXPECT_FALSE(status2.ok());
- EXPECT_EQ(0, status1.get());
- EXPECT_EQ(13, status1.error());
- EXPECT_EQ(0, status2.get());
- EXPECT_EQ(13, status2.error());
-}
-
-TEST(Status, Move) {
- Status<std::unique_ptr<int>> status1;
- Status<std::unique_ptr<int>> status2;
-
- status1 = Status<std::unique_ptr<int>>{std::make_unique<int>(int{11})};
- status2 = Status<std::unique_ptr<int>>{std::make_unique<int>(int{12})};
- EXPECT_FALSE(status1.empty());
- EXPECT_FALSE(status2.empty());
- EXPECT_TRUE(status1.ok());
- EXPECT_TRUE(status2.ok());
- EXPECT_EQ(11, *status1.get());
- EXPECT_EQ(12, *status2.get());
-
- Status<std::unique_ptr<int>> status3 = std::move(status2);
- EXPECT_FALSE(status1.empty());
- EXPECT_TRUE(status2.empty());
- EXPECT_FALSE(status3.empty());
- EXPECT_TRUE(status1.ok());
- EXPECT_FALSE(status2.ok());
- EXPECT_TRUE(status3.ok());
- EXPECT_EQ(11, *status1.get());
- EXPECT_EQ(nullptr, status2.get());
- EXPECT_EQ(12, *status3.get());
-
- std::swap(status1, status3);
- EXPECT_EQ(12, *status1.get());
- EXPECT_EQ(11, *status3.get());
-
- status3 = std::move(status1);
- EXPECT_TRUE(status1.empty());
- EXPECT_EQ(12, *status3.get());
-}
-
-TEST(Status, Take) {
- Status<std::unique_ptr<int>> status{std::make_unique<int>(int{123})};
- EXPECT_FALSE(status.empty());
- EXPECT_NE(nullptr, status.get());
-
- auto data = status.take();
- EXPECT_TRUE(status.empty());
- EXPECT_EQ(nullptr, status.get());
- EXPECT_EQ(123, *data);
-}
diff --git a/libs/vr/libpdx/thread_local_buffer_tests.cpp b/libs/vr/libpdx/thread_local_buffer_tests.cpp
deleted file mode 100644
index 6cdaf10..0000000
--- a/libs/vr/libpdx/thread_local_buffer_tests.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <memory>
-#include <string>
-#include <thread>
-#include <utility>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/message_buffer.h>
-
-namespace android {
-namespace pdx {
-namespace rpc {
-
-class ThreadLocalBufferTest {
- public:
- // Returns the unique address of the thread-local buffer. Used to test the
- // correct behavior of the type-based thread local storage slot mapping
- // mechanism.
- template <typename Slot>
- static std::uintptr_t GetSlotAddress() {
- return reinterpret_cast<std::uintptr_t>(&MessageBuffer<Slot>::buffer_);
- }
-
- // Returns the raw value of the thread local buffer. Used to test the behavior
- // of backing buffer initialization.
- template <typename Slot>
- static std::uintptr_t GetSlotValue() {
- return reinterpret_cast<std::uintptr_t>(MessageBuffer<Slot>::buffer_);
- }
-};
-
-} // namespace rpc
-} // namespace pdx
-} // namespace android
-
-using namespace android::pdx::rpc;
-
-namespace {
-
-struct TypeTagA;
-struct TypeTagB;
-
-constexpr std::size_t kSendBufferIndex = 0;
-constexpr std::size_t kReceiveBufferIndex = 1;
-
-using SendSlotA = ThreadLocalSlot<TypeTagA, kSendBufferIndex>;
-using SendSlotB = ThreadLocalSlot<TypeTagB, kSendBufferIndex>;
-using ReceiveSlotA = ThreadLocalSlot<TypeTagA, kReceiveBufferIndex>;
-using ReceiveSlotB = ThreadLocalSlot<TypeTagB, kReceiveBufferIndex>;
-
-} // anonymous namespace
-
-// Tests that index and type-based thread-local slot addressing works by
-// checking that the slot address is the same when the same index/type
-// combination is used and different when different combinations are used.
-TEST(ThreadLocalBufferTest, TypeSlots) {
- auto id1 = ThreadLocalBufferTest::GetSlotAddress<SendSlotA>();
- auto id2 = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotA>();
- auto id3 = ThreadLocalBufferTest::GetSlotAddress<SendSlotB>();
- auto id4 = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotB>();
-
- EXPECT_NE(id1, id2);
- EXPECT_NE(id3, id4);
- EXPECT_NE(id1, id3);
- EXPECT_NE(id2, id4);
-
- auto id1_alias = ThreadLocalBufferTest::GetSlotAddress<SendSlotA>();
- auto id2_alias = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotA>();
- auto id3_alias = ThreadLocalBufferTest::GetSlotAddress<SendSlotB>();
- auto id4_alias = ThreadLocalBufferTest::GetSlotAddress<ReceiveSlotB>();
-
- EXPECT_EQ(id1, id1_alias);
- EXPECT_EQ(id2, id2_alias);
- EXPECT_EQ(id3, id3_alias);
- EXPECT_EQ(id4, id4_alias);
-}
-
-// Tests that different threads get different buffers for the same slot address.
-TEST(ThreadLocalBufferTest, ThreadSlots) {
- auto id1 = ThreadLocalBufferTest::GetSlotAddress<SendBuffer>();
- std::uintptr_t id2 = 0U;
-
- std::thread thread([&id2]() mutable {
- id2 = ThreadLocalBufferTest::GetSlotAddress<SendBuffer>();
- });
- thread.join();
-
- EXPECT_NE(0U, id1);
- EXPECT_NE(0U, id2);
- EXPECT_NE(id1, id2);
-}
-
-// Tests that thread-local buffers are allocated at the first buffer request.
-TEST(ThreadLocalBufferTest, InitialValue) {
- struct TypeTagX;
- using SendSlotX = ThreadLocalSlot<TypeTagX, kSendBufferIndex>;
-
- auto value1 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
- MessageBuffer<SendSlotX>::GetBuffer();
- auto value2 = ThreadLocalBufferTest::GetSlotValue<SendSlotX>();
-
- EXPECT_EQ(0U, value1);
- EXPECT_NE(0U, value2);
-}
-
-// Tests that the underlying buffers are the same for a given index/type pair
-// and different across index/type combinations.
-TEST(ThreadLocalBufferTest, BackingBuffer) {
- auto& buffer1 = MessageBuffer<SendSlotA>::GetBuffer();
- auto& buffer2 = MessageBuffer<SendSlotA>::GetBuffer();
- auto& buffer3 = MessageBuffer<SendSlotB>::GetBuffer();
- auto& buffer4 = MessageBuffer<SendSlotB>::GetBuffer();
-
- EXPECT_EQ(buffer1.data(), buffer2.data());
- EXPECT_EQ(buffer3.data(), buffer4.data());
- EXPECT_NE(buffer1.data(), buffer3.data());
- EXPECT_NE(buffer2.data(), buffer4.data());
-}
diff --git a/libs/vr/libpdx/variant_tests.cpp b/libs/vr/libpdx/variant_tests.cpp
deleted file mode 100644
index a977fd3..0000000
--- a/libs/vr/libpdx/variant_tests.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-#include <array>
-#include <cstdint>
-#include <functional>
-#include <memory>
-#include <string>
-#include <type_traits>
-
-#include <gtest/gtest.h>
-#include <pdx/rpc/variant.h>
-
-using namespace android::pdx;
-using namespace android::pdx::rpc;
-
-namespace {
-
-struct BaseType {
- // NOLINTNEXTLINE(google-explicit-constructor)
- BaseType(int value) : value(value) {}
- int value;
-};
-
-struct DerivedType : BaseType {
- // NOLINTNEXTLINE(google-explicit-constructor)
- DerivedType(int value) : BaseType{value} {};
-};
-
-template <typename T>
-class TestType {
- public:
- // NOLINTNEXTLINE(google-explicit-constructor)
- TestType(const T& value) : value_(value) {}
- // NOLINTNEXTLINE(google-explicit-constructor)
- TestType(T&& value) : value_(std::move(value)) {}
- TestType(const TestType&) = default;
- TestType(TestType&&) = default;
-
- TestType& operator=(const TestType&) = default;
- TestType& operator=(TestType&&) = default;
-
- const T& get() const { return value_; }
- T&& take() { return std::move(value_); }
-
- private:
- T value_;
-};
-
-template <typename T>
-class InstrumentType {
- public:
- // NOLINTNEXTLINE(google-explicit-constructor)
- InstrumentType(const T& value) : value_(value) { constructor_count_++; }
- // NOLINTNEXTLINE(google-explicit-constructor)
- InstrumentType(T&& value) : value_(std::move(value)) { constructor_count_++; }
- InstrumentType(const InstrumentType& other) : value_(other.value_) {
- constructor_count_++;
- }
- InstrumentType(InstrumentType&& other) : value_(std::move(other.value_)) {
- constructor_count_++;
- }
- // NOLINTNEXTLINE(google-explicit-constructor)
- InstrumentType(const TestType<T>& other) : value_(other.get()) {
- constructor_count_++;
- }
- // NOLINTNEXTLINE(google-explicit-constructor)
- InstrumentType(TestType<T>&& other) : value_(other.take()) {
- constructor_count_++;
- }
- ~InstrumentType() { destructor_count_++; }
-
- InstrumentType& operator=(const InstrumentType& other) {
- copy_assignment_count_++;
- value_ = other.value_;
- return *this;
- }
- InstrumentType& operator=(InstrumentType&& other) {
- move_assignment_count_++;
- value_ = std::move(other.value_);
- return *this;
- }
-
- InstrumentType& operator=(const TestType<T>& other) {
- copy_assignment_count_++;
- value_ = other.get();
- return *this;
- }
- InstrumentType& operator=(TestType<T>&& other) {
- move_assignment_count_++;
- value_ = other.take();
- return *this;
- }
-
- static std::size_t constructor_count() { return constructor_count_; }
- static std::size_t destructor_count() { return destructor_count_; }
- static std::size_t move_assignment_count() { return move_assignment_count_; }
- static std::size_t copy_assignment_count() { return copy_assignment_count_; }
-
- const T& get() const { return value_; }
- T&& take() { return std::move(value_); }
-
- static void clear() {
- constructor_count_ = 0;
- destructor_count_ = 0;
- move_assignment_count_ = 0;
- copy_assignment_count_ = 0;
- }
-
- private:
- T value_;
-
- static std::size_t constructor_count_;
- static std::size_t destructor_count_;
- static std::size_t move_assignment_count_;
- static std::size_t copy_assignment_count_;
-};
-
-template <typename T>
-std::size_t InstrumentType<T>::constructor_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::destructor_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::move_assignment_count_ = 0;
-template <typename T>
-std::size_t InstrumentType<T>::copy_assignment_count_ = 0;
-
-} // anonymous namespace
-
-TEST(Variant, Assignment) {
- // Assert basic type properties.
- {
- Variant<int, bool, float> v;
- ASSERT_EQ(-1, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_FALSE(v.is<bool>());
- ASSERT_FALSE(v.is<float>());
- }
-
- {
- Variant<int, bool, float> v;
- v = 10;
- ASSERT_EQ(0, v.index());
- ASSERT_TRUE(v.is<int>());
- ASSERT_FALSE(v.is<bool>());
- ASSERT_FALSE(v.is<float>());
- EXPECT_EQ(10, std::get<int>(v));
- }
-
- {
- Variant<int, bool, float> v;
- v = false;
- ASSERT_EQ(1, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_TRUE(v.is<bool>());
- ASSERT_FALSE(v.is<float>());
- EXPECT_EQ(false, std::get<bool>(v));
- }
-
- {
- Variant<int, bool, float> v;
- v = 1.0f;
- ASSERT_EQ(2, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_FALSE(v.is<bool>());
- ASSERT_TRUE(v.is<float>());
- EXPECT_FLOAT_EQ(1.0f, std::get<float>(v));
- }
-
- {
- Variant<int, bool, float> v;
- // ERROR: More than one type is implicitly convertible from double.
- // v = 1.0;
- v = static_cast<float>(1.0);
- }
-
- {
- Variant<int, bool, float> v;
-
- double x = 1.1;
- v = static_cast<float>(x);
- ASSERT_EQ(2, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_FALSE(v.is<bool>());
- ASSERT_TRUE(v.is<float>());
- EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
- }
-
- {
- Variant<int, std::string> v;
- ASSERT_EQ(-1, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_FALSE(v.is<std::string>());
- }
-
- {
- Variant<int, std::string> v;
- v = 20;
- ASSERT_EQ(0, v.index());
- ASSERT_TRUE(v.is<int>());
- ASSERT_FALSE(v.is<std::string>());
- EXPECT_EQ(20, std::get<int>(v));
- }
-
- {
- Variant<int, std::string> v;
- v = std::string("test");
- ASSERT_EQ(1, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(v));
- }
-
- {
- Variant<int, std::string> v;
- v = "test";
- ASSERT_EQ(1, v.index());
- ASSERT_FALSE(v.is<int>());
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(v));
- }
-
- {
- Variant<const char*> v1;
- Variant<std::string> v2;
-
- v1 = "test";
- ASSERT_TRUE(v1.is<const char*>());
- v2 = v1;
- ASSERT_TRUE(v2.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(v2));
- }
-
- {
- Variant<int> a(1);
- Variant<int> b;
- ASSERT_TRUE(!a.empty());
- ASSERT_TRUE(b.empty());
-
- a = b;
- ASSERT_TRUE(a.empty());
- ASSERT_TRUE(b.empty());
- }
-
- {
- Variant<int*, char*> v;
-
- // ERROR: More than one type is implicitly convertible from nullptr.
- // v = nullptr;
-
- v = static_cast<int*>(nullptr);
- EXPECT_TRUE(v.is<int*>());
-
- v = static_cast<char*>(nullptr);
- EXPECT_TRUE(v.is<char*>());
- }
-
- {
- Variant<int*, char*> v;
- int a = 10;
- char b = 20;
-
- v = &b;
- ASSERT_TRUE(v.is<char*>());
- EXPECT_EQ(&b, std::get<char*>(v));
- EXPECT_EQ(b, *std::get<char*>(v));
-
- v = &a;
- ASSERT_TRUE(v.is<int*>());
- EXPECT_EQ(&a, std::get<int*>(v));
- EXPECT_EQ(a, *std::get<int*>(v));
- }
-
- {
- using IntRef = std::reference_wrapper<int>;
- Variant<IntRef> v;
- int a = 10;
-
- v = a;
- ASSERT_TRUE(v.is<IntRef>());
- EXPECT_EQ(a, std::get<IntRef>(v));
-
- a = 20;
- EXPECT_EQ(a, std::get<IntRef>(v));
- }
-}
-
-TEST(Variant, MoveAssignment) {
- {
- Variant<std::string> v;
- std::string s = "test";
- v = std::move(s);
-
- EXPECT_TRUE(s.empty());
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(v));
- }
-
- {
- Variant<std::string> v("test");
- std::string s = "fizz";
- s = std::move(std::get<std::string>(v));
-
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(v).empty());
- EXPECT_EQ("test", s);
- }
-
- {
- Variant<std::string> a("test");
- Variant<std::string> b;
-
- b = std::move(a);
- ASSERT_TRUE(a.is<std::string>());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(a).empty());
- EXPECT_EQ("test", std::get<std::string>(b));
- }
-
- {
- Variant<std::string> a("test");
- Variant<std::string> b("fizz");
-
- b = std::move(a);
- ASSERT_TRUE(a.is<std::string>());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(a).empty());
- EXPECT_EQ("test", std::get<std::string>(b));
- }
-
- {
- Variant<int, std::string> a("test");
- Variant<int, std::string> b(10);
-
- b = std::move(a);
- ASSERT_TRUE(a.is<std::string>());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(a).empty());
- EXPECT_EQ("test", std::get<std::string>(b));
- }
-
- {
- Variant<int, std::string> a(10);
- Variant<int, std::string> b("test");
-
- b = std::move(a);
- ASSERT_TRUE(a.is<int>());
- ASSERT_TRUE(b.is<int>());
- EXPECT_EQ(10, std::get<int>(a));
- EXPECT_EQ(10, std::get<int>(b));
- }
-}
-
-TEST(Variant, Constructor) {
- {
- Variant<int, bool, float> v(true);
- EXPECT_TRUE(v.is<bool>());
- }
-
- {
- Variant<int, bool, float> v(10);
- EXPECT_TRUE(v.is<int>());
- }
-
- {
- Variant<int, bool, float> v(10.1f);
- EXPECT_TRUE(v.is<float>());
- }
-
- {
- Variant<float, std::string> v(10.);
- EXPECT_TRUE(v.is<float>());
- }
-
- {
- TestType<int> i(1);
- Variant<int, bool, float> v(i.take());
- ASSERT_TRUE(v.is<int>());
- EXPECT_EQ(1, std::get<int>(v));
- }
-
- {
- TestType<int> i(1);
- Variant<int, bool, float> v(i.get());
- ASSERT_TRUE(v.is<int>());
- EXPECT_EQ(1, std::get<int>(v));
- }
-
- {
- TestType<bool> b(true);
- Variant<int, bool, float> v(b.take());
- ASSERT_TRUE(v.is<bool>());
- EXPECT_EQ(true, std::get<bool>(v));
- }
-
- {
- TestType<bool> b(true);
- Variant<int, bool, float> v(b.get());
- ASSERT_TRUE(v.is<bool>());
- EXPECT_EQ(true, std::get<bool>(v));
- }
-
- {
- Variant<const char*> c("test");
- Variant<std::string> s(c);
- ASSERT_TRUE(s.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(s));
- }
-
- {
- Variant<int, bool, float> a(true);
- Variant<int, bool, float> b(a);
-
- ASSERT_TRUE(b.is<bool>());
- }
-
- {
- using IntRef = std::reference_wrapper<int>;
- int a = 10;
- Variant<IntRef> v(a);
- TestType<IntRef> t(a);
-
- ASSERT_TRUE(v.is<IntRef>());
- EXPECT_EQ(a, std::get<IntRef>(v));
- EXPECT_EQ(a, t.get());
-
- a = 20;
- EXPECT_EQ(a, std::get<IntRef>(v));
- EXPECT_EQ(a, t.get());
- }
-}
-
-// Verify correct ctor/dtor and assignment behavior used an instrumented type.
-TEST(Variant, CopyMoveConstructAssign) {
- {
- InstrumentType<int>::clear();
-
- // Default construct to empty, no InstrumentType activity.
- Variant<int, InstrumentType<int>> v;
- ASSERT_EQ(0u, InstrumentType<int>::constructor_count());
- ASSERT_EQ(0u, InstrumentType<int>::destructor_count());
- ASSERT_EQ(0u, InstrumentType<int>::move_assignment_count());
- ASSERT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from int type, no InstrumentType activity.
- Variant<int, InstrumentType<int>> v;
- v = 10;
- EXPECT_EQ(0u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from int type, no InstrumentType activity.
- Variant<int, InstrumentType<int>> v(10);
- EXPECT_EQ(0u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v;
- v = InstrumentType<int>(25);
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
- // Assign from temporary, temporary ctor/dtor.
- v = InstrumentType<int>(35);
- EXPECT_EQ(3u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
- // dtor.
- v = 10;
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-
- {
- InstrumentType<int>::clear();
-
- // Construct from other temporary.
- Variant<int, InstrumentType<int>> v(TestType<int>(10));
- EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from other temporary.
- Variant<int, InstrumentType<int>> v(TestType<int>(10));
- // Assign from other temporary.
- v = TestType<int>(11);
- EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from other temporary.
- Variant<int, InstrumentType<int>> v(TestType<int>(10));
- // Assign from empty Variant.
- v = Variant<int, InstrumentType<int>>();
- EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(1u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- TestType<int> other(10);
- // Construct from other.
- Variant<int, InstrumentType<int>> v(other);
-
- EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from other temporary.
- Variant<int, InstrumentType<int>> v(TestType<int>(0));
- TestType<int> other(10);
- // Assign from other.
- v = other;
- EXPECT_EQ(1u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(1u, InstrumentType<int>::copy_assignment_count());
- }
-
- {
- InstrumentType<int>::clear();
-
- // Construct from temporary, temporary ctor/dtor.
- Variant<int, InstrumentType<int>> v(InstrumentType<int>(25));
-
- // Assign EmptyVariant.
- v = EmptyVariant{};
-
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
- }
- EXPECT_EQ(2u, InstrumentType<int>::constructor_count());
- EXPECT_EQ(2u, InstrumentType<int>::destructor_count());
- EXPECT_EQ(0u, InstrumentType<int>::move_assignment_count());
- EXPECT_EQ(0u, InstrumentType<int>::copy_assignment_count());
-}
-
-TEST(Variant, MoveConstructor) {
- {
- std::unique_ptr<int> pointer = std::make_unique<int>(10);
- Variant<std::unique_ptr<int>> v(std::move(pointer));
- ASSERT_TRUE(v.is<std::unique_ptr<int>>());
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) != nullptr);
- EXPECT_TRUE(pointer == nullptr);
- }
-
- {
- Variant<std::unique_ptr<int>> a(std::make_unique<int>(10));
- Variant<std::unique_ptr<int>> b(std::move(a));
-
- ASSERT_TRUE(a.is<std::unique_ptr<int>>());
- ASSERT_TRUE(b.is<std::unique_ptr<int>>());
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(a) == nullptr);
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(b) != nullptr);
- }
-}
-
-TEST(Variant, IndexOf) {
- Variant<int, bool, float> v1;
-
- EXPECT_EQ(0, v1.index_of<int>());
- EXPECT_EQ(1, v1.index_of<bool>());
- EXPECT_EQ(2, v1.index_of<float>());
-
- Variant<int, bool, float, int> v2;
-
- EXPECT_EQ(0, v2.index_of<int>());
- EXPECT_EQ(1, v2.index_of<bool>());
- EXPECT_EQ(2, v2.index_of<float>());
-}
-
-struct Visitor {
- int int_value = 0;
- bool bool_value = false;
- float float_value = 0.0;
- bool empty_value = false;
-
- void Visit(int value) { int_value = value; }
- void Visit(bool value) { bool_value = value; }
- void Visit(float value) { float_value = value; }
- void Visit(EmptyVariant) { empty_value = true; }
-};
-
-TEST(Variant, Visit) {
- {
- Variant<int, bool, float> v(10);
- EXPECT_TRUE(v.is<int>());
-
- Visitor visitor;
- v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
- EXPECT_EQ(10, visitor.int_value);
-
- visitor = {};
- v = true;
- v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
- EXPECT_EQ(true, visitor.bool_value);
- }
-
- {
- Variant<int, bool, float> v;
- EXPECT_EQ(-1, v.index());
-
- Visitor visitor;
- v.Visit([&visitor](const auto& value) { visitor.Visit(value); });
- EXPECT_TRUE(visitor.empty_value);
- }
-
- {
- Variant<std::string> v("test");
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_FALSE(std::get<std::string>(v).empty());
-
- v.Visit([](auto&& value) {
- std::remove_reference_t<decltype(value)> empty;
- std::swap(empty, value);
- });
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(v).empty());
- }
-}
-
-TEST(Variant, Become) {
- {
- Variant<int, bool, float> v;
-
- v.Become(0);
- EXPECT_TRUE(v.is<int>());
-
- v.Become(1);
- EXPECT_TRUE(v.is<bool>());
-
- v.Become(2);
- EXPECT_TRUE(v.is<float>());
-
- v.Become(3);
- EXPECT_TRUE(v.empty());
-
- v.Become(-1);
- EXPECT_TRUE(v.empty());
-
- v.Become(-2);
- EXPECT_TRUE(v.empty());
- }
-
- {
- Variant<int, bool, float> v;
-
- v.Become(0, 10);
- ASSERT_TRUE(v.is<int>());
- EXPECT_EQ(10, std::get<int>(v));
-
- v.Become(1, true);
- ASSERT_TRUE(v.is<bool>());
- EXPECT_EQ(true, std::get<bool>(v));
-
- v.Become(2, 2.0f);
- ASSERT_TRUE(v.is<float>());
- EXPECT_FLOAT_EQ(2.0f, std::get<float>(v));
-
- v.Become(3, 10);
- EXPECT_TRUE(v.empty());
-
- v.Become(-1, 10);
- EXPECT_TRUE(v.empty());
-
- v.Become(-2, 20);
- EXPECT_TRUE(v.empty());
- }
-
- {
- Variant<std::string> v;
-
- v.Become(0);
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_TRUE(std::get<std::string>(v).empty());
- }
-
- {
- Variant<std::string> v;
-
- v.Become(0, "test");
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("test", std::get<std::string>(v));
- }
-
- {
- Variant<std::string> v("foo");
-
- v.Become(0, "bar");
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("foo", std::get<std::string>(v));
- }
-}
-
-TEST(Variant, Swap) {
- {
- Variant<std::string> a;
- Variant<std::string> b;
-
- std::swap(a, b);
- EXPECT_TRUE(a.empty());
- EXPECT_TRUE(b.empty());
- }
-
- {
- Variant<std::string> a("1");
- Variant<std::string> b;
-
- std::swap(a, b);
- EXPECT_TRUE(a.empty());
- EXPECT_TRUE(!b.empty());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_EQ("1", std::get<std::string>(b));
- }
-
- {
- Variant<std::string> a;
- Variant<std::string> b("1");
-
- std::swap(a, b);
- EXPECT_TRUE(!a.empty());
- EXPECT_TRUE(b.empty());
- ASSERT_TRUE(a.is<std::string>());
- EXPECT_EQ("1", std::get<std::string>(a));
- }
-
- {
- Variant<std::string> a("1");
- Variant<std::string> b("2");
-
- std::swap(a, b);
- ASSERT_TRUE(a.is<std::string>());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_EQ("2", std::get<std::string>(a));
- EXPECT_EQ("1", std::get<std::string>(b));
- }
-
- {
- Variant<int, std::string> a(10);
- Variant<int, std::string> b("1");
-
- std::swap(a, b);
- ASSERT_TRUE(a.is<std::string>());
- ASSERT_TRUE(b.is<int>());
- EXPECT_EQ("1", std::get<std::string>(a));
- EXPECT_EQ(10, std::get<int>(b));
- }
-
- {
- Variant<int, std::string> a("1");
- Variant<int, std::string> b(10);
-
- std::swap(a, b);
- ASSERT_TRUE(a.is<int>());
- ASSERT_TRUE(b.is<std::string>());
- EXPECT_EQ(10, std::get<int>(a));
- EXPECT_EQ("1", std::get<std::string>(b));
- }
-}
-
-TEST(Variant, Get) {
- {
- Variant<int, bool, float, int> v;
-
- EXPECT_EQ(nullptr, &std::get<int>(v));
- EXPECT_EQ(nullptr, &std::get<bool>(v));
- EXPECT_EQ(nullptr, &std::get<float>(v));
- EXPECT_EQ(nullptr, &std::get<0>(v));
- EXPECT_EQ(nullptr, &std::get<1>(v));
- EXPECT_EQ(nullptr, &std::get<2>(v));
- EXPECT_EQ(nullptr, &std::get<3>(v));
- }
-
- {
- Variant<int, bool, float, int> v;
- v = 9;
- ASSERT_TRUE(v.is<int>())
- << "Expected type " << v.index_of<int>() << " got type " << v.index();
- EXPECT_EQ(9, std::get<int>(v));
- EXPECT_EQ(9, std::get<0>(v));
-
- std::get<int>(v) = 10;
- EXPECT_EQ(10, std::get<int>(v));
- EXPECT_EQ(10, std::get<0>(v));
-
- std::get<0>(v) = 11;
- EXPECT_EQ(11, std::get<int>(v));
- EXPECT_EQ(11, std::get<0>(v));
-
- std::get<3>(v) = 12;
- EXPECT_EQ(12, std::get<int>(v));
- EXPECT_EQ(12, std::get<3>(v));
- }
-
- {
- Variant<int, bool, float, int> v;
- v = false;
- ASSERT_TRUE(v.is<bool>())
- << "Expected type " << v.index_of<bool>() << " got type " << v.index();
- EXPECT_EQ(false, std::get<bool>(v));
- EXPECT_EQ(false, std::get<1>(v));
-
- std::get<bool>(v) = true;
- EXPECT_EQ(true, std::get<bool>(v));
- EXPECT_EQ(true, std::get<1>(v));
-
- std::get<bool>(v) = false;
- EXPECT_EQ(false, std::get<bool>(v));
- EXPECT_EQ(false, std::get<1>(v));
-
- std::get<1>(v) = true;
- EXPECT_EQ(true, std::get<bool>(v));
- EXPECT_EQ(true, std::get<1>(v));
-
- std::get<1>(v) = false;
- EXPECT_EQ(false, std::get<bool>(v));
- EXPECT_EQ(false, std::get<1>(v));
- }
-
- {
- Variant<int, bool, float, int> v;
- v = 1.0f;
- ASSERT_TRUE(v.is<float>())
- << "Expected type " << v.index_of<float>() << " got type " << v.index();
- EXPECT_EQ(2, v.index());
- EXPECT_FLOAT_EQ(1.0, std::get<float>(v));
- EXPECT_FLOAT_EQ(1.0, std::get<2>(v));
-
- std::get<float>(v) = 1.1;
- EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
- EXPECT_FLOAT_EQ(1.1, std::get<2>(v));
-
- std::get<float>(v) = -3.0;
- EXPECT_FLOAT_EQ(-3.0, std::get<float>(v));
- EXPECT_FLOAT_EQ(-3.0, std::get<2>(v));
-
- std::get<2>(v) = 1.1;
- EXPECT_FLOAT_EQ(1.1, std::get<float>(v));
- EXPECT_FLOAT_EQ(1.1, std::get<2>(v));
-
- std::get<2>(v) = -3.0;
- EXPECT_FLOAT_EQ(-3.0, std::get<float>(v));
- EXPECT_FLOAT_EQ(-3.0, std::get<2>(v));
- }
-
- {
- Variant<std::unique_ptr<int>> v(std::make_unique<int>(10));
- std::unique_ptr<int> pointer = std::move(std::get<std::unique_ptr<int>>(v));
- ASSERT_FALSE(v.empty());
- EXPECT_TRUE(pointer != nullptr);
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
- }
-
- {
- Variant<std::string> v("test");
- std::string s = std::get<std::string>(std::move(v));
- EXPECT_EQ("test", s);
- }
-}
-
-TEST(Variant, IfAnyOf) {
- {
- Variant<int, float> v(10);
- ASSERT_TRUE(v.is<int>());
-
- bool b = false;
- EXPECT_TRUE(IfAnyOf<int>::Get(&v, &b));
- EXPECT_TRUE(b);
-
- float f = 0.0f;
- EXPECT_TRUE((IfAnyOf<int, float>::Get(&v, &f)));
- EXPECT_FLOAT_EQ(10.f, f);
- }
-
- {
- const Variant<int, float> v(10);
- ASSERT_TRUE(v.is<int>());
-
- bool b = false;
- EXPECT_TRUE(IfAnyOf<int>::Get(&v, &b));
- EXPECT_TRUE(b);
-
- float f = 0.0f;
- EXPECT_TRUE((IfAnyOf<int, float>::Get(&v, &f)));
- EXPECT_FLOAT_EQ(10.f, f);
- }
-
- {
- Variant<int, float> v(10);
- ASSERT_TRUE(v.is<int>());
-
- bool b = false;
- EXPECT_TRUE(IfAnyOf<int>::Call(&v, [&b](const auto& value) { b = value; }));
- EXPECT_TRUE(b);
-
- float f = 0.0f;
- EXPECT_TRUE((
- IfAnyOf<int, float>::Call(&v, [&f](const auto& value) { f = value; })));
- EXPECT_FLOAT_EQ(10.f, f);
- }
-
- {
- Variant<std::unique_ptr<int>, int> v(std::make_unique<int>(10));
- ASSERT_TRUE(v.is<std::unique_ptr<int>>());
- const int* original_v = std::get<std::unique_ptr<int>>(v).get();
-
- std::unique_ptr<int> u(std::make_unique<int>(20));
-
- EXPECT_TRUE(IfAnyOf<std::unique_ptr<int>>::Take(&v, &u));
- ASSERT_TRUE(v.is<std::unique_ptr<int>>());
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
- EXPECT_EQ(u.get(), original_v);
- }
-
- {
- Variant<std::unique_ptr<DerivedType>, int> v(
- std::make_unique<DerivedType>(10));
- ASSERT_TRUE(v.is<std::unique_ptr<DerivedType>>());
- const DerivedType* original_v =
- std::get<std::unique_ptr<DerivedType>>(v).get();
-
- std::unique_ptr<BaseType> u(std::make_unique<BaseType>(20));
-
- EXPECT_TRUE(IfAnyOf<std::unique_ptr<DerivedType>>::Take(&v, &u));
- ASSERT_TRUE(v.is<std::unique_ptr<DerivedType>>());
- EXPECT_TRUE(std::get<std::unique_ptr<DerivedType>>(v) == nullptr);
- EXPECT_EQ(u.get(), original_v);
- }
-
- {
- Variant<std::unique_ptr<int>, int> v(std::make_unique<int>(10));
- ASSERT_TRUE(v.is<std::unique_ptr<int>>());
- const int* original_v = std::get<std::unique_ptr<int>>(v).get();
-
- std::unique_ptr<int> u(std::make_unique<int>(20));
-
- EXPECT_TRUE(IfAnyOf<std::unique_ptr<int>>::Call(
- &v, [&u](auto&& value) { u = std::move(value); }));
- ASSERT_TRUE(v.is<std::unique_ptr<int>>());
- EXPECT_TRUE(std::get<std::unique_ptr<int>>(v) == nullptr);
- EXPECT_EQ(u.get(), original_v);
- }
-
- {
- Variant<int, bool, float> v(true);
- ASSERT_TRUE(v.is<bool>());
-
- float f = 0.f;
- EXPECT_FALSE((IfAnyOf<int, float>::Get(&v, &f)));
- EXPECT_FLOAT_EQ(0.f, f);
- }
-
- {
- Variant<std::string, int> v("foo");
- ASSERT_TRUE(v.is<std::string>());
-
- std::string s = "bar";
- EXPECT_TRUE(IfAnyOf<std::string>::Swap(&v, &s));
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("bar", std::get<std::string>(v));
- EXPECT_EQ("foo", s);
- }
-
- {
- Variant<std::string, const char*> v(static_cast<const char*>("foo"));
- ASSERT_TRUE(v.is<const char*>());
-
- std::string s = "bar";
- EXPECT_TRUE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
- ASSERT_TRUE(v.is<const char*>());
- EXPECT_EQ("foo", std::get<const char*>(v));
- EXPECT_EQ("foo", s);
-
- v = std::string("bar");
- ASSERT_TRUE(v.is<std::string>());
-
- EXPECT_TRUE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
- ASSERT_TRUE(v.is<std::string>());
- EXPECT_EQ("bar", s);
- }
-
- {
- Variant<std::string, const char*> v;
- ASSERT_TRUE(v.empty());
-
- std::string s = "bar";
- EXPECT_FALSE((IfAnyOf<std::string, const char*>::Take(&v, &s)));
- EXPECT_EQ("bar", s);
- }
-
- {
- Variant<std::string, const char*> v(static_cast<const char*>("test"));
- ASSERT_TRUE(v.is<const char*>());
-
- std::string s;
- EXPECT_FALSE(IfAnyOf<>::Take(&v, &s));
- EXPECT_TRUE(s.empty());
- }
-}
-
-TEST(Variant, ConstVolatile) {
- {
- Variant<const int> v(10);
- ASSERT_TRUE(v.is<const int>());
- EXPECT_EQ(10, std::get<const int>(v));
- }
-
- {
- Variant<const std::string> v("test");
- ASSERT_TRUE(v.is<const std::string>());
- EXPECT_EQ("test", std::get<const std::string>(v));
- }
-
- {
- Variant<volatile int, std::string> v(10);
- ASSERT_TRUE(v.is<volatile int>());
- EXPECT_EQ(10, std::get<volatile int>(v));
- }
-}
-
-TEST(Variant, HasType) {
- EXPECT_TRUE((detail::HasType<int, int, float, bool>::value));
- EXPECT_FALSE((detail::HasType<char, int, float, bool>::value));
- EXPECT_FALSE(detail::HasType<>::value);
-
- EXPECT_TRUE((detail::HasType<int&, int, float, bool>::value));
- EXPECT_FALSE((detail::HasType<char&, int, float, bool>::value));
-}
-
-TEST(Variant, IsConstructible) {
- using ArrayType = const float[3];
- struct ImplicitBool {
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator bool() const { return true; }
- };
- struct ExplicitBool {
- explicit operator bool() const { return true; }
- };
- struct NonBool {};
- struct TwoArgs {
- TwoArgs(int, bool) {}
- };
-
- EXPECT_FALSE((detail::IsConstructible<bool, ArrayType>::value));
- EXPECT_TRUE((detail::IsConstructible<bool, int>::value));
- EXPECT_TRUE((detail::IsConstructible<bool, ImplicitBool>::value));
- EXPECT_TRUE((detail::IsConstructible<bool, ExplicitBool>::value));
- EXPECT_FALSE((detail::IsConstructible<bool, NonBool>::value));
- EXPECT_TRUE((detail::IsConstructible<TwoArgs, int, bool>::value));
- EXPECT_FALSE((detail::IsConstructible<TwoArgs, int, std::string>::value));
- EXPECT_FALSE((detail::IsConstructible<TwoArgs, int>::value));
-}
-
-TEST(Variant, Set) {
- EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<int, bool,
- float>::value));
- EXPECT_TRUE(
- (detail::Set<int, bool, float>::template IsSubset<bool, float>::value));
- EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<float>::value));
- EXPECT_TRUE((detail::Set<int, bool, float>::template IsSubset<>::value));
-
- EXPECT_FALSE(
- (detail::Set<int, bool, float>::template IsSubset<int, bool, float,
- char>::value));
- EXPECT_FALSE((detail::Set<int, bool, float>::template IsSubset<bool, float,
- char>::value));
- EXPECT_FALSE(
- (detail::Set<int, bool, float>::template IsSubset<float, char>::value));
- EXPECT_FALSE((detail::Set<int, bool, float>::template IsSubset<char>::value));
-
- EXPECT_TRUE(detail::Set<>::template IsSubset<>::value);
- EXPECT_FALSE(detail::Set<>::template IsSubset<int>::value);
- EXPECT_FALSE((detail::Set<>::template IsSubset<int, float>::value));
-}
diff --git a/libs/vr/libpdx_default_transport/Android.bp b/libs/vr/libpdx_default_transport/Android.bp
deleted file mode 100644
index a5758b5..0000000
--- a/libs/vr/libpdx_default_transport/Android.bp
+++ /dev/null
@@ -1,88 +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_defaults {
- name: "pdx_default_transport_compiler_defaults",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
-}
-
-cc_defaults {
- name: "pdx_default_transport_lib_defaults",
- export_include_dirs: ["private"],
- whole_static_libs: ["libpdx"],
-}
-
-cc_defaults {
- name: "pdx_use_transport_servicefs",
- export_include_dirs: ["private/servicefs"],
- whole_static_libs: [
- "libpdx_servicefs",
- "libservicefs",
- ],
-}
-
-cc_defaults {
- name: "pdx_use_transport_uds",
- export_include_dirs: ["private/uds"],
- whole_static_libs: ["libpdx_uds"],
-}
-
-cc_library_shared {
- name: "libpdx_default_transport",
- defaults: [
- "pdx_default_transport_compiler_defaults",
- "pdx_default_transport_lib_defaults",
- "pdx_use_transport_uds",
- ],
- shared_libs: [
- "libbase",
- "libbinder",
- "libcutils",
- "liblog",
- "libutils",
- "libselinux",
- ],
-}
-
-cc_binary {
- name: "pdx_tool",
- system_ext_specific: true,
- defaults: ["pdx_default_transport_compiler_defaults"],
- srcs: [
- "pdx_tool.cpp",
- ],
- shared_libs: [
- "libbinder",
- "libcutils",
- "liblog",
- "libpdx_default_transport",
- ],
-}
-
-// Benchmarks.
-cc_binary {
- name: "pdx_benchmarks",
- defaults: ["pdx_default_transport_compiler_defaults"],
- srcs: [
- "pdx_benchmarks.cpp",
- ],
- shared_libs: [
- "libbase",
- "libbinder",
- "libchrome",
- "libcutils",
- "liblog",
- "libutils",
- "libpdx_default_transport",
- ],
-}
diff --git a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp b/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
deleted file mode 100644
index 5c9e74c..0000000
--- a/libs/vr/libpdx_default_transport/pdx_benchmarks.cpp
+++ /dev/null
@@ -1,1090 +0,0 @@
-// Use ALWAYS at the tag level. Control is performed manually during command
-// line processing.
-#define ATRACE_TAG ATRACE_TAG_ALWAYS
-#include <utils/Trace.h>
-
-#include <base/files/file_util.h>
-#include <base/logging.h>
-#include <base/strings/string_split.h>
-#include <errno.h>
-#include <getopt.h>
-#include <pdx/client.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <pdx/rpc/default_initialization_allocator.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/service.h>
-#include <sys/prctl.h>
-#include <time.h>
-#include <unistd.h>
-
-#include <atomic>
-#include <cstdlib>
-#include <functional>
-#include <future>
-#include <iomanip>
-#include <ios>
-#include <iostream>
-#include <memory>
-#include <numeric>
-#include <sstream>
-#include <string>
-#include <thread>
-#include <vector>
-
-using android::pdx::Channel;
-using android::pdx::ClientBase;
-using android::pdx::Endpoint;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Service;
-using android::pdx::ServiceBase;
-using android::pdx::default_transport::ClientChannelFactory;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::rpc::BufferWrapper;
-using android::pdx::rpc::DefaultInitializationAllocator;
-using android::pdx::rpc::MessageBuffer;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::RemoteMethodReturn;
-using android::pdx::rpc::ReplyBuffer;
-using android::pdx::rpc::Void;
-using android::pdx::rpc::WrapBuffer;
-
-namespace {
-
-constexpr size_t kMaxMessageSize = 4096 * 1024;
-
-std::string GetServicePath(const std::string& path, int instance_id) {
- return path + std::to_string(instance_id);
-}
-
-void SetThreadName(const std::string& name) {
- prctl(PR_SET_NAME, reinterpret_cast<unsigned long>(name.c_str()), 0, 0, 0);
-}
-
-constexpr uint64_t kNanosPerSecond = 1000000000LLU;
-
-uint64_t GetClockNs() {
- timespec t;
- clock_gettime(CLOCK_MONOTONIC, &t);
- return kNanosPerSecond * t.tv_sec + t.tv_nsec;
-}
-
-template <typename T>
-ssize_t ssizeof(const T&) {
- return static_cast<ssize_t>(sizeof(T));
-}
-
-class SchedStats {
- public:
- SchedStats() : SchedStats(gettid()) {}
- explicit SchedStats(pid_t task_id) : task_id_(task_id) {}
- SchedStats(const SchedStats&) = default;
- SchedStats& operator=(const SchedStats&) = default;
-
- void Update() {
- const std::string stats_path =
- "/proc/" + std::to_string(task_id_) + "/schedstat";
-
- std::string line;
- base::ReadFileToString(base::FilePath{stats_path}, &line);
- std::vector<std::string> stats = base::SplitString(
- line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
- CHECK_EQ(3u, stats.size());
-
- // Calculate the deltas since the last update. Each value is absolute since
- // the task started.
- uint64_t current_cpu_time_ns = std::stoull(stats[0]);
- uint64_t current_wait_ns = std::stoull(stats[1]);
- uint64_t current_timeslices = std::stoull(stats[2]);
- cpu_time_ns_ = current_cpu_time_ns - last_cpu_time_ns_;
- wait_ns_ = current_wait_ns - last_wait_ns_;
- timeslices_ = current_timeslices - last_timeslices_;
- last_cpu_time_ns_ = current_cpu_time_ns;
- last_wait_ns_ = current_wait_ns;
- last_timeslices_ = current_timeslices;
- }
-
- pid_t task_id() const { return task_id_; }
- uint64_t cpu_time_ns() const { return cpu_time_ns_; }
- uint64_t wait_ns() const { return wait_ns_; }
- uint64_t timeslices() const { return timeslices_; }
-
- double cpu_time_s() const {
- return static_cast<double>(cpu_time_ns_) / kNanosPerSecond;
- }
- double wait_s() const {
- return static_cast<double>(wait_ns_) / kNanosPerSecond;
- }
-
- private:
- int32_t task_id_;
- uint64_t cpu_time_ns_ = 0;
- uint64_t last_cpu_time_ns_ = 0;
- uint64_t wait_ns_ = 0;
- uint64_t last_wait_ns_ = 0;
- uint64_t timeslices_ = 0;
- uint64_t last_timeslices_ = 0;
-
- PDX_SERIALIZABLE_MEMBERS(SchedStats, task_id_, cpu_time_ns_, wait_ns_,
- timeslices_);
-};
-
-// Opcodes for client/service protocol.
-struct BenchmarkOps {
- enum : int {
- Nop,
- Read,
- Write,
- Echo,
- Stats,
- WriteVector,
- EchoVector,
- Quit,
- };
-};
-
-struct BenchmarkRPC {
- PDX_REMOTE_METHOD(Stats, BenchmarkOps::Stats,
- std::tuple<uint64_t, uint64_t, SchedStats>(Void));
- PDX_REMOTE_METHOD(WriteVector, BenchmarkOps::WriteVector,
- int(const BufferWrapper<std::vector<uint8_t>> data));
- PDX_REMOTE_METHOD(EchoVector, BenchmarkOps::EchoVector,
- BufferWrapper<std::vector<uint8_t>>(
- const BufferWrapper<std::vector<uint8_t>> data));
-};
-
-struct BenchmarkResult {
- int thread_id = 0;
- int service_id = 0;
- double time_delta_s = 0.0;
- uint64_t bytes_sent = 0;
- SchedStats sched_stats = {};
-};
-
-// Global command line option values.
-struct Options {
- bool verbose = false;
- int threads = 1;
- int opcode = BenchmarkOps::Read;
- int blocksize = 1;
- int count = 1;
- int instances = 1;
- int timeout = 1;
- int warmup = 0;
-} ProgramOptions;
-
-// Command line option names.
-const char kOptionService[] = "service";
-const char kOptionClient[] = "client";
-const char kOptionVerbose[] = "verbose";
-const char kOptionOpcode[] = "op";
-const char kOptionBlocksize[] = "bs";
-const char kOptionCount[] = "count";
-const char kOptionThreads[] = "threads";
-const char kOptionInstances[] = "instances";
-const char kOptionTimeout[] = "timeout";
-const char kOptionTrace[] = "trace";
-const char kOptionWarmup[] = "warmup";
-
-// getopt() long options.
-static option long_options[] = {
- {kOptionService, required_argument, 0, 0},
- {kOptionClient, required_argument, 0, 0},
- {kOptionVerbose, no_argument, 0, 0},
- {kOptionOpcode, required_argument, 0, 0},
- {kOptionBlocksize, required_argument, 0, 0},
- {kOptionCount, required_argument, 0, 0},
- {kOptionThreads, required_argument, 0, 0},
- {kOptionInstances, required_argument, 0, 0},
- {kOptionTimeout, required_argument, 0, 0},
- {kOptionTrace, no_argument, 0, 0},
- {kOptionWarmup, required_argument, 0, 0},
- {0, 0, 0, 0},
-};
-
-// Parses the argument for kOptionOpcode and sets the value of
-// ProgramOptions.opcode.
-void ParseOpcodeOption(const std::string& argument) {
- if (argument == "read") {
- ProgramOptions.opcode = BenchmarkOps::Read;
- } else if (argument == "write") {
- ProgramOptions.opcode = BenchmarkOps::Write;
- } else if (argument == "echo") {
- ProgramOptions.opcode = BenchmarkOps::Echo;
- } else if (argument == "writevec") {
- ProgramOptions.opcode = BenchmarkOps::WriteVector;
- } else if (argument == "echovec") {
- ProgramOptions.opcode = BenchmarkOps::EchoVector;
- } else if (argument == "quit") {
- ProgramOptions.opcode = BenchmarkOps::Quit;
- } else if (argument == "nop") {
- ProgramOptions.opcode = BenchmarkOps::Nop;
- } else if (argument == "stats") {
- ProgramOptions.opcode = BenchmarkOps::Stats;
- } else {
- ProgramOptions.opcode = std::stoi(argument);
- }
-}
-
-// Implements the service side of the benchmark.
-class BenchmarkService : public ServiceBase<BenchmarkService> {
- public:
- std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
- VLOG(1) << "BenchmarkService::OnChannelCreate: cid="
- << message.GetChannelId();
- return nullptr;
- }
-
- void OnChannelClose(Message& message,
- const std::shared_ptr<Channel>& /*channel*/) override {
- VLOG(1) << "BenchmarkService::OnChannelClose: cid="
- << message.GetChannelId();
- }
-
- Status<void> HandleMessage(Message& message) override {
- ATRACE_NAME("BenchmarkService::HandleMessage");
-
- switch (message.GetOp()) {
- case BenchmarkOps::Nop:
- VLOG(1) << "BenchmarkService::HandleMessage: op=nop";
- {
- ATRACE_NAME("Reply");
- CHECK(message.Reply(0));
- }
- return {};
-
- case BenchmarkOps::Write: {
- VLOG(1) << "BenchmarkService::HandleMessage: op=write send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- Status<void> status;
- if (message.GetSendLength())
- status = message.ReadAll(send_buffer.data(), message.GetSendLength());
-
- {
- ATRACE_NAME("Reply");
- if (!status)
- CHECK(message.ReplyError(status.error()));
- else
- CHECK(message.Reply(message.GetSendLength()));
- }
- return {};
- }
-
- case BenchmarkOps::Read: {
- VLOG(1) << "BenchmarkService::HandleMessage: op=read send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- Status<void> status;
- if (message.GetReceiveLength()) {
- status = message.WriteAll(receive_buffer.data(),
- message.GetReceiveLength());
- }
-
- {
- ATRACE_NAME("Reply");
- if (!status)
- CHECK(message.ReplyError(status.error()));
- else
- CHECK(message.Reply(message.GetReceiveLength()));
- }
- return {};
- }
-
- case BenchmarkOps::Echo: {
- VLOG(1) << "BenchmarkService::HandleMessage: op=echo send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- Status<void> status;
- if (message.GetSendLength())
- status = message.ReadAll(send_buffer.data(), message.GetSendLength());
-
- if (!status) {
- CHECK(message.ReplyError(status.error()));
- return {};
- }
-
- if (message.GetSendLength()) {
- status =
- message.WriteAll(send_buffer.data(), message.GetSendLength());
- }
-
- {
- ATRACE_NAME("Reply");
- if (!status)
- CHECK(message.ReplyError(status.error()));
- else
- CHECK(message.Reply(message.GetSendLength()));
- }
- return {};
- }
-
- case BenchmarkOps::Stats: {
- VLOG(1) << "BenchmarkService::HandleMessage: op=echo send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- // Snapshot the stats when the message is received.
- const uint64_t receive_time_ns = GetClockNs();
- sched_stats_.Update();
-
- // Use the RPC system to return the results.
- RemoteMethodReturn<BenchmarkRPC::Stats>(
- message, BenchmarkRPC::Stats::Return{receive_time_ns, GetClockNs(),
- sched_stats_});
- return {};
- }
-
- case BenchmarkOps::WriteVector:
- VLOG(1) << "BenchmarkService::HandleMessage: op=writevec send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- DispatchRemoteMethod<BenchmarkRPC::WriteVector>(
- *this, &BenchmarkService::OnWriteVector, message, kMaxMessageSize);
- return {};
-
- case BenchmarkOps::EchoVector:
- VLOG(1) << "BenchmarkService::HandleMessage: op=echovec send_length="
- << message.GetSendLength()
- << " receive_length=" << message.GetReceiveLength();
-
- DispatchRemoteMethod<BenchmarkRPC::EchoVector>(
- *this, &BenchmarkService::OnEchoVector, message, kMaxMessageSize);
- return {};
-
- case BenchmarkOps::Quit:
- Cancel();
- return ErrorStatus{ESHUTDOWN};
-
- default:
- VLOG(1) << "BenchmarkService::HandleMessage: default case; op="
- << message.GetOp();
- return Service::DefaultHandleMessage(message);
- }
- }
-
- // Updates the scheduler stats from procfs for this thread.
- void UpdateSchedStats() { sched_stats_.Update(); }
-
- private:
- friend BASE;
-
- explicit BenchmarkService(std::unique_ptr<Endpoint> endpoint)
- : BASE("BenchmarkService", std::move(endpoint)),
- send_buffer(kMaxMessageSize),
- receive_buffer(kMaxMessageSize) {}
-
- std::vector<uint8_t> send_buffer;
- std::vector<uint8_t> receive_buffer;
-
- // Each service thread has its own scheduler stats object.
- static thread_local SchedStats sched_stats_;
-
- using BufferType = BufferWrapper<
- std::vector<uint8_t, DefaultInitializationAllocator<uint8_t>>>;
-
- int OnWriteVector(Message&, const BufferType& data) { return data.size(); }
- BufferType OnEchoVector(Message&, BufferType&& data) {
- return std::move(data);
- }
-
- BenchmarkService(const BenchmarkService&) = delete;
- void operator=(const BenchmarkService&) = delete;
-};
-
-thread_local SchedStats BenchmarkService::sched_stats_;
-
-// Implements the client side of the benchmark.
-class BenchmarkClient : public ClientBase<BenchmarkClient> {
- public:
- int Nop() {
- ATRACE_NAME("BenchmarkClient::Nop");
- VLOG(1) << "BenchmarkClient::Nop";
- Transaction transaction{*this};
- return ReturnStatusOrError(transaction.Send<int>(BenchmarkOps::Nop));
- }
-
- int Write(const void* buffer, size_t length) {
- ATRACE_NAME("BenchmarkClient::Write");
- VLOG(1) << "BenchmarkClient::Write: buffer=" << buffer
- << " length=" << length;
- Transaction transaction{*this};
- return ReturnStatusOrError(
- transaction.Send<int>(BenchmarkOps::Write, buffer, length, nullptr, 0));
- // return write(endpoint_fd(), buffer, length);
- }
-
- int Read(void* buffer, size_t length) {
- ATRACE_NAME("BenchmarkClient::Read");
- VLOG(1) << "BenchmarkClient::Read: buffer=" << buffer
- << " length=" << length;
- Transaction transaction{*this};
- return ReturnStatusOrError(
- transaction.Send<int>(BenchmarkOps::Read, nullptr, 0, buffer, length));
- // return read(endpoint_fd(), buffer, length);
- }
-
- int Echo(const void* send_buffer, size_t send_length, void* receive_buffer,
- size_t receive_length) {
- ATRACE_NAME("BenchmarkClient::Echo");
- VLOG(1) << "BenchmarkClient::Echo: send_buffer=" << send_buffer
- << " send_length=" << send_length
- << " receive_buffer=" << receive_buffer
- << " receive_length=" << receive_length;
- Transaction transaction{*this};
- return ReturnStatusOrError(
- transaction.Send<int>(BenchmarkOps::Echo, send_buffer, send_length,
- receive_buffer, receive_length));
- }
-
- int Stats(std::tuple<uint64_t, uint64_t, SchedStats>* stats_out) {
- ATRACE_NAME("BenchmarkClient::Stats");
- VLOG(1) << "BenchmarkClient::Stats";
-
- auto status = InvokeRemoteMethodInPlace<BenchmarkRPC::Stats>(stats_out);
- return status ? 0 : -status.error();
- }
-
- int WriteVector(const BufferWrapper<std::vector<uint8_t>>& data) {
- ATRACE_NAME("BenchmarkClient::Stats");
- VLOG(1) << "BenchmarkClient::Stats";
-
- auto status = InvokeRemoteMethod<BenchmarkRPC::WriteVector>(data);
- return ReturnStatusOrError(status);
- }
-
- template <typename T>
- int WriteVector(const BufferWrapper<T>& data) {
- ATRACE_NAME("BenchmarkClient::WriteVector");
- VLOG(1) << "BenchmarkClient::WriteVector";
-
- auto status = InvokeRemoteMethod<BenchmarkRPC::WriteVector>(data);
- return ReturnStatusOrError(status);
- }
-
- template <typename T, typename U>
- int EchoVector(const BufferWrapper<T>& data, BufferWrapper<U>* data_out) {
- ATRACE_NAME("BenchmarkClient::EchoVector");
- VLOG(1) << "BenchmarkClient::EchoVector";
-
- MessageBuffer<ReplyBuffer>::Reserve(kMaxMessageSize - 1);
- auto status =
- InvokeRemoteMethodInPlace<BenchmarkRPC::EchoVector>(data_out, data);
- return status ? 0 : -status.error();
- }
-
- int Quit() {
- VLOG(1) << "BenchmarkClient::Quit";
- Transaction transaction{*this};
- return ReturnStatusOrError(transaction.Send<int>(BenchmarkOps::Echo));
- }
-
- private:
- friend BASE;
-
- explicit BenchmarkClient(const std::string& service_path)
- : BASE(ClientChannelFactory::Create(service_path),
- ProgramOptions.timeout) {}
-
- BenchmarkClient(const BenchmarkClient&) = delete;
- void operator=(const BenchmarkClient&) = delete;
-};
-
-// Creates a benchmark service at |path| and dispatches messages.
-int ServiceCommand(const std::string& path) {
- if (path.empty())
- return -EINVAL;
-
- // Start the requested number of dispatch threads.
- std::vector<std::thread> dispatch_threads;
- int service_count = ProgramOptions.instances;
- int service_id_counter = 0;
- int thread_id_counter = 0;
- std::atomic<bool> done(false);
-
- while (service_count--) {
- std::cerr << "Starting service instance " << service_id_counter
- << std::endl;
- auto service = BenchmarkService::Create(
- android::pdx::default_transport::Endpoint::CreateAndBindSocket(
- GetServicePath(path, service_id_counter),
- android::pdx::default_transport::Endpoint::kBlocking));
- if (!service) {
- std::cerr << "Failed to create service instance!!" << std::endl;
- done = true;
- break;
- }
-
- int thread_count = ProgramOptions.threads;
- while (thread_count--) {
- std::cerr << "Starting dispatch thread " << thread_id_counter
- << " service " << service_id_counter << std::endl;
-
- dispatch_threads.emplace_back(
- [&](const int thread_id, const int service_id,
- const std::shared_ptr<BenchmarkService>& local_service) {
- SetThreadName("service" + std::to_string(service_id));
-
- // Read the initial schedstats for this thread from procfs.
- local_service->UpdateSchedStats();
-
- ATRACE_NAME("BenchmarkService::Dispatch");
- while (!done) {
- auto ret = local_service->ReceiveAndDispatch();
- if (!ret) {
- if (ret.error() != ESHUTDOWN) {
- std::cerr << "Error while dispatching message on thread "
- << thread_id << " service " << service_id << ": "
- << ret.GetErrorMessage() << std::endl;
- } else {
- std::cerr << "Quitting thread " << thread_id << " service "
- << service_id << std::endl;
- }
- done = true;
- return;
- }
- }
- },
- thread_id_counter++, service_id_counter, service);
- }
-
- service_id_counter++;
- }
-
- // Wait for the dispatch threads to exit.
- for (auto& thread : dispatch_threads) {
- thread.join();
- }
-
- return 0;
-}
-
-int ClientCommand(const std::string& path) {
- // Start the requested number of client threads.
- std::vector<std::thread> client_threads;
- std::vector<std::future<BenchmarkResult>> client_results;
- int service_count = ProgramOptions.instances;
- int thread_id_counter = 0;
- int service_id_counter = 0;
-
- // Aggregate statistics, updated when worker threads exit.
- std::atomic<uint64_t> total_bytes(0);
- std::atomic<uint64_t> total_time_ns(0);
-
- // Samples for variance calculation.
- std::vector<uint64_t> latency_samples_ns(
- ProgramOptions.instances * ProgramOptions.threads * ProgramOptions.count);
- const size_t samples_per_thread = ProgramOptions.count;
-
- std::vector<uint8_t> send_buffer(ProgramOptions.blocksize);
- std::vector<uint8_t> receive_buffer(kMaxMessageSize);
-
- // Barriers for synchronizing thread start.
- std::vector<std::future<void>> ready_barrier_futures;
- std::promise<void> go_barrier_promise;
- std::future<void> go_barrier_future = go_barrier_promise.get_future();
-
- // Barrier for synchronizing thread tear down.
- std::promise<void> done_barrier_promise;
- std::future<void> done_barrier_future = done_barrier_promise.get_future();
-
- while (service_count--) {
- int thread_count = ProgramOptions.threads;
- while (thread_count--) {
- std::cerr << "Starting client thread " << thread_id_counter << " service "
- << service_id_counter << std::endl;
-
- std::promise<BenchmarkResult> result_promise;
- client_results.push_back(result_promise.get_future());
-
- std::promise<void> ready_barrier_promise;
- ready_barrier_futures.push_back(ready_barrier_promise.get_future());
-
- client_threads.emplace_back(
- [&](const int thread_id, const int service_id,
- std::promise<BenchmarkResult> result, std::promise<void> ready) {
- SetThreadName("client" + std::to_string(thread_id) + "/" +
- std::to_string(service_id));
-
- ATRACE_NAME("BenchmarkClient::Dispatch");
-
- auto client =
- BenchmarkClient::Create(GetServicePath(path, service_id));
- if (!client) {
- std::cerr << "Failed to create client for service " << service_id
- << std::endl;
- return -ENOMEM;
- }
-
- uint64_t* thread_samples =
- &latency_samples_ns[samples_per_thread * thread_id];
-
- // Per-thread statistics.
- uint64_t bytes_sent = 0;
- uint64_t time_start_ns;
- uint64_t time_end_ns;
- SchedStats sched_stats;
-
- // Signal ready and wait for go.
- ready.set_value();
- go_barrier_future.wait();
-
- // Warmup the scheduler.
- int warmup = ProgramOptions.warmup;
- while (warmup--) {
- for (int i = 0; i < 1000000; i++)
- ;
- }
-
- sched_stats.Update();
- time_start_ns = GetClockNs();
-
- int count = ProgramOptions.count;
- while (count--) {
- uint64_t iteration_start_ns = GetClockNs();
-
- switch (ProgramOptions.opcode) {
- case BenchmarkOps::Nop: {
- const int ret = client->Nop();
- if (ret < 0) {
- std::cerr << "Failed to send nop: " << strerror(-ret)
- << std::endl;
- return ret;
- } else {
- VLOG(1) << "Success";
- }
- break;
- }
-
- case BenchmarkOps::Read: {
- const int ret = client->Read(receive_buffer.data(),
- ProgramOptions.blocksize);
- if (ret < 0) {
- std::cerr << "Failed to read: " << strerror(-ret)
- << std::endl;
- return ret;
- } else if (ret != ProgramOptions.blocksize) {
- std::cerr << "Expected ret=" << ProgramOptions.blocksize
- << "; actual ret=" << ret << std::endl;
- return -EINVAL;
- } else {
- VLOG(1) << "Success";
- bytes_sent += ret;
- }
- break;
- }
-
- case BenchmarkOps::Write: {
- const int ret =
- client->Write(send_buffer.data(), send_buffer.size());
- if (ret < 0) {
- std::cerr << "Failed to write: " << strerror(-ret)
- << std::endl;
- return ret;
- } else if (ret != ProgramOptions.blocksize) {
- std::cerr << "Expected ret=" << ProgramOptions.blocksize
- << "; actual ret=" << ret << std::endl;
- return -EINVAL;
- } else {
- VLOG(1) << "Success";
- bytes_sent += ret;
- }
- break;
- }
-
- case BenchmarkOps::Echo: {
- const int ret = client->Echo(
- send_buffer.data(), send_buffer.size(),
- receive_buffer.data(), receive_buffer.size());
- if (ret < 0) {
- std::cerr << "Failed to echo: " << strerror(-ret)
- << std::endl;
- return ret;
- } else if (ret != ProgramOptions.blocksize) {
- std::cerr << "Expected ret=" << ProgramOptions.blocksize
- << "; actual ret=" << ret << std::endl;
- return -EINVAL;
- } else {
- VLOG(1) << "Success";
- bytes_sent += ret * 2;
- }
- break;
- }
-
- case BenchmarkOps::Stats: {
- std::tuple<uint64_t, uint64_t, SchedStats> stats;
- const int ret = client->Stats(&stats);
- if (ret < 0) {
- std::cerr << "Failed to get stats: " << strerror(-ret)
- << std::endl;
- return ret;
- } else {
- VLOG(1) << "Success";
- std::cerr
- << "Round trip: receive_time_ns=" << std::get<0>(stats)
- << " reply_time_ns=" << std::get<1>(stats)
- << " cpu_time_s=" << std::get<2>(stats).cpu_time_s()
- << " wait_s=" << std::get<2>(stats).wait_s()
- << std::endl;
- }
- break;
- }
-
- case BenchmarkOps::WriteVector: {
- const int ret = client->WriteVector(
- WrapBuffer(send_buffer.data(), ProgramOptions.blocksize));
- if (ret < 0) {
- std::cerr << "Failed to write vector: " << strerror(-ret)
- << std::endl;
- return ret;
- } else {
- VLOG(1) << "Success";
- bytes_sent += ret;
- }
- break;
- }
-
- case BenchmarkOps::EchoVector: {
- thread_local BufferWrapper<std::vector<
- uint8_t, DefaultInitializationAllocator<uint8_t>>>
- response_buffer;
- const int ret = client->EchoVector(
- WrapBuffer(send_buffer.data(), ProgramOptions.blocksize),
- &response_buffer);
- if (ret < 0) {
- std::cerr << "Failed to echo vector: " << strerror(-ret)
- << std::endl;
- return ret;
- } else {
- VLOG(1) << "Success";
- bytes_sent += send_buffer.size() + response_buffer.size();
- }
- break;
- }
-
- case BenchmarkOps::Quit: {
- const int ret = client->Quit();
- if (ret < 0 && ret != -ESHUTDOWN) {
- std::cerr << "Failed to send quit: " << strerror(-ret);
- return ret;
- } else {
- VLOG(1) << "Success";
- }
- break;
- }
-
- default:
- std::cerr
- << "Invalid client operation: " << ProgramOptions.opcode
- << std::endl;
- return -EINVAL;
- }
-
- uint64_t iteration_end_ns = GetClockNs();
- uint64_t iteration_delta_ns =
- iteration_end_ns - iteration_start_ns;
- thread_samples[count] = iteration_delta_ns;
-
- if (iteration_delta_ns > (kNanosPerSecond / 100)) {
- SchedStats stats = sched_stats;
- stats.Update();
- std::cerr << "Thread " << thread_id << " iteration_delta_s="
- << (static_cast<double>(iteration_delta_ns) /
- kNanosPerSecond)
- << " " << stats.cpu_time_s() << " " << stats.wait_s()
- << std::endl;
- }
- }
-
- time_end_ns = GetClockNs();
- sched_stats.Update();
-
- const double time_delta_s =
- static_cast<double>(time_end_ns - time_start_ns) /
- kNanosPerSecond;
-
- total_bytes += bytes_sent;
- total_time_ns += time_end_ns - time_start_ns;
-
- result.set_value(
- {thread_id, service_id, time_delta_s, bytes_sent, sched_stats});
- done_barrier_future.wait();
-
- return 0;
- },
- thread_id_counter++, service_id_counter, std::move(result_promise),
- std::move(ready_barrier_promise));
- }
-
- service_id_counter++;
- }
-
- // Wait for workers to be ready.
- std::cerr << "Waiting for workers to be ready..." << std::endl;
- for (auto& ready : ready_barrier_futures)
- ready.wait();
-
- // Signal workers to go.
- std::cerr << "Kicking off benchmark." << std::endl;
- go_barrier_promise.set_value();
-
- // Wait for all the worker threas to finish.
- for (auto& result : client_results)
- result.wait();
-
- // Report worker thread results.
- for (auto& result : client_results) {
- BenchmarkResult benchmark_result = result.get();
- std::cerr << std::fixed << "Thread " << benchmark_result.thread_id
- << " service " << benchmark_result.service_id << ":" << std::endl;
- std::cerr << "\t " << benchmark_result.bytes_sent << " bytes in "
- << benchmark_result.time_delta_s << " seconds ("
- << std::setprecision(0) << (benchmark_result.bytes_sent / 1024.0 /
- benchmark_result.time_delta_s)
- << " K/s; " << std::setprecision(3)
- << (ProgramOptions.count / benchmark_result.time_delta_s)
- << " txn/s; " << std::setprecision(9)
- << (benchmark_result.time_delta_s / ProgramOptions.count)
- << " s/txn)" << std::endl;
- std::cerr << "\tStats: " << benchmark_result.sched_stats.cpu_time_s() << " "
- << (benchmark_result.sched_stats.cpu_time_s() /
- ProgramOptions.count)
- << " " << benchmark_result.sched_stats.wait_s() << " "
- << (benchmark_result.sched_stats.wait_s() / ProgramOptions.count)
- << " " << benchmark_result.sched_stats.timeslices() << std::endl;
- }
-
- // Signal worker threads to exit.
- done_barrier_promise.set_value();
-
- // Wait for the worker threads to exit.
- for (auto& thread : client_threads) {
- thread.join();
- }
-
- // Report aggregate results.
- const int total_threads = ProgramOptions.threads * ProgramOptions.instances;
- const int iterations = ProgramOptions.count;
- const double total_time_s =
- static_cast<double>(total_time_ns) / kNanosPerSecond;
- // This is about how much wall time it took to completely transfer all the
- // paylaods.
- const double average_time_s = total_time_s / total_threads;
-
- const uint64_t min_sample_time_ns =
- *std::min_element(latency_samples_ns.begin(), latency_samples_ns.end());
- const double min_sample_time_s =
- static_cast<double>(min_sample_time_ns) / kNanosPerSecond;
-
- const uint64_t max_sample_time_ns =
- *std::max_element(latency_samples_ns.begin(), latency_samples_ns.end());
- const double max_sample_time_s =
- static_cast<double>(max_sample_time_ns) / kNanosPerSecond;
-
- const double total_sample_time_s =
- std::accumulate(latency_samples_ns.begin(), latency_samples_ns.end(), 0.0,
- [](double s, uint64_t ns) {
- return s + static_cast<double>(ns) / kNanosPerSecond;
- });
- const double average_sample_time_s =
- total_sample_time_s / latency_samples_ns.size();
-
- const double sum_of_squared_deviations = std::accumulate(
- latency_samples_ns.begin(), latency_samples_ns.end(), 0.0,
- [&](double s, uint64_t ns) {
- const double delta =
- static_cast<double>(ns) / kNanosPerSecond - average_sample_time_s;
- return s + delta * delta;
- });
- const double variance = sum_of_squared_deviations / latency_samples_ns.size();
- const double standard_deviation = std::sqrt(variance);
-
- const int num_buckets = 200;
- const uint64_t sample_range_ns = max_sample_time_ns - min_sample_time_ns;
- const uint64_t ns_per_bucket = sample_range_ns / num_buckets;
- std::array<uint64_t, num_buckets> sample_buckets = {{0}};
-
- // Count samples in each bucket range.
- for (uint64_t sample_ns : latency_samples_ns) {
- sample_buckets[(sample_ns - min_sample_time_ns) / (ns_per_bucket + 1)] += 1;
- }
-
- // Calculate population percentiles.
- const uint64_t percent_50 =
- static_cast<uint64_t>(latency_samples_ns.size() * 0.5);
- const uint64_t percent_90 =
- static_cast<uint64_t>(latency_samples_ns.size() * 0.9);
- const uint64_t percent_95 =
- static_cast<uint64_t>(latency_samples_ns.size() * 0.95);
- const uint64_t percent_99 =
- static_cast<uint64_t>(latency_samples_ns.size() * 0.99);
-
- uint64_t sample_count = 0;
- double latency_50th_percentile_s, latency_90th_percentile_s,
- latency_95th_percentile_s, latency_99th_percentile_s;
- for (int i = 0; i < num_buckets; i++) {
- // Report the midpoint of the bucket range as the value of the
- // corresponding
- // percentile.
- const double bucket_midpoint_time_s =
- (ns_per_bucket * i + 0.5 * ns_per_bucket + min_sample_time_ns) /
- kNanosPerSecond;
- if (sample_count < percent_50 &&
- (sample_count + sample_buckets[i]) >= percent_50) {
- latency_50th_percentile_s = bucket_midpoint_time_s;
- }
- if (sample_count < percent_90 &&
- (sample_count + sample_buckets[i]) >= percent_90) {
- latency_90th_percentile_s = bucket_midpoint_time_s;
- }
- if (sample_count < percent_95 &&
- (sample_count + sample_buckets[i]) >= percent_95) {
- latency_95th_percentile_s = bucket_midpoint_time_s;
- }
- if (sample_count < percent_99 &&
- (sample_count + sample_buckets[i]) >= percent_99) {
- latency_99th_percentile_s = bucket_midpoint_time_s;
- }
- sample_count += sample_buckets[i];
- }
-
- std::cerr << std::fixed << "Total throughput over " << total_threads
- << " threads:\n\t " << total_bytes << " bytes in " << average_time_s
- << " seconds (" << std::setprecision(0)
- << (total_bytes / 1024.0 / average_time_s) << " K/s; "
- << std::setprecision(3)
- << (iterations * total_threads / average_time_s)
- << std::setprecision(9) << " txn/s; "
- << (average_time_s / (iterations * total_threads)) << " s/txn)"
- << std::endl;
- std::cerr << "Sample statistics: " << std::endl;
- std::cerr << total_sample_time_s << " s total sample time" << std::endl;
- std::cerr << average_sample_time_s << " s avg" << std::endl;
- std::cerr << standard_deviation << " s std dev" << std::endl;
- std::cerr << min_sample_time_s << " s min" << std::endl;
- std::cerr << max_sample_time_s << " s max" << std::endl;
- std::cerr << "Latency percentiles:" << std::endl;
- std::cerr << "50th: " << latency_50th_percentile_s << " s" << std::endl;
- std::cerr << "90th: " << latency_90th_percentile_s << " s" << std::endl;
- std::cerr << "95th: " << latency_95th_percentile_s << " s" << std::endl;
- std::cerr << "99th: " << latency_99th_percentile_s << " s" << std::endl;
-
- std::cout << total_time_ns << " " << std::fixed << std::setprecision(9)
- << average_sample_time_s << " " << std::fixed
- << std::setprecision(9) << standard_deviation << std::endl;
- return 0;
-}
-
-int Usage(const std::string& command_name) {
- // clang-format off
- std::cout << "Usage: " << command_name << " [options]" << std::endl;
- std::cout << "\t--verbose : Use verbose messages." << std::endl;
- std::cout << "\t--service <endpoint path> : Start service at the given path." << std::endl;
- std::cout << "\t--client <endpoint path> : Start client to the given path." << std::endl;
- std::cout << "\t--op <read | write | echo> : Sepcify client operation mode." << std::endl;
- std::cout << "\t--bs <block size bytes> : Sepcify block size to use." << std::endl;
- std::cout << "\t--count <count> : Sepcify number of transactions to make." << std::endl;
- std::cout << "\t--instances <count> : Specify number of service instances." << std::endl;
- std::cout << "\t--threads <count> : Sepcify number of threads per instance." << std::endl;
- std::cout << "\t--timeout <timeout ms | -1> : Timeout to wait for services." << std::endl;
- std::cout << "\t--trace : Enable systrace logging." << std::endl;
- std::cout << "\t--warmup <iterations> : Busy loops before running benchmarks." << std::endl;
- // clang-format on
- return -1;
-}
-
-} // anonymous namespace
-
-int main(int argc, char** argv) {
- logging::LoggingSettings logging_settings;
- logging_settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
- logging::InitLogging(logging_settings);
-
- int getopt_code;
- int option_index;
- std::string option = "";
- std::string command = "";
- std::string command_argument = "";
- bool tracing_enabled = false;
-
- // Process command line options.
- while ((getopt_code =
- getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
- option = long_options[option_index].name;
- VLOG(1) << "option=" << option;
- switch (getopt_code) {
- case 0:
- if (option == kOptionVerbose) {
- ProgramOptions.verbose = true;
- logging::SetMinLogLevel(-1);
- } else if (option == kOptionOpcode) {
- ParseOpcodeOption(optarg);
- } else if (option == kOptionBlocksize) {
- ProgramOptions.blocksize = std::stoi(optarg);
- if (ProgramOptions.blocksize < 0) {
- std::cerr << "Invalid blocksize argument: "
- << ProgramOptions.blocksize << std::endl;
- return -EINVAL;
- }
- } else if (option == kOptionCount) {
- ProgramOptions.count = std::stoi(optarg);
- if (ProgramOptions.count < 1) {
- std::cerr << "Invalid count argument: " << ProgramOptions.count
- << std::endl;
- return -EINVAL;
- }
- } else if (option == kOptionThreads) {
- ProgramOptions.threads = std::stoi(optarg);
- if (ProgramOptions.threads < 1) {
- std::cerr << "Invalid threads argument: " << ProgramOptions.threads
- << std::endl;
- return -EINVAL;
- }
- } else if (option == kOptionInstances) {
- ProgramOptions.instances = std::stoi(optarg);
- if (ProgramOptions.instances < 1) {
- std::cerr << "Invalid instances argument: "
- << ProgramOptions.instances << std::endl;
- return -EINVAL;
- }
- } else if (option == kOptionTimeout) {
- ProgramOptions.timeout = std::stoi(optarg);
- } else if (option == kOptionTrace) {
- tracing_enabled = true;
- } else if (option == kOptionWarmup) {
- ProgramOptions.warmup = std::stoi(optarg);
- } else {
- command = option;
- if (optarg)
- command_argument = optarg;
- }
- break;
- }
- }
-
- // Setup ATRACE/systrace based on command line.
- atrace_setup();
- atrace_set_tracing_enabled(tracing_enabled);
-
- VLOG(1) << "command=" << command << " command_argument=" << command_argument;
-
- if (command == "") {
- return Usage(argv[0]);
- } else if (command == kOptionService) {
- return ServiceCommand(command_argument);
- } else if (command == kOptionClient) {
- return ClientCommand(command_argument);
- } else {
- return Usage(argv[0]);
- }
-}
diff --git a/libs/vr/libpdx_default_transport/pdx_tool.cpp b/libs/vr/libpdx_default_transport/pdx_tool.cpp
deleted file mode 100644
index 60eedb3..0000000
--- a/libs/vr/libpdx_default_transport/pdx_tool.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <errno.h>
-#include <ftw.h>
-#include <getopt.h>
-#include <pdx/client.h>
-#include <pdx/service.h>
-#include <sys/stat.h>
-
-#include <algorithm>
-#include <vector>
-
-#include <pdx/default_transport/client_channel_factory.h>
-
-using android::pdx::default_transport::ClientChannelFactory;
-
-namespace {
-
-constexpr long kClientTimeoutMs = 0; // Don't wait for non-existent services.
-constexpr int kDumpBufferSize = 2 * 4096; // Two pages.
-
-class ControlClient : public android::pdx::ClientBase<ControlClient> {
- public:
- explicit ControlClient(const std::string& service_path, long timeout_ms);
-
- void Reload();
- std::string Dump();
-
- private:
- friend BASE;
-
- ControlClient(const ControlClient&) = delete;
- void operator=(const ControlClient&) = delete;
-};
-
-bool option_verbose = false;
-
-static struct option long_options[] = {
- {"reload", required_argument, 0, 0},
- {"dump", required_argument, 0, 0},
- {"verbose", no_argument, 0, 0},
- {0, 0, 0, 0},
-};
-
-#define printf_verbose(fmt, ... /*args*/) \
- do { \
- if (option_verbose) \
- printf(fmt, ##__VA_ARGS__); \
- } while (0)
-
-void HexDump(const void* pointer, size_t length);
-
-ControlClient::ControlClient(const std::string& service_path, long timeout_ms)
- : BASE{ClientChannelFactory::Create(service_path), timeout_ms} {}
-
-void ControlClient::Reload() {
- android::pdx::Transaction trans{*this};
- auto status = trans.Send<void>(android::pdx::opcodes::REPORT_SYSPROP_CHANGE,
- nullptr, 0, nullptr, 0);
- if (!status) {
- fprintf(stderr, "Failed to send reload: %s\n",
- status.GetErrorMessage().c_str());
- }
-}
-
-std::string ControlClient::Dump() {
- android::pdx::Transaction trans{*this};
- std::vector<char> buffer(kDumpBufferSize);
- auto status = trans.Send<int>(android::pdx::opcodes::DUMP_STATE, nullptr, 0,
- buffer.data(), buffer.size());
-
- printf_verbose("ControlClient::Dump: ret=%d\n", ReturnStatusOrError(status));
-
- if (!status) {
- fprintf(stderr, "Failed to send dump request: %s\n",
- status.GetErrorMessage().c_str());
- return "";
- } else if (status.get() > static_cast<ssize_t>(buffer.capacity())) {
- fprintf(stderr, "Service returned a larger size than requested: %d\n",
- status.get());
- return "";
- }
-
- if (option_verbose)
- HexDump(buffer.data(), status.get());
-
- return std::string(buffer.data(), status.get());
-}
-
-int Usage(const std::string& command_name) {
- printf("Usage: %s [options]\n", command_name.c_str());
- printf("\t--verbose : Use verbose messages.\n");
- printf(
- "\t--reload <all | service path> : Ask service(s) to reload system "
- "properties.\n");
- printf("\t--dump <all | service path> : Dump service(s) state.\n");
- return -1;
-}
-
-typedef int (*CallbackType)(const char* path, const struct stat* sb,
- int type_flag, FTW* ftw_buffer);
-
-int ReloadCommandCallback(const char* path, const struct stat* sb,
- int type_flag, FTW* ftw_buffer);
-int DumpCommandCallback(const char* path, const struct stat* sb, int type_flag,
- FTW* ftw_buffer);
-
-void CallOnAllFiles(CallbackType callback, const std::string& base_path) {
- const int kMaxDepth = 32;
- nftw(base_path.c_str(), callback, kMaxDepth, FTW_PHYS);
-}
-
-int ReloadCommand(const std::string& service_path) {
- printf_verbose("ReloadCommand: service_path=%s\n", service_path.c_str());
-
- if (service_path == "" || service_path == "all") {
- CallOnAllFiles(ReloadCommandCallback,
- ClientChannelFactory::GetRootEndpointPath());
- return 0;
- } else {
- auto client = ControlClient::Create(service_path, kClientTimeoutMs);
- if (!client) {
- fprintf(stderr, "Failed to open service at \"%s\".\n",
- service_path.c_str());
- return -1;
- }
-
- client->Reload();
- return 0;
- }
-}
-
-int DumpCommand(const std::string& service_path) {
- printf_verbose("DumpCommand: service_path=%s\n", service_path.c_str());
-
- if (service_path == "" || service_path == "all") {
- CallOnAllFiles(DumpCommandCallback,
- ClientChannelFactory::GetRootEndpointPath());
- return 0;
- } else {
- auto client = ControlClient::Create(service_path, kClientTimeoutMs);
- if (!client) {
- fprintf(stderr, "Failed to open service at \"%s\".\n",
- service_path.c_str());
- return -1;
- }
-
- std::string response = client->Dump();
- if (!response.empty()) {
- printf(
- "--------------------------------------------------------------------"
- "---\n");
- printf("%s:\n", service_path.c_str());
- printf("%s\n", response.c_str());
- }
- return 0;
- }
-}
-
-int ReloadCommandCallback(const char* path, const struct stat*, int type_flag,
- FTW*) {
- if (type_flag == FTW_F)
- ReloadCommand(path);
- return 0;
-}
-
-int DumpCommandCallback(const char* path, const struct stat*, int type_flag,
- FTW*) {
- if (type_flag == FTW_F)
- DumpCommand(path);
- return 0;
-}
-
-void HexDump(const void* pointer, size_t length) {
- uintptr_t address = reinterpret_cast<uintptr_t>(pointer);
-
- for (size_t count = 0; count < length; count += 16, address += 16) {
- printf("0x%08lx: ", static_cast<unsigned long>(address));
-
- for (size_t i = 0; i < 16u; i++) {
- if (i < std::min(length - count, static_cast<size_t>(16))) {
- printf("%02x ", *reinterpret_cast<const uint8_t*>(address + i));
- } else {
- printf(" ");
- }
- }
-
- printf("|");
-
- for (size_t i = 0; i < 16u; i++) {
- if (i < std::min(length - count, static_cast<size_t>(16))) {
- char c = *reinterpret_cast<const char*>(address + i);
- if (isalnum(c) || c == ' ') {
- printf("%c", c);
- } else {
- printf(".");
- }
- } else {
- printf(" ");
- }
- }
-
- printf("|\n");
- }
-}
-
-} // anonymous namespace
-
-int main(int argc, char** argv) {
- int getopt_code;
- int option_index;
- std::string option = "";
- std::string command = "";
- std::string command_argument = "";
-
- // Process command line options.
- while ((getopt_code =
- getopt_long(argc, argv, "", long_options, &option_index)) != -1) {
- option = long_options[option_index].name;
- printf_verbose("option=%s\n", option.c_str());
- switch (getopt_code) {
- case 0:
- if (option == "verbose") {
- option_verbose = true;
- } else {
- command = option;
- if (optarg)
- command_argument = optarg;
- }
- break;
- }
- }
-
- printf_verbose("command=%s command_argument=%s\n", command.c_str(),
- command_argument.c_str());
-
- if (command == "") {
- return Usage(argv[0]);
- } else if (command == "reload") {
- return ReloadCommand(command_argument);
- } else if (command == "dump") {
- return DumpCommand(command_argument);
- } else {
- return Usage(argv[0]);
- }
-}
diff --git a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h b/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
deleted file mode 100644
index 3ebab86..0000000
--- a/libs/vr/libpdx_default_transport/private/pdx/default_transport/service_utility.h
+++ /dev/null
@@ -1,92 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
-
-#include <ftw.h>
-
-#include <pdx/client.h>
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/service.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-class ServiceUtility : public ClientBase<ServiceUtility> {
- public:
- Status<int> ReloadSystemProperties() {
- Transaction transaction{*this};
- return ReturnStatusOrError(
- transaction.Send<int>(opcodes::REPORT_SYSPROP_CHANGE));
- }
-
- static std::string GetRootEndpointPath() {
- return ClientChannelFactory::GetRootEndpointPath();
- }
- static std::string GetEndpointPath(const std::string& endpoint_path) {
- return ClientChannelFactory::GetEndpointPath(endpoint_path);
- }
-
- // Traverses the PDX service path space and sends a message to reload system
- // properties to each service endpoint it finds along the way.
- // NOTE: This method is used by atrace to poke PDX services. Please avoid
- // unnecessary changes to this mechanism to minimize impact on atrace.
- static bool PokeServices() {
- const int kMaxDepth = 16;
- const int result =
- nftw(GetRootEndpointPath().c_str(), PokeService, kMaxDepth, FTW_PHYS);
- return result == 0 ? true : false;
- }
-
- private:
- friend BASE;
-
- explicit ServiceUtility(const std::string& endpoint_path,
- int* error = nullptr)
- : BASE(ClientChannelFactory::Create(endpoint_path), 0) {
- if (error)
- *error = Client::error();
- }
-
- // Sends the sysprop_change message to the service at fpath, so it re-reads
- // its system properties. Returns 0 on success or a negated errno code on
- // failure.
- // NOTE: This method is used by atrace to poke PDX services. Please avoid
- // unnecessary changes to this mechanism to minimize impact on atrace.
- static int PokeService(const char* fpath, const struct stat* /*sb*/,
- int typeflag, struct FTW* /*ftwbuf*/) {
- const bool kIgnoreErrors = true;
-
- if (typeflag == FTW_F) {
- int error;
- auto utility = ServiceUtility::Create(fpath, &error);
- if (!utility) {
- if (error != -ECONNREFUSED) {
- ALOGE("ServiceUtility::PokeService: Failed to open %s: %s.", fpath,
- strerror(-error));
- }
- return kIgnoreErrors ? 0 : error;
- }
-
- auto status = utility->ReloadSystemProperties();
- if (!status) {
- ALOGE(
- "ServiceUtility::PokeService: Failed to send sysprop change to %s: "
- "%s",
- fpath, status.GetErrorMessage().c_str());
- return kIgnoreErrors ? 0 : -status.error();
- }
- }
-
- return 0;
- }
-
- ServiceUtility(const ServiceUtility&) = delete;
- void operator=(const ServiceUtility&) = delete;
-};
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICE_UTILITY_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h
deleted file mode 100644
index 11163b3..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_manager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
-
-#include <servicefs/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelManager = ::android::pdx::servicefs::ChannelManager;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h
deleted file mode 100644
index a8623b2..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/channel_parcelable.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
-
-#include <servicefs/channel_parcelable.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelParcelable = ::android::pdx::servicefs::ChannelParcelable;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h
deleted file mode 100644
index d171780..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
-
-#include <servicefs/client_channel.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannel = ::android::pdx::servicefs::ClientChannel;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h
deleted file mode 100644
index 77b5cac..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/client_channel_factory.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <servicefs/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannelFactory = ::android::pdx::servicefs::ClientChannelFactory;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h b/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h
deleted file mode 100644
index 8f413c1..0000000
--- a/libs/vr/libpdx_default_transport/private/servicefs/pdx/default_transport/service_endpoint.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_SERVICE_ENDPOINT_H_
-
-#include <servicefs/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using Endpoint = ::android::pdx::servicefs::Endpoint;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_SERVICEFS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h
deleted file mode 100644
index f34636f..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_manager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
-
-#include <uds/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelManager = ::android::pdx::uds::ChannelManager;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h
deleted file mode 100644
index bcd74e6..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/channel_parcelable.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
-
-#include <uds/channel_parcelable.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ChannelParcelable = ::android::pdx::uds::ChannelParcelable;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h
deleted file mode 100644
index bf632d7..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
-
-#include <uds/client_channel.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannel = ::android::pdx::uds::ClientChannel;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h
deleted file mode 100644
index e5c4e30..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/client_channel_factory.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <uds/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using ClientChannelFactory = ::android::pdx::uds::ClientChannelFactory;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h b/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h
deleted file mode 100644
index 1fd6103..0000000
--- a/libs/vr/libpdx_default_transport/private/uds/pdx/default_transport/service_endpoint.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef ANDROID_PDX_DEFAULT_TRANSPORT_UDS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_DEFAULT_TRANSPORT_UDS_SERVICE_ENDPOINT_H_
-
-#include <uds/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace default_transport {
-
-using Endpoint = ::android::pdx::uds::Endpoint;
-
-} // namespace default_transport
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_DEFAULT_TRANSPORT_UDS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_uds/Android.bp b/libs/vr/libpdx_uds/Android.bp
deleted file mode 100644
index 7f88daf..0000000
--- a/libs/vr/libpdx_uds/Android.bp
+++ /dev/null
@@ -1,67 +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: "libpdx_uds",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- "-DLOG_TAG=\"libpdx_uds\"",
- "-DTRACE=0",
- ],
- export_include_dirs: ["private"],
- local_include_dirs: ["private"],
- srcs: [
- "channel_event_set.cpp",
- "channel_manager.cpp",
- "channel_parcelable.cpp",
- "client_channel_factory.cpp",
- "client_channel.cpp",
- "ipc_helper.cpp",
- "service_endpoint.cpp",
- ],
- static_libs: [
- "libcutils",
- "libbase",
- "libpdx",
- ],
- shared_libs: [
- "libbinder",
- "libselinux",
- ],
-}
-
-cc_test {
- name: "libpdx_uds_tests",
- cflags: [
- "-Wall",
- "-Wextra",
- "-Werror",
- ],
- srcs: [
- "client_channel_tests.cpp",
- "ipc_helper_tests.cpp",
- "remote_method_tests.cpp",
- "service_framework_tests.cpp",
- ],
- static_libs: [
- "libgmock",
- "libpdx_uds",
- "libpdx",
- ],
- shared_libs: [
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
- "libbinder",
- "libselinux",
- ],
-}
diff --git a/libs/vr/libpdx_uds/channel_event_set.cpp b/libs/vr/libpdx_uds/channel_event_set.cpp
deleted file mode 100644
index c68968e..0000000
--- a/libs/vr/libpdx_uds/channel_event_set.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-#include "private/uds/channel_event_set.h"
-
-#include <errno.h>
-#include <log/log.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-
-#include <uds/ipc_helper.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-template <typename FileHandleType>
-Status<void> SetupHandle(int fd, FileHandleType* handle,
- const char* error_name) {
- const int error = errno;
- handle->Reset(fd);
- if (!*handle) {
- ALOGE("SetupHandle: Failed to setup %s handle: %s", error_name,
- strerror(error));
- return ErrorStatus{error};
- }
- return {};
-}
-
-} // anonymous namespace
-
-ChannelEventSet::ChannelEventSet() {
- const int flags = EFD_CLOEXEC | EFD_NONBLOCK;
- LocalHandle pollin_event_fd, pollhup_event_fd;
-
- if (!SetupHandle(eventfd(0, flags), &pollin_event_fd, "pollin_event") ||
- !SetupHandle(eventfd(0, flags), &pollhup_event_fd, "pollhup_event")) {
- return;
- }
-
- pollin_event_fd_ = std::move(pollin_event_fd);
- pollhup_event_fd_ = std::move(pollhup_event_fd);
-}
-
-int ChannelEventSet::ModifyEvents(int clear_mask, int set_mask) {
- ALOGD_IF(TRACE, "ChannelEventSet::ModifyEvents: clear_mask=%x set_mask=%x",
- clear_mask, set_mask);
- const int old_bits = event_bits_;
- const int new_bits = (event_bits_ & ~clear_mask) | set_mask;
- event_bits_ = new_bits;
- eventfd_t value;
-
- // Calculate which bits changed and how. Bits that haven't changed since last
- // modification will not change the state of an eventfd.
- const int set_bits = new_bits & ~old_bits;
- const int clear_bits = ~new_bits & old_bits;
-
- if (set_bits & EPOLLIN)
- eventfd_write(pollin_event_fd_.Get(), 1);
- else if (clear_bits & EPOLLIN)
- eventfd_read(pollin_event_fd_.Get(), &value);
-
- if (set_bits & EPOLLHUP)
- eventfd_write(pollhup_event_fd_.Get(), 1);
- else if (clear_bits & EPOLLHUP)
- eventfd_read(pollhup_event_fd_.Get(), &value);
-
- return 0;
-}
-
-ChannelEventReceiver::ChannelEventReceiver(LocalHandle data_fd,
- LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd) {
- LocalHandle epoll_fd;
- if (!SetupHandle(epoll_create1(EPOLL_CLOEXEC), &epoll_fd, "epoll")) {
- return;
- }
-
- epoll_event event;
- event.events = EPOLLHUP | EPOLLRDHUP;
- event.data.u32 = 0;
- if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, data_fd.Get(), &event) < 0) {
- const int error = errno;
- ALOGE("ChannelEventSet::ChannelEventSet: Failed to add data_fd: %s",
- strerror(error));
- return;
- }
-
- event.events = EPOLLIN;
- event.data.u32 = 0;
- if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, pollin_event_fd.Get(), &event) <
- 0) {
- const int error = errno;
- ALOGE("ChannelEventSet::ChannelEventSet: Failed to add pollin_event_fd: %s",
- strerror(error));
- return;
- }
-
- event.events = EPOLLIN;
- event.data.u32 = 0;
- if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, pollhup_event_fd.Get(), &event) <
- 0) {
- const int error = errno;
- ALOGE(
- "ChannelEventSet::ChannelEventSet: Failed to add pollhup_event_fd: %s",
- strerror(error));
- return;
- }
-
- pollin_event_fd_ = std::move(pollin_event_fd);
- pollhup_event_fd_ = std::move(pollhup_event_fd);
- data_fd_ = std::move(data_fd);
- epoll_fd_ = std::move(epoll_fd);
-}
-
-Status<int> ChannelEventReceiver::PollPendingEvents(int timeout_ms) const {
- std::array<pollfd, 3> pfds = {{{pollin_event_fd_.Get(), POLLIN, 0},
- {pollhup_event_fd_.Get(), POLLIN, 0},
- {data_fd_.Get(), POLLHUP | POLLRDHUP, 0}}};
- if (RETRY_EINTR(poll(pfds.data(), pfds.size(), timeout_ms)) < 0) {
- const int error = errno;
- ALOGE(
- "ChannelEventReceiver::PollPendingEvents: Failed to poll for events: "
- "%s",
- strerror(error));
- return ErrorStatus{error};
- }
-
- const int event_mask =
- ((pfds[0].revents & POLLIN) ? EPOLLIN : 0) |
- ((pfds[1].revents & POLLIN) ? EPOLLHUP : 0) |
- ((pfds[2].revents & (POLLHUP | POLLRDHUP)) ? EPOLLHUP : 0);
- return {event_mask};
-}
-
-Status<int> ChannelEventReceiver::GetPendingEvents() const {
- constexpr long kTimeoutMs = 0;
- return PollPendingEvents(kTimeoutMs);
-}
-
-std::vector<ClientChannel::EventSource> ChannelEventReceiver::GetEventSources()
- const {
- return {{data_fd_.Get(), EPOLLHUP | EPOLLRDHUP},
- {pollin_event_fd_.Get(), EPOLLIN},
- {pollhup_event_fd_.Get(), POLLIN}};
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/channel_manager.cpp b/libs/vr/libpdx_uds/channel_manager.cpp
deleted file mode 100644
index 43ebe05..0000000
--- a/libs/vr/libpdx_uds/channel_manager.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <uds/channel_manager.h>
-
-#include <log/log.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-ChannelManager& ChannelManager::Get() {
- static ChannelManager instance;
- return instance;
-}
-
-void ChannelManager::CloseHandle(int32_t handle) {
- std::lock_guard<std::mutex> autolock(mutex_);
- auto channel = channels_.find(handle);
- if (channel == channels_.end()) {
- ALOGE("Invalid channel handle: %d", handle);
- } else {
- channels_.erase(channel);
- }
-}
-
-LocalChannelHandle ChannelManager::CreateHandle(LocalHandle data_fd,
- LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd) {
- if (data_fd && pollin_event_fd && pollhup_event_fd) {
- std::lock_guard<std::mutex> autolock(mutex_);
- const int32_t handle = data_fd.Get();
- channels_.emplace(
- handle,
- ChannelEventReceiver{std::move(data_fd), std::move(pollin_event_fd),
- std::move(pollhup_event_fd)});
- return LocalChannelHandle(this, handle);
- } else {
- ALOGE(
- "ChannelManager::CreateHandle: Invalid arguments: data_fd=%d "
- "pollin_event_fd=%d pollhup_event_fd=%d",
- data_fd.Get(), pollin_event_fd.Get(), pollhup_event_fd.Get());
- return LocalChannelHandle(nullptr, -1);
- }
-}
-
-ChannelEventReceiver* ChannelManager::GetChannelData(int32_t handle) {
- std::lock_guard<std::mutex> autolock(mutex_);
- auto channel = channels_.find(handle);
- return channel != channels_.end() ? &channel->second : nullptr;
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/channel_parcelable.cpp b/libs/vr/libpdx_uds/channel_parcelable.cpp
deleted file mode 100644
index 5156846..0000000
--- a/libs/vr/libpdx_uds/channel_parcelable.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-#include "uds/channel_parcelable.h"
-
-#include <binder/Parcel.h>
-#include <uds/channel_manager.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-static constexpr uint32_t kUdsMagicParcelHeader = 0x7564736d; // 'udsm'.
-
-} // namespace
-
-ChannelParcelable::ChannelParcelable(LocalHandle data_fd,
- LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd)
- : data_fd_{std::move(data_fd)},
- pollin_event_fd_{std::move(pollin_event_fd)},
- pollhup_event_fd_{std::move(pollhup_event_fd)} {}
-
-bool ChannelParcelable::IsValid() const {
- return !!data_fd_ && !!pollin_event_fd_ && !!pollhup_event_fd_;
-}
-
-LocalChannelHandle ChannelParcelable::TakeChannelHandle() {
- if (!IsValid()) {
- ALOGE("ChannelParcelable::TakeChannelHandle: Invalid channel parcel.");
- return {}; // Returns an empty channel handle.
- }
-
- return ChannelManager::Get().CreateHandle(std::move(data_fd_),
- std::move(pollin_event_fd_),
- std::move(pollhup_event_fd_));
-}
-
-status_t ChannelParcelable::writeToParcel(Parcel* parcel) const {
- status_t res = OK;
-
- if (!IsValid()) {
- ALOGE("ChannelParcelable::writeToParcel: Invalid channel parcel.");
- return BAD_VALUE;
- }
-
- res = parcel->writeUint32(kUdsMagicParcelHeader);
- if (res != OK) {
- ALOGE("ChannelParcelable::writeToParcel: Cannot write magic: res=%d.", res);
- return res;
- }
-
- res = parcel->writeFileDescriptor(data_fd_.Get());
- if (res != OK) {
- ALOGE("ChannelParcelable::writeToParcel: Cannot write data fd: res=%d.",
- res);
- return res;
- }
-
- res = parcel->writeFileDescriptor(pollin_event_fd_.Get());
- if (res != OK) {
- ALOGE(
- "ChannelParcelable::writeToParcel: Cannot write pollin event fd: "
- "res=%d.",
- res);
- return res;
- }
-
- res = parcel->writeFileDescriptor(pollhup_event_fd_.Get());
- if (res != OK) {
- ALOGE(
- "ChannelParcelable::writeToParcel: Cannot write pollhup event fd: "
- "res=%d.",
- res);
- return res;
- }
-
- return res;
-}
-
-status_t ChannelParcelable::readFromParcel(const Parcel* parcel) {
- uint32_t magic = 0;
- status_t res = OK;
-
- if (IsValid()) {
- ALOGE(
- "ChannelParcelable::readFromParcel: This channel parcel is already "
- "initailzied.");
- return ALREADY_EXISTS;
- }
-
- res = parcel->readUint32(&magic);
- if (res != OK) {
- ALOGE("ChannelParcelable::readFromParcel: Failed to read magic: res=%d.",
- res);
- return res;
- }
-
- if (magic != kUdsMagicParcelHeader) {
- ALOGE(
- "ChannelParcelable::readFromParcel: Unknown magic: 0x%x, epxected: "
- "0x%x",
- magic, kUdsMagicParcelHeader);
- return BAD_VALUE;
- }
-
- // TODO(b/69010509): We have to dup() the FD from android::Parcel as it
- // doesn't support taking out the FD's ownership. We can remove the dup() here
- // once android::Parcel support such operation.
- data_fd_.Reset(dup(parcel->readFileDescriptor()));
- pollin_event_fd_.Reset(dup(parcel->readFileDescriptor()));
- pollhup_event_fd_.Reset(dup(parcel->readFileDescriptor()));
- if (!IsValid()) {
- ALOGE(
- "ChannelParcelable::readFromParcel: Cannot read fd from parcel: "
- "data_fd=%d, pollin_event_fd=%d, pollhup_event_fd=%d.",
- data_fd_.Get(), pollin_event_fd_.Get(), pollhup_event_fd_.Get());
- return DEAD_OBJECT;
- }
-
- return res;
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel.cpp b/libs/vr/libpdx_uds/client_channel.cpp
deleted file mode 100644
index 6073c3c..0000000
--- a/libs/vr/libpdx_uds/client_channel.cpp
+++ /dev/null
@@ -1,321 +0,0 @@
-#include "uds/channel_parcelable.h"
-#include "uds/client_channel.h"
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-
-#include <pdx/client.h>
-#include <pdx/service_endpoint.h>
-#include <uds/ipc_helper.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-struct TransactionState {
- bool GetLocalFileHandle(int index, LocalHandle* handle) {
- if (index < 0) {
- handle->Reset(index);
- } else if (static_cast<size_t>(index) < response.file_descriptors.size()) {
- *handle = std::move(response.file_descriptors[index]);
- } else {
- return false;
- }
- return true;
- }
-
- bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
- if (index < 0) {
- *handle = LocalChannelHandle{nullptr, index};
- } else if (static_cast<size_t>(index) < response.channels.size()) {
- auto& channel_info = response.channels[index];
- *handle = ChannelManager::Get().CreateHandle(
- std::move(channel_info.data_fd),
- std::move(channel_info.pollin_event_fd),
- std::move(channel_info.pollhup_event_fd));
- } else {
- return false;
- }
- return true;
- }
-
- FileReference PushFileHandle(BorrowedHandle handle) {
- if (!handle)
- return handle.Get();
- request.file_descriptors.push_back(std::move(handle));
- return request.file_descriptors.size() - 1;
- }
-
- ChannelReference PushChannelHandle(BorrowedChannelHandle handle) {
- if (!handle)
- return handle.value();
-
- if (auto* channel_data =
- ChannelManager::Get().GetChannelData(handle.value())) {
- ChannelInfo<BorrowedHandle> channel_info{
- channel_data->data_fd(), channel_data->pollin_event_fd(),
- channel_data->pollhup_event_fd()};
- request.channels.push_back(std::move(channel_info));
- return request.channels.size() - 1;
- } else {
- return -1;
- }
- }
-
- RequestHeader<BorrowedHandle> request;
- ResponseHeader<LocalHandle> response;
-};
-
-Status<void> ReadAndDiscardData(const BorrowedHandle& socket_fd, size_t size) {
- while (size > 0) {
- // If there is more data to read in the message than the buffers provided
- // by the caller, read and discard the extra data from the socket.
- char buffer[1024];
- size_t size_to_read = std::min(sizeof(buffer), size);
- auto status = ReceiveData(socket_fd, buffer, size_to_read);
- if (!status)
- return status;
- size -= size_to_read;
- }
- // We still want to return EIO error to the caller in case we had unexpected
- // data in the socket stream.
- return ErrorStatus(EIO);
-}
-
-Status<void> SendRequest(const BorrowedHandle& socket_fd,
- TransactionState* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- size_t max_recv_len) {
- size_t send_len = CountVectorSize(send_vector, send_count);
- InitRequest(&transaction_state->request, opcode, send_len, max_recv_len,
- false);
- if (send_len == 0) {
- send_vector = nullptr;
- send_count = 0;
- }
- return SendData(socket_fd, transaction_state->request, send_vector,
- send_count);
-}
-
-Status<void> ReceiveResponse(const BorrowedHandle& socket_fd,
- TransactionState* transaction_state,
- const iovec* receive_vector, size_t receive_count,
- size_t max_recv_len) {
- auto status = ReceiveData(socket_fd, &transaction_state->response);
- if (!status)
- return status;
-
- if (transaction_state->response.recv_len > 0) {
- std::vector<iovec> read_buffers;
- size_t size_remaining = 0;
- if (transaction_state->response.recv_len != max_recv_len) {
- // If the receive buffer not exactly the size of data available, recreate
- // the vector list to consume the data exactly since ReceiveDataVector()
- // validates that the number of bytes received equals the number of bytes
- // requested.
- size_remaining = transaction_state->response.recv_len;
- for (size_t i = 0; i < receive_count && size_remaining > 0; i++) {
- read_buffers.push_back(receive_vector[i]);
- iovec& last_vec = read_buffers.back();
- if (last_vec.iov_len > size_remaining)
- last_vec.iov_len = size_remaining;
- size_remaining -= last_vec.iov_len;
- }
- receive_vector = read_buffers.data();
- receive_count = read_buffers.size();
- }
- status = ReceiveDataVector(socket_fd, receive_vector, receive_count);
- if (status && size_remaining > 0)
- status = ReadAndDiscardData(socket_fd, size_remaining);
- }
- return status;
-}
-
-} // anonymous namespace
-
-ClientChannel::ClientChannel(LocalChannelHandle channel_handle)
- : channel_handle_{std::move(channel_handle)} {
- channel_data_ = ChannelManager::Get().GetChannelData(channel_handle_.value());
-}
-
-std::unique_ptr<pdx::ClientChannel> ClientChannel::Create(
- LocalChannelHandle channel_handle) {
- return std::unique_ptr<pdx::ClientChannel>{
- new ClientChannel{std::move(channel_handle)}};
-}
-
-ClientChannel::~ClientChannel() {
- if (channel_handle_)
- shutdown(channel_handle_.value(), SHUT_WR);
-}
-
-void* ClientChannel::AllocateTransactionState() { return new TransactionState; }
-
-void ClientChannel::FreeTransactionState(void* state) {
- delete static_cast<TransactionState*>(state);
-}
-
-Status<void> ClientChannel::SendImpulse(int opcode, const void* buffer,
- size_t length) {
- std::unique_lock<std::mutex> lock(socket_mutex_);
- Status<void> status;
- android::pdx::uds::RequestHeader<BorrowedHandle> request;
- if (length > request.impulse_payload.size() ||
- (buffer == nullptr && length != 0)) {
- status.SetError(EINVAL);
- return status;
- }
-
- InitRequest(&request, opcode, length, 0, true);
- memcpy(request.impulse_payload.data(), buffer, length);
- return SendData(BorrowedHandle{channel_handle_.value()}, request);
-}
-
-Status<int> ClientChannel::SendAndReceive(void* transaction_state, int opcode,
- const iovec* send_vector,
- size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- std::unique_lock<std::mutex> lock(socket_mutex_);
- Status<int> result;
- if ((send_vector == nullptr && send_count != 0) ||
- (receive_vector == nullptr && receive_count != 0)) {
- result.SetError(EINVAL);
- return result;
- }
-
- auto* state = static_cast<TransactionState*>(transaction_state);
- size_t max_recv_len = CountVectorSize(receive_vector, receive_count);
-
- auto status = SendRequest(BorrowedHandle{channel_handle_.value()}, state,
- opcode, send_vector, send_count, max_recv_len);
- if (status) {
- status = ReceiveResponse(BorrowedHandle{channel_handle_.value()}, state,
- receive_vector, receive_count, max_recv_len);
- }
- if (!result.PropagateError(status)) {
- const int return_code = state->response.ret_code;
- if (return_code >= 0)
- result.SetValue(return_code);
- else
- result.SetError(-return_code);
- }
- return result;
-}
-
-Status<int> ClientChannel::SendWithInt(void* transaction_state, int opcode,
- const iovec* send_vector,
- size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) {
- return SendAndReceive(transaction_state, opcode, send_vector, send_count,
- receive_vector, receive_count);
-}
-
-Status<LocalHandle> ClientChannel::SendWithFileHandle(
- void* transaction_state, int opcode, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector, size_t receive_count) {
- Status<int> int_status =
- SendAndReceive(transaction_state, opcode, send_vector, send_count,
- receive_vector, receive_count);
- Status<LocalHandle> status;
- if (status.PropagateError(int_status))
- return status;
-
- auto* state = static_cast<TransactionState*>(transaction_state);
- LocalHandle handle;
- if (state->GetLocalFileHandle(int_status.get(), &handle)) {
- status.SetValue(std::move(handle));
- } else {
- status.SetError(EINVAL);
- }
- return status;
-}
-
-Status<LocalChannelHandle> ClientChannel::SendWithChannelHandle(
- void* transaction_state, int opcode, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector, size_t receive_count) {
- Status<int> int_status =
- SendAndReceive(transaction_state, opcode, send_vector, send_count,
- receive_vector, receive_count);
- Status<LocalChannelHandle> status;
- if (status.PropagateError(int_status))
- return status;
-
- auto* state = static_cast<TransactionState*>(transaction_state);
- LocalChannelHandle handle;
- if (state->GetLocalChannelHandle(int_status.get(), &handle)) {
- status.SetValue(std::move(handle));
- } else {
- status.SetError(EINVAL);
- }
- return status;
-}
-
-FileReference ClientChannel::PushFileHandle(void* transaction_state,
- const LocalHandle& handle) {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->PushFileHandle(handle.Borrow());
-}
-
-FileReference ClientChannel::PushFileHandle(void* transaction_state,
- const BorrowedHandle& handle) {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->PushFileHandle(handle.Duplicate());
-}
-
-ChannelReference ClientChannel::PushChannelHandle(
- void* transaction_state, const LocalChannelHandle& handle) {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->PushChannelHandle(handle.Borrow());
-}
-
-ChannelReference ClientChannel::PushChannelHandle(
- void* transaction_state, const BorrowedChannelHandle& handle) {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->PushChannelHandle(handle.Duplicate());
-}
-
-bool ClientChannel::GetFileHandle(void* transaction_state, FileReference ref,
- LocalHandle* handle) const {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->GetLocalFileHandle(ref, handle);
-}
-
-bool ClientChannel::GetChannelHandle(void* transaction_state,
- ChannelReference ref,
- LocalChannelHandle* handle) const {
- auto* state = static_cast<TransactionState*>(transaction_state);
- return state->GetLocalChannelHandle(ref, handle);
-}
-
-std::unique_ptr<pdx::ChannelParcelable> ClientChannel::TakeChannelParcelable()
- {
- if (!channel_handle_)
- return nullptr;
-
- if (auto* channel_data =
- ChannelManager::Get().GetChannelData(channel_handle_.value())) {
- auto fds = channel_data->TakeFds();
- auto parcelable = std::make_unique<ChannelParcelable>(
- std::move(std::get<0>(fds)), std::move(std::get<1>(fds)),
- std::move(std::get<2>(fds)));
-
- // Here we need to explicitly close the channel handle so that the channel
- // won't get shutdown in the destructor, while the FDs in ChannelParcelable
- // can keep the channel alive so that new client can be created from it
- // later.
- channel_handle_.Close();
- return parcelable;
- } else {
- return nullptr;
- }
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel_factory.cpp b/libs/vr/libpdx_uds/client_channel_factory.cpp
deleted file mode 100644
index 09dc7be..0000000
--- a/libs/vr/libpdx_uds/client_channel_factory.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-#include <uds/client_channel_factory.h>
-
-#include <errno.h>
-#include <log/log.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include <chrono>
-#include <thread>
-
-#include <uds/channel_manager.h>
-#include <uds/client_channel.h>
-#include <uds/ipc_helper.h>
-
-using std::chrono::duration_cast;
-using std::chrono::steady_clock;
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-std::string ClientChannelFactory::GetRootEndpointPath() {
- return "/dev/socket/pdx";
-}
-
-std::string ClientChannelFactory::GetEndpointPath(
- const std::string& endpoint_path) {
- std::string path;
- if (!endpoint_path.empty()) {
- if (endpoint_path.front() == '/')
- path = endpoint_path;
- else
- path = GetRootEndpointPath() + '/' + endpoint_path;
- }
- return path;
-}
-
-ClientChannelFactory::ClientChannelFactory(const std::string& endpoint_path)
- : endpoint_path_{GetEndpointPath(endpoint_path)} {}
-
-ClientChannelFactory::ClientChannelFactory(LocalHandle socket)
- : socket_{std::move(socket)} {}
-
-std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
- const std::string& endpoint_path) {
- return std::unique_ptr<pdx::ClientChannelFactory>{
- new ClientChannelFactory{endpoint_path}};
-}
-
-std::unique_ptr<pdx::ClientChannelFactory> ClientChannelFactory::Create(
- LocalHandle socket) {
- return std::unique_ptr<pdx::ClientChannelFactory>{
- new ClientChannelFactory{std::move(socket)}};
-}
-
-Status<std::unique_ptr<pdx::ClientChannel>> ClientChannelFactory::Connect(
- int64_t timeout_ms) const {
- Status<void> status;
-
- bool connected = socket_.IsValid();
- if (!connected) {
- socket_.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
- LOG_ALWAYS_FATAL_IF(
- endpoint_path_.empty(),
- "ClientChannelFactory::Connect: unspecified socket path");
- }
-
- if (!socket_) {
- ALOGE("ClientChannelFactory::Connect: socket error: %s", strerror(errno));
- return ErrorStatus(errno);
- }
-
- bool use_timeout = (timeout_ms >= 0);
- auto now = steady_clock::now();
- auto time_end = now + std::chrono::milliseconds{timeout_ms};
-
- int max_eaccess = 5; // Max number of times to retry when EACCES returned.
- while (!connected) {
- int64_t timeout = -1;
- if (use_timeout) {
- auto remaining = time_end - now;
- timeout = duration_cast<std::chrono::milliseconds>(remaining).count();
- if (timeout < 0)
- return ErrorStatus(ETIMEDOUT);
- }
- sockaddr_un remote;
- remote.sun_family = AF_UNIX;
- strncpy(remote.sun_path, endpoint_path_.c_str(), sizeof(remote.sun_path));
- remote.sun_path[sizeof(remote.sun_path) - 1] = '\0';
- ALOGD("ClientChannelFactory: Waiting for endpoint at %s", remote.sun_path);
- status = WaitForEndpoint(endpoint_path_, timeout);
- if (!status)
- return ErrorStatus(status.error());
-
- ALOGD("ClientChannelFactory: Connecting to %s", remote.sun_path);
- int ret = RETRY_EINTR(connect(
- socket_.Get(), reinterpret_cast<sockaddr*>(&remote), sizeof(remote)));
- if (ret == -1) {
- ALOGD("ClientChannelFactory: Connect error %d: %s", errno,
- strerror(errno));
- // if |max_eaccess| below reaches zero when errno is EACCES, the control
- // flows into the next "else if" statement and a permanent error is
- // returned from this function.
- if (errno == ECONNREFUSED || (errno == EACCES && max_eaccess-- > 0)) {
- // Connection refused/Permission denied can be the result of connecting
- // too early (the service socket is created but its access rights are
- // not set or not being listened to yet).
- ALOGD("ClientChannelFactory: %s, waiting...", strerror(errno));
- using namespace std::literals::chrono_literals;
- std::this_thread::sleep_for(100ms);
- } else if (errno != ENOENT && errno != ENOTDIR) {
- // ENOENT/ENOTDIR might mean that the socket file/directory containing
- // it has been just deleted. Try to wait for its creation and do not
- // return an error immediately.
- ALOGE(
- "ClientChannelFactory::Connect: Failed to initialize connection "
- "when connecting: %s",
- strerror(errno));
- return ErrorStatus(errno);
- }
- } else {
- connected = true;
- ALOGD("ClientChannelFactory: Connected successfully to %s...",
- remote.sun_path);
- ChannelConnectionInfo<LocalHandle> connection_info;
- status = ReceiveData(socket_.Borrow(), &connection_info);
- if (!status)
- return status.error_status();
- socket_ = std::move(connection_info.channel_fd);
- if (!socket_) {
- ALOGE("ClientChannelFactory::Connect: Failed to obtain channel socket");
- return ErrorStatus(EIO);
- }
- }
- if (use_timeout)
- now = steady_clock::now();
- } // while (!connected)
-
- RequestHeader<BorrowedHandle> request;
- InitRequest(&request, opcodes::CHANNEL_OPEN, 0, 0, false);
-
- status = SendData(socket_.Borrow(), request);
- if (!status)
- return status.error_status();
-
- ResponseHeader<LocalHandle> response;
- status = ReceiveData(socket_.Borrow(), &response);
- if (!status)
- return status.error_status();
- else if (response.ret_code < 0 || response.channels.size() != 1)
- return ErrorStatus(EIO);
-
- LocalHandle pollin_event_fd = std::move(response.channels[0].pollin_event_fd);
- LocalHandle pollhup_event_fd =
- std::move(response.channels[0].pollhup_event_fd);
-
- if (!pollin_event_fd || !pollhup_event_fd) {
- ALOGE(
- "ClientChannelFactory::Connect: Required fd was not returned from the "
- "service: pollin_event_fd=%d pollhup_event_fd=%d",
- pollin_event_fd.Get(), pollhup_event_fd.Get());
- return ErrorStatus(EIO);
- }
-
- return ClientChannel::Create(ChannelManager::Get().CreateHandle(
- std::move(socket_), std::move(pollin_event_fd),
- std::move(pollhup_event_fd)));
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/client_channel_tests.cpp b/libs/vr/libpdx_uds/client_channel_tests.cpp
deleted file mode 100644
index c9c5d15..0000000
--- a/libs/vr/libpdx_uds/client_channel_tests.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-#include <uds/client_channel.h>
-
-#include <sys/socket.h>
-
-#include <algorithm>
-#include <limits>
-#include <random>
-#include <thread>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include <pdx/client.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using testing::Return;
-using testing::_;
-
-using android::pdx::ClientBase;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::uds::ClientChannel;
-using android::pdx::uds::ClientChannelFactory;
-using android::pdx::uds::Endpoint;
-
-namespace {
-
-struct TestProtocol {
- using DataType = int8_t;
- enum {
- kOpSum = 0,
- };
- PDX_REMOTE_METHOD(Sum, kOpSum, int64_t(const std::vector<DataType>&));
-};
-
-class TestService : public ServiceBase<TestService> {
- public:
- explicit TestService(std::unique_ptr<Endpoint> endpoint)
- : ServiceBase{"TestService", std::move(endpoint)} {}
-
- Status<void> HandleMessage(Message& message) override {
- switch (message.GetOp()) {
- case TestProtocol::kOpSum:
- DispatchRemoteMethod<TestProtocol::Sum>(*this, &TestService::OnSum,
- message);
- return {};
-
- default:
- return Service::HandleMessage(message);
- }
- }
-
- int64_t OnSum(Message& /*message*/,
- const std::vector<TestProtocol::DataType>& data) {
- return std::accumulate(data.begin(), data.end(), int64_t{0});
- }
-};
-
-class TestClient : public ClientBase<TestClient> {
- public:
- using ClientBase::ClientBase;
-
- int64_t Sum(const std::vector<TestProtocol::DataType>& data) {
- auto status = InvokeRemoteMethod<TestProtocol::Sum>(data);
- return status ? status.get() : -1;
- }
-};
-
-class TestServiceRunner {
- public:
- explicit TestServiceRunner(LocalHandle channel_socket) {
- auto endpoint = Endpoint::CreateFromSocketFd(LocalHandle{});
- endpoint->RegisterNewChannelForTests(std::move(channel_socket));
- service_ = TestService::Create(std::move(endpoint));
- dispatcher_ = ServiceDispatcher::Create();
- dispatcher_->AddService(service_);
- dispatch_thread_ = std::thread(
- std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
- }
-
- ~TestServiceRunner() {
- dispatcher_->SetCanceled(true);
- dispatch_thread_.join();
- dispatcher_->RemoveService(service_);
- }
-
- private:
- std::shared_ptr<TestService> service_;
- std::unique_ptr<ServiceDispatcher> dispatcher_;
- std::thread dispatch_thread_;
-};
-
-class ClientChannelTest : public testing::Test {
- public:
- void SetUp() override {
- int channel_sockets[2] = {};
- ASSERT_EQ(
- 0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_sockets));
- LocalHandle service_channel{channel_sockets[0]};
- LocalHandle client_channel{channel_sockets[1]};
-
- service_runner_.reset(new TestServiceRunner{std::move(service_channel)});
- auto factory = ClientChannelFactory::Create(std::move(client_channel));
- auto status = factory->Connect(android::pdx::Client::kInfiniteTimeout);
- ASSERT_TRUE(status);
- client_ = TestClient::Create(status.take());
- }
-
- void TearDown() override {
- service_runner_.reset();
- client_.reset();
- }
-
- protected:
- std::unique_ptr<TestServiceRunner> service_runner_;
- std::shared_ptr<TestClient> client_;
-};
-
-TEST_F(ClientChannelTest, MultithreadedClient) {
- constexpr int kNumTestThreads = 8;
- constexpr size_t kDataSize = 1000; // Try to keep RPC buffer size below 4K.
-
- std::random_device rd;
- std::mt19937 gen{rd()};
- std::uniform_int_distribution<TestProtocol::DataType> dist{
- std::numeric_limits<TestProtocol::DataType>::min(),
- std::numeric_limits<TestProtocol::DataType>::max()};
-
- auto worker = [](std::shared_ptr<TestClient> client,
- std::vector<TestProtocol::DataType> data) {
- constexpr int kMaxIterations = 500;
- int64_t expected = std::accumulate(data.begin(), data.end(), int64_t{0});
- for (int i = 0; i < kMaxIterations; i++) {
- ASSERT_EQ(expected, client->Sum(data));
- }
- };
-
- // Start client threads.
- std::vector<TestProtocol::DataType> data;
- data.resize(kDataSize);
- std::vector<std::thread> threads;
- for (int i = 0; i < kNumTestThreads; i++) {
- std::generate(data.begin(), data.end(),
- [&dist, &gen]() { return dist(gen); });
- threads.emplace_back(worker, client_, data);
- }
-
- // Wait for threads to finish.
- for (auto& thread : threads)
- thread.join();
-}
-
-} // namespace
diff --git a/libs/vr/libpdx_uds/ipc_helper.cpp b/libs/vr/libpdx_uds/ipc_helper.cpp
deleted file mode 100644
index f85b3bb..0000000
--- a/libs/vr/libpdx_uds/ipc_helper.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-#include "uds/ipc_helper.h"
-
-#include <alloca.h>
-#include <errno.h>
-#include <log/log.h>
-#include <poll.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-
-#include <algorithm>
-
-#include <pdx/service.h>
-#include <pdx/utility.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-namespace {
-
-constexpr size_t kMaxFdCount =
- 256; // Total of 1KiB of data to transfer these FDs.
-
-// Default implementations of Send/Receive interfaces to use standard socket
-// send/sendmsg/recv/recvmsg functions.
-class SocketSender : public SendInterface {
- public:
- ssize_t Send(int socket_fd, const void* data, size_t size,
- int flags) override {
- return send(socket_fd, data, size, flags);
- }
- ssize_t SendMessage(int socket_fd, const msghdr* msg, int flags) override {
- return sendmsg(socket_fd, msg, flags);
- }
-} g_socket_sender;
-
-class SocketReceiver : public RecvInterface {
- public:
- ssize_t Receive(int socket_fd, void* data, size_t size, int flags) override {
- return recv(socket_fd, data, size, flags);
- }
- ssize_t ReceiveMessage(int socket_fd, msghdr* msg, int flags) override {
- return recvmsg(socket_fd, msg, flags);
- }
-} g_socket_receiver;
-
-} // anonymous namespace
-
-// Helper wrappers around send()/sendmsg() which repeat send() calls on data
-// that was not sent with the initial call to send/sendmsg. This is important to
-// handle transmissions interrupted by signals.
-Status<void> SendAll(SendInterface* sender, const BorrowedHandle& socket_fd,
- const void* data, size_t size) {
- Status<void> ret;
- const uint8_t* ptr = static_cast<const uint8_t*>(data);
- while (size > 0) {
- ssize_t size_written =
- RETRY_EINTR(sender->Send(socket_fd.Get(), ptr, size, MSG_NOSIGNAL));
- if (size_written < 0) {
- ret.SetError(errno);
- ALOGE("SendAll: Failed to send data over socket: %s",
- ret.GetErrorMessage().c_str());
- break;
- }
- size -= size_written;
- ptr += size_written;
- }
- return ret;
-}
-
-Status<void> SendMsgAll(SendInterface* sender, const BorrowedHandle& socket_fd,
- const msghdr* msg) {
- Status<void> ret;
- ssize_t sent_size =
- RETRY_EINTR(sender->SendMessage(socket_fd.Get(), msg, MSG_NOSIGNAL));
- if (sent_size < 0) {
- ret.SetError(errno);
- ALOGE("SendMsgAll: Failed to send data over socket: %s",
- ret.GetErrorMessage().c_str());
- return ret;
- }
-
- ssize_t chunk_start_offset = 0;
- for (size_t i = 0; i < msg->msg_iovlen; i++) {
- ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len;
- if (sent_size < chunk_end_offset) {
- size_t offset_within_chunk = sent_size - chunk_start_offset;
- size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk;
- const uint8_t* chunk_base =
- static_cast<const uint8_t*>(msg->msg_iov[i].iov_base);
- ret = SendAll(sender, socket_fd, chunk_base + offset_within_chunk,
- data_size);
- if (!ret)
- break;
- sent_size += data_size;
- }
- chunk_start_offset = chunk_end_offset;
- }
- return ret;
-}
-
-// Helper wrappers around recv()/recvmsg() which repeat recv() calls on data
-// that was not received with the initial call to recvmsg(). This is important
-// to handle transmissions interrupted by signals as well as the case when
-// initial data did not arrive in a single chunk over the socket (e.g. socket
-// buffer was full at the time of transmission, and only portion of initial
-// message was sent and the rest was blocked until the buffer was cleared by the
-// receiving side).
-Status<void> RecvMsgAll(RecvInterface* receiver,
- const BorrowedHandle& socket_fd, msghdr* msg) {
- Status<void> ret;
- ssize_t size_read = RETRY_EINTR(receiver->ReceiveMessage(
- socket_fd.Get(), msg, MSG_WAITALL | MSG_CMSG_CLOEXEC));
- if (size_read < 0) {
- ret.SetError(errno);
- ALOGE("RecvMsgAll: Failed to receive data from socket: %s",
- ret.GetErrorMessage().c_str());
- return ret;
- } else if (size_read == 0) {
- ret.SetError(ESHUTDOWN);
- ALOGW("RecvMsgAll: Socket has been shut down");
- return ret;
- }
-
- ssize_t chunk_start_offset = 0;
- for (size_t i = 0; i < msg->msg_iovlen; i++) {
- ssize_t chunk_end_offset = chunk_start_offset + msg->msg_iov[i].iov_len;
- if (size_read < chunk_end_offset) {
- size_t offset_within_chunk = size_read - chunk_start_offset;
- size_t data_size = msg->msg_iov[i].iov_len - offset_within_chunk;
- uint8_t* chunk_base = static_cast<uint8_t*>(msg->msg_iov[i].iov_base);
- ret = RecvAll(receiver, socket_fd, chunk_base + offset_within_chunk,
- data_size);
- if (!ret)
- break;
- size_read += data_size;
- }
- chunk_start_offset = chunk_end_offset;
- }
- return ret;
-}
-
-Status<void> RecvAll(RecvInterface* receiver, const BorrowedHandle& socket_fd,
- void* data, size_t size) {
- Status<void> ret;
- uint8_t* ptr = static_cast<uint8_t*>(data);
- while (size > 0) {
- ssize_t size_read = RETRY_EINTR(receiver->Receive(
- socket_fd.Get(), ptr, size, MSG_WAITALL | MSG_CMSG_CLOEXEC));
- if (size_read < 0) {
- ret.SetError(errno);
- ALOGE("RecvAll: Failed to receive data from socket: %s",
- ret.GetErrorMessage().c_str());
- break;
- } else if (size_read == 0) {
- ret.SetError(ESHUTDOWN);
- ALOGW("RecvAll: Socket has been shut down");
- break;
- }
- size -= size_read;
- ptr += size_read;
- }
- return ret;
-}
-
-uint32_t kMagicPreamble = 0x7564736d; // 'udsm'.
-
-struct MessagePreamble {
- uint32_t magic{0};
- uint32_t data_size{0};
- uint32_t fd_count{0};
-};
-
-Status<void> SendPayload::Send(const BorrowedHandle& socket_fd) {
- return Send(socket_fd, nullptr);
-}
-
-Status<void> SendPayload::Send(const BorrowedHandle& socket_fd,
- const ucred* cred, const iovec* data_vec,
- size_t vec_count) {
- if (file_handles_.size() > kMaxFdCount) {
- ALOGE(
- "SendPayload::Send: Trying to send too many file descriptors (%zu), "
- "max allowed = %zu",
- file_handles_.size(), kMaxFdCount);
- return ErrorStatus{EINVAL};
- }
-
- SendInterface* sender = sender_ ? sender_ : &g_socket_sender;
- MessagePreamble preamble;
- preamble.magic = kMagicPreamble;
- preamble.data_size = buffer_.size();
- preamble.fd_count = file_handles_.size();
-
- msghdr msg = {};
- msg.msg_iovlen = 2 + vec_count;
- msg.msg_iov = static_cast<iovec*>(alloca(sizeof(iovec) * msg.msg_iovlen));
- msg.msg_iov[0].iov_base = &preamble;
- msg.msg_iov[0].iov_len = sizeof(preamble);
- msg.msg_iov[1].iov_base = buffer_.data();
- msg.msg_iov[1].iov_len = buffer_.size();
- for (size_t i = 0; i < vec_count; i++)
- msg.msg_iov[i + 2] = data_vec[i];
-
- if (cred || !file_handles_.empty()) {
- const size_t fd_bytes = file_handles_.size() * sizeof(int);
- msg.msg_controllen = (cred ? CMSG_SPACE(sizeof(ucred)) : 0) +
- (fd_bytes == 0 ? 0 : CMSG_SPACE(fd_bytes));
- msg.msg_control = alloca(msg.msg_controllen);
-
- cmsghdr* control = CMSG_FIRSTHDR(&msg);
- if (cred) {
- control->cmsg_level = SOL_SOCKET;
- control->cmsg_type = SCM_CREDENTIALS;
- control->cmsg_len = CMSG_LEN(sizeof(ucred));
- memcpy(CMSG_DATA(control), cred, sizeof(ucred));
- control = CMSG_NXTHDR(&msg, control);
- }
-
- if (fd_bytes) {
- control->cmsg_level = SOL_SOCKET;
- control->cmsg_type = SCM_RIGHTS;
- control->cmsg_len = CMSG_LEN(fd_bytes);
- memcpy(CMSG_DATA(control), file_handles_.data(), fd_bytes);
- }
- }
-
- return SendMsgAll(sender, socket_fd, &msg);
-}
-
-// MessageWriter
-void* SendPayload::GetNextWriteBufferSection(size_t size) {
- return buffer_.grow_by(size);
-}
-
-OutputResourceMapper* SendPayload::GetOutputResourceMapper() { return this; }
-
-// OutputResourceMapper
-Status<FileReference> SendPayload::PushFileHandle(const LocalHandle& handle) {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.Get());
- return ref;
- } else {
- return handle.Get();
- }
-}
-
-Status<FileReference> SendPayload::PushFileHandle(
- const BorrowedHandle& handle) {
- if (handle) {
- const int ref = file_handles_.size();
- file_handles_.push_back(handle.Get());
- return ref;
- } else {
- return handle.Get();
- }
-}
-
-Status<FileReference> SendPayload::PushFileHandle(const RemoteHandle& handle) {
- return handle.Get();
-}
-
-Status<ChannelReference> SendPayload::PushChannelHandle(
- const LocalChannelHandle& /*handle*/) {
- return ErrorStatus{EOPNOTSUPP};
-}
-Status<ChannelReference> SendPayload::PushChannelHandle(
- const BorrowedChannelHandle& /*handle*/) {
- return ErrorStatus{EOPNOTSUPP};
-}
-Status<ChannelReference> SendPayload::PushChannelHandle(
- const RemoteChannelHandle& /*handle*/) {
- return ErrorStatus{EOPNOTSUPP};
-}
-
-Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd) {
- return Receive(socket_fd, nullptr);
-}
-
-Status<void> ReceivePayload::Receive(const BorrowedHandle& socket_fd,
- ucred* cred) {
- RecvInterface* receiver = receiver_ ? receiver_ : &g_socket_receiver;
- MessagePreamble preamble;
- msghdr msg = {};
- iovec recv_vect = {&preamble, sizeof(preamble)};
- msg.msg_iov = &recv_vect;
- msg.msg_iovlen = 1;
- const size_t receive_fd_bytes = kMaxFdCount * sizeof(int);
- msg.msg_controllen = CMSG_SPACE(sizeof(ucred)) + CMSG_SPACE(receive_fd_bytes);
- msg.msg_control = alloca(msg.msg_controllen);
-
- Status<void> ret = RecvMsgAll(receiver, socket_fd, &msg);
- if (!ret)
- return ret;
-
- if (preamble.magic != kMagicPreamble) {
- ALOGE("ReceivePayload::Receive: Message header is invalid");
- ret.SetError(EIO);
- return ret;
- }
-
- buffer_.resize(preamble.data_size);
- file_handles_.clear();
- read_pos_ = 0;
-
- bool cred_available = false;
- file_handles_.reserve(preamble.fd_count);
- cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
- while (cmsg) {
- if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS &&
- cred && cmsg->cmsg_len == CMSG_LEN(sizeof(ucred))) {
- cred_available = true;
- memcpy(cred, CMSG_DATA(cmsg), sizeof(ucred));
- } else if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS) {
- socklen_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
- const int* fds = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
- size_t fd_count = payload_len / sizeof(int);
- std::transform(fds, fds + fd_count, std::back_inserter(file_handles_),
- [](int fd) { return LocalHandle{fd}; });
- }
- cmsg = CMSG_NXTHDR(&msg, cmsg);
- }
-
- ret = RecvAll(receiver, socket_fd, buffer_.data(), buffer_.size());
- if (!ret)
- return ret;
-
- if (cred && !cred_available) {
- ALOGE("ReceivePayload::Receive: Failed to obtain message credentials");
- ret.SetError(EIO);
- }
-
- return ret;
-}
-
-// MessageReader
-MessageReader::BufferSection ReceivePayload::GetNextReadBufferSection() {
- return {buffer_.data() + read_pos_, &*buffer_.end()};
-}
-
-void ReceivePayload::ConsumeReadBufferSectionData(const void* new_start) {
- read_pos_ = PointerDistance(new_start, buffer_.data());
-}
-
-InputResourceMapper* ReceivePayload::GetInputResourceMapper() { return this; }
-
-// InputResourceMapper
-bool ReceivePayload::GetFileHandle(FileReference ref, LocalHandle* handle) {
- if (ref < 0) {
- *handle = LocalHandle{ref};
- return true;
- }
- if (static_cast<size_t>(ref) > file_handles_.size())
- return false;
- *handle = std::move(file_handles_[ref]);
- return true;
-}
-
-bool ReceivePayload::GetChannelHandle(ChannelReference /*ref*/,
- LocalChannelHandle* /*handle*/) {
- return false;
-}
-
-Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
- size_t size) {
- return SendAll(&g_socket_sender, socket_fd, data, size);
-}
-
-Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
- size_t count) {
- msghdr msg = {};
- msg.msg_iov = const_cast<iovec*>(data);
- msg.msg_iovlen = count;
- return SendMsgAll(&g_socket_sender, socket_fd, &msg);
-}
-
-Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
- size_t size) {
- return RecvAll(&g_socket_receiver, socket_fd, data, size);
-}
-
-Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
- const iovec* data, size_t count) {
- msghdr msg = {};
- msg.msg_iov = const_cast<iovec*>(data);
- msg.msg_iovlen = count;
- return RecvMsgAll(&g_socket_receiver, socket_fd, &msg);
-}
-
-size_t CountVectorSize(const iovec* vector, size_t count) {
- return std::accumulate(
- vector, vector + count, size_t{0},
- [](size_t size, const iovec& vec) { return size + vec.iov_len; });
-}
-
-void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request,
- int opcode, uint32_t send_len, uint32_t max_recv_len,
- bool is_impulse) {
- request->op = opcode;
- request->cred.pid = getpid();
- request->cred.uid = geteuid();
- request->cred.gid = getegid();
- request->send_len = send_len;
- request->max_recv_len = max_recv_len;
- request->is_impulse = is_impulse;
-}
-
-Status<void> WaitForEndpoint(const std::string& endpoint_path,
- int64_t timeout_ms) {
- // Endpoint path must be absolute.
- if (endpoint_path.empty() || endpoint_path.front() != '/')
- return ErrorStatus(EINVAL);
-
- // Create inotify fd.
- LocalHandle fd{inotify_init()};
- if (!fd)
- return ErrorStatus(errno);
-
- // Set the inotify fd to non-blocking.
- int ret = fcntl(fd.Get(), F_GETFL);
- fcntl(fd.Get(), F_SETFL, ret | O_NONBLOCK);
-
- // Setup the pollfd.
- pollfd pfd = {fd.Get(), POLLIN, 0};
-
- // Find locations of each path separator.
- std::vector<size_t> separators{0}; // The path is absolute, so '/' is at #0.
- size_t pos = endpoint_path.find('/', 1);
- while (pos != std::string::npos) {
- separators.push_back(pos);
- pos = endpoint_path.find('/', pos + 1);
- }
- separators.push_back(endpoint_path.size());
-
- // Walk down the path, checking for existence and waiting if needed.
- pos = 1;
- size_t links = 0;
- std::string current;
- while (pos < separators.size() && links <= MAXSYMLINKS) {
- std::string previous = current;
- current = endpoint_path.substr(0, separators[pos]);
-
- // Check for existence; proceed to setup a watch if not.
- if (access(current.c_str(), F_OK) < 0) {
- if (errno != ENOENT)
- return ErrorStatus(errno);
-
- // Extract the name of the path component to wait for.
- std::string next = current.substr(
- separators[pos - 1] + 1, separators[pos] - separators[pos - 1] - 1);
-
- // Add a watch on the last existing directory we reach.
- int wd = inotify_add_watch(
- fd.Get(), previous.c_str(),
- IN_CREATE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MOVED_TO);
- if (wd < 0) {
- if (errno != ENOENT)
- return ErrorStatus(errno);
- // Restart at the beginning if previous was deleted.
- links = 0;
- current.clear();
- pos = 1;
- continue;
- }
-
- // Make sure current didn't get created before the watch was added.
- ret = access(current.c_str(), F_OK);
- if (ret < 0) {
- if (errno != ENOENT)
- return ErrorStatus(errno);
-
- bool exit_poll = false;
- while (!exit_poll) {
- // Wait for an event or timeout.
- ret = poll(&pfd, 1, timeout_ms);
- if (ret <= 0)
- return ErrorStatus(ret == 0 ? ETIMEDOUT : errno);
-
- // Read events.
- char buffer[sizeof(inotify_event) + NAME_MAX + 1];
-
- ret = read(fd.Get(), buffer, sizeof(buffer));
- if (ret < 0) {
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- continue;
- else
- return ErrorStatus(errno);
- } else if (static_cast<size_t>(ret) < sizeof(struct inotify_event)) {
- return ErrorStatus(EIO);
- }
-
- auto* event = reinterpret_cast<const inotify_event*>(buffer);
- auto* end = reinterpret_cast<const inotify_event*>(buffer + ret);
- while (event < end) {
- std::string event_for;
- if (event->len > 0)
- event_for = event->name;
-
- if (event->mask & (IN_CREATE | IN_MOVED_TO)) {
- // See if this is the droid we're looking for.
- if (next == event_for) {
- exit_poll = true;
- break;
- }
- } else if (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)) {
- // Restart at the beginning if our watch dir is deleted.
- links = 0;
- current.clear();
- pos = 0;
- exit_poll = true;
- break;
- }
-
- event = reinterpret_cast<const inotify_event*>(AdvancePointer(
- event, sizeof(struct inotify_event) + event->len));
- } // while (event < end)
- } // while (!exit_poll)
- } // Current dir doesn't exist.
- ret = inotify_rm_watch(fd.Get(), wd);
- if (ret < 0 && errno != EINVAL)
- return ErrorStatus(errno);
- } // if (access(current.c_str(), F_OK) < 0)
-
- // Check for symbolic link and update link count.
- struct stat stat_buf;
- ret = lstat(current.c_str(), &stat_buf);
- if (ret < 0 && errno != ENOENT)
- return ErrorStatus(errno);
- else if (ret == 0 && S_ISLNK(stat_buf.st_mode))
- links++;
- pos++;
- } // while (pos < separators.size() && links <= MAXSYMLINKS)
-
- return {};
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/ipc_helper_tests.cpp b/libs/vr/libpdx_uds/ipc_helper_tests.cpp
deleted file mode 100644
index bfa827e..0000000
--- a/libs/vr/libpdx_uds/ipc_helper_tests.cpp
+++ /dev/null
@@ -1,365 +0,0 @@
-#include "uds/ipc_helper.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-using testing::Return;
-using testing::SetErrnoAndReturn;
-using testing::_;
-
-using android::pdx::BorrowedHandle;
-using android::pdx::uds::SendInterface;
-using android::pdx::uds::RecvInterface;
-using android::pdx::uds::SendAll;
-using android::pdx::uds::SendMsgAll;
-using android::pdx::uds::RecvAll;
-using android::pdx::uds::RecvMsgAll;
-
-namespace {
-
-// Useful constants for tests.
-static constexpr intptr_t kPtr = 1234;
-static constexpr int kSocketFd = 5678;
-static const BorrowedHandle kSocket{kSocketFd};
-
-// Helper functions to construct test data pointer values.
-void* IntToPtr(intptr_t value) { return reinterpret_cast<void*>(value); }
-const void* IntToConstPtr(intptr_t value) {
- return reinterpret_cast<const void*>(value);
-}
-
-// Mock classes for SendInterface/RecvInterface.
-class MockSender : public SendInterface {
- public:
- MOCK_METHOD4(Send, ssize_t(int socket_fd, const void* data, size_t size,
- int flags));
- MOCK_METHOD3(SendMessage,
- ssize_t(int socket_fd, const msghdr* msg, int flags));
-};
-
-class MockReceiver : public RecvInterface {
- public:
- MOCK_METHOD4(Receive,
- ssize_t(int socket_fd, void* data, size_t size, int flags));
- MOCK_METHOD3(ReceiveMessage, ssize_t(int socket_fd, msghdr* msg, int flags));
-};
-
-// Test case classes.
-class SendTest : public testing::Test {
- public:
- SendTest() {
- ON_CALL(sender_, Send(_, _, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- ON_CALL(sender_, SendMessage(_, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- }
-
- protected:
- MockSender sender_;
-};
-
-class RecvTest : public testing::Test {
- public:
- RecvTest() {
- ON_CALL(receiver_, Receive(_, _, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- ON_CALL(receiver_, ReceiveMessage(_, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- }
-
- protected:
- MockReceiver receiver_;
-};
-
-class MessageTestBase : public testing::Test {
- public:
- MessageTestBase() {
- memset(&msg_, 0, sizeof(msg_));
- msg_.msg_iovlen = data_.size();
- msg_.msg_iov = data_.data();
- }
-
- protected:
- static constexpr intptr_t kPtr1 = kPtr;
- static constexpr intptr_t kPtr2 = kPtr + 200;
- static constexpr intptr_t kPtr3 = kPtr + 1000;
-
- MockSender sender_;
- msghdr msg_;
- std::vector<iovec> data_{
- {IntToPtr(kPtr1), 100}, {IntToPtr(kPtr2), 200}, {IntToPtr(kPtr3), 300}};
-};
-
-class SendMessageTest : public MessageTestBase {
- public:
- SendMessageTest() {
- ON_CALL(sender_, Send(_, _, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- ON_CALL(sender_, SendMessage(_, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- }
-
- protected:
- MockSender sender_;
-};
-
-class RecvMessageTest : public MessageTestBase {
- public:
- RecvMessageTest() {
- ON_CALL(receiver_, Receive(_, _, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- ON_CALL(receiver_, ReceiveMessage(_, _, _))
- .WillByDefault(SetErrnoAndReturn(EIO, -1));
- }
-
- protected:
- MockReceiver receiver_;
-};
-
-// Actual tests.
-
-// SendAll
-TEST_F(SendTest, Complete) {
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
- .WillOnce(Return(100));
-
- auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Signal) {
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
- .WillOnce(Return(20));
- EXPECT_CALL(sender_,
- Send(kSocketFd, IntToConstPtr(kPtr + 20), 80, MSG_NOSIGNAL))
- .WillOnce(Return(40));
- EXPECT_CALL(sender_,
- Send(kSocketFd, IntToConstPtr(kPtr + 60), 40, MSG_NOSIGNAL))
- .WillOnce(Return(40));
-
- auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Eintr) {
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(100));
-
- auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendTest, Error) {
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
- .WillOnce(SetErrnoAndReturn(EIO, -1));
-
- auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(SendTest, Error2) {
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr), 100, MSG_NOSIGNAL))
- .WillOnce(Return(50));
- EXPECT_CALL(sender_,
- Send(kSocketFd, IntToConstPtr(kPtr + 50), 50, MSG_NOSIGNAL))
- .WillOnce(SetErrnoAndReturn(EIO, -1));
-
- auto status = SendAll(&sender_, kSocket, IntToConstPtr(kPtr), 100);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-// RecvAll
-TEST_F(RecvTest, Complete) {
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100,
- MSG_WAITALL | MSG_CMSG_CLOEXEC))
- .WillOnce(Return(100));
-
- auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Signal) {
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
- .WillOnce(Return(20));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 20), 80, _))
- .WillOnce(Return(40));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 60), 40, _))
- .WillOnce(Return(40));
-
- auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Eintr) {
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(100));
-
- auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvTest, Error) {
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
- .WillOnce(SetErrnoAndReturn(EIO, -1));
-
- auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-TEST_F(RecvTest, Error2) {
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr), 100, _))
- .WillOnce(Return(30));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr + 30), 70, _))
- .WillOnce(SetErrnoAndReturn(EIO, -1));
-
- auto status = RecvAll(&receiver_, kSocket, IntToPtr(kPtr), 100);
- ASSERT_FALSE(status);
- EXPECT_EQ(EIO, status.error());
-}
-
-// SendMsgAll
-TEST_F(SendMessageTest, Complete) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, MSG_NOSIGNAL))
- .WillOnce(Return(600));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Partial) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(70));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 70), 30, _))
- .WillOnce(Return(30));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2), 200, _))
- .WillOnce(Return(190));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2 + 190), 10, _))
- .WillOnce(Return(10));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3), 300, _))
- .WillOnce(Return(300));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Partial2) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(310));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3 + 10), 290, _))
- .WillOnce(Return(290));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Eintr) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(70));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 70), 30, _))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(30));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr2), 200, _))
- .WillOnce(Return(200));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr3), 300, _))
- .WillOnce(Return(300));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(SendMessageTest, Error) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _))
- .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- ASSERT_FALSE(status);
- EXPECT_EQ(EBADF, status.error());
-}
-
-TEST_F(SendMessageTest, Error2) {
- EXPECT_CALL(sender_, SendMessage(kSocketFd, &msg_, _)).WillOnce(Return(20));
- EXPECT_CALL(sender_, Send(kSocketFd, IntToConstPtr(kPtr1 + 20), 80, _))
- .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
- auto status = SendMsgAll(&sender_, kSocket, &msg_);
- ASSERT_FALSE(status);
- EXPECT_EQ(EBADF, status.error());
-}
-
-// RecvMsgAll
-TEST_F(RecvMessageTest, Complete) {
- EXPECT_CALL(receiver_,
- ReceiveMessage(kSocketFd, &msg_, MSG_WAITALL | MSG_CMSG_CLOEXEC))
- .WillOnce(Return(600));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Partial) {
- EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
- .WillOnce(Return(70));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 70), 30, _))
- .WillOnce(Return(30));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2), 200, _))
- .WillOnce(Return(190));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2 + 190), 10, _))
- .WillOnce(Return(10));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3), 300, _))
- .WillOnce(Return(300));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Partial2) {
- EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
- .WillOnce(Return(310));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3 + 10), 290, _))
- .WillOnce(Return(290));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Eintr) {
- EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(70));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 70), 30, _))
- .WillOnce(SetErrnoAndReturn(EINTR, -1))
- .WillOnce(Return(30));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr2), 200, _))
- .WillOnce(Return(200));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr3), 300, _))
- .WillOnce(Return(300));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- EXPECT_TRUE(status);
-}
-
-TEST_F(RecvMessageTest, Error) {
- EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
- .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- ASSERT_FALSE(status);
- EXPECT_EQ(EBADF, status.error());
-}
-
-TEST_F(RecvMessageTest, Error2) {
- EXPECT_CALL(receiver_, ReceiveMessage(kSocketFd, &msg_, _))
- .WillOnce(Return(20));
- EXPECT_CALL(receiver_, Receive(kSocketFd, IntToPtr(kPtr1 + 20), 80, _))
- .WillOnce(SetErrnoAndReturn(EBADF, -1));
-
- auto status = RecvMsgAll(&receiver_, kSocket, &msg_);
- ASSERT_FALSE(status);
- EXPECT_EQ(EBADF, status.error());
-}
-
-} // namespace
diff --git a/libs/vr/libpdx_uds/private/uds/channel_event_set.h b/libs/vr/libpdx_uds/private/uds/channel_event_set.h
deleted file mode 100644
index e960740..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_event_set.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
-#define ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
-
-#include <vector>
-
-#include <pdx/client_channel.h>
-#include <pdx/file_handle.h>
-#include <pdx/status.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelEventSet {
- public:
- ChannelEventSet();
- ChannelEventSet(ChannelEventSet&&) = default;
- ChannelEventSet& operator=(ChannelEventSet&&) = default;
-
- BorrowedHandle pollin_event_fd() const { return pollin_event_fd_.Borrow(); }
- BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
-
- explicit operator bool() const {
- return !!pollin_event_fd_ && !!pollhup_event_fd_;
- }
-
- int ModifyEvents(int clear_mask, int set_mask);
-
- private:
- LocalHandle pollin_event_fd_;
- LocalHandle pollhup_event_fd_;
- uint32_t event_bits_ = 0;
-
- ChannelEventSet(const ChannelEventSet&) = delete;
- void operator=(const ChannelEventSet&) = delete;
-};
-
-class ChannelEventReceiver {
- public:
- ChannelEventReceiver() = default;
- ChannelEventReceiver(LocalHandle data_fd, LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd);
- ChannelEventReceiver(ChannelEventReceiver&&) = default;
- ChannelEventReceiver& operator=(ChannelEventReceiver&&) = default;
-
- explicit operator bool() const {
- return !!pollin_event_fd_ && !!pollhup_event_fd_ && !!data_fd_ &&
- !!epoll_fd_;
- }
-
- BorrowedHandle event_fd() const { return epoll_fd_.Borrow(); }
-
- BorrowedHandle pollin_event_fd() const { return pollin_event_fd_.Borrow(); }
- BorrowedHandle pollhup_event_fd() const { return pollhup_event_fd_.Borrow(); }
- BorrowedHandle data_fd() const { return data_fd_.Borrow(); }
-
- // Moves file descriptors out of ChannelEventReceiver. Note these operations
- // immediately invalidates the receiver.
- std::tuple<LocalHandle, LocalHandle, LocalHandle> TakeFds() {
- epoll_fd_.Close();
- return {std::move(data_fd_), std::move(pollin_event_fd_),
- std::move(pollhup_event_fd_)};
- }
-
- Status<int> GetPendingEvents() const;
- Status<int> PollPendingEvents(int timeout_ms) const;
-
- std::vector<ClientChannel::EventSource> GetEventSources() const;
-
- private:
- LocalHandle data_fd_;
- LocalHandle pollin_event_fd_;
- LocalHandle pollhup_event_fd_;
- LocalHandle epoll_fd_;
-
- ChannelEventReceiver(const ChannelEventReceiver&) = delete;
- void operator=(const ChannelEventReceiver&) = delete;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_CHANNEL_EVENT_SET_H_
diff --git a/libs/vr/libpdx_uds/private/uds/channel_manager.h b/libs/vr/libpdx_uds/private/uds/channel_manager.h
deleted file mode 100644
index 5f6a514..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_manager.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
-#define ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
-
-#include <mutex>
-#include <unordered_map>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <uds/channel_event_set.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelManager : public ChannelManagerInterface {
- public:
- static ChannelManager& Get();
-
- LocalChannelHandle CreateHandle(LocalHandle data_fd,
- LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd);
-
- ChannelEventReceiver* GetChannelData(int32_t handle);
-
- private:
- ChannelManager() = default;
-
- void CloseHandle(int32_t handle) override;
-
- std::mutex mutex_;
- std::unordered_map<int32_t, ChannelEventReceiver> channels_;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_CHANNEL_MANAGER_H_
diff --git a/libs/vr/libpdx_uds/private/uds/channel_parcelable.h b/libs/vr/libpdx_uds/private/uds/channel_parcelable.h
deleted file mode 100644
index 1c3fae9..0000000
--- a/libs/vr/libpdx_uds/private/uds/channel_parcelable.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
-#define ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
-
-#include <pdx/channel_parcelable.h>
-#include <pdx/file_handle.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ChannelParcelable : public pdx::ChannelParcelable {
- public:
- ChannelParcelable() = default;
- ChannelParcelable(LocalHandle data_fd, LocalHandle pollin_event_fd,
- LocalHandle pollhup_event_fd);
-
- // Implements pdx::ChannelParcelable interface.
- bool IsValid() const override;
- LocalChannelHandle TakeChannelHandle() override;
-
- // Implements android::Parcelable interface.
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
-
- private:
- LocalHandle data_fd_;
- LocalHandle pollin_event_fd_;
- LocalHandle pollhup_event_fd_;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_CHANNEL_PARCELABLE_H_
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel.h b/libs/vr/libpdx_uds/private/uds/client_channel.h
deleted file mode 100644
index 3561c6f..0000000
--- a/libs/vr/libpdx_uds/private/uds/client_channel.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
-#define ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
-
-#include <pdx/client_channel.h>
-
-#include <mutex>
-
-#include <uds/channel_event_set.h>
-#include <uds/channel_manager.h>
-#include <uds/service_endpoint.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ClientChannel : public pdx::ClientChannel {
- public:
- ~ClientChannel() override;
-
- static std::unique_ptr<pdx::ClientChannel> Create(
- LocalChannelHandle channel_handle);
-
- uint32_t GetIpcTag() const override { return Endpoint::kIpcTag; }
-
- int event_fd() const override {
- return channel_data_ ? channel_data_->event_fd().Get() : -1;
- }
-
- std::vector<EventSource> GetEventSources() const override {
- if (channel_data_)
- return channel_data_->GetEventSources();
- else
- return {};
- }
-
- Status<int> GetEventMask(int /*events*/) override {
- if (channel_data_)
- return channel_data_->GetPendingEvents();
- else
- return ErrorStatus(EINVAL);
- }
-
- LocalChannelHandle& GetChannelHandle() override { return channel_handle_; }
- const LocalChannelHandle& GetChannelHandle() const override {
- return channel_handle_;
- }
- void* AllocateTransactionState() override;
- void FreeTransactionState(void* state) override;
-
- Status<void> SendImpulse(int opcode, const void* buffer,
- size_t length) override;
-
- Status<int> SendWithInt(void* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) override;
- Status<LocalHandle> SendWithFileHandle(void* transaction_state, int opcode,
- const iovec* send_vector,
- size_t send_count,
- const iovec* receive_vector,
- size_t receive_count) override;
- Status<LocalChannelHandle> SendWithChannelHandle(
- void* transaction_state, int opcode, const iovec* send_vector,
- size_t send_count, const iovec* receive_vector,
- size_t receive_count) override;
-
- FileReference PushFileHandle(void* transaction_state,
- const LocalHandle& handle) override;
- FileReference PushFileHandle(void* transaction_state,
- const BorrowedHandle& handle) override;
- ChannelReference PushChannelHandle(void* transaction_state,
- const LocalChannelHandle& handle) override;
- ChannelReference PushChannelHandle(
- void* transaction_state, const BorrowedChannelHandle& handle) override;
- bool GetFileHandle(void* transaction_state, FileReference ref,
- LocalHandle* handle) const override;
- bool GetChannelHandle(void* transaction_state, ChannelReference ref,
- LocalChannelHandle* handle) const override;
-
- std::unique_ptr<pdx::ChannelParcelable> TakeChannelParcelable() override;
-
- private:
- explicit ClientChannel(LocalChannelHandle channel_handle);
-
- Status<int> SendAndReceive(void* transaction_state, int opcode,
- const iovec* send_vector, size_t send_count,
- const iovec* receive_vector, size_t receive_count);
-
- LocalChannelHandle channel_handle_;
- ChannelEventReceiver* channel_data_;
- std::mutex socket_mutex_;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_CLIENT_CHANNEL_H_
diff --git a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h b/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
deleted file mode 100644
index c43c5c7..0000000
--- a/libs/vr/libpdx_uds/private/uds/client_channel_factory.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
-#define ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
-
-#include <string>
-
-#include <pdx/client_channel_factory.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class ClientChannelFactory : public pdx::ClientChannelFactory {
- public:
- static std::unique_ptr<pdx::ClientChannelFactory> Create(
- const std::string& endpoint_path);
- static std::unique_ptr<pdx::ClientChannelFactory> Create(LocalHandle socket);
-
- Status<std::unique_ptr<pdx::ClientChannel>> Connect(
- int64_t timeout_ms) const override;
-
- static std::string GetRootEndpointPath();
- static std::string GetEndpointPath(const std::string& endpoint_path);
-
- private:
- explicit ClientChannelFactory(const std::string& endpoint_path);
- explicit ClientChannelFactory(LocalHandle socket);
-
- mutable LocalHandle socket_;
- std::string endpoint_path_;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_CLIENT_CHANNEL_FACTORY_H_
diff --git a/libs/vr/libpdx_uds/private/uds/ipc_helper.h b/libs/vr/libpdx_uds/private/uds/ipc_helper.h
deleted file mode 100644
index 704a569..0000000
--- a/libs/vr/libpdx_uds/private/uds/ipc_helper.h
+++ /dev/null
@@ -1,222 +0,0 @@
-#ifndef ANDROID_PDX_UDS_IPC_HELPER_H_
-#define ANDROID_PDX_UDS_IPC_HELPER_H_
-
-#include <sys/socket.h>
-#include <utility>
-#include <vector>
-
-#include <pdx/rpc/serializable.h>
-#include <pdx/rpc/serialization.h>
-#include <pdx/status.h>
-#include <pdx/utility.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-// Test interfaces used for unit-testing payload sending/receiving over sockets.
-class SendInterface {
- public:
- virtual ssize_t Send(int socket_fd, const void* data, size_t size,
- int flags) = 0;
- virtual ssize_t SendMessage(int socket_fd, const msghdr* msg, int flags) = 0;
-
- protected:
- virtual ~SendInterface() = default;
-};
-
-class RecvInterface {
- public:
- virtual ssize_t Receive(int socket_fd, void* data, size_t size,
- int flags) = 0;
- virtual ssize_t ReceiveMessage(int socket_fd, msghdr* msg, int flags) = 0;
-
- protected:
- virtual ~RecvInterface() = default;
-};
-
-// Helper methods that allow to send/receive data through abstract interfaces.
-// Useful for mocking out the underlying socket I/O.
-Status<void> SendAll(SendInterface* sender, const BorrowedHandle& socket_fd,
- const void* data, size_t size);
-Status<void> SendMsgAll(SendInterface* sender, const BorrowedHandle& socket_fd,
- const msghdr* msg);
-Status<void> RecvAll(RecvInterface* receiver, const BorrowedHandle& socket_fd,
- void* data, size_t size);
-Status<void> RecvMsgAll(RecvInterface* receiver,
- const BorrowedHandle& socket_fd, msghdr* msg);
-
-#define RETRY_EINTR(fnc_call) \
- ([&]() -> decltype(fnc_call) { \
- decltype(fnc_call) result; \
- do { \
- result = (fnc_call); \
- } while (result == -1 && errno == EINTR); \
- return result; \
- })()
-
-class SendPayload : public MessageWriter, public OutputResourceMapper {
- public:
- explicit SendPayload(SendInterface* sender = nullptr) : sender_{sender} {}
- Status<void> Send(const BorrowedHandle& socket_fd);
- Status<void> Send(const BorrowedHandle& socket_fd, const ucred* cred,
- const iovec* data_vec = nullptr, size_t vec_count = 0);
-
- // MessageWriter
- void* GetNextWriteBufferSection(size_t size) override;
- OutputResourceMapper* GetOutputResourceMapper() override;
-
- // OutputResourceMapper
- Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
- Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
- Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const LocalChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const BorrowedChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- const RemoteChannelHandle& handle) override;
-
- private:
- SendInterface* sender_;
- ByteBuffer buffer_;
- std::vector<int> file_handles_;
-};
-
-class ReceivePayload : public MessageReader, public InputResourceMapper {
- public:
- explicit ReceivePayload(RecvInterface* receiver = nullptr)
- : receiver_{receiver} {}
- Status<void> Receive(const BorrowedHandle& socket_fd);
- Status<void> Receive(const BorrowedHandle& socket_fd, ucred* cred);
-
- // MessageReader
- BufferSection GetNextReadBufferSection() override;
- void ConsumeReadBufferSectionData(const void* new_start) override;
- InputResourceMapper* GetInputResourceMapper() override;
-
- // InputResourceMapper
- bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
- bool GetChannelHandle(ChannelReference ref,
- LocalChannelHandle* handle) override;
-
- private:
- RecvInterface* receiver_;
- ByteBuffer buffer_;
- std::vector<LocalHandle> file_handles_;
- size_t read_pos_{0};
-};
-
-template <typename FileHandleType>
-class ChannelInfo {
- public:
- FileHandleType data_fd;
- FileHandleType pollin_event_fd;
- FileHandleType pollhup_event_fd;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(ChannelInfo, data_fd, pollin_event_fd,
- pollhup_event_fd);
-};
-
-template <typename FileHandleType>
-class ChannelConnectionInfo {
- public:
- FileHandleType channel_fd;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(ChannelConnectionInfo, channel_fd);
-};
-
-template <typename FileHandleType>
-class RequestHeader {
- public:
- int32_t op{0};
- ucred cred;
- uint32_t send_len{0};
- uint32_t max_recv_len{0};
- std::vector<FileHandleType> file_descriptors;
- std::vector<ChannelInfo<FileHandleType>> channels;
- std::array<uint8_t, 32> impulse_payload;
- bool is_impulse{false};
-
- private:
- PDX_SERIALIZABLE_MEMBERS(RequestHeader, op, send_len, max_recv_len,
- file_descriptors, channels, impulse_payload,
- is_impulse);
-};
-
-template <typename FileHandleType>
-class ResponseHeader {
- public:
- int32_t ret_code{0};
- uint32_t recv_len{0};
- std::vector<FileHandleType> file_descriptors;
- std::vector<ChannelInfo<FileHandleType>> channels;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(ResponseHeader, ret_code, recv_len, file_descriptors,
- channels);
-};
-
-template <typename T>
-inline Status<void> SendData(const BorrowedHandle& socket_fd, const T& data,
- const iovec* data_vec = nullptr,
- size_t vec_count = 0) {
- SendPayload payload;
- rpc::Serialize(data, &payload);
- return payload.Send(socket_fd, nullptr, data_vec, vec_count);
-}
-
-template <typename FileHandleType>
-inline Status<void> SendData(const BorrowedHandle& socket_fd,
- const RequestHeader<FileHandleType>& request,
- const iovec* data_vec = nullptr,
- size_t vec_count = 0) {
- SendPayload payload;
- rpc::Serialize(request, &payload);
- return payload.Send(socket_fd, &request.cred, data_vec, vec_count);
-}
-
-Status<void> SendData(const BorrowedHandle& socket_fd, const void* data,
- size_t size);
-Status<void> SendDataVector(const BorrowedHandle& socket_fd, const iovec* data,
- size_t count);
-
-template <typename T>
-inline Status<void> ReceiveData(const BorrowedHandle& socket_fd, T* data) {
- ReceivePayload payload;
- Status<void> status = payload.Receive(socket_fd);
- if (status && rpc::Deserialize(data, &payload) != rpc::ErrorCode::NO_ERROR)
- status.SetError(EIO);
- return status;
-}
-
-template <typename FileHandleType>
-inline Status<void> ReceiveData(const BorrowedHandle& socket_fd,
- RequestHeader<FileHandleType>* request) {
- ReceivePayload payload;
- Status<void> status = payload.Receive(socket_fd, &request->cred);
- if (status && rpc::Deserialize(request, &payload) != rpc::ErrorCode::NO_ERROR)
- status.SetError(EIO);
- return status;
-}
-
-Status<void> ReceiveData(const BorrowedHandle& socket_fd, void* data,
- size_t size);
-Status<void> ReceiveDataVector(const BorrowedHandle& socket_fd,
- const iovec* data, size_t count);
-
-size_t CountVectorSize(const iovec* data, size_t count);
-void InitRequest(android::pdx::uds::RequestHeader<BorrowedHandle>* request,
- int opcode, uint32_t send_len, uint32_t max_recv_len,
- bool is_impulse);
-
-Status<void> WaitForEndpoint(const std::string& endpoint_path,
- int64_t timeout_ms);
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_IPC_HELPER_H_
diff --git a/libs/vr/libpdx_uds/private/uds/service_endpoint.h b/libs/vr/libpdx_uds/private/uds/service_endpoint.h
deleted file mode 100644
index 50fc484..0000000
--- a/libs/vr/libpdx_uds/private/uds/service_endpoint.h
+++ /dev/null
@@ -1,168 +0,0 @@
-#ifndef ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
-#define ANDROID_PDX_UDS_SERVICE_ENDPOINT_H_
-
-#include <sys/stat.h>
-#include <map>
-#include <memory>
-#include <mutex>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include <pdx/service.h>
-#include <pdx/service_endpoint.h>
-#include <uds/channel_event_set.h>
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-class Endpoint : public pdx::Endpoint {
- public:
- enum {
- kIpcTag = 0x00736674, // 'uds'
- };
-
- // Blocking modes for service endpoint. Controls whether the epoll set is in
- // blocking mode or not for message receive.
- enum {
- kBlocking = true,
- kNonBlocking = false,
- kDefaultBlocking = kNonBlocking,
- };
-
- enum : mode_t {
- kDefaultMode = 0,
- };
-
- ~Endpoint() override = default;
-
- uint32_t GetIpcTag() const override { return kIpcTag; }
- Status<void> SetService(Service* service) override;
- Status<void> SetChannel(int channel_id, Channel* channel) override;
- Status<void> CloseChannel(int channel_id) override;
- Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask) override;
- Status<RemoteChannelHandle> PushChannel(Message* message, int flags,
- Channel* channel,
- int* channel_id) override;
- Status<int> CheckChannel(const Message* message, ChannelReference ref,
- Channel** channel) override;
- Status<void> MessageReceive(Message* message) override;
- Status<void> MessageReply(Message* message, int return_code) override;
- Status<void> MessageReplyFd(Message* message, unsigned int push_fd) override;
- Status<void> MessageReplyChannelHandle(
- Message* message, const LocalChannelHandle& handle) override;
- Status<void> MessageReplyChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) override;
- Status<void> MessageReplyChannelHandle(
- Message* message, const RemoteChannelHandle& handle) override;
- Status<size_t> ReadMessageData(Message* message, const iovec* vector,
- size_t vector_length) override;
- Status<size_t> WriteMessageData(Message* message, const iovec* vector,
- size_t vector_length) override;
- Status<FileReference> PushFileHandle(Message* message,
- const LocalHandle& handle) override;
- Status<FileReference> PushFileHandle(Message* message,
- const BorrowedHandle& handle) override;
- Status<FileReference> PushFileHandle(Message* message,
- const RemoteHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- Message* message, const LocalChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) override;
- Status<ChannelReference> PushChannelHandle(
- Message* message, const RemoteChannelHandle& handle) override;
- LocalHandle GetFileHandle(Message* message, FileReference ref) const override;
- LocalChannelHandle GetChannelHandle(Message* message,
- ChannelReference ref) const override;
-
- void* AllocateMessageState() override;
- void FreeMessageState(void* state) override;
-
- Status<void> Cancel() override;
-
- // Open an endpoint at the given path.
- // Second parameter is unused for UDS, but we have it here for compatibility
- // in signature with servicefs::Endpoint::Create().
- // This method uses |endpoint_path| as a relative path to endpoint socket
- // created by init process.
- static std::unique_ptr<Endpoint> Create(const std::string& endpoint_path,
- mode_t /*unused_mode*/ = kDefaultMode,
- bool blocking = kDefaultBlocking);
-
- // Helper method to create an endpoint at the given UDS socket path. This
- // method physically creates and binds a socket at that path.
- static std::unique_ptr<Endpoint> CreateAndBindSocket(
- const std::string& endpoint_path, bool blocking = kDefaultBlocking);
-
- // Helper method to create an endpoint from an existing socket FD.
- // Mostly helpful for tests.
- static std::unique_ptr<Endpoint> CreateFromSocketFd(LocalHandle socket_fd);
-
- // Test helper method to register a new channel identified by |channel_fd|
- // socket file descriptor.
- Status<void> RegisterNewChannelForTests(LocalHandle channel_fd);
-
- int epoll_fd() const override { return epoll_fd_.Get(); }
-
- private:
- struct ChannelData {
- LocalHandle data_fd;
- ChannelEventSet event_set;
- Channel* channel_state{nullptr};
- };
-
- // This class must be instantiated using Create() static methods above.
- Endpoint(const std::string& endpoint_path, bool blocking,
- bool use_init_socket_fd = true);
- explicit Endpoint(LocalHandle socket_fd);
-
- void Init(LocalHandle socket_fd);
-
- Endpoint(const Endpoint&) = delete;
- void operator=(const Endpoint&) = delete;
-
- uint32_t GetNextAvailableMessageId() {
- return next_message_id_.fetch_add(1, std::memory_order_relaxed);
- }
-
- void BuildCloseMessage(int32_t channel_id, Message* message);
-
- Status<void> AcceptConnection(Message* message);
- Status<void> ReceiveMessageForChannel(const BorrowedHandle& channel_fd,
- Message* message);
- Status<void> OnNewChannel(LocalHandle channel_fd);
- Status<std::pair<int32_t, ChannelData*>> OnNewChannelLocked(
- LocalHandle channel_fd, Channel* channel_state);
- Status<void> CloseChannelLocked(int32_t channel_id);
- Status<void> ReenableEpollEvent(const BorrowedHandle& channel_fd);
- Channel* GetChannelState(int32_t channel_id);
- BorrowedHandle GetChannelSocketFd(int32_t channel_id);
- Status<std::pair<BorrowedHandle, BorrowedHandle>> GetChannelEventFd(
- int32_t channel_id);
- int32_t GetChannelId(const BorrowedHandle& channel_fd);
- Status<void> CreateChannelSocketPair(LocalHandle* local_socket,
- LocalHandle* remote_socket);
-
- std::string endpoint_path_;
- bool is_blocking_;
- LocalHandle socket_fd_;
- LocalHandle cancel_event_fd_;
- LocalHandle epoll_fd_;
-
- mutable std::mutex channel_mutex_;
- std::map<int32_t, ChannelData> channels_;
- std::map<int, int32_t> channel_fd_to_id_;
- int32_t last_channel_id_{0};
-
- Service* service_{nullptr};
- std::atomic<uint32_t> next_message_id_;
-};
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
-
-#endif // ANDROID_PDX_UDS_PDX_SERVICE_ENDPOINT_H_
diff --git a/libs/vr/libpdx_uds/remote_method_tests.cpp b/libs/vr/libpdx_uds/remote_method_tests.cpp
deleted file mode 100644
index 4f0670e..0000000
--- a/libs/vr/libpdx_uds/remote_method_tests.cpp
+++ /dev/null
@@ -1,951 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <array>
-#include <cstdint>
-#include <memory>
-#include <numeric>
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-#include <pdx/channel_handle.h>
-#include <pdx/client.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/serializable.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <uds/client_channel.h>
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ClientBase;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::RemoteHandle;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::uds::Endpoint;
-using namespace android::pdx::rpc;
-
-namespace {
-
-std::string Rot13(const std::string& s) {
- std::string text = s;
- std::transform(std::begin(text), std::end(text), std::begin(text),
- [](char c) -> char {
- if (!std::isalpha(c)) {
- return c;
- } else {
- const char pivot = std::isupper(c) ? 'A' : 'a';
- return (c - pivot + 13) % 26 + pivot;
- }
- });
- return text;
-}
-
-// Defines a serializable user type that may be transferred between client and
-// service.
-struct TestType {
- int a;
- float b;
- std::string c;
-
- TestType() {}
- TestType(int a, float b, const std::string& c) : a(a), b(b), c(c) {}
-
- // Make gtest expressions simpler by defining equality operator. This is not
- // needed for serialization.
- bool operator==(const TestType& other) const {
- return a == other.a && b == other.b && c == other.c;
- }
-
- private:
- PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c);
-};
-
-struct DerivedTestType : public TestType {
- DerivedTestType() : TestType() {}
- DerivedTestType(int a, float b) : TestType(a, b, "constant") {}
-};
-
-// Defines a serializable user type with a LocalHandle member.
-struct TestFdType {
- int a;
- LocalHandle fd;
-
- TestFdType() {}
- TestFdType(int a, LocalHandle fd) : a(a), fd(std::move(fd)) {}
-
- private:
- PDX_SERIALIZABLE_MEMBERS(TestFdType, a, fd);
-};
-
-// Defines a serializable user template type with a FileHandle member.
-template <typename FileHandleType>
-struct TestTemplateType {
- FileHandleType fd;
-
- TestTemplateType() {}
- explicit TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
-
- private:
- PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
-};
-
-struct BasicStruct {
- int a;
- int b;
- std::string c;
-
- private:
- PDX_SERIALIZABLE_MEMBERS(BasicStruct, a, b, c);
-};
-
-using BasicStructTraits = SerializableTraits<BasicStruct>;
-
-struct NonSerializableType {
- int a;
- int b;
- std::string c;
-};
-
-struct IncorrectlyDefinedSerializableType {
- int a;
- int b;
-
- private:
- using SerializableMembers = std::tuple<int, int>;
-};
-
-// Defines the contract between the client and service, including ServiceFS
-// endpoint path, method opcodes, and remote method signatures.
-struct TestInterface final {
- // Service path.
- static constexpr char kClientPath[] = "socket_test";
-
- // Op codes.
- enum {
- kOpAdd = 0,
- kOpFoo,
- kOpConcatenate,
- kOpWriteBuffer,
- kOpStringLength,
- kOpSendTestType,
- kOpSendBasicStruct,
- kOpSendVector,
- kOpRot13,
- kOpNoArgs,
- kOpSendFile,
- kOpGetFile,
- kOpGetTestFdType,
- kOpOpenFiles,
- kOpReadFile,
- kOpPushChannel,
- kOpPositive,
- };
-
- // Methods.
- PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
- PDX_REMOTE_METHOD(Foo, kOpFoo, int(int, const std::string&));
- PDX_REMOTE_METHOD(Concatenate, kOpConcatenate,
- std::string(const std::string&, const std::string&));
- PDX_REMOTE_METHOD(SumVector, kOpWriteBuffer, int(const std::vector<int>&));
- PDX_REMOTE_METHOD(StringLength, kOpStringLength, int(const std::string&));
- PDX_REMOTE_METHOD(SendTestType, kOpSendTestType, TestType(const TestType&));
- PDX_REMOTE_METHOD(SendBasicStruct, kOpSendBasicStruct,
- BasicStruct(const BasicStruct&));
- PDX_REMOTE_METHOD(SendVector, kOpSendVector,
- std::string(const std::vector<TestType>&));
- PDX_REMOTE_METHOD(Rot13, kOpRot13, std::string(const std::string&));
- PDX_REMOTE_METHOD(NoArgs, kOpNoArgs, int(Void));
- PDX_REMOTE_METHOD(SendFile, kOpSendFile, int(const LocalHandle& fd));
- PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
- PDX_REMOTE_METHOD(GetTestFdType, kOpGetTestFdType,
- TestFdType(int, const std::string&, int));
- PDX_REMOTE_METHOD(OpenFiles, kOpOpenFiles,
- std::vector<LocalHandle>(
- const std::vector<std::pair<std::string, int>>&));
- PDX_REMOTE_METHOD(ReadFile, kOpReadFile,
- std::pair<int, BufferWrapper<std::uint8_t*>>(
- const std::string&, int, std::size_t));
- PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
- PDX_REMOTE_METHOD(Positive, kOpPositive, void(int));
-
- PDX_REMOTE_API(API, Add, Foo, Concatenate, SumVector, StringLength,
- SendTestType, SendVector, Rot13, NoArgs, SendFile, GetFile,
- GetTestFdType, OpenFiles, PushChannel, Positive);
-};
-
-constexpr char TestInterface::kClientPath[];
-
-// Test client to send messages to the test service.
-class TestClient : public ClientBase<TestClient> {
- public:
- int Add(int a, int b) {
- return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Add>(a, b));
- }
-
- int Foo(int a, const std::string& b) {
- return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Foo>(a, b));
- }
-
- std::string Concatenate(const std::string& a, const std::string& b) {
- std::string return_value;
-
- Status<std::string> status =
- InvokeRemoteMethod<TestInterface::Concatenate>(a, b);
- if (!status)
- return std::string("[Error]");
- else
- return status.take();
- }
-
- int SumVector(const int* buffer, std::size_t size) {
- return ReturnStatusOrError(
- InvokeRemoteMethod<TestInterface::SumVector>(WrapArray(buffer, size)));
- }
-
- int SumVector(const std::vector<int>& buffer) {
- return ReturnStatusOrError(
- InvokeRemoteMethod<TestInterface::SumVector>(buffer));
- }
-
- int StringLength(const char* string, std::size_t size) {
- return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::StringLength>(
- WrapString(string, size)));
- }
-
- int StringLength(const std::string& string) {
- return ReturnStatusOrError(
- InvokeRemoteMethod<TestInterface::StringLength>(string));
- }
-
- TestType SendTestType(const TestType& tt) {
- Status<TestType> status =
- InvokeRemoteMethod<TestInterface::SendTestType>(tt);
- if (!status)
- return TestType(0, 0.0, "[Error]");
- else
- return status.take();
- }
-
- BasicStruct SendBasicStruct(const BasicStruct& bs) {
- Status<BasicStruct> status =
- InvokeRemoteMethod<TestInterface::SendBasicStruct>(bs);
- if (!status)
- return BasicStruct{0, 0, "[Error]"};
- else
- return status.take();
- }
-
- std::string SendVector(const std::vector<TestType>& v) {
- Status<std::string> status =
- InvokeRemoteMethod<TestInterface::SendVector>(v);
- if (!status)
- return "[Error]";
- else
- return status.take();
- }
-
- std::string Rot13(const std::string& string) {
- Status<std::string> status =
- InvokeRemoteMethod<TestInterface::Rot13>(string);
- return status ? status.get() : string;
- }
-
- int NoArgs() {
- return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::NoArgs>());
- }
-
- int SendFile(const LocalHandle& fd) {
- return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::SendFile>(fd));
- }
-
- LocalHandle GetFile(const std::string& path, int mode) {
- Status<LocalHandle> status =
- InvokeRemoteMethod<TestInterface::GetFile>(path, mode);
- if (!status)
- return LocalHandle(-status.error());
- else
- return status.take();
- }
-
- int GetFile(const std::string& path, int mode, LocalHandle* fd_out) {
- Status<void> status =
- InvokeRemoteMethodInPlace<TestInterface::GetFile>(fd_out, path, mode);
- return status ? 0 : -status.error();
- }
-
- TestFdType GetTestFdType(int a, const std::string& path, int mode) {
- Status<TestFdType> status =
- InvokeRemoteMethod<TestInterface::GetTestFdType>(a, path, mode);
- if (!status)
- return {};
- else
- return status.take();
- }
-
- std::vector<LocalHandle> OpenFiles(
- const std::vector<std::pair<std::string, int>>& file_specs) {
- Status<std::vector<LocalHandle>> status =
- InvokeRemoteMethod<TestInterface::OpenFiles>(file_specs);
- if (!status)
- return {};
- else
- return status.take();
- }
-
- int ReadFile(void* buffer, std::size_t size, const std::string& path,
- int mode) {
- auto buffer_wrapper = WrapBuffer(buffer, size);
- auto return_value = std::make_pair(-1, buffer_wrapper);
-
- Status<void> status = InvokeRemoteMethodInPlace<TestInterface::ReadFile>(
- &return_value, path, mode, size);
- return status ? return_value.first : -status.error();
- }
-
- int PushChannel(LocalChannelHandle* fd_out) {
- auto status = InvokeRemoteMethodInPlace<TestInterface::PushChannel>(fd_out);
- return status ? 0 : -status.error();
- }
-
- bool Positive(int test_value) {
- auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value);
- return status.ok();
- }
-
- int GetFd() const { return event_fd(); }
-
- private:
- friend BASE;
-
- explicit TestClient(LocalChannelHandle channel_handle)
- : BASE{android::pdx::uds::ClientChannel::Create(
- std::move(channel_handle))} {}
- TestClient()
- : BASE{android::pdx::uds::ClientChannelFactory::Create(
- TestInterface::kClientPath)} {}
-
- TestClient(const TestClient&) = delete;
- void operator=(const TestClient&) = delete;
-};
-
-// Test service that encodes/decodes messages from clients.
-class TestService : public ServiceBase<TestService> {
- public:
- Status<void> HandleMessage(Message& message) override {
- switch (message.GetOp()) {
- case TestInterface::Add::Opcode:
- DispatchRemoteMethod<TestInterface::Add>(*this, &TestService::OnAdd,
- message);
- return {};
-
- case TestInterface::Foo::Opcode:
- DispatchRemoteMethod<TestInterface::Foo>(*this, &TestService::OnFoo,
- message);
- return {};
-
- case TestInterface::Concatenate::Opcode:
- DispatchRemoteMethod<TestInterface::Concatenate>(
- *this, &TestService::OnConcatenate, message);
- return {};
-
- case TestInterface::SumVector::Opcode:
- DispatchRemoteMethod<TestInterface::SumVector>(
- *this, &TestService::OnSumVector, message);
- return {};
-
- case TestInterface::StringLength::Opcode:
- DispatchRemoteMethod<TestInterface::StringLength>(
- *this, &TestService::OnStringLength, message);
- return {};
-
- case TestInterface::SendTestType::Opcode:
- DispatchRemoteMethod<TestInterface::SendTestType>(
- *this, &TestService::OnSendTestType, message);
- return {};
-
- case TestInterface::SendVector::Opcode:
- DispatchRemoteMethod<TestInterface::SendVector>(
- *this, &TestService::OnSendVector, message);
- return {};
-
- case TestInterface::Rot13::Opcode:
- DispatchRemoteMethod<TestInterface::Rot13>(*this, &TestService::OnRot13,
- message);
- return {};
-
- case TestInterface::NoArgs::Opcode:
- DispatchRemoteMethod<TestInterface::NoArgs>(
- *this, &TestService::OnNoArgs, message);
- return {};
-
- case TestInterface::SendFile::Opcode:
- DispatchRemoteMethod<TestInterface::SendFile>(
- *this, &TestService::OnSendFile, message);
- return {};
-
- case TestInterface::GetFile::Opcode:
- DispatchRemoteMethod<TestInterface::GetFile>(
- *this, &TestService::OnGetFile, message);
- return {};
-
- case TestInterface::GetTestFdType::Opcode:
- DispatchRemoteMethod<TestInterface::GetTestFdType>(
- *this, &TestService::OnGetTestFdType, message);
- return {};
-
- case TestInterface::OpenFiles::Opcode:
- DispatchRemoteMethod<TestInterface::OpenFiles>(
- *this, &TestService::OnOpenFiles, message);
- return {};
-
- case TestInterface::ReadFile::Opcode:
- DispatchRemoteMethod<TestInterface::ReadFile>(
- *this, &TestService::OnReadFile, message);
- return {};
-
- case TestInterface::PushChannel::Opcode:
- DispatchRemoteMethod<TestInterface::PushChannel>(
- *this, &TestService::OnPushChannel, message);
- return {};
-
- case TestInterface::Positive::Opcode:
- DispatchRemoteMethod<TestInterface::Positive>(
- *this, &TestService::OnPositive, message);
- return {};
-
- default:
- return Service::DefaultHandleMessage(message);
- }
- }
-
- private:
- friend BASE;
-
- TestService()
- : BASE("TestService",
- Endpoint::CreateAndBindSocket(TestInterface::kClientPath)) {}
-
- int OnAdd(Message&, int a, int b) { return a + b; }
-
- int OnFoo(Message&, int a, const std::string& b) { return a + b.length(); }
-
- std::string OnConcatenate(Message&, const std::string& a,
- const std::string& b) {
- return a + b;
- }
-
- int OnSumVector(Message&, const std::vector<int>& vector) {
- return std::accumulate(vector.begin(), vector.end(), 0);
- }
-
- int OnStringLength(Message&, const std::string& string) {
- return string.length();
- }
-
- TestType OnSendTestType(Message&, const TestType& tt) {
- return TestType(tt.a + 20, tt.b - 2.0, tt.c + "foo");
- }
-
- std::string OnSendVector(Message&, const std::vector<TestType>& v) {
- std::string return_value = "";
-
- for (const auto& tt : v)
- return_value += tt.c;
-
- return return_value;
- }
-
- Status<std::string> OnRot13(Message&, const std::string& s) {
- return {Rot13(s)};
- }
-
- int OnNoArgs(Message&) { return 1; }
-
- int OnSendFile(Message&, const LocalHandle& fd) { return fd.Get(); }
-
- LocalHandle OnGetFile(Message& message, const std::string& path, int mode) {
- LocalHandle fd(path.c_str(), mode);
- if (!fd)
- message.ReplyError(errno);
- return fd;
- }
-
- TestFdType OnGetTestFdType(Message& message, int a, const std::string& path,
- int mode) {
- TestFdType return_value(a, LocalHandle(path, mode));
- if (!return_value.fd)
- message.ReplyError(errno);
- return return_value;
- }
-
- std::vector<LocalHandle> OnOpenFiles(
- Message&, const std::vector<std::pair<std::string, int>>& file_specs) {
- std::vector<LocalHandle> return_value;
- for (auto& spec : file_specs) {
- LocalHandle fd(spec.first, spec.second);
- if (fd)
- return_value.emplace_back(std::move(fd));
- else
- return_value.emplace_back(-errno);
- }
- return return_value;
- }
-
- std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> OnReadFile(
- Message& message, const std::string& path, int mode, std::size_t length) {
- std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> return_value;
- LocalHandle fd(path, mode);
- if (!fd) {
- message.ReplyError(errno);
- return return_value;
- }
-
- return_value.second.reserve(length);
- const int ret = read(fd.Get(), return_value.second.data(), length);
- if (ret < 0) {
- message.ReplyError(errno);
- return return_value;
- }
-
- return_value.second.resize(ret);
- return_value.first = ret;
- return return_value;
- }
-
- RemoteChannelHandle OnPushChannel(Message& message) {
- auto status = message.PushChannel(0, nullptr, nullptr);
- if (!status) {
- message.ReplyError(status.error());
- return {};
- }
- return status.take();
- }
-
- Status<void> OnPositive(Message& /*message*/, int test_value) {
- if (test_value >= 0)
- return {};
- else
- return ErrorStatus(EINVAL);
- }
-
- TestService(const TestService&) = delete;
- void operator=(const TestService&) = delete;
-};
-
-} // anonymous namespace
-
-// Use a test fixture to ensure proper order of cleanup between clients,
-// services, and the dispatcher. As these objects are cleaned up in the same
-// thread, either the service or client must be destroyed before stopping the
-// dispatcher. The reason for this is that clients send blocking "close"
-// messages to their respective services on destruction. If this happens after
-// stopping the dispatcher the client destructor will get blocked waiting for a
-// reply that will never come. In normal use of the service framework this is
-// never an issue because clients and the dispatcher for the same service are
-// never destructed in the same thread (they live in different processes).
-class RemoteMethodTest : public ::testing::Test {
- protected:
- std::unique_ptr<ServiceDispatcher> dispatcher_;
- std::thread dispatch_thread_;
-
- void SetUp() override {
- // Create a dispatcher to handle messages to services.
- dispatcher_ = android::pdx::ServiceDispatcher::Create();
- ASSERT_NE(nullptr, dispatcher_);
-
- // Start the message dispatch loop in a separate thread.
- dispatch_thread_ = std::thread(
- std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
- }
-
- void TearDown() override {
- if (dispatcher_) {
- // Cancel the dispatcher and wait for the thread to terminate.
- // Explicitly
- // join the thread so that destruction doesn't deallocate the
- // dispatcher
- // before the thread finishes.
- dispatcher_->SetCanceled(true);
- dispatch_thread_.join();
- }
- }
-};
-
-// Test basic operation of TestService/TestClient classes.
-TEST_F(RemoteMethodTest, BasicClientService) {
- // Create a test service and add it to the dispatcher.
-
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- const int sum = client->Add(10, 25);
- EXPECT_GE(35, sum);
-
- const auto cat = client->Concatenate("This is a string", ", that it is.");
- EXPECT_EQ("This is a string, that it is.", cat);
-
- std::string alphabet = "abcdefghijklmnopqrstuvwxyz";
- const auto rot13_alphabet = client->Rot13(alphabet);
- EXPECT_EQ(Rot13(alphabet), rot13_alphabet);
-
- const auto length = client->Foo(10, "123");
- EXPECT_EQ(13, length);
-
- const std::vector<int> vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- const int vector_sum = client->SumVector(vector.data(), vector.size());
- const int vector_sum2 = client->SumVector(vector);
- EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum);
- EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum2);
-
- const auto string_length1 = client->StringLength("This is a string");
- EXPECT_EQ(16, string_length1);
-
- const auto string_length2 = client->StringLength("1234567890");
- EXPECT_EQ(10, string_length2);
-
- std::string string = "1234567890";
- const auto string_length3 =
- client->StringLength(string.c_str(), string.length());
- EXPECT_EQ(10, string_length3);
-
- TestType tt{10, 0.0, "string"};
- const auto tt_result = client->SendTestType(tt);
- EXPECT_EQ(TestType(30, -2.0, "stringfoo"), tt_result);
-
- std::vector<TestType> ttv = {TestType(0, 0.0, "abc"),
- TestType(0, 0.0, "123")};
- const std::string string_result = client->SendVector(ttv);
- EXPECT_EQ("abc123", string_result);
-
- const int int_result = client->NoArgs();
- EXPECT_EQ(1, int_result);
-}
-
-TEST_F(RemoteMethodTest, LocalHandle) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- LocalHandle fd("/dev/zero", O_RDONLY);
- ASSERT_TRUE(fd.IsValid());
-
- int fd_result = client->SendFile(fd);
- EXPECT_LE(0, fd_result);
- EXPECT_NE(fd.Get(), fd_result);
- fd = LocalHandle(-3);
- fd_result = client->SendFile(fd);
- EXPECT_EQ(fd.Get(), fd_result);
-
- fd = client->GetFile("/dev/zero", O_RDONLY);
- ASSERT_TRUE(fd.IsValid()) << "Error code: " << fd.Get();
-
- std::array<uint8_t, 10> buffer;
- buffer.fill(1);
- EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
- EXPECT_EQ(buffer, decltype(buffer){{0}});
- fd.Close();
-
- const int error = client->GetFile("/dev/zero", O_RDONLY, &fd);
- EXPECT_EQ(0, error);
- EXPECT_TRUE(fd.IsValid());
-
- buffer.fill(1);
- EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size()));
- EXPECT_EQ(buffer, decltype(buffer){{0}});
-
- /*
- Seg fault.
- fd = client->GetFile("/dev/foobar", O_RDONLY);
- EXPECT_FALSE(fd.IsValid());
- */
-}
-
-TEST_F(RemoteMethodTest, PushChannel) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- // Get a new channel as an fd.
- LocalChannelHandle channel;
- const int ret = client->PushChannel(&channel);
- EXPECT_EQ(0, ret);
- EXPECT_TRUE(channel.valid());
-
- // Create a new client from the channel.
- auto client2 = TestClient::Create(std::move(channel));
- ASSERT_NE(nullptr, client2);
-
- // Test that the new channel works.
- const int sum = client2->Add(10, 25);
- EXPECT_GE(35, sum);
-}
-
-TEST_F(RemoteMethodTest, Positive) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- ASSERT_TRUE(client->Positive(0));
- ASSERT_TRUE(client->Positive(1));
- ASSERT_FALSE(client->Positive(-1));
-}
-
-TEST_F(RemoteMethodTest, AggregateLocalHandle) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- TestFdType result = client->GetTestFdType(10, "/dev/zero", O_RDONLY);
- EXPECT_TRUE(result.fd.IsValid());
- EXPECT_EQ(10, result.a);
-
- std::vector<LocalHandle> files =
- client->OpenFiles({{{"/dev/zero", O_RDONLY},
- {"/dev/null", O_WRONLY},
- {"/dev/zero", O_RDONLY}}});
- ASSERT_EQ(3u, files.size());
- EXPECT_TRUE(files[0].IsValid());
- EXPECT_TRUE(files[1].IsValid());
- EXPECT_TRUE(files[2].IsValid());
-}
-
-TEST_F(RemoteMethodTest, BufferWrapper) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create();
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create();
- ASSERT_NE(nullptr, client);
-
- const int buffer_size = 20;
- std::vector<std::uint8_t> buffer(buffer_size, 'x');
- std::vector<std::uint8_t> expected(buffer_size, 0);
- int ret =
- client->ReadFile(buffer.data(), buffer.size(), "/dev/zero", O_RDONLY);
- EXPECT_EQ(buffer_size, ret);
- EXPECT_EQ(expected, buffer);
-}
-
-//
-// RemoteMethodFramework: Tests the type-based framework that remote method
-// support is built upon.
-//
-
-// Test logical And template.
-TEST(RemoteMethodFramework, And) {
- EXPECT_TRUE((And<std::true_type, std::true_type>::value));
- EXPECT_FALSE((And<std::true_type, std::false_type>::value));
- EXPECT_FALSE((And<std::false_type, std::true_type>::value));
- EXPECT_FALSE((And<std::false_type, std::false_type>::value));
-
- EXPECT_TRUE((And<std::true_type, std::true_type, std::true_type>::value));
- EXPECT_FALSE((And<std::true_type, std::true_type, std::false_type>::value));
- EXPECT_FALSE((And<std::true_type, std::false_type, std::true_type>::value));
- EXPECT_FALSE((And<std::true_type, std::false_type, std::false_type>::value));
- EXPECT_FALSE((And<std::false_type, std::true_type, std::true_type>::value));
- EXPECT_FALSE((And<std::false_type, std::true_type, std::false_type>::value));
- EXPECT_FALSE((And<std::false_type, std::false_type, std::true_type>::value));
- EXPECT_FALSE((And<std::false_type, std::false_type, std::false_type>::value));
-}
-
-// Test convertible type constraints.
-TEST(RemoteMethodFramework, IsConvertible) {
- // std::pair.
- EXPECT_TRUE(
- (IsConvertible<std::pair<int, float>, std::pair<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::pair<int, float>, std::pair<float, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::pair<int, float>, std::pair<float, int>>::value));
-
- // Nested std::pair.
- EXPECT_TRUE((IsConvertible<std::pair<std::pair<int, float>, float>,
- std::pair<std::pair<int, float>, float>>::value));
- EXPECT_FALSE((IsConvertible<std::pair<std::pair<int, float>, float>,
- std::pair<std::pair<float, int>, float>>::value));
-
- // std::tuple and std::pair.
- EXPECT_TRUE(
- (IsConvertible<std::pair<int, float>, std::tuple<int, float>>::value));
- EXPECT_TRUE(
- (IsConvertible<std::tuple<int, float>, std::pair<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::pair<float, float>, std::tuple<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::tuple<float, float>, std::pair<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::pair<int, int>, std::tuple<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::tuple<int, int>, std::pair<int, float>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::pair<int, int>, std::tuple<int, int, int>>::value));
- EXPECT_FALSE(
- (IsConvertible<std::tuple<int, int, int>, std::pair<int, int>>::value));
-
- // std::vector.
- EXPECT_TRUE((IsConvertible<std::vector<int>, std::vector<int>>::value));
- EXPECT_FALSE((IsConvertible<std::vector<int>, std::vector<float>>::value));
-
- // Nested std::vector.
- EXPECT_TRUE((IsConvertible<std::vector<std::pair<int, int>>,
- std::vector<std::pair<int, int>>>::value));
- EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
- std::vector<std::pair<int, float>>>::value));
- EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
- std::vector<std::pair<float, int>>>::value));
- EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>,
- std::vector<std::pair<float, float>>>::value));
-
- // std::vector with nested convertible types.
- EXPECT_TRUE((IsConvertible<std::vector<StringWrapper<char>>,
- std::vector<std::string>>::value));
-
- // std::map and std::unordered_map.
- EXPECT_TRUE((IsConvertible<std::map<int, float>,
- std::unordered_map<int, float>>::value));
- EXPECT_FALSE((IsConvertible<std::map<float, float>,
- std::unordered_map<int, float>>::value));
- EXPECT_FALSE((IsConvertible<std::map<float, float>,
- std::unordered_map<float, int>>::value));
- EXPECT_FALSE((IsConvertible<std::map<float, float>,
- std::unordered_map<int, int>>::value));
- EXPECT_TRUE((IsConvertible<std::unordered_map<int, float>,
- std::map<int, float>>::value));
- EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
- std::map<int, float>>::value));
- EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
- std::map<float, int>>::value));
- EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>,
- std::map<int, int>>::value));
-
- // std::map with nested convertible types.
- EXPECT_TRUE((IsConvertible<std::map<int, std::string>,
- std::map<int, StringWrapper<char>>>::value));
- EXPECT_TRUE(
- (IsConvertible<std::map<std::tuple<int, int>, std::string>,
- std::map<std::pair<int, int>, std::string>>::value));
-
- // std::unordered_map with nested convertible types.
- EXPECT_TRUE(
- (IsConvertible<std::unordered_map<int, std::string>,
- std::unordered_map<int, StringWrapper<char>>>::value));
- EXPECT_TRUE((IsConvertible<
- std::unordered_map<std::tuple<int, int>, std::string>,
- std::unordered_map<std::pair<int, int>, std::string>>::value));
-
- // std::string.
- EXPECT_TRUE((IsConvertible<std::string, std::string>::value));
- EXPECT_FALSE((IsConvertible<std::string, int>::value));
- EXPECT_FALSE((IsConvertible<int, std::string>::value));
-
- // Nested std::string.
- EXPECT_TRUE((IsConvertible<std::pair<std::string, std::string>,
- std::pair<std::string, std::string>>::value));
- EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
- std::pair<std::string, int>>::value));
- EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
- std::pair<int, std::string>>::value));
- EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>,
- std::pair<int, int>>::value));
-
- // StringWrapper.
- EXPECT_TRUE((IsConvertible<StringWrapper<char>, StringWrapper<char>>::value));
- EXPECT_TRUE((IsConvertible<StringWrapper<char>, std::string>::value));
- EXPECT_TRUE((IsConvertible<std::string, StringWrapper<char>>::value));
- EXPECT_FALSE((IsConvertible<StringWrapper<char>, int>::value));
- EXPECT_FALSE(
- (IsConvertible<StringWrapper<char>, BufferWrapper<char*>>::value));
-
- // BufferWrapper.
- EXPECT_TRUE(
- (IsConvertible<BufferWrapper<char*>, BufferWrapper<char*>>::value));
- EXPECT_TRUE(
- (IsConvertible<BufferWrapper<char*>, BufferWrapper<const char*>>::value));
- EXPECT_FALSE(
- (IsConvertible<BufferWrapper<char*>, BufferWrapper<int*>>::value));
- EXPECT_TRUE((IsConvertible<BufferWrapper<char*>,
- BufferWrapper<std::vector<char>>>::value));
-
- // RemoteHandle and BorrowedHandle.
- EXPECT_TRUE((IsConvertible<LocalHandle, RemoteHandle>::value));
- EXPECT_TRUE((IsConvertible<LocalHandle, BorrowedHandle>::value));
-
- // Test rewriting user defined types.
- EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
- TestTemplateType<RemoteHandle>>::value));
- EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>,
- TestTemplateType<BorrowedHandle>>::value));
- EXPECT_FALSE((IsConvertible<TestTemplateType<RemoteHandle>,
- TestTemplateType<LocalHandle>>::value));
- EXPECT_FALSE((IsConvertible<TestTemplateType<BorrowedHandle>,
- TestTemplateType<LocalHandle>>::value));
-
- // TODO(eieio): More thorough testing of convertible types.
-}
-
-TEST(RemoteMethodFramework, SerializableMembers) {
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
-
- EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
- TestTemplateType<LocalHandle>>>::value);
- EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
- TestTemplateType<RemoteHandle>>>::value);
- EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers<
- TestTemplateType<BorrowedHandle>>>::value);
-
- EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
-
- EXPECT_TRUE(HasSerializableMembers<BasicStruct>::value);
- EXPECT_TRUE(HasSerializableMembers<TestType>::value);
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value);
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value);
- EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value);
- EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value);
- EXPECT_FALSE(HasSerializableMembers<NonSerializableType>::value);
- EXPECT_FALSE(
- HasSerializableMembers<IncorrectlyDefinedSerializableType>::value);
-}
-
-TEST(RemoteMethodFramework, RemoteAPITypes) {
- EXPECT_EQ(0u, TestInterface::API::MethodIndex<TestInterface::Add>());
-}
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
deleted file mode 100644
index 810eb19..0000000
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ /dev/null
@@ -1,789 +0,0 @@
-#include "uds/service_endpoint.h"
-
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <algorithm> // std::min
-
-#include <android-base/logging.h>
-#include <android-base/strings.h>
-#include <cutils/sockets.h>
-#include <pdx/service.h>
-#include <selinux/selinux.h>
-#include <uds/channel_manager.h>
-#include <uds/client_channel_factory.h>
-#include <uds/ipc_helper.h>
-
-namespace {
-
-constexpr int kMaxBackLogForSocketListen = 1;
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::BorrowedHandle;
-using android::pdx::ChannelReference;
-using android::pdx::ErrorStatus;
-using android::pdx::FileReference;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Status;
-using android::pdx::uds::ChannelInfo;
-using android::pdx::uds::ChannelManager;
-
-struct MessageState {
- bool GetLocalFileHandle(int index, LocalHandle* handle) {
- if (index < 0) {
- handle->Reset(index);
- } else if (static_cast<size_t>(index) < request.file_descriptors.size()) {
- *handle = std::move(request.file_descriptors[index]);
- } else {
- return false;
- }
- return true;
- }
-
- bool GetLocalChannelHandle(int index, LocalChannelHandle* handle) {
- if (index < 0) {
- *handle = LocalChannelHandle{nullptr, index};
- } else if (static_cast<size_t>(index) < request.channels.size()) {
- auto& channel_info = request.channels[index];
- *handle = ChannelManager::Get().CreateHandle(
- std::move(channel_info.data_fd),
- std::move(channel_info.pollin_event_fd),
- std::move(channel_info.pollhup_event_fd));
- } else {
- return false;
- }
- return true;
- }
-
- Status<FileReference> PushFileHandle(BorrowedHandle handle) {
- if (!handle)
- return handle.Get();
- response.file_descriptors.push_back(std::move(handle));
- return response.file_descriptors.size() - 1;
- }
-
- Status<ChannelReference> PushChannelHandle(BorrowedChannelHandle handle) {
- if (!handle)
- return handle.value();
-
- if (auto* channel_data =
- ChannelManager::Get().GetChannelData(handle.value())) {
- ChannelInfo<BorrowedHandle> channel_info{
- channel_data->data_fd(), channel_data->pollin_event_fd(),
- channel_data->pollhup_event_fd()};
- response.channels.push_back(std::move(channel_info));
- return response.channels.size() - 1;
- } else {
- return ErrorStatus{EINVAL};
- }
- }
-
- Status<ChannelReference> PushChannelHandle(BorrowedHandle data_fd,
- BorrowedHandle pollin_event_fd,
- BorrowedHandle pollhup_event_fd) {
- if (!data_fd || !pollin_event_fd || !pollhup_event_fd)
- return ErrorStatus{EINVAL};
- ChannelInfo<BorrowedHandle> channel_info{std::move(data_fd),
- std::move(pollin_event_fd),
- std::move(pollhup_event_fd)};
- response.channels.push_back(std::move(channel_info));
- return response.channels.size() - 1;
- }
-
- Status<size_t> WriteData(const iovec* vector, size_t vector_length) {
- size_t size = 0;
- for (size_t i = 0; i < vector_length; i++) {
- const auto* data = reinterpret_cast<const uint8_t*>(vector[i].iov_base);
- response_data.insert(response_data.end(), data, data + vector[i].iov_len);
- size += vector[i].iov_len;
- }
- return size;
- }
-
- Status<size_t> ReadData(const iovec* vector, size_t vector_length) {
- size_t size_remaining = request_data.size() - request_data_read_pos;
- size_t size = 0;
- for (size_t i = 0; i < vector_length && size_remaining > 0; i++) {
- size_t size_to_copy = std::min(size_remaining, vector[i].iov_len);
- memcpy(vector[i].iov_base, request_data.data() + request_data_read_pos,
- size_to_copy);
- size += size_to_copy;
- request_data_read_pos += size_to_copy;
- size_remaining -= size_to_copy;
- }
- return size;
- }
-
- android::pdx::uds::RequestHeader<LocalHandle> request;
- android::pdx::uds::ResponseHeader<BorrowedHandle> response;
- std::vector<LocalHandle> sockets_to_close;
- std::vector<uint8_t> request_data;
- size_t request_data_read_pos{0};
- std::vector<uint8_t> response_data;
-};
-
-} // anonymous namespace
-
-namespace android {
-namespace pdx {
-namespace uds {
-
-Endpoint::Endpoint(const std::string& endpoint_path, bool blocking,
- bool use_init_socket_fd)
- : endpoint_path_{ClientChannelFactory::GetEndpointPath(endpoint_path)},
- is_blocking_{blocking} {
- LocalHandle fd;
- if (use_init_socket_fd) {
- // Cut off the /dev/socket/ prefix from the full socket path and use the
- // resulting "name" to retrieve the file descriptor for the socket created
- // by the init process.
- constexpr char prefix[] = "/dev/socket/";
- CHECK(android::base::StartsWith(endpoint_path_, prefix))
- << "Endpoint::Endpoint: Socket name '" << endpoint_path_
- << "' must begin with '" << prefix << "'";
- std::string socket_name = endpoint_path_.substr(sizeof(prefix) - 1);
- fd.Reset(android_get_control_socket(socket_name.c_str()));
- CHECK(fd.IsValid())
- << "Endpoint::Endpoint: Unable to obtain the control socket fd for '"
- << socket_name << "'";
- fcntl(fd.Get(), F_SETFD, FD_CLOEXEC);
- } else {
- fd.Reset(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0));
- CHECK(fd.IsValid()) << "Endpoint::Endpoint: Failed to create socket: "
- << strerror(errno);
-
- sockaddr_un local;
- local.sun_family = AF_UNIX;
- strncpy(local.sun_path, endpoint_path_.c_str(), sizeof(local.sun_path));
- local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
- unlink(local.sun_path);
- int ret =
- bind(fd.Get(), reinterpret_cast<sockaddr*>(&local), sizeof(local));
- CHECK_EQ(ret, 0) << "Endpoint::Endpoint: bind error: " << strerror(errno);
- }
- Init(std::move(fd));
-}
-
-Endpoint::Endpoint(LocalHandle socket_fd) { Init(std::move(socket_fd)); }
-
-void Endpoint::Init(LocalHandle socket_fd) {
- if (socket_fd) {
- CHECK_EQ(listen(socket_fd.Get(), kMaxBackLogForSocketListen), 0)
- << "Endpoint::Endpoint: listen error: " << strerror(errno);
- }
- cancel_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
- CHECK(cancel_event_fd_.IsValid())
- << "Endpoint::Endpoint: Failed to create event fd: " << strerror(errno);
-
- epoll_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
- CHECK(epoll_fd_.IsValid())
- << "Endpoint::Endpoint: Failed to create epoll fd: " << strerror(errno);
-
- if (socket_fd) {
- epoll_event socket_event;
- socket_event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
- socket_event.data.fd = socket_fd.Get();
- int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, socket_fd.Get(),
- &socket_event);
- CHECK_EQ(ret, 0)
- << "Endpoint::Endpoint: Failed to add socket fd to epoll fd: "
- << strerror(errno);
- }
-
- epoll_event cancel_event;
- cancel_event.events = EPOLLIN;
- cancel_event.data.fd = cancel_event_fd_.Get();
-
- int ret = epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, cancel_event_fd_.Get(),
- &cancel_event);
- CHECK_EQ(ret, 0)
- << "Endpoint::Endpoint: Failed to add cancel event fd to epoll fd: "
- << strerror(errno);
- socket_fd_ = std::move(socket_fd);
-}
-
-void* Endpoint::AllocateMessageState() { return new MessageState; }
-
-void Endpoint::FreeMessageState(void* state) {
- delete static_cast<MessageState*>(state);
-}
-
-Status<void> Endpoint::AcceptConnection(Message* message) {
- if (!socket_fd_)
- return ErrorStatus(EBADF);
-
- sockaddr_un remote;
- socklen_t addrlen = sizeof(remote);
- LocalHandle connection_fd{accept4(socket_fd_.Get(),
- reinterpret_cast<sockaddr*>(&remote),
- &addrlen, SOCK_CLOEXEC)};
- if (!connection_fd) {
- ALOGE("Endpoint::AcceptConnection: failed to accept connection: %s",
- strerror(errno));
- return ErrorStatus(errno);
- }
-
- LocalHandle local_socket;
- LocalHandle remote_socket;
- auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
- if (!status)
- return status;
-
- // Borrow the local channel handle before we move it into OnNewChannel().
- BorrowedHandle channel_handle = local_socket.Borrow();
- status = OnNewChannel(std::move(local_socket));
- if (!status)
- return status;
-
- // Send the channel socket fd to the client.
- ChannelConnectionInfo<LocalHandle> connection_info;
- connection_info.channel_fd = std::move(remote_socket);
- status = SendData(connection_fd.Borrow(), connection_info);
-
- if (status) {
- // Get the CHANNEL_OPEN message from client over the channel socket.
- status = ReceiveMessageForChannel(channel_handle, message);
- } else {
- CloseChannel(GetChannelId(channel_handle));
- }
-
- // Don't need the connection socket anymore. Further communication should
- // happen over the channel socket.
- shutdown(connection_fd.Get(), SHUT_WR);
- return status;
-}
-
-Status<void> Endpoint::SetService(Service* service) {
- service_ = service;
- return {};
-}
-
-Status<void> Endpoint::SetChannel(int channel_id, Channel* channel) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- auto channel_data = channels_.find(channel_id);
- if (channel_data == channels_.end())
- return ErrorStatus{EINVAL};
- channel_data->second.channel_state = channel;
- return {};
-}
-
-Status<void> Endpoint::OnNewChannel(LocalHandle channel_fd) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- Status<void> status;
- status.PropagateError(OnNewChannelLocked(std::move(channel_fd), nullptr));
- return status;
-}
-
-Status<std::pair<int32_t, Endpoint::ChannelData*>> Endpoint::OnNewChannelLocked(
- LocalHandle channel_fd, Channel* channel_state) {
- epoll_event event;
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
- event.data.fd = channel_fd.Get();
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, channel_fd.Get(), &event) < 0) {
- ALOGE(
- "Endpoint::OnNewChannelLocked: Failed to add channel to endpoint: %s\n",
- strerror(errno));
- return ErrorStatus(errno);
- }
- ChannelData channel_data;
- channel_data.data_fd = std::move(channel_fd);
- channel_data.channel_state = channel_state;
- for (;;) {
- // Try new channel IDs until we find one which is not already in the map.
- if (last_channel_id_++ == std::numeric_limits<int32_t>::max())
- last_channel_id_ = 1;
- auto iter = channels_.lower_bound(last_channel_id_);
- if (iter == channels_.end() || iter->first != last_channel_id_) {
- channel_fd_to_id_.emplace(channel_data.data_fd.Get(), last_channel_id_);
- iter = channels_.emplace_hint(iter, last_channel_id_,
- std::move(channel_data));
- return std::make_pair(last_channel_id_, &iter->second);
- }
- }
-}
-
-Status<void> Endpoint::ReenableEpollEvent(const BorrowedHandle& fd) {
- epoll_event event;
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
- event.data.fd = fd.Get();
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, fd.Get(), &event) < 0) {
- ALOGE(
- "Endpoint::ReenableEpollEvent: Failed to re-enable channel to "
- "endpoint: %s\n",
- strerror(errno));
- return ErrorStatus(errno);
- }
- return {};
-}
-
-Status<void> Endpoint::CloseChannel(int channel_id) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- return CloseChannelLocked(channel_id);
-}
-
-Status<void> Endpoint::CloseChannelLocked(int32_t channel_id) {
- ALOGD_IF(TRACE, "Endpoint::CloseChannelLocked: channel_id=%d", channel_id);
-
- auto iter = channels_.find(channel_id);
- if (iter == channels_.end())
- return ErrorStatus{EINVAL};
-
- int channel_fd = iter->second.data_fd.Get();
- Status<void> status;
- epoll_event ee; // See BUGS in man 2 epoll_ctl.
- if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, channel_fd, &ee) < 0) {
- status.SetError(errno);
- ALOGE(
- "Endpoint::CloseChannelLocked: Failed to remove channel from endpoint: "
- "%s\n",
- strerror(errno));
- } else {
- status.SetValue();
- }
-
- channel_fd_to_id_.erase(channel_fd);
- channels_.erase(iter);
- return status;
-}
-
-Status<void> Endpoint::ModifyChannelEvents(int channel_id, int clear_mask,
- int set_mask) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
-
- auto search = channels_.find(channel_id);
- if (search != channels_.end()) {
- auto& channel_data = search->second;
- channel_data.event_set.ModifyEvents(clear_mask, set_mask);
- return {};
- }
-
- return ErrorStatus{EINVAL};
-}
-
-Status<void> Endpoint::CreateChannelSocketPair(LocalHandle* local_socket,
- LocalHandle* remote_socket) {
- Status<void> status;
- char* endpoint_context = nullptr;
- // Make sure the channel socket has the correct SELinux label applied.
- // Here we get the label from the endpoint file descriptor, which should be
- // something like "u:object_r:pdx_service_endpoint_socket:s0" and replace
- // "endpoint" with "channel" to produce the channel label such as this:
- // "u:object_r:pdx_service_channel_socket:s0".
- if (fgetfilecon_raw(socket_fd_.Get(), &endpoint_context) > 0) {
- std::string channel_context = endpoint_context;
- freecon(endpoint_context);
- const std::string suffix = "_endpoint_socket";
- auto pos = channel_context.find(suffix);
- if (pos != std::string::npos) {
- channel_context.replace(pos, suffix.size(), "_channel_socket");
- } else {
- ALOGW(
- "Endpoint::CreateChannelSocketPair: Endpoint security context '%s' "
- "does not contain expected substring '%s'",
- channel_context.c_str(), suffix.c_str());
- }
- ALOGE_IF(setsockcreatecon_raw(channel_context.c_str()) == -1,
- "Endpoint::CreateChannelSocketPair: Failed to set channel socket "
- "security context: %s",
- strerror(errno));
- } else {
- ALOGE(
- "Endpoint::CreateChannelSocketPair: Failed to obtain the endpoint "
- "socket's security context: %s",
- strerror(errno));
- }
-
- int channel_pair[2] = {};
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, channel_pair) == -1) {
- ALOGE("Endpoint::CreateChannelSocketPair: Failed to create socket pair: %s",
- strerror(errno));
- status.SetError(errno);
- return status;
- }
-
- setsockcreatecon_raw(nullptr);
-
- local_socket->Reset(channel_pair[0]);
- remote_socket->Reset(channel_pair[1]);
-
- int optval = 1;
- if (setsockopt(local_socket->Get(), SOL_SOCKET, SO_PASSCRED, &optval,
- sizeof(optval)) == -1) {
- ALOGE(
- "Endpoint::CreateChannelSocketPair: Failed to enable the receiving of "
- "the credentials for channel %d: %s",
- local_socket->Get(), strerror(errno));
- status.SetError(errno);
- }
- return status;
-}
-
-Status<RemoteChannelHandle> Endpoint::PushChannel(Message* message,
- int /*flags*/,
- Channel* channel,
- int* channel_id) {
- LocalHandle local_socket;
- LocalHandle remote_socket;
- auto status = CreateChannelSocketPair(&local_socket, &remote_socket);
- if (!status)
- return status.error_status();
-
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- auto channel_data_status =
- OnNewChannelLocked(std::move(local_socket), channel);
- if (!channel_data_status)
- return channel_data_status.error_status();
-
- ChannelData* channel_data;
- std::tie(*channel_id, channel_data) = channel_data_status.take();
-
- // Flags are ignored for now.
- // TODO(xiaohuit): Implement those.
-
- auto* state = static_cast<MessageState*>(message->GetState());
- Status<ChannelReference> ref = state->PushChannelHandle(
- remote_socket.Borrow(), channel_data->event_set.pollin_event_fd(),
- channel_data->event_set.pollhup_event_fd());
- if (!ref)
- return ref.error_status();
- state->sockets_to_close.push_back(std::move(remote_socket));
- return RemoteChannelHandle{ref.get()};
-}
-
-Status<int> Endpoint::CheckChannel(const Message* /*message*/,
- ChannelReference /*ref*/,
- Channel** /*channel*/) {
- // TODO(xiaohuit): Implement this.
- return ErrorStatus(EFAULT);
-}
-
-Channel* Endpoint::GetChannelState(int32_t channel_id) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- auto channel_data = channels_.find(channel_id);
- return (channel_data != channels_.end()) ? channel_data->second.channel_state
- : nullptr;
-}
-
-BorrowedHandle Endpoint::GetChannelSocketFd(int32_t channel_id) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- BorrowedHandle handle;
- auto channel_data = channels_.find(channel_id);
- if (channel_data != channels_.end())
- handle = channel_data->second.data_fd.Borrow();
- return handle;
-}
-
-Status<std::pair<BorrowedHandle, BorrowedHandle>> Endpoint::GetChannelEventFd(
- int32_t channel_id) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- auto channel_data = channels_.find(channel_id);
- if (channel_data != channels_.end()) {
- return {{channel_data->second.event_set.pollin_event_fd(),
- channel_data->second.event_set.pollhup_event_fd()}};
- }
- return ErrorStatus(ENOENT);
-}
-
-int32_t Endpoint::GetChannelId(const BorrowedHandle& channel_fd) {
- std::lock_guard<std::mutex> autolock(channel_mutex_);
- auto iter = channel_fd_to_id_.find(channel_fd.Get());
- return (iter != channel_fd_to_id_.end()) ? iter->second : -1;
-}
-
-Status<void> Endpoint::ReceiveMessageForChannel(
- const BorrowedHandle& channel_fd, Message* message) {
- RequestHeader<LocalHandle> request;
- int32_t channel_id = GetChannelId(channel_fd);
- auto status = ReceiveData(channel_fd.Borrow(), &request);
- if (!status) {
- if (status.error() == ESHUTDOWN) {
- BuildCloseMessage(channel_id, message);
- return {};
- } else {
- CloseChannel(channel_id);
- return status;
- }
- }
-
- MessageInfo info;
- info.pid = request.cred.pid;
- info.tid = -1;
- info.cid = channel_id;
- info.mid = request.is_impulse ? Message::IMPULSE_MESSAGE_ID
- : GetNextAvailableMessageId();
- info.euid = request.cred.uid;
- info.egid = request.cred.gid;
- info.op = request.op;
- info.flags = 0;
- info.service = service_;
- info.channel = GetChannelState(channel_id);
- if (info.channel != nullptr) {
- info.channel->SetActiveProcessId(request.cred.pid);
- }
- info.send_len = request.send_len;
- info.recv_len = request.max_recv_len;
- info.fd_count = request.file_descriptors.size();
- static_assert(sizeof(info.impulse) == request.impulse_payload.size(),
- "Impulse payload sizes must be the same in RequestHeader and "
- "MessageInfo");
- memcpy(info.impulse, request.impulse_payload.data(),
- request.impulse_payload.size());
- *message = Message{info};
- auto* state = static_cast<MessageState*>(message->GetState());
- state->request = std::move(request);
- if (state->request.send_len > 0 && !state->request.is_impulse) {
- state->request_data.resize(state->request.send_len);
- status = ReceiveData(channel_fd, state->request_data.data(),
- state->request_data.size());
- }
-
- if (status && state->request.is_impulse)
- status = ReenableEpollEvent(channel_fd);
-
- if (!status) {
- if (status.error() == ESHUTDOWN) {
- BuildCloseMessage(channel_id, message);
- return {};
- } else {
- CloseChannel(channel_id);
- return status;
- }
- }
-
- return status;
-}
-
-void Endpoint::BuildCloseMessage(int32_t channel_id, Message* message) {
- ALOGD_IF(TRACE, "Endpoint::BuildCloseMessage: channel_id=%d", channel_id);
- MessageInfo info;
- info.pid = -1;
- info.tid = -1;
- info.cid = channel_id;
- info.mid = GetNextAvailableMessageId();
- info.euid = -1;
- info.egid = -1;
- info.op = opcodes::CHANNEL_CLOSE;
- info.flags = 0;
- info.service = service_;
- info.channel = GetChannelState(channel_id);
- info.send_len = 0;
- info.recv_len = 0;
- info.fd_count = 0;
- *message = Message{info};
-}
-
-Status<void> Endpoint::MessageReceive(Message* message) {
- // Receive at most one event from the epoll set. This should prevent multiple
- // dispatch threads from attempting to handle messages on the same socket at
- // the same time.
- epoll_event event;
- int count = RETRY_EINTR(
- epoll_wait(epoll_fd_.Get(), &event, 1, is_blocking_ ? -1 : 0));
- if (count < 0) {
- ALOGE("Endpoint::MessageReceive: Failed to wait for epoll events: %s\n",
- strerror(errno));
- return ErrorStatus{errno};
- } else if (count == 0) {
- return ErrorStatus{ETIMEDOUT};
- }
-
- if (event.data.fd == cancel_event_fd_.Get()) {
- return ErrorStatus{ESHUTDOWN};
- }
-
- if (socket_fd_ && event.data.fd == socket_fd_.Get()) {
- auto status = AcceptConnection(message);
- auto reenable_status = ReenableEpollEvent(socket_fd_.Borrow());
- if (!reenable_status)
- return reenable_status;
- return status;
- }
-
- BorrowedHandle channel_fd{event.data.fd};
- return ReceiveMessageForChannel(channel_fd, message);
-}
-
-Status<void> Endpoint::MessageReply(Message* message, int return_code) {
- const int32_t channel_id = message->GetChannelId();
- auto channel_socket = GetChannelSocketFd(channel_id);
- if (!channel_socket)
- return ErrorStatus{EBADF};
-
- auto* state = static_cast<MessageState*>(message->GetState());
- switch (message->GetOp()) {
- case opcodes::CHANNEL_CLOSE:
- return CloseChannel(channel_id);
-
- case opcodes::CHANNEL_OPEN:
- if (return_code < 0) {
- return CloseChannel(channel_id);
- } else {
- // Open messages do not have a payload and may not transfer any channels
- // or file descriptors on behalf of the service.
- state->response_data.clear();
- state->response.file_descriptors.clear();
- state->response.channels.clear();
-
- // Return the channel event-related fds in a single ChannelInfo entry
- // with an empty data_fd member.
- auto status = GetChannelEventFd(channel_id);
- if (!status)
- return status.error_status();
-
- auto handles = status.take();
- state->response.channels.push_back({BorrowedHandle(),
- std::move(handles.first),
- std::move(handles.second)});
- return_code = 0;
- }
- break;
- }
-
- state->response.ret_code = return_code;
- state->response.recv_len = state->response_data.size();
- auto status = SendData(channel_socket, state->response);
- if (status && !state->response_data.empty()) {
- status = SendData(channel_socket, state->response_data.data(),
- state->response_data.size());
- }
-
- if (status)
- status = ReenableEpollEvent(channel_socket);
-
- return status;
-}
-
-Status<void> Endpoint::MessageReplyFd(Message* message, unsigned int push_fd) {
- auto* state = static_cast<MessageState*>(message->GetState());
- auto ref = state->PushFileHandle(BorrowedHandle{static_cast<int>(push_fd)});
- if (!ref)
- return ref.error_status();
- return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
- Message* message, const LocalChannelHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- auto ref = state->PushChannelHandle(handle.Borrow());
- if (!ref)
- return ref.error_status();
- return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- auto ref = state->PushChannelHandle(handle.Duplicate());
- if (!ref)
- return ref.error_status();
- return MessageReply(message, ref.get());
-}
-
-Status<void> Endpoint::MessageReplyChannelHandle(
- Message* message, const RemoteChannelHandle& handle) {
- return MessageReply(message, handle.value());
-}
-
-Status<size_t> Endpoint::ReadMessageData(Message* message, const iovec* vector,
- size_t vector_length) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->ReadData(vector, vector_length);
-}
-
-Status<size_t> Endpoint::WriteMessageData(Message* message, const iovec* vector,
- size_t vector_length) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->WriteData(vector, vector_length);
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* message,
- const LocalHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->PushFileHandle(handle.Borrow());
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* message,
- const BorrowedHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->PushFileHandle(handle.Duplicate());
-}
-
-Status<FileReference> Endpoint::PushFileHandle(Message* /*message*/,
- const RemoteHandle& handle) {
- return handle.Get();
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
- Message* message, const LocalChannelHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->PushChannelHandle(handle.Borrow());
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
- Message* message, const BorrowedChannelHandle& handle) {
- auto* state = static_cast<MessageState*>(message->GetState());
- return state->PushChannelHandle(handle.Duplicate());
-}
-
-Status<ChannelReference> Endpoint::PushChannelHandle(
- Message* /*message*/, const RemoteChannelHandle& handle) {
- return handle.value();
-}
-
-LocalHandle Endpoint::GetFileHandle(Message* message, FileReference ref) const {
- LocalHandle handle;
- auto* state = static_cast<MessageState*>(message->GetState());
- state->GetLocalFileHandle(ref, &handle);
- return handle;
-}
-
-LocalChannelHandle Endpoint::GetChannelHandle(Message* message,
- ChannelReference ref) const {
- LocalChannelHandle handle;
- auto* state = static_cast<MessageState*>(message->GetState());
- state->GetLocalChannelHandle(ref, &handle);
- return handle;
-}
-
-Status<void> Endpoint::Cancel() {
- if (eventfd_write(cancel_event_fd_.Get(), 1) < 0)
- return ErrorStatus{errno};
- return {};
-}
-
-std::unique_ptr<Endpoint> Endpoint::Create(const std::string& endpoint_path,
- mode_t /*unused_mode*/,
- bool blocking) {
- return std::unique_ptr<Endpoint>(new Endpoint(endpoint_path, blocking));
-}
-
-std::unique_ptr<Endpoint> Endpoint::CreateAndBindSocket(
- const std::string& endpoint_path, bool blocking) {
- return std::unique_ptr<Endpoint>(
- new Endpoint(endpoint_path, blocking, false));
-}
-
-std::unique_ptr<Endpoint> Endpoint::CreateFromSocketFd(LocalHandle socket_fd) {
- return std::unique_ptr<Endpoint>(new Endpoint(std::move(socket_fd)));
-}
-
-Status<void> Endpoint::RegisterNewChannelForTests(LocalHandle channel_fd) {
- int optval = 1;
- if (setsockopt(channel_fd.Get(), SOL_SOCKET, SO_PASSCRED, &optval,
- sizeof(optval)) == -1) {
- ALOGE(
- "Endpoint::RegisterNewChannelForTests: Failed to enable the receiving"
- "of the credentials for channel %d: %s",
- channel_fd.Get(), strerror(errno));
- return ErrorStatus(errno);
- }
- return OnNewChannel(std::move(channel_fd));
-}
-
-} // namespace uds
-} // namespace pdx
-} // namespace android
diff --git a/libs/vr/libpdx_uds/service_framework_tests.cpp b/libs/vr/libpdx_uds/service_framework_tests.cpp
deleted file mode 100644
index 2742716..0000000
--- a/libs/vr/libpdx_uds/service_framework_tests.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-#include <errno.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <unistd.h>
-
-#include <array>
-#include <atomic>
-#include <memory>
-#include <numeric>
-#include <string>
-#include <thread>
-
-#include <gtest/gtest.h>
-#include <pdx/channel_handle.h>
-#include <pdx/client.h>
-#include <pdx/file_handle.h>
-#include <pdx/service.h>
-#include <pdx/service_dispatcher.h>
-#include <private/android_filesystem_config.h>
-#include <uds/client_channel.h>
-#include <uds/client_channel_factory.h>
-#include <uds/service_endpoint.h>
-
-using android::pdx::BorrowedChannelHandle;
-using android::pdx::Channel;
-using android::pdx::ChannelReference;
-using android::pdx::ClientBase;
-using android::pdx::ErrorStatus;
-using android::pdx::LocalChannelHandle;
-using android::pdx::LocalHandle;
-using android::pdx::Message;
-using android::pdx::MessageInfo;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::ServiceBase;
-using android::pdx::ServiceDispatcher;
-using android::pdx::Status;
-using android::pdx::Transaction;
-using android::pdx::uds::Endpoint;
-
-namespace {
-
-const size_t kLargeDataSize = 100000;
-
-const char kTestServicePath[] = "socket_test";
-const char kTestService1[] = "1";
-const char kTestService2[] = "2";
-
-enum test_op_codes {
- TEST_OP_GET_SERVICE_ID,
- TEST_OP_SET_TEST_CHANNEL,
- TEST_OP_GET_THIS_CHANNEL_ID,
- TEST_OP_GET_TEST_CHANNEL_ID,
- TEST_OP_CHECK_CHANNEL_ID,
- TEST_OP_CHECK_CHANNEL_OBJECT,
- TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE,
- TEST_OP_GET_NEW_CHANNEL,
- TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE,
- TEST_OP_GET_THIS_PROCESS_ID,
- TEST_OP_GET_THIS_THREAD_ID,
- TEST_OP_GET_THIS_EUID,
- TEST_OP_GET_THIS_EGID,
- TEST_OP_IMPULSE,
- TEST_OP_POLLHUP_FROM_SERVICE,
- TEST_OP_POLLIN_FROM_SERVICE,
- TEST_OP_SEND_LARGE_DATA_RETURN_SUM,
-};
-
-using ImpulsePayload = std::array<std::uint8_t, sizeof(MessageInfo::impulse)>;
-
-// The test service creates a TestChannel for every client (channel) that
-// connects. This represents the service-side context for each client.
-class TestChannel : public Channel {
- public:
- explicit TestChannel(int channel_id) : channel_id_(channel_id) {}
-
- int channel_id() const { return channel_id_; }
-
- private:
- friend class TestService;
-
- int channel_id_;
-
- TestChannel(const TestChannel&) = delete;
- void operator=(const TestChannel&) = delete;
-};
-
-// Test service that creates a TestChannel for each channel and responds to test
-// messages.
-class TestService : public ServiceBase<TestService> {
- public:
- std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
- return std::make_shared<TestChannel>(message.GetChannelId());
- }
-
- void OnChannelClose(Message& /*message*/,
- const std::shared_ptr<Channel>& channel) override {
- if (test_channel_ == channel)
- test_channel_ = nullptr;
- }
-
- void HandleImpulse(Message& message) override {
- switch (message.GetOp()) {
- case TEST_OP_SET_TEST_CHANNEL:
- test_channel_ = message.GetChannel<TestChannel>();
- break;
-
- case TEST_OP_IMPULSE: {
- impulse_payload_.fill(0);
- std::copy(message.ImpulseBegin(), message.ImpulseEnd(),
- impulse_payload_.begin());
- break;
- }
-
- case TEST_OP_POLLHUP_FROM_SERVICE: {
- message.ModifyChannelEvents(0, EPOLLHUP);
- break;
- }
- }
- }
-
- Status<void> HandleMessage(Message& message) override {
- switch (message.GetOp()) {
- case TEST_OP_GET_SERVICE_ID:
- REPLY_MESSAGE_RETURN(message, service_id_, {});
-
- // Set the test channel to the TestChannel for the current channel. Other
- // messages can use this to perform tests.
- case TEST_OP_SET_TEST_CHANNEL:
- test_channel_ = message.GetChannel<TestChannel>();
- REPLY_MESSAGE_RETURN(message, 0, {});
-
- // Return the channel id for the current channel.
- case TEST_OP_GET_THIS_CHANNEL_ID:
- REPLY_MESSAGE_RETURN(message, message.GetChannelId(), {});
-
- // Return the channel id for the test channel.
- case TEST_OP_GET_TEST_CHANNEL_ID:
- if (test_channel_)
- REPLY_MESSAGE_RETURN(message, test_channel_->channel_id(), {});
- else
- REPLY_ERROR_RETURN(message, ENOENT, {});
-
- // Test check channel feature.
- case TEST_OP_CHECK_CHANNEL_ID: {
- ChannelReference ref = 0;
- if (!message.ReadAll(&ref, sizeof(ref)))
- REPLY_ERROR_RETURN(message, EIO, {});
-
- const Status<int> ret = message.CheckChannel<TestChannel>(ref, nullptr);
- REPLY_MESSAGE_RETURN(message, ret, {});
- }
-
- case TEST_OP_CHECK_CHANNEL_OBJECT: {
- std::shared_ptr<TestChannel> channel;
- ChannelReference ref = 0;
- if (!message.ReadAll(&ref, sizeof(ref)))
- REPLY_ERROR_RETURN(message, EIO, {});
-
- const Status<int> ret =
- message.CheckChannel<TestChannel>(ref, &channel);
- if (!ret)
- REPLY_MESSAGE_RETURN(message, ret, {});
-
- if (channel != nullptr)
- REPLY_MESSAGE_RETURN(message, channel->channel_id(), {});
- else
- REPLY_ERROR_RETURN(message, ENODATA, {});
- }
-
- case TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE: {
- ChannelReference ref = 0;
- if (!message.ReadAll(&ref, sizeof(ref)))
- REPLY_ERROR_RETURN(message, EIO, {});
-
- const Status<int> ret = message.CheckChannel<TestChannel>(
- other_service_.get(), ref, nullptr);
- REPLY_MESSAGE_RETURN(message, ret, {});
- }
-
- case TEST_OP_GET_NEW_CHANNEL: {
- auto channel = std::make_shared<TestChannel>(-1);
- Status<RemoteChannelHandle> channel_handle =
- message.PushChannel(0, channel, &channel->channel_id_);
- REPLY_MESSAGE_RETURN(message, channel_handle, {});
- }
-
- case TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE: {
- if (!other_service_)
- REPLY_ERROR_RETURN(message, EINVAL, {});
-
- auto channel = std::make_shared<TestChannel>(-1);
- Status<RemoteChannelHandle> channel_handle = message.PushChannel(
- other_service_.get(), 0, channel, &channel->channel_id_);
- REPLY_MESSAGE_RETURN(message, channel_handle, {});
- }
-
- case TEST_OP_GET_THIS_PROCESS_ID:
- REPLY_MESSAGE_RETURN(message, message.GetProcessId(), {});
-
- case TEST_OP_GET_THIS_THREAD_ID:
- REPLY_MESSAGE_RETURN(message, message.GetThreadId(), {});
-
- case TEST_OP_GET_THIS_EUID:
- REPLY_MESSAGE_RETURN(message, message.GetEffectiveUserId(), {});
-
- case TEST_OP_GET_THIS_EGID:
- REPLY_MESSAGE_RETURN(message, message.GetEffectiveGroupId(), {});
-
- case TEST_OP_POLLIN_FROM_SERVICE:
- REPLY_MESSAGE_RETURN(message, message.ModifyChannelEvents(0, EPOLLIN),
- {});
-
- case TEST_OP_SEND_LARGE_DATA_RETURN_SUM: {
- std::array<int, kLargeDataSize> data_array;
- size_t size_to_read = data_array.size() * sizeof(int);
- if (!message.ReadAll(data_array.data(), size_to_read)) {
- REPLY_ERROR_RETURN(message, EIO, {});
- }
- int sum = std::accumulate(data_array.begin(), data_array.end(), 0);
- REPLY_MESSAGE_RETURN(message, sum, {});
- }
-
- default:
- return Service::DefaultHandleMessage(message);
- }
- }
-
- const ImpulsePayload& GetImpulsePayload() const { return impulse_payload_; }
-
- private:
- friend BASE;
-
- std::shared_ptr<TestChannel> test_channel_;
- std::shared_ptr<TestService> other_service_;
- int service_id_;
- ImpulsePayload impulse_payload_;
-
- static std::atomic<int> service_counter_;
-
- TestService(const std::string& name,
- const std::shared_ptr<TestService>& other_service)
- : TestService(name, other_service, false) {}
-
- TestService(const std::string& name,
- const std::shared_ptr<TestService>& other_service, bool blocking)
- : BASE(std::string("TestService") + name,
- Endpoint::CreateAndBindSocket(kTestServicePath + name, blocking)),
- other_service_(other_service),
- service_id_(service_counter_++) {}
-
- explicit TestService(const std::string& name) : TestService(name, nullptr) {}
-
- TestService(const TestService&) = delete;
- void operator=(const TestService&) = delete;
-};
-
-std::atomic<int> TestService::service_counter_;
-
-// Test client to send messages to the test service.
-class TestClient : public ClientBase<TestClient> {
- public:
- // Requests the service id of the service this channel is connected to.
- int GetServiceId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_SERVICE_ID));
- }
-
- // Requests the test channel to be set to this client's channel.
- int SetTestChannel() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_SET_TEST_CHANNEL));
- }
-
- // Request the test channel to be set to this client's channel using an async
- // message.
- int SetTestChannelAsync() {
- return ReturnStatusOrError(SendImpulse(TEST_OP_SET_TEST_CHANNEL));
- }
-
- // Sends a test async message with payload.
- int SendAsync(const void* buffer, size_t length) {
- Transaction trans{*this};
- return ReturnStatusOrError(SendImpulse(TEST_OP_IMPULSE, buffer, length));
- }
-
- // Requests the channel id for this client.
- int GetThisChannelId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_CHANNEL_ID));
- }
-
- // Requests the channel id of the test channel.
- int GetTestChannelId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_TEST_CHANNEL_ID));
- }
-
- // Checks whether the fd |channel_id| is a channel to the test service.
- // Returns the channel id of the channel.
- int CheckChannelIdArgument(BorrowedChannelHandle channel) {
- Transaction trans{*this};
- ChannelReference ref = trans.PushChannelHandle(channel).get();
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_ID, &ref,
- sizeof(ref), nullptr, 0));
- }
-
- // Checks whether the fd |channel_id| is a channel to the test service.
- // Returns the channel id of the channel exercising the context pointer.
- int CheckChannelObjectArgument(BorrowedChannelHandle channel) {
- Transaction trans{*this};
- ChannelReference ref = trans.PushChannelHandle(channel).get();
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_OBJECT,
- &ref, sizeof(ref), nullptr, 0));
- }
-
- // Checks whether the fd |channel_fd| is a channel to the other test service.
- // Returns 0 on success.
- int CheckChannelFromOtherService(BorrowedChannelHandle channel) {
- Transaction trans{*this};
- ChannelReference ref = trans.PushChannelHandle(channel).get();
- return ReturnStatusOrError(
- trans.Send<int>(TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE, &ref,
- sizeof(ref), nullptr, 0));
- }
-
- // Requests a new channel to the service.
- std::unique_ptr<TestClient> GetNewChannel() {
- Transaction trans{*this};
- auto status = trans.Send<LocalChannelHandle>(TEST_OP_GET_NEW_CHANNEL);
- if (status)
- return TestClient::Create(status.take());
- else
- return nullptr;
- }
-
- // Requests a new channel to the other service.
- std::unique_ptr<TestClient> GetNewChannelFromOtherService() {
- Transaction trans{*this};
- auto status = trans.Send<LocalChannelHandle>(
- TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE);
- if (status)
- return TestClient::Create(status.take());
- else
- return nullptr;
- }
-
- // Requests an id from the message description.
- pid_t GetThisProcessId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_PROCESS_ID));
- }
- pid_t GetThisThreadId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_THREAD_ID));
- }
- uid_t GetThisEffectiveUserId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EUID));
- }
- gid_t GetThisEffectiveGroupId() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EGID));
- }
-
- int SendPollHupEvent() {
- return ReturnStatusOrError(SendImpulse(TEST_OP_POLLHUP_FROM_SERVICE));
- }
-
- int SendPollInEvent() {
- Transaction trans{*this};
- return ReturnStatusOrError(trans.Send<int>(TEST_OP_POLLIN_FROM_SERVICE));
- }
-
- int SendLargeDataReturnSum(
- const std::array<int, kLargeDataSize>& data_array) {
- Transaction trans{*this};
- return ReturnStatusOrError(
- trans.Send<int>(TEST_OP_SEND_LARGE_DATA_RETURN_SUM, data_array.data(),
- data_array.size() * sizeof(int), nullptr, 0));
- }
-
- Status<int> GetEventMask(int events) {
- if (auto* client_channel = GetChannel()) {
- return client_channel->GetEventMask(events);
- } else {
- return ErrorStatus(EINVAL);
- }
- }
-
- using ClientBase<TestClient>::event_fd;
-
- enum : size_t { kMaxPayload = MAX_IMPULSE_LENGTH };
-
- private:
- friend BASE;
-
- explicit TestClient(const std::string& name)
- : BASE{android::pdx::uds::ClientChannelFactory::Create(kTestServicePath +
- name)} {}
-
- explicit TestClient(LocalChannelHandle channel)
- : BASE{android::pdx::uds::ClientChannel::Create(std::move(channel))} {}
-
- TestClient(const TestClient&) = delete;
- void operator=(const TestClient&) = delete;
-};
-
-} // anonymous namespace
-
-// Use a test fixture to ensure proper order of cleanup between clients,
-// services, and the dispatcher. These objects are cleaned up in the same
-// thread, order is important; either the service or the client must be
-// destroyed before the dispatcher is stopped. The reason for this is that
-// clients send blocking "close" messages to their respective services on
-// destruction. If this happens after the dispatcher is stopped the client
-// destructor will get blocked waiting for a reply that will never come. In
-// normal use of the service framework this is never an issue because clients
-// and the dispatcher for the same service are never destructed in the same
-// thread (they live in different processes).
-class ServiceFrameworkTest : public ::testing::Test {
- protected:
- std::unique_ptr<ServiceDispatcher> dispatcher_;
- std::thread dispatch_thread_;
-
- void SetUp() override {
- // Create a dispatcher to handle messages to services.
- dispatcher_ = android::pdx::ServiceDispatcher::Create();
- ASSERT_NE(nullptr, dispatcher_);
-
- // Start the message dispatch loop in a separate thread.
- dispatch_thread_ = std::thread(
- std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
- }
-
- void TearDown() override {
- if (dispatcher_) {
- // Cancel the dispatcher and wait for the thread to terminate. Explicitly
- // join the thread so that destruction doesn't deallocate the dispatcher
- // before the thread finishes.
- dispatcher_->SetCanceled(true);
- dispatch_thread_.join();
- }
- }
-};
-
-// Test basic operation of TestService/TestClient classes.
-TEST_F(ServiceFrameworkTest, BasicClientService) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- // Get the channel id that will be returned by the next tests.
- const int channel_id = client->GetThisChannelId();
- EXPECT_LE(0, channel_id);
-
- // Check return value before test channel is set.
- EXPECT_EQ(-ENOENT, client->GetTestChannelId());
-
- // Set test channel and perform the test again.
- EXPECT_EQ(0, client->SetTestChannel());
- EXPECT_EQ(channel_id, client->GetTestChannelId());
-}
-
-// Test impulses.
-TEST_F(ServiceFrameworkTest, Impulse) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- // Get the channel id that will be returned by the next tests.
- const int channel_id = client->GetThisChannelId();
- EXPECT_LE(0, channel_id);
-
- // Check return value before test channel is set.
- EXPECT_EQ(-ENOENT, client->GetTestChannelId());
-
- // Set test channel with an impulse and perform the test again.
- EXPECT_EQ(0, client->SetTestChannelAsync());
- EXPECT_EQ(channel_id, client->GetTestChannelId());
-
- ImpulsePayload expected_payload = {{'a', 'b', 'c'}};
- EXPECT_EQ(0, client->SendAsync(expected_payload.data(), 3));
- // Send a synchronous message to make sure the async message is handled before
- // we check the payload.
- client->GetThisChannelId();
- EXPECT_EQ(expected_payload, service->GetImpulsePayload());
-
- // Impulse payloads are limited to 4 machine words.
- EXPECT_EQ(
- 0, client->SendAsync(expected_payload.data(), TestClient::kMaxPayload));
- EXPECT_EQ(-EINVAL, client->SendAsync(expected_payload.data(),
- TestClient::kMaxPayload + 1));
-
- // Test invalid pointer.
- const std::uint8_t* invalid_pointer = nullptr;
- EXPECT_EQ(-EINVAL, client->SendAsync(invalid_pointer, sizeof(int)));
-}
-
-// Test impulses.
-TEST_F(ServiceFrameworkTest, ImpulseHangup) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- const int kMaxIterations = 1000;
- for (int i = 0; i < kMaxIterations; i++) {
- auto impulse_client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, impulse_client);
-
- const uint8_t a = (i >> 0) & 0xff;
- const uint8_t b = (i >> 8) & 0xff;
- const uint8_t c = (i >> 16) & 0xff;
- const uint8_t d = (i >> 24) & 0xff;
- ImpulsePayload expected_payload = {{a, b, c, d}};
- EXPECT_EQ(0, impulse_client->SendAsync(expected_payload.data(), 4));
-
- // Hangup the impulse test client, then send a sync message over client to
- // make sure the hangup message is handled before checking the impulse
- // payload.
- impulse_client = nullptr;
- client->GetThisChannelId();
- EXPECT_EQ(expected_payload, service->GetImpulsePayload());
- }
-}
-
-// Test Message::PushChannel/Service::PushChannel API.
-TEST_F(ServiceFrameworkTest, PushChannel) {
- // Create a test service and add it to the dispatcher.
- auto other_service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, other_service);
- ASSERT_EQ(0, dispatcher_->AddService(other_service));
-
- // Create a second test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService2, other_service);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to the second test service.
- auto client1 = TestClient::Create(kTestService2);
- ASSERT_NE(nullptr, client1);
-
- // Test the creation of new channels using the push APIs.
- const int channel_id1 = client1->GetThisChannelId();
- EXPECT_LE(0, channel_id1);
-
- auto client2 = client1->GetNewChannel();
- EXPECT_NE(nullptr, client2);
- EXPECT_NE(client1->event_fd(), client2->event_fd());
-
- const int channel_id2 = client2->GetThisChannelId();
- EXPECT_LE(0, channel_id2);
- EXPECT_NE(channel_id1, channel_id2);
-
- auto client3 = client1->GetNewChannelFromOtherService();
- EXPECT_NE(nullptr, client3);
- EXPECT_NE(client1->event_fd(), client3->event_fd());
-
- const int channel_id3 = client3->GetThisChannelId();
- EXPECT_LE(0, channel_id3);
-
- // Test which services the channels are connected to.
- const int service_id1 = client1->GetServiceId();
- EXPECT_LE(0, service_id1);
-
- const int service_id2 = client2->GetServiceId();
- EXPECT_LE(0, service_id2);
-
- const int service_id3 = client3->GetServiceId();
- EXPECT_LE(0, service_id3);
-
- EXPECT_EQ(service_id1, service_id2);
- EXPECT_NE(service_id1, service_id3);
-}
-
-// Tests process id, thread id, effective user id, and effective group id
-// returned in the message description.
-TEST_F(ServiceFrameworkTest, Ids) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- // Pids 0-2 are defined, no user task should have them.
-
- const pid_t process_id1 = client->GetThisProcessId();
- EXPECT_LT(2, process_id1);
-
- pid_t process_id2;
-
- std::thread thread([&]() { process_id2 = client->GetThisProcessId(); });
- thread.join();
-
- EXPECT_LT(2, process_id2);
- EXPECT_EQ(process_id1, process_id2);
-
- // This test must run as root for the rest of these tests to work.
- const int euid1 = client->GetThisEffectiveUserId();
- ASSERT_EQ(0, euid1);
-
- const int egid1 = client->GetThisEffectiveGroupId();
- EXPECT_EQ(0, egid1);
-
- // Set effective uid/gid to system.
- ASSERT_EQ(0, setegid(AID_SYSTEM));
- ASSERT_EQ(0, seteuid(AID_SYSTEM));
-
- const int euid2 = client->GetThisEffectiveUserId();
- EXPECT_EQ(AID_SYSTEM, euid2);
-
- const int egid2 = client->GetThisEffectiveGroupId();
- EXPECT_EQ(AID_SYSTEM, egid2);
-
- // Set the euid/egid back to root.
- ASSERT_EQ(0, setegid(0));
- ASSERT_EQ(0, seteuid(0));
-}
-
-TEST_F(ServiceFrameworkTest, PollIn) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- pollfd pfd{client->event_fd(), POLLIN, 0};
- int count = poll(&pfd, 1, 0);
- ASSERT_EQ(0, count);
-
- client->SendPollInEvent();
-
- count = poll(&pfd, 1, 10000 /*10s*/);
- ASSERT_EQ(1, count);
- ASSERT_TRUE((POLLIN & pfd.revents) != 0);
-}
-
-TEST_F(ServiceFrameworkTest, PollHup) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- pollfd pfd{client->event_fd(), POLLIN, 0};
- int count = poll(&pfd, 1, 0);
- ASSERT_EQ(0, count);
-
- client->SendPollHupEvent();
-
- count = poll(&pfd, 1, 10000 /*10s*/);
- ASSERT_EQ(1, count);
- auto event_status = client->GetEventMask(pfd.revents);
- ASSERT_TRUE(event_status.ok());
- ASSERT_TRUE((EPOLLHUP & event_status.get()) != 0);
-}
-
-TEST_F(ServiceFrameworkTest, LargeDataSum) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- std::array<int, kLargeDataSize> data_array;
- std::iota(data_array.begin(), data_array.end(), 0);
- int expected_sum = std::accumulate(data_array.begin(), data_array.end(), 0);
- int sum = client->SendLargeDataReturnSum(data_array);
- ASSERT_EQ(expected_sum, sum);
-}
-
-TEST_F(ServiceFrameworkTest, Cancel) {
- // Create a test service and add it to the dispatcher.
- auto service = TestService::Create(kTestService1, nullptr, true);
- ASSERT_NE(nullptr, service);
- ASSERT_EQ(0, dispatcher_->AddService(service));
-
- // Create a client to service.
- auto client = TestClient::Create(kTestService1);
- ASSERT_NE(nullptr, client);
-
- auto previous_time = std::chrono::system_clock::now();
- dispatcher_->ReceiveAndDispatch(100); // 0.1 seconds should block.
- auto time = std::chrono::system_clock::now();
- ASSERT_LE(100, std::chrono::duration_cast<std::chrono::milliseconds>(
- time - previous_time)
- .count());
- service->Cancel();
- // Non-blocking. Return immediately.
- dispatcher_->ReceiveAndDispatch(-1);
- dispatcher_->ReceiveAndDispatch(-1);
-}
diff --git a/libs/vr/libperformance/Android.bp b/libs/vr/libperformance/Android.bp
deleted file mode 100644
index 38bf4ea..0000000
--- a/libs/vr/libperformance/Android.bp
+++ /dev/null
@@ -1,51 +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 = [
- "performance_client.cpp",
- "performance_rpc.cpp",
-]
-
-includeFiles = [ "include" ]
-
-sharedLibraries = [
- "libbase",
- "libbinder",
- "libcutils",
- "liblog",
- "libutils",
- "libpdx_default_transport",
-]
-
-cc_library {
- srcs: sourceFiles,
- cflags: [
- "-DLOG_TAG=\"libperformance\"",
- "-DTRACE=0",
- "-Wall",
- "-Werror",
- ],
- export_include_dirs: includeFiles,
- shared_libs: sharedLibraries,
- name: "libperformance",
-}
diff --git a/libs/vr/libperformance/include/CPPLINT.cfg b/libs/vr/libperformance/include/CPPLINT.cfg
deleted file mode 100644
index 2f8a3c0..0000000
--- a/libs/vr/libperformance/include/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-build/header_guard
diff --git a/libs/vr/libperformance/include/dvr/performance_client_api.h b/libs/vr/libperformance/include/dvr/performance_client_api.h
deleted file mode 100644
index 9d617cb..0000000
--- a/libs/vr/libperformance/include/dvr/performance_client_api.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
-#define ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
-
-#include <stddef.h>
-#include <unistd.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/// Sets the scheduler policy for a task.
-///
-/// Sets the scheduler policy for a task to the class described by a semantic
-/// string.
-///
-/// Supported policies are device-specific.
-///
-/// @param task_id The task id of task to set the policy for. When task_id is 0
-/// the current task id is substituted.
-/// @param scheduler_policy NULL-terminated ASCII string containing the desired
-/// scheduler policy.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
-/// Sets the CPU partition for a task.
-///
-/// Sets the CPU partition for a task to the partition described by a CPU
-/// partition path.
-///
-/// TODO(eieio): Describe supported partitions and rules governing assignment.
-///
-/// @param task_id The task id of task to attach to a partition. When task_id is
-/// 0 the current task id is substituted.
-/// @param partition NULL-terminated ASCII string describing the CPU partition
-/// to attach the task to.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetCpuPartition(pid_t task_id, const char* partition);
-
-/// Sets the scheduler class for a task.
-///
-/// Sets the scheduler class for a task to the class described by a semantic
-/// string.
-///
-/// Supported classes for applications are: audio, graphics, normal, and
-/// background. Additional options following a ':' to be supported in the
-/// future.
-///
-/// @param task_id The task id of task to attach to a partition. When task_id is
-/// 0 the current task id is substituted.
-/// @param scheduler_class NULL-terminated ASCII string containing the desired
-/// scheduler class.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrSetSchedulerClass(pid_t task_id, const char* scheduler_class);
-
-/// Gets the CPU partition for a task.
-///
-/// Gets the CPU partition path for a task as a NULL-terminated ASCII string. If
-/// the path is too large to fit in the supplied buffer, -ENOBUFS is returned.
-///
-/// @param task_id The task id of the task to retrieve the partition for. When
-/// task_id is 0 the current task id is substituted.
-/// @param partition Pointer to an ASCII string buffer to store the partition
-/// path.
-/// @param size Size of the string buffer in bytes, including space for the NULL
-/// terminator.
-/// @returns Returns 0 on success or a negative errno error code on error.
-int dvrGetCpuPartition(pid_t task_id, char* partition, size_t size);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_PERFORMANCE_CLIENT_API_H_
diff --git a/libs/vr/libperformance/include/private/dvr/performance_client.h b/libs/vr/libperformance/include/private/dvr/performance_client.h
deleted file mode 100644
index 3bd90dc..0000000
--- a/libs/vr/libperformance/include/private/dvr/performance_client.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_CLIENT_H_
-#define ANDROID_DVR_PERFORMANCE_CLIENT_H_
-
-#include <sys/types.h>
-
-#include <cstddef>
-#include <string>
-#include <tuple>
-
-#include <pdx/client.h>
-
-namespace android {
-namespace dvr {
-
-class PerformanceClient : public pdx::ClientBase<PerformanceClient> {
- public:
- int SetSchedulerPolicy(pid_t task_id, const std::string& scheduler_policy);
- int SetSchedulerPolicy(pid_t task_id, const char* scheduler_policy);
-
- // TODO(eieio): Consider deprecating this API.
- int SetCpuPartition(pid_t task_id, const std::string& partition);
- int SetCpuPartition(pid_t task_id, const char* partition);
- int SetSchedulerClass(pid_t task_id, const std::string& scheduler_class);
- int SetSchedulerClass(pid_t task_id, const char* scheduler_class);
- int GetCpuPartition(pid_t task_id, std::string* partition_out);
- int GetCpuPartition(pid_t task_id, char* partition_out, std::size_t size);
-
- private:
- friend BASE;
-
- explicit PerformanceClient(int* error);
-
- PerformanceClient(const PerformanceClient&) = delete;
- void operator=(const PerformanceClient&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCE_CLIENT_H_
diff --git a/libs/vr/libperformance/include/private/dvr/performance_rpc.h b/libs/vr/libperformance/include/private/dvr/performance_rpc.h
deleted file mode 100644
index d57bbe8..0000000
--- a/libs/vr/libperformance/include/private/dvr/performance_rpc.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCE_RPC_H_
-#define ANDROID_DVR_PERFORMANCE_RPC_H_
-
-#include <sys/types.h>
-
-#include <string>
-
-#include <pdx/rpc/remote_method_type.h>
-
-namespace android {
-namespace dvr {
-
-// Performance Service RPC interface. Defines the endpoint paths, op codes, and
-// method type signatures supported by performanced.
-struct PerformanceRPC {
- // Service path.
- static constexpr char kClientPath[] = "system/performance/client";
-
- // Op codes.
- enum {
- kOpSetCpuPartition = 0,
- kOpSetSchedulerClass,
- kOpGetCpuPartition,
- kOpSetSchedulerPolicy,
- };
-
- // Methods.
- PDX_REMOTE_METHOD(SetCpuPartition, kOpSetCpuPartition,
- void(pid_t, const std::string&));
- PDX_REMOTE_METHOD(SetSchedulerClass, kOpSetSchedulerClass,
- void(pid_t, const std::string&));
- PDX_REMOTE_METHOD(GetCpuPartition, kOpGetCpuPartition, std::string(pid_t));
- PDX_REMOTE_METHOD(SetSchedulerPolicy, kOpSetSchedulerPolicy,
- void(pid_t, const std::string&));
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCE_RPC_H_
diff --git a/libs/vr/libperformance/performance_client.cpp b/libs/vr/libperformance/performance_client.cpp
deleted file mode 100644
index bf3726e..0000000
--- a/libs/vr/libperformance/performance_client.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-#include "include/private/dvr/performance_client.h"
-
-#include <sys/types.h>
-
-#include <pdx/default_transport/client_channel_factory.h>
-#include <pdx/rpc/remote_method.h>
-#include <pdx/rpc/string_wrapper.h>
-#include <private/dvr/performance_rpc.h>
-
-using android::pdx::rpc::WrapString;
-
-namespace android {
-namespace dvr {
-
-PerformanceClient::PerformanceClient(int* error)
- : BASE(pdx::default_transport::ClientChannelFactory::Create(
- PerformanceRPC::kClientPath)) {
- if (error)
- *error = Client::error();
-}
-
-int PerformanceClient::SetCpuPartition(pid_t task_id,
- const std::string& partition) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetCpuPartition>(task_id, partition));
-}
-
-int PerformanceClient::SetCpuPartition(pid_t task_id, const char* partition) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetCpuPartition>(
- task_id, WrapString(partition)));
-}
-
-int PerformanceClient::SetSchedulerPolicy(pid_t task_id,
- const std::string& scheduler_policy) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(task_id,
- scheduler_policy));
-}
-
-int PerformanceClient::SetSchedulerPolicy(pid_t task_id,
- const char* scheduler_policy) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(
- task_id, WrapString(scheduler_policy)));
-}
-
-int PerformanceClient::SetSchedulerClass(pid_t task_id,
- const std::string& scheduler_class) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetSchedulerClass>(task_id,
- scheduler_class));
-}
-
-int PerformanceClient::SetSchedulerClass(pid_t task_id,
- const char* scheduler_class) {
- if (task_id == 0)
- task_id = gettid();
-
- return ReturnStatusOrError(
- InvokeRemoteMethod<PerformanceRPC::SetSchedulerClass>(
- task_id, WrapString(scheduler_class)));
-}
-
-int PerformanceClient::GetCpuPartition(pid_t task_id,
- std::string* partition_out) {
- if (partition_out == nullptr)
- return -EINVAL;
-
- if (task_id == 0)
- task_id = gettid();
-
- auto status = InvokeRemoteMethodInPlace<PerformanceRPC::GetCpuPartition>(
- partition_out, task_id);
- return status ? 0 : -status.error();
-}
-
-int PerformanceClient::GetCpuPartition(pid_t task_id, char* partition_out,
- std::size_t size) {
- if (partition_out == nullptr)
- return -EINVAL;
-
- if (task_id == 0)
- task_id = gettid();
-
- auto wrapper = WrapString(partition_out, size);
- auto status = InvokeRemoteMethodInPlace<PerformanceRPC::GetCpuPartition>(
- &wrapper, task_id);
- if (!status)
- return -status.error();
-
- if (wrapper.size() < size)
- partition_out[wrapper.size()] = '\0';
-
- return 0;
-}
-
-} // namespace dvr
-} // namespace android
-
-extern "C" int dvrSetCpuPartition(pid_t task_id, const char* partition) {
- int error;
- if (auto client = android::dvr::PerformanceClient::Create(&error))
- return client->SetCpuPartition(task_id, partition);
- else
- return error;
-}
-
-extern "C" int dvrSetSchedulerPolicy(pid_t task_id,
- const char* scheduler_policy) {
- int error;
- if (auto client = android::dvr::PerformanceClient::Create(&error))
- return client->SetSchedulerPolicy(task_id, scheduler_policy);
- else
- return error;
-}
-
-extern "C" int dvrSetSchedulerClass(pid_t task_id,
- const char* scheduler_class) {
- int error;
- if (auto client = android::dvr::PerformanceClient::Create(&error))
- return client->SetSchedulerClass(task_id, scheduler_class);
- else
- return error;
-}
-
-extern "C" int dvrGetCpuPartition(pid_t task_id, char* partition, size_t size) {
- int error;
- if (auto client = android::dvr::PerformanceClient::Create(&error))
- return client->GetCpuPartition(task_id, partition, size);
- else
- return error;
-}
diff --git a/libs/vr/libperformance/performance_rpc.cpp b/libs/vr/libperformance/performance_rpc.cpp
deleted file mode 100644
index 9135349..0000000
--- a/libs/vr/libperformance/performance_rpc.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#include "include/private/dvr/performance_rpc.h"
-
-namespace android {
-namespace dvr {
-
-constexpr char PerformanceRPC::kClientPath[];
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libvr_manager/Android.bp b/libs/vr/libvr_manager/Android.bp
deleted file mode 100644
index 6f2ada4..0000000
--- a/libs/vr/libvr_manager/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "frameworks_native_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_library_static {
- name: "libvr_manager",
- srcs: [
- "vr_manager.cpp",
- "trusted_uids.cpp",
- ],
- include_dirs: ["frameworks/native/include/vr/vr_manager"],
- export_include_dirs: [ "include" ],
- cflags: ["-Wall", "-Werror", "-Wunused", "-Wunreachable-code"],
- shared_libs: [
- "libutils",
- "libbinder",
- ],
-}
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
deleted file mode 100644
index 4496fbf..0000000
--- a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
-#define ANDROID_DVR_TRUSTED_UIDS_H_
-
-#include <sys/types.h>
-
-namespace android {
-namespace dvr {
-
-/**
- * Tells if a provided UID can be trusted to access restricted VR APIs.
- *
- * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
- * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
- *
- * UIDs are guaranteed not to be reused until the next reboot even in case
- * of package reinstall. For performance reasons this method caches results by
- * default, as otherwise every check would trigger a Java call.
- *
- * This function is thread-safe.
- *
- * @param uid The uid to check.
- * @param use_cache If true any cached result for the provided uid will be
- * reused. If false this call will reach the Application Manager Service
- * in Java to get updated values. Any updates will be stored in the cache.
- * @return true if the uid is trusted, false if not or if the VR Manager Service
- * could not be reached to verify the uid.
- */
-bool IsTrustedUid(uid_t uid, bool use_cache = true);
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
deleted file mode 100644
index 4228a05..0000000
--- a/libs/vr/libvr_manager/trusted_uids.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "private/dvr/trusted_uids.h"
-
-#include <mutex>
-#include <unordered_map>
-
-#include <binder/IPermissionController.h>
-#include <binder/IServiceManager.h>
-#include <private/android_filesystem_config.h>
-#include <utils/String16.h>
-#include <vr/vr_manager/vr_manager.h>
-
-namespace android {
-namespace dvr {
-
-bool IsTrustedUid(uid_t uid, bool use_cache) {
- static std::unordered_map<uid_t, bool> uid_cache;
- static std::mutex uid_cache_mutex;
-
- // Whitelist requests from the system UID.
- // These are already whitelisted by the permission service, but it might not
- // be available if the ActivityManagerService is up during boot.
- // This ensures the correct result for system services while booting up.
- if (uid == AID_SYSTEM)
- return true;
-
- std::lock_guard<std::mutex> lock(uid_cache_mutex);
-
- if (use_cache) {
- auto it = uid_cache.find(uid);
- if (it != uid_cache.end())
- return it->second;
- }
-
- sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
- if (binder == 0) {
- ALOGW("Could not access permission service");
- return false;
- }
-
- // Note: we ignore the pid because it's only used to automatically reply
- // true if the caller is the Activity Manager Service.
- bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
- String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
-
- // Cache the information for this uid to avoid future Java calls.
- uid_cache[uid] = trusted;
- return trusted;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/libs/vr/libvr_manager/vr_manager.cpp b/libs/vr/libvr_manager/vr_manager.cpp
deleted file mode 100644
index 5cfc22e..0000000
--- a/libs/vr/libvr_manager/vr_manager.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "VrManager"
-#include <utils/Log.h>
-
-#include <vr/vr_manager/vr_manager.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-
-namespace android {
-
-// Must be kept in sync with interface defined in IVrStateCallbacks.aidl.
-
-class BpVrStateCallbacks : public BpInterface<IVrStateCallbacks> {
- public:
- explicit BpVrStateCallbacks(const sp<IBinder>& impl)
- : BpInterface<IVrStateCallbacks>(impl) {}
-
- void onVrStateChanged(bool enabled) {
- Parcel data, reply;
- data.writeInterfaceToken(IVrStateCallbacks::getInterfaceDescriptor());
- data.writeBool(enabled);
- remote()->transact(ON_VR_STATE_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(VrStateCallbacks, "android.service.vr.IVrStateCallbacks");
-
-status_t BnVrStateCallbacks::onTransact(uint32_t code, const Parcel& data,
- Parcel* reply, uint32_t flags) {
- switch(code) {
- case ON_VR_STATE_CHANGED: {
- CHECK_INTERFACE(IVrStateCallbacks, data, reply);
- onVrStateChanged(data.readBool());
- return OK;
- }
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// Must be kept in sync with interface defined in
-// IPersistentVrStateCallbacks.aidl.
-
-class BpPersistentVrStateCallbacks
- : public BpInterface<IPersistentVrStateCallbacks> {
- public:
- explicit BpPersistentVrStateCallbacks(const sp<IBinder>& impl)
- : BpInterface<IPersistentVrStateCallbacks>(impl) {}
-
- void onPersistentVrStateChanged(bool enabled) {
- Parcel data, reply;
- data.writeInterfaceToken(
- IPersistentVrStateCallbacks::getInterfaceDescriptor());
- data.writeBool(enabled);
- remote()->transact(ON_PERSISTENT_VR_STATE_CHANGED,
- data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(PersistentVrStateCallbacks,
- "android.service.vr.IPersistentVrStateCallbacks");
-
-status_t BnPersistentVrStateCallbacks::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
- switch(code) {
- case ON_PERSISTENT_VR_STATE_CHANGED: {
- CHECK_INTERFACE(IPersistentVrStateCallbacks, data, reply);
- onPersistentVrStateChanged(data.readBool());
- return OK;
- }
- }
- return BBinder::onTransact(code, data, reply, flags);
-}
-
-// Must be kept in sync with interface defined in IVrManager.aidl.
-
-class BpVrManager : public BpInterface<IVrManager> {
- public:
- explicit BpVrManager(const sp<IBinder>& impl)
- : BpInterface<IVrManager>(impl) {}
-
- void registerListener(const sp<IVrStateCallbacks>& cb) override {
- Parcel data;
- data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cb));
- remote()->transact(REGISTER_LISTENER, data, NULL);
- }
-
- void unregisterListener(const sp<IVrStateCallbacks>& cb) override {
- Parcel data;
- data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cb));
- remote()->transact(UNREGISTER_LISTENER, data, NULL);
- }
-
- void registerPersistentVrStateListener(
- const sp<IPersistentVrStateCallbacks>& cb) override {
- Parcel data;
- data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cb));
- remote()->transact(REGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
- }
-
- void unregisterPersistentVrStateListener(
- const sp<IPersistentVrStateCallbacks>& cb) override {
- Parcel data;
- data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
- data.writeStrongBinder(IInterface::asBinder(cb));
- remote()->transact(UNREGISTER_PERSISTENT_VR_STATE_LISTENER, data, NULL);
- }
-
- bool getVrModeState() override {
- Parcel data, reply;
- data.writeInterfaceToken(IVrManager::getInterfaceDescriptor());
- remote()->transact(GET_VR_MODE_STATE, data, &reply);
- int32_t ret = reply.readExceptionCode();
- if (ret != 0) {
- return false;
- }
- return reply.readBool();
- }
-};
-
-IMPLEMENT_META_INTERFACE(VrManager, "android.service.vr.IVrManager");
-
-} // namespace android
diff --git a/libs/vr/public.libraries-google.txt b/libs/vr/public.libraries-google.txt
deleted file mode 100644
index 8271b94..0000000
--- a/libs/vr/public.libraries-google.txt
+++ /dev/null
@@ -1 +0,0 @@
-libdvr.google.so
\ No newline at end of file
diff --git a/services/gpuservice/bpfprogs/Android.bp b/services/gpuservice/bpfprogs/Android.bp
index 680b291..a391c81 100644
--- a/services/gpuservice/bpfprogs/Android.bp
+++ b/services/gpuservice/bpfprogs/Android.bp
@@ -24,9 +24,4 @@
bpf {
name: "gpuMem.o",
srcs: ["gpuMem.c"],
- btf: true,
- cflags: [
- "-Wall",
- "-Werror",
- ],
}
diff --git a/services/gpuservice/gpuwork/bpfprogs/Android.bp b/services/gpuservice/gpuwork/bpfprogs/Android.bp
index fe45c98..8e872fb 100644
--- a/services/gpuservice/gpuwork/bpfprogs/Android.bp
+++ b/services/gpuservice/gpuwork/bpfprogs/Android.bp
@@ -19,12 +19,10 @@
bpf {
name: "gpuWork.o",
srcs: ["gpuWork.c"],
+ // Without btf disabled, presubmits will fail.
+ btf: false,
cflags: [
- "-Wall",
- "-Werror",
- "-Wformat",
"-Wthread-safety",
- "-Wunused",
"-Wunreachable-code",
],
}
diff --git a/services/inputflinger/InputDeviceMetricsCollector.cpp b/services/inputflinger/InputDeviceMetricsCollector.cpp
index b5cb3cb..4621144 100644
--- a/services/inputflinger/InputDeviceMetricsCollector.cpp
+++ b/services/inputflinger/InputDeviceMetricsCollector.cpp
@@ -133,15 +133,6 @@
mNextListener.notify(args);
}
-void InputDeviceMetricsCollector::notifyConfigurationChanged(
- const NotifyConfigurationChangedArgs& args) {
- {
- std::scoped_lock lock(mLock);
- reportCompletedSessions();
- }
- mNextListener.notify(args);
-}
-
void InputDeviceMetricsCollector::notifyKey(const NotifyKeyArgs& args) {
{
std::scoped_lock lock(mLock);
diff --git a/services/inputflinger/InputDeviceMetricsCollector.h b/services/inputflinger/InputDeviceMetricsCollector.h
index 1bcd527..0a520e6 100644
--- a/services/inputflinger/InputDeviceMetricsCollector.h
+++ b/services/inputflinger/InputDeviceMetricsCollector.h
@@ -107,7 +107,6 @@
std::chrono::nanoseconds usageSessionTimeout);
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/InputFilter.cpp b/services/inputflinger/InputFilter.cpp
index 8e73ce5..e4d73fc 100644
--- a/services/inputflinger/InputFilter.cpp
+++ b/services/inputflinger/InputFilter.cpp
@@ -67,10 +67,6 @@
mNextListener.notify(args);
}
-void InputFilter::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- mNextListener.notify(args);
-}
-
void InputFilter::notifyKey(const NotifyKeyArgs& args) {
if (isFilterEnabled()) {
LOG_ALWAYS_FATAL_IF(!mInputFilterRust->notifyKey(notifyKeyArgsToKeyEvent(args)).isOk());
diff --git a/services/inputflinger/InputFilter.h b/services/inputflinger/InputFilter.h
index 4ddc9f4..f626703 100644
--- a/services/inputflinger/InputFilter.h
+++ b/services/inputflinger/InputFilter.h
@@ -53,7 +53,6 @@
InputFilterPolicyInterface& policy);
~InputFilter() override = default;
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index 016ae04..8b6accf 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -47,7 +47,6 @@
void InputListenerInterface::notify(const NotifyArgs& generalArgs) {
Visitor v{
[&](const NotifyInputDevicesChangedArgs& args) { notifyInputDevicesChanged(args); },
- [&](const NotifyConfigurationChangedArgs& args) { notifyConfigurationChanged(args); },
[&](const NotifyKeyArgs& args) { notifyKey(args); },
[&](const NotifyMotionArgs& args) { notifyMotion(args); },
[&](const NotifySwitchArgs& args) { notifySwitch(args); },
@@ -68,10 +67,6 @@
mArgsQueue.emplace_back(args);
}
-void QueuedInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- mArgsQueue.emplace_back(args);
-}
-
void QueuedInputListener::notifyKey(const NotifyKeyArgs& args) {
mArgsQueue.emplace_back(args);
}
@@ -119,13 +114,6 @@
mInnerListener.notify(args);
}
-void TracedInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- constexpr static auto& fnName = __func__;
- ATRACE_NAME_IF(ATRACE_ENABLED(),
- StringPrintf("%s::%s(id=0x%" PRIx32 ")", mName, fnName, args.id));
- mInnerListener.notify(args);
-}
-
void TracedInputListener::notifyKey(const NotifyKeyArgs& args) {
constexpr static auto& fnName = __func__;
ATRACE_NAME_IF(ATRACE_ENABLED(),
diff --git a/services/inputflinger/InputProcessor.cpp b/services/inputflinger/InputProcessor.cpp
index 6dd267c..8b8b1ad 100644
--- a/services/inputflinger/InputProcessor.cpp
+++ b/services/inputflinger/InputProcessor.cpp
@@ -419,12 +419,6 @@
mQueuedListener.flush();
}
-void InputProcessor::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- // pass through
- mQueuedListener.notifyConfigurationChanged(args);
- mQueuedListener.flush();
-}
-
void InputProcessor::notifyKey(const NotifyKeyArgs& args) {
// pass through
mQueuedListener.notifyKey(args);
diff --git a/services/inputflinger/InputProcessor.h b/services/inputflinger/InputProcessor.h
index 7a00a2d..2945dd2 100644
--- a/services/inputflinger/InputProcessor.h
+++ b/services/inputflinger/InputProcessor.h
@@ -246,7 +246,6 @@
explicit InputProcessor(InputListenerInterface& listener);
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/NotifyArgs.cpp b/services/inputflinger/NotifyArgs.cpp
index 19a4f26..b2680a2 100644
--- a/services/inputflinger/NotifyArgs.cpp
+++ b/services/inputflinger/NotifyArgs.cpp
@@ -35,11 +35,6 @@
std::vector<InputDeviceInfo> infos)
: id(id), inputDeviceInfos(std::move(infos)) {}
-// --- NotifyConfigurationChangedArgs ---
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(int32_t id, nsecs_t eventTime)
- : id(id), eventTime(eventTime) {}
-
// --- NotifyKeyArgs ---
NotifyKeyArgs::NotifyKeyArgs(int32_t id, nsecs_t eventTime, nsecs_t readTime, int32_t deviceId,
@@ -198,7 +193,6 @@
const char* toString(const NotifyArgs& args) {
Visitor toStringVisitor{
[&](const NotifyInputDevicesChangedArgs&) { return "NotifyInputDevicesChangedArgs"; },
- [&](const NotifyConfigurationChangedArgs&) { return "NotifyConfigurationChangedArgs"; },
[&](const NotifyKeyArgs&) { return "NotifyKeyArgs"; },
[&](const NotifyMotionArgs&) { return "NotifyMotionArgs"; },
[&](const NotifySensorArgs&) { return "NotifySensorArgs"; },
diff --git a/services/inputflinger/PointerChoreographer.cpp b/services/inputflinger/PointerChoreographer.cpp
index 31fbb51..625599a 100644
--- a/services/inputflinger/PointerChoreographer.cpp
+++ b/services/inputflinger/PointerChoreographer.cpp
@@ -165,10 +165,6 @@
mNextListener.notify(args);
}
-void PointerChoreographer::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- mNextListener.notify(args);
-}
-
void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
fadeMouseCursorOnKeyPress(args);
mNextListener.notify(args);
@@ -368,7 +364,8 @@
const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
std::array<uint32_t, MAX_POINTER_ID + 1> idToIndex;
BitSet32 idBits;
- if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL) {
+ if (maskedAction != AMOTION_EVENT_ACTION_UP && maskedAction != AMOTION_EVENT_ACTION_CANCEL &&
+ maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
for (size_t i = 0; i < args.getPointerCount(); i++) {
if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP && actionIndex == i) {
continue;
diff --git a/services/inputflinger/PointerChoreographer.h b/services/inputflinger/PointerChoreographer.h
index aaf1e3e..635487b 100644
--- a/services/inputflinger/PointerChoreographer.h
+++ b/services/inputflinger/PointerChoreographer.h
@@ -105,7 +105,6 @@
void setFocusedDisplay(ui::LogicalDisplayId displayId) override;
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index a4dd909..018de5d 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -149,6 +149,9 @@
},
{
"name": "monkey_test"
+ },
+ {
+ "name": "CtsSurfaceControlTests"
}
],
"postsubmit": [
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index 1e2b9b3a..0e9ec91 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -342,12 +342,6 @@
bool enablePalmRejection)
: mQueuedListener(listener), mEnablePalmRejection(enablePalmRejection) {}
-void UnwantedInteractionBlocker::notifyConfigurationChanged(
- const NotifyConfigurationChangedArgs& args) {
- mQueuedListener.notifyConfigurationChanged(args);
- mQueuedListener.flush();
-}
-
void UnwantedInteractionBlocker::notifyKey(const NotifyKeyArgs& args) {
mQueuedListener.notifyKey(args);
mQueuedListener.flush();
diff --git a/services/inputflinger/UnwantedInteractionBlocker.h b/services/inputflinger/UnwantedInteractionBlocker.h
index 419da83..8a66e25 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.h
+++ b/services/inputflinger/UnwantedInteractionBlocker.h
@@ -91,7 +91,6 @@
explicit UnwantedInteractionBlocker(InputListenerInterface& listener, bool enablePalmRejection);
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/dispatcher/Entry.cpp b/services/inputflinger/dispatcher/Entry.cpp
index ad9cec1..ff407af 100644
--- a/services/inputflinger/dispatcher/Entry.cpp
+++ b/services/inputflinger/dispatcher/Entry.cpp
@@ -68,15 +68,6 @@
injectionState(nullptr),
dispatchInProgress(false) {}
-// --- ConfigurationChangedEntry ---
-
-ConfigurationChangedEntry::ConfigurationChangedEntry(int32_t id, nsecs_t eventTime)
- : EventEntry(id, Type::CONFIGURATION_CHANGED, eventTime, 0) {}
-
-std::string ConfigurationChangedEntry::getDescription() const {
- return StringPrintf("ConfigurationChangedEvent(), policyFlags=0x%08x", policyFlags);
-}
-
// --- DeviceResetEntry ---
DeviceResetEntry::DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId)
diff --git a/services/inputflinger/dispatcher/Entry.h b/services/inputflinger/dispatcher/Entry.h
index f2f31d8..becfb05 100644
--- a/services/inputflinger/dispatcher/Entry.h
+++ b/services/inputflinger/dispatcher/Entry.h
@@ -32,7 +32,6 @@
struct EventEntry {
enum class Type {
- CONFIGURATION_CHANGED,
DEVICE_RESET,
FOCUS,
KEY,
@@ -78,11 +77,6 @@
virtual ~EventEntry() = default;
};
-struct ConfigurationChangedEntry : EventEntry {
- explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
- std::string getDescription() const override;
-};
-
struct DeviceResetEntry : EventEntry {
int32_t deviceId;
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 23c95e5..af4a04d 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -558,7 +558,6 @@
// Returns true if the event type passed as argument represents a user activity.
bool isUserActivityEvent(const EventEntry& eventEntry) {
switch (eventEntry.type) {
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::DRAG:
case EventEntry::Type::FOCUS:
@@ -901,6 +900,24 @@
const nsecs_t mProcessingTimestamp;
};
+/**
+ * This is needed to help use "InputEventInjectionResult" with base::Result.
+ */
+template <typename T>
+struct EnumErrorWrapper {
+ T mVal;
+ EnumErrorWrapper(T&& e) : mVal(std::forward<T>(e)) {}
+ operator const T&() const { return mVal; }
+ T value() const { return mVal; }
+ std::string print() const { return ftl::enum_string(mVal); }
+};
+
+Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInjectionResult&& e) {
+ LOG_ALWAYS_FATAL_IF(e == InputEventInjectionResult::SUCCEEDED);
+ return Error<EnumErrorWrapper<InputEventInjectionResult>>(
+ std::forward<InputEventInjectionResult>(e));
+}
+
} // namespace
// --- InputDispatcher ---
@@ -1153,14 +1170,6 @@
}
switch (mPendingEvent->type) {
- case EventEntry::Type::CONFIGURATION_CHANGED: {
- const ConfigurationChangedEntry& typedEntry =
- static_cast<const ConfigurationChangedEntry&>(*mPendingEvent);
- done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
- dropReason = DropReason::NOT_DROPPED; // configuration changes are never dropped
- break;
- }
-
case EventEntry::Type::DEVICE_RESET: {
const DeviceResetEntry& typedEntry =
static_cast<const DeviceResetEntry&>(*mPendingEvent);
@@ -1308,7 +1317,7 @@
// Alternatively, maybe there's a spy window that could handle this event.
const std::vector<sp<WindowInfoHandle>> touchedSpies =
- findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
+ findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, motionEntry.deviceId);
for (const auto& windowHandle : touchedSpies) {
const std::shared_ptr<Connection> connection =
getConnectionLocked(windowHandle->getToken());
@@ -1392,7 +1401,6 @@
break;
}
case EventEntry::Type::TOUCH_MODE_CHANGED:
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
@@ -1463,15 +1471,27 @@
}
std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
- ui::LogicalDisplayId displayId, float x, float y, bool isStylus) const {
+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const {
// Traverse windows from front to back and gather the touched spy windows.
std::vector<sp<WindowInfoHandle>> spyWindows;
const auto& windowHandles = getWindowHandlesLocked(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
const WindowInfo& info = *windowHandle->getInfo();
-
if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
- continue;
+ // Generally, we would skip any pointer that's outside of the window. However, if the
+ // spy prevents splitting, and already has some of the pointers from this device, then
+ // it should get more pointers from the same device, even if they are outside of that
+ // window
+ if (info.supportsSplitTouch()) {
+ continue;
+ }
+
+ // We know that split touch is not supported. Skip this window only if it doesn't have
+ // any touching pointers for this device already.
+ if (!windowHasTouchingPointersLocked(windowHandle, deviceId)) {
+ continue;
+ }
+ // If it already has pointers down for this device, then give it this pointer, too.
}
if (!info.isSpy()) {
// The first touched non-spy window was found, so return the spy windows touched so far.
@@ -1554,7 +1574,6 @@
}
case EventEntry::Type::FOCUS:
case EventEntry::Type::TOUCH_MODE_CHANGED:
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
break;
@@ -1643,24 +1662,6 @@
return newEntry;
}
-bool InputDispatcher::dispatchConfigurationChangedLocked(nsecs_t currentTime,
- const ConfigurationChangedEntry& entry) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("dispatchConfigurationChanged - eventTime=%" PRId64, entry.eventTime);
- }
-
- // Reset key repeating in case a keyboard device was added or removed or something.
- resetKeyRepeatLocked();
-
- // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
- auto command = [this, eventTime = entry.eventTime]() REQUIRES(mLock) {
- scoped_unlock unlock(mLock);
- mPolicy.notifyConfigurationChanged(eventTime);
- };
- postCommandLocked(std::move(command));
- return true;
-}
-
bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
const DeviceResetEntry& entry) {
if (DEBUG_OUTBOUND_EVENT_DETAILS) {
@@ -1923,20 +1924,21 @@
}
// Identify targets.
- InputEventInjectionResult injectionResult;
- sp<WindowInfoHandle> focusedWindow =
- findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime,
- /*byref*/ injectionResult);
- if (injectionResult == InputEventInjectionResult::PENDING) {
- return false;
- }
+ Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
+ findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
- setInjectionResult(*entry, injectionResult);
- if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
+ if (!result.ok()) {
+ if (result.error().code() == InputEventInjectionResult::PENDING) {
+ return false;
+ }
+ setInjectionResult(*entry, result.error().code());
return true;
}
+ sp<WindowInfoHandle>& focusedWindow = *result;
LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
+ setInjectionResult(*entry, InputEventInjectionResult::SUCCEEDED);
+
std::vector<InputTarget> inputTargets;
addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
@@ -2041,19 +2043,28 @@
pilferPointersLocked(mDragState->dragWindow->getToken());
}
- inputTargets =
- findTouchedWindowTargetsLocked(currentTime, *entry, /*byref*/ injectionResult);
- LOG_ALWAYS_FATAL_IF(injectionResult != InputEventInjectionResult::SUCCEEDED &&
- !inputTargets.empty());
+ Result<std::vector<InputTarget>, InputEventInjectionResult> result =
+ findTouchedWindowTargetsLocked(currentTime, *entry);
+
+ if (result.ok()) {
+ inputTargets = std::move(*result);
+ injectionResult = InputEventInjectionResult::SUCCEEDED;
+ } else {
+ injectionResult = result.error().code();
+ }
} else {
// Non touch event. (eg. trackball)
- sp<WindowInfoHandle> focusedWindow =
- findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime, injectionResult);
- if (injectionResult == InputEventInjectionResult::SUCCEEDED) {
+ Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
+ findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
+ if (result.ok()) {
+ sp<WindowInfoHandle>& focusedWindow = *result;
LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
InputTarget::Flags::FOREGROUND, getDownTime(*entry),
inputTargets);
+ injectionResult = InputEventInjectionResult::SUCCEEDED;
+ } else {
+ injectionResult = result.error().code();
}
}
if (injectionResult == InputEventInjectionResult::PENDING) {
@@ -2218,7 +2229,6 @@
case EventEntry::Type::TOUCH_MODE_CHANGED:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::FOCUS:
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR:
case EventEntry::Type::DRAG: {
@@ -2260,11 +2270,9 @@
return false;
}
-sp<WindowInfoHandle> InputDispatcher::findFocusedWindowTargetLocked(
- nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime,
- InputEventInjectionResult& outInjectionResult) {
- outInjectionResult = InputEventInjectionResult::FAILED; // Default result
-
+Result<sp<WindowInfoHandle>, InputEventInjectionResult>
+InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
+ nsecs_t& nextWakeupTime) {
ui::LogicalDisplayId displayId = getTargetDisplayId(entry);
sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
@@ -2276,12 +2284,12 @@
ALOGI("Dropping %s event because there is no focused window or focused application in "
"display %s.",
ftl::enum_string(entry.type).c_str(), displayId.toString().c_str());
- return nullptr;
+ return injectionError(InputEventInjectionResult::FAILED);
}
// Drop key events if requested by input feature
if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
- return nullptr;
+ return injectionError(InputEventInjectionResult::FAILED);
}
// Compatibility behavior: raise ANR if there is a focused application, but no focused window.
@@ -2301,17 +2309,15 @@
"window when it finishes starting up. Will wait for %" PRId64 "ms",
mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
nextWakeupTime = std::min(nextWakeupTime, *mNoFocusedWindowTimeoutTime);
- outInjectionResult = InputEventInjectionResult::PENDING;
- return nullptr;
+ return injectionError(InputEventInjectionResult::PENDING);
} else if (currentTime > *mNoFocusedWindowTimeoutTime) {
// Already raised ANR. Drop the event
ALOGE("Dropping %s event because there is no focused window",
ftl::enum_string(entry.type).c_str());
- return nullptr;
+ return injectionError(InputEventInjectionResult::FAILED);
} else {
// Still waiting for the focused window
- outInjectionResult = InputEventInjectionResult::PENDING;
- return nullptr;
+ return injectionError(InputEventInjectionResult::PENDING);
}
}
@@ -2321,15 +2327,13 @@
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
ALOGW("Dropping injected event: %s", (*err).c_str());
- outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
- return nullptr;
+ return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
}
if (focusedWindowHandle->getInfo()->inputConfig.test(
WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
- outInjectionResult = InputEventInjectionResult::PENDING;
- return nullptr;
+ return injectionError(InputEventInjectionResult::PENDING);
}
// If the event is a key event, then we must wait for all previous events to
@@ -2346,12 +2350,10 @@
if (entry.type == EventEntry::Type::KEY) {
if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
nextWakeupTime = std::min(nextWakeupTime, *mKeyIsWaitingForEventsTimeout);
- outInjectionResult = InputEventInjectionResult::PENDING;
- return nullptr;
+ return injectionError(InputEventInjectionResult::PENDING);
}
}
-
- outInjectionResult = InputEventInjectionResult::SUCCEEDED;
+ // Success!
return focusedWindowHandle;
}
@@ -2375,9 +2377,8 @@
return responsiveMonitors;
}
-std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked(
- nsecs_t currentTime, const MotionEntry& entry,
- InputEventInjectionResult& outInjectionResult) {
+base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
+InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
ATRACE_CALL();
std::vector<InputTarget> targets;
@@ -2387,9 +2388,6 @@
const int32_t action = entry.action;
const int32_t maskedAction = MotionEvent::getActionMasked(action);
- // Update the touch state as needed based on the properties of the touch event.
- outInjectionResult = InputEventInjectionResult::PENDING;
-
// Copy current touch state into tempTouchState.
// This state will be used to update mTouchStatesByDisplay at the end of this function.
// If no state for the specified display exists, then our initial state will be empty.
@@ -2429,8 +2427,7 @@
// Started hovering, but the device is already down: reject the hover event
LOG(ERROR) << "Got hover event " << entry.getDescription()
<< " but the device is already down " << oldState->dump();
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
// For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
// all of the existing hovering pointers and recompute.
@@ -2451,20 +2448,25 @@
if (isDown) {
targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
}
+ LOG_IF(INFO, newTouchedWindowHandle == nullptr)
+ << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
+ << ") in display " << displayId;
// Handle the case where we did not find a window.
- if (newTouchedWindowHandle == nullptr) {
- ALOGD("No new touched window at (%.1f, %.1f) in display %s", x, y,
- displayId.toString().c_str());
- // Try to assign the pointer to the first foreground window we find, if there is one.
- newTouchedWindowHandle = tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
+ if (!input_flags::split_all_touches()) {
+ // If we are force splitting all touches, then touches outside of the window should
+ // be dropped, even if this device already has pointers down in another window.
+ if (newTouchedWindowHandle == nullptr) {
+ // Try to assign the pointer to the first foreground window we find, if there is
+ // one.
+ newTouchedWindowHandle =
+ tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
+ }
}
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
ALOGW("Dropping injected touch event: %s", (*err).c_str());
- outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
- newTouchedWindowHandle = nullptr;
- return {};
+ return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
}
// Figure out whether splitting will be allowed for this window.
@@ -2487,7 +2489,7 @@
}
std::vector<sp<WindowInfoHandle>> newTouchedWindows =
- findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus);
+ findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, entry.deviceId);
if (newTouchedWindowHandle != nullptr) {
// Process the foreground window first so that it is the first to receive the event.
newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
@@ -2496,8 +2498,7 @@
if (newTouchedWindows.empty()) {
LOG(INFO) << "Dropping event because there is no touchable window at (" << x << ", "
<< y << ") on display " << displayId << ": " << entry;
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
@@ -2597,8 +2598,7 @@
<< " is not down or we previously dropped the pointer down event in "
<< "display " << displayId << ": " << entry.getDescription();
}
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
// If the pointer is not currently hovering, then ignore the event.
@@ -2609,8 +2609,7 @@
LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
"display "
<< displayId << ": " << entry.getDescription();
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
}
@@ -2631,8 +2630,7 @@
// Verify targeted injection.
if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
ALOGW("Dropping injected event: %s", (*err).c_str());
- outInjectionResult = os::InputEventInjectionResult::TARGET_MISMATCH;
- return {};
+ return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
}
// Do not slide events to the window which can not receive motion event
@@ -2701,6 +2699,9 @@
if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
continue;
}
+ if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
+ continue;
+ }
touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
}
}
@@ -2732,8 +2733,7 @@
ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
"%s:%s",
entry.injectionState->targetUid->toString().c_str(), errs.c_str());
- outInjectionResult = InputEventInjectionResult::TARGET_MISMATCH;
- return {};
+ return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
}
}
@@ -2790,8 +2790,7 @@
if (targets.empty()) {
LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
// If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
@@ -2801,12 +2800,9 @@
})) {
LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
<< entry.getDescription();
- outInjectionResult = InputEventInjectionResult::FAILED;
- return {};
+ return injectionError(InputEventInjectionResult::FAILED);
}
- outInjectionResult = InputEventInjectionResult::SUCCEEDED;
-
// Now that we have generated all of the input targets for this event, reset the dispatch
// mode for all touched window to AS_IS.
for (TouchedWindow& touchedWindow : tempTouchState.windows) {
@@ -3614,7 +3610,6 @@
LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
break;
}
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET: {
LOG_ALWAYS_FATAL("%s events should not go to apps",
ftl::enum_string(eventEntry->type).c_str());
@@ -3875,7 +3870,6 @@
break;
}
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR: {
LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
@@ -4271,7 +4265,6 @@
ftl::enum_string(cancelationEventEntry->type).c_str());
break;
}
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::SENSOR: {
LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
@@ -4354,7 +4347,6 @@
case EventEntry::Type::KEY:
case EventEntry::Type::FOCUS:
case EventEntry::Type::TOUCH_MODE_CHANGED:
- case EventEntry::Type::CONFIGURATION_CHANGED:
case EventEntry::Type::DEVICE_RESET:
case EventEntry::Type::POINTER_CAPTURE_CHANGED:
case EventEntry::Type::SENSOR:
@@ -4440,28 +4432,11 @@
void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
std::scoped_lock _l(mLock);
+ // Reset key repeating in case a keyboard device was added or removed or something.
+ resetKeyRepeatLocked();
mLatencyTracker.setInputDevices(args.inputDeviceInfos);
}
-void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- if (debugInboundEventDetails()) {
- ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
- }
-
- bool needWake = false;
- { // acquire lock
- std::scoped_lock _l(mLock);
-
- std::unique_ptr<ConfigurationChangedEntry> newEntry =
- std::make_unique<ConfigurationChangedEntry>(args.id, args.eventTime);
- needWake = enqueueInboundEventLocked(std::move(newEntry));
- } // release lock
-
- if (needWake) {
- mLooper->wake();
- }
-}
-
void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
ALOGD_IF(debugInboundEventDetails(),
"notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
@@ -5676,7 +5651,7 @@
mMaximumObscuringOpacityForTouch = opacity;
}
-std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId /*displayId*/>
+std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
for (auto& [displayId, state] : mTouchStatesByDisplay) {
for (TouchedWindow& w : state.windows) {
@@ -5688,6 +5663,22 @@
return std::make_tuple(nullptr, nullptr, ui::LogicalDisplayId::DEFAULT);
}
+std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
+InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const {
+ return const_cast<InputDispatcher*>(this)->findTouchStateWindowAndDisplayLocked(token);
+}
+
+bool InputDispatcher::windowHasTouchingPointersLocked(const sp<WindowInfoHandle>& windowHandle,
+ DeviceId deviceId) const {
+ const auto& [touchState, touchedWindow, _] =
+ findTouchStateWindowAndDisplayLocked(windowHandle->getToken());
+ if (touchState == nullptr) {
+ // No touching pointers at all
+ return false;
+ }
+ return touchState->hasTouchingPointers(deviceId);
+}
+
bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
bool isDragDrop) {
if (fromToken == toToken) {
@@ -7023,6 +7014,13 @@
for (const auto& info : update.windowInfos) {
handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
+ if (input_flags::split_all_touches()) {
+ handlesPerDisplay[info.displayId]
+ .back()
+ ->editInfo()
+ ->setInputConfig(android::gui::WindowInfo::InputConfig::PREVENT_SPLITTING,
+ false);
+ }
}
{ // acquire lock
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index e2fc7a0..698bdba 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -97,7 +97,6 @@
status_t stop() override;
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
void notifyKey(const NotifyKeyArgs& args) override;
void notifyMotion(const NotifyMotionArgs& args) override;
void notifySwitch(const NotifySwitchArgs& args) override;
@@ -258,7 +257,8 @@
int32_t pointerId) const REQUIRES(mLock);
std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAtLocked(
- ui::LogicalDisplayId displayId, float x, float y, bool isStylus) const REQUIRES(mLock);
+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus,
+ DeviceId deviceId) const REQUIRES(mLock);
sp<android::gui::WindowInfoHandle> findTouchedForegroundWindowLocked(
ui::LogicalDisplayId displayId) const REQUIRES(mLock);
@@ -446,8 +446,6 @@
REQUIRES(mLock);
// Dispatch inbound events.
- bool dispatchConfigurationChangedLocked(nsecs_t currentTime,
- const ConfigurationChangedEntry& entry) REQUIRES(mLock);
bool dispatchDeviceResetLocked(nsecs_t currentTime, const DeviceResetEntry& entry)
REQUIRES(mLock);
bool dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
@@ -536,12 +534,11 @@
void resetNoFocusedWindowTimeoutLocked() REQUIRES(mLock);
ui::LogicalDisplayId getTargetDisplayId(const EventEntry& entry);
- sp<android::gui::WindowInfoHandle> findFocusedWindowTargetLocked(
- nsecs_t currentTime, const EventEntry& entry, nsecs_t& nextWakeupTime,
- android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
- std::vector<InputTarget> findTouchedWindowTargetsLocked(
- nsecs_t currentTime, const MotionEntry& entry,
- android::os::InputEventInjectionResult& outInjectionResult) REQUIRES(mLock);
+ base::Result<sp<android::gui::WindowInfoHandle>, android::os::InputEventInjectionResult>
+ findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
+ nsecs_t& nextWakeupTime) REQUIRES(mLock);
+ base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
+ findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) REQUIRES(mLock);
std::vector<Monitor> selectResponsiveMonitorsLocked(
const std::vector<Monitor>& gestureMonitors) const REQUIRES(mLock);
@@ -684,16 +681,21 @@
const std::string& reason) REQUIRES(mLock);
void updateLastAnrStateLocked(const std::string& windowLabel, const std::string& reason)
REQUIRES(mLock);
- std::map<ui::LogicalDisplayId /*displayId*/, InputVerifier> mVerifiersByDisplay;
+ std::map<ui::LogicalDisplayId, InputVerifier> mVerifiersByDisplay;
// Returns a fallback KeyEntry that should be sent to the connection, if required.
std::unique_ptr<const KeyEntry> afterKeyEventLockedInterruptable(
const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
bool handled) REQUIRES(mLock);
// Find touched state and touched window by token.
- std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId /*displayId*/>
+ std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) REQUIRES(mLock);
+ std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
+ findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const REQUIRES(mLock);
+ bool windowHasTouchingPointersLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
+ DeviceId deviceId) const REQUIRES(mLock);
+
// Statistics gathering.
LatencyAggregator mLatencyAggregator GUARDED_BY(mLock);
LatencyTracker mLatencyTracker GUARDED_BY(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
index 65fb76d..b885ba1 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherPolicyInterface.h
@@ -43,9 +43,6 @@
InputDispatcherPolicyInterface() = default;
virtual ~InputDispatcherPolicyInterface() = default;
- /* Notifies the system that a configuration change has occurred. */
- virtual void notifyConfigurationChanged(nsecs_t when) = 0;
-
/* Notifies the system that an application does not have a focused window.
*/
virtual void notifyNoFocusedWindowAnr(
diff --git a/services/inputflinger/include/InputListener.h b/services/inputflinger/include/InputListener.h
index 0b7f7c2..d8a9afa 100644
--- a/services/inputflinger/include/InputListener.h
+++ b/services/inputflinger/include/InputListener.h
@@ -38,7 +38,6 @@
virtual ~InputListenerInterface() { }
virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) = 0;
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) = 0;
virtual void notifyKey(const NotifyKeyArgs& args) = 0;
virtual void notifyMotion(const NotifyMotionArgs& args) = 0;
virtual void notifySwitch(const NotifySwitchArgs& args) = 0;
@@ -60,7 +59,6 @@
explicit QueuedInputListener(InputListenerInterface& innerListener);
virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
virtual void notifyKey(const NotifyKeyArgs& args) override;
virtual void notifyMotion(const NotifyMotionArgs& args) override;
virtual void notifySwitch(const NotifySwitchArgs& args) override;
@@ -84,7 +82,6 @@
explicit TracedInputListener(const char* name, InputListenerInterface& innerListener);
virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
virtual void notifyKey(const NotifyKeyArgs& args) override;
virtual void notifyMotion(const NotifyMotionArgs& args) override;
virtual void notifySwitch(const NotifySwitchArgs& args) override;
diff --git a/services/inputflinger/include/NotifyArgs.h b/services/inputflinger/include/NotifyArgs.h
index db417cf..14487fe 100644
--- a/services/inputflinger/include/NotifyArgs.h
+++ b/services/inputflinger/include/NotifyArgs.h
@@ -39,21 +39,6 @@
NotifyInputDevicesChangedArgs& operator=(const NotifyInputDevicesChangedArgs&) = default;
};
-/* Describes a configuration change event. */
-struct NotifyConfigurationChangedArgs {
- int32_t id;
- nsecs_t eventTime;
-
- inline NotifyConfigurationChangedArgs() {}
-
- NotifyConfigurationChangedArgs(int32_t id, nsecs_t eventTime);
-
- bool operator==(const NotifyConfigurationChangedArgs& rhs) const = default;
-
- NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other) = default;
- NotifyConfigurationChangedArgs& operator=(const NotifyConfigurationChangedArgs&) = default;
-};
-
/* Describes a key event. */
struct NotifyKeyArgs {
int32_t id;
@@ -234,8 +219,8 @@
};
using NotifyArgs =
- std::variant<NotifyInputDevicesChangedArgs, NotifyConfigurationChangedArgs, NotifyKeyArgs,
- NotifyMotionArgs, NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs,
+ std::variant<NotifyInputDevicesChangedArgs, NotifyKeyArgs, NotifyMotionArgs,
+ NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs,
NotifyPointerCaptureChangedArgs, NotifyVibratorStateArgs>;
const char* toString(const NotifyArgs& args);
diff --git a/services/inputflinger/reader/Android.bp b/services/inputflinger/reader/Android.bp
index a052a4e..b76e8c5 100644
--- a/services/inputflinger/reader/Android.bp
+++ b/services/inputflinger/reader/Android.bp
@@ -78,6 +78,7 @@
name: "libinputreader_defaults",
srcs: [":libinputreader_sources"],
shared_libs: [
+ "android.companion.virtualdevice.flags-aconfig-cc",
"libbase",
"libcap",
"libcrypto",
@@ -115,7 +116,6 @@
"libinputreader_defaults",
],
shared_libs: [
- "android.companion.virtualdevice.flags-aconfig-cc-host",
"libinputflinger_base",
],
export_header_lib_headers: [
@@ -141,7 +141,6 @@
shared_libs: [
// This should consist only of dependencies from inputflinger. Other dependencies should be
// in cc_defaults so that they are included in the tests.
- "android.companion.virtualdevice.flags-aconfig-cc-host",
"libinputflinger_base",
"libjsoncpp",
],
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 9381580..e11adb8 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -888,7 +888,6 @@
: mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
mNextDeviceId(1),
mControllerNumbers(),
- mNeedToSendFinishedDeviceScan(false),
mNeedToReopenDevices(false),
mNeedToScanDevices(true),
mPendingEventCount(0),
@@ -1877,7 +1876,6 @@
.type = DEVICE_REMOVED,
});
it = mClosingDevices.erase(it);
- mNeedToSendFinishedDeviceScan = true;
if (events.size() == EVENT_BUFFER_SIZE) {
break;
}
@@ -1886,7 +1884,6 @@
if (mNeedToScanDevices) {
mNeedToScanDevices = false;
scanDevicesLocked();
- mNeedToSendFinishedDeviceScan = true;
}
while (!mOpeningDevices.empty()) {
@@ -1915,18 +1912,6 @@
if (!inserted) {
ALOGW("Device id %d exists, replaced.", device->id);
}
- mNeedToSendFinishedDeviceScan = true;
- if (events.size() == EVENT_BUFFER_SIZE) {
- break;
- }
- }
-
- if (mNeedToSendFinishedDeviceScan) {
- mNeedToSendFinishedDeviceScan = false;
- events.push_back({
- .when = now,
- .type = FINISHED_DEVICE_SCAN,
- });
if (events.size() == EVENT_BUFFER_SIZE) {
break;
}
diff --git a/services/inputflinger/reader/InputReader.cpp b/services/inputflinger/reader/InputReader.cpp
index 0073fd1..f0e53b5 100644
--- a/services/inputflinger/reader/InputReader.cpp
+++ b/services/inputflinger/reader/InputReader.cpp
@@ -180,6 +180,9 @@
}
if (oldGeneration != mGeneration) {
+ // Reset global meta state because it depends on connected input devices.
+ updateGlobalMetaStateLocked();
+
inputDevicesChanged = true;
inputDevices = getInputDevicesLocked();
mPendingArgs.emplace_back(
@@ -247,9 +250,6 @@
case EventHubInterface::DEVICE_REMOVED:
removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
break;
- case EventHubInterface::FINISHED_DEVICE_SCAN:
- handleConfigurationChangedLocked(rawEvent->when);
- break;
default:
ALOG_ASSERT(false); // can't happen
break;
@@ -414,14 +414,6 @@
return ++mNextInputDeviceId;
}
-void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
- // Reset global meta state because it depends on the list of all configured devices.
- updateGlobalMetaStateLocked();
-
- // Enqueue configuration changed.
- mPendingArgs.emplace_back(NotifyConfigurationChangedArgs{mContext.getNextId(), when});
-}
-
void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index c647558..657126a 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -254,9 +254,6 @@
DEVICE_ADDED = 0x10000000,
// Sent when a device is removed.
DEVICE_REMOVED = 0x20000000,
- // Sent when all added/removed devices from the most recent scan have been reported.
- // This event is always sent at least once.
- FINISHED_DEVICE_SCAN = 0x30000000,
FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
};
@@ -789,7 +786,6 @@
std::vector<std::unique_ptr<Device>> mOpeningDevices;
std::vector<std::unique_ptr<Device>> mClosingDevices;
- bool mNeedToSendFinishedDeviceScan;
bool mNeedToReopenDevices;
bool mNeedToScanDevices;
std::vector<std::string> mExcludedDevices;
diff --git a/services/inputflinger/reader/include/InputDevice.h b/services/inputflinger/reader/include/InputDevice.h
index f2fdc37..93785f6 100644
--- a/services/inputflinger/reader/include/InputDevice.h
+++ b/services/inputflinger/reader/include/InputDevice.h
@@ -43,7 +43,7 @@
public:
InputDevice(InputReaderContext* context, int32_t id, int32_t generation,
const InputDeviceIdentifier& identifier);
- ~InputDevice();
+ virtual ~InputDevice();
inline InputReaderContext* getContext() { return mContext; }
inline int32_t getId() const { return mId; }
@@ -56,7 +56,7 @@
}
inline const std::string getLocation() const { return mIdentifier.location; }
inline ftl::Flags<InputDeviceClass> getClasses() const { return mClasses; }
- inline uint32_t getSources() const { return mSources; }
+ inline virtual uint32_t getSources() const { return mSources; }
inline bool hasEventHubDevices() const { return !mDevices.empty(); }
inline bool isExternal() { return mIsExternal; }
@@ -72,7 +72,7 @@
inline std::optional<std::string> getDeviceTypeAssociation() const {
return mAssociatedDeviceType;
}
- inline std::optional<DisplayViewport> getAssociatedViewport() const {
+ inline virtual std::optional<DisplayViewport> getAssociatedViewport() const {
return mAssociatedViewport;
}
inline bool hasMic() const { return mHasMic; }
@@ -132,7 +132,7 @@
[[nodiscard]] NotifyDeviceResetArgs notifyReset(nsecs_t when);
- inline const PropertyMap& getConfiguration() { return mConfiguration; }
+ inline virtual const PropertyMap& getConfiguration() const { return mConfiguration; }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
std::optional<ui::LogicalDisplayId> getAssociatedDisplayId();
@@ -299,6 +299,7 @@
inline ftl::Flags<InputDeviceClass> getDeviceClasses() const {
return mEventHub->getDeviceClasses(mId);
}
+ inline uint32_t getDeviceSources() const { return mDevice.getSources(); }
inline InputDeviceIdentifier getDeviceIdentifier() const {
return mEventHub->getDeviceIdentifier(mId);
}
diff --git a/services/inputflinger/reader/include/InputReader.h b/services/inputflinger/reader/include/InputReader.h
index 03ca840..4f60a8a 100644
--- a/services/inputflinger/reader/include/InputReader.h
+++ b/services/inputflinger/reader/include/InputReader.h
@@ -221,8 +221,6 @@
size_t count) REQUIRES(mLock);
[[nodiscard]] std::list<NotifyArgs> timeoutExpiredLocked(nsecs_t when) REQUIRES(mLock);
- void handleConfigurationChangedLocked(nsecs_t when) REQUIRES(mLock);
-
int32_t mGlobalMetaState GUARDED_BY(mLock);
void updateGlobalMetaStateLocked() REQUIRES(mLock);
int32_t getGlobalMetaStateLocked() REQUIRES(mLock);
diff --git a/services/inputflinger/reader/mapper/CursorInputMapper.h b/services/inputflinger/reader/mapper/CursorInputMapper.h
index 2108488..3fc370c 100644
--- a/services/inputflinger/reader/mapper/CursorInputMapper.h
+++ b/services/inputflinger/reader/mapper/CursorInputMapper.h
@@ -25,9 +25,6 @@
namespace android {
-class CursorButtonAccumulator;
-class CursorScrollAccumulator;
-
/* Keeps track of cursor movements. */
class CursorMotionAccumulator {
public:
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
index 4a21e48..38dcd65 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.cpp
@@ -98,10 +98,10 @@
KeyboardInputMapper::KeyboardInputMapper(InputDeviceContext& deviceContext,
const InputReaderConfiguration& readerConfig,
uint32_t source)
- : InputMapper(deviceContext, readerConfig), mSource(source) {}
+ : InputMapper(deviceContext, readerConfig), mMapperSource(source) {}
uint32_t KeyboardInputMapper::getSources() const {
- return mSource;
+ return mMapperSource;
}
ui::Rotation KeyboardInputMapper::getOrientation() {
@@ -351,8 +351,8 @@
policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
}
- out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, deviceId, mSource,
- getDisplayId(), policyFlags,
+ out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when, readTime, deviceId,
+ getEventSource(), getDisplayId(), policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, flags,
keyCode, scanCode, keyMetaState, downTime));
return out;
@@ -478,12 +478,12 @@
std::list<NotifyArgs> out;
size_t n = mKeyDowns.size();
for (size_t i = 0; i < n; i++) {
- out.emplace_back(NotifyKeyArgs(getContext()->getNextId(), when,
- systemTime(SYSTEM_TIME_MONOTONIC), getDeviceId(), mSource,
- getDisplayId(), /*policyFlags=*/0, AKEY_EVENT_ACTION_UP,
- mKeyDowns[i].flags | AKEY_EVENT_FLAG_CANCELED,
- mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
- mKeyDowns[i].downTime));
+ out.emplace_back(
+ NotifyKeyArgs(getContext()->getNextId(), when, systemTime(SYSTEM_TIME_MONOTONIC),
+ getDeviceId(), getEventSource(), getDisplayId(), /*policyFlags=*/0,
+ AKEY_EVENT_ACTION_UP, mKeyDowns[i].flags | AKEY_EVENT_FLAG_CANCELED,
+ mKeyDowns[i].keyCode, mKeyDowns[i].scanCode, AMETA_NONE,
+ mKeyDowns[i].downTime));
}
mKeyDowns.clear();
mMetaState = AMETA_NONE;
@@ -495,4 +495,14 @@
context.setLastKeyDownTimestamp(downTime);
}
+uint32_t KeyboardInputMapper::getEventSource() const {
+ // For all input events generated by this mapper, use the source that's shared across all
+ // KeyboardInputMappers for this device in case there are more than one.
+ static constexpr auto ALL_KEYBOARD_SOURCES =
+ AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD;
+ const auto deviceSources = getDeviceContext().getDeviceSources();
+ LOG_ALWAYS_FATAL_IF((deviceSources & mMapperSource) != mMapperSource);
+ return deviceSources & ALL_KEYBOARD_SOURCES;
+}
+
} // namespace android
diff --git a/services/inputflinger/reader/mapper/KeyboardInputMapper.h b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
index c7df558..2df0b85 100644
--- a/services/inputflinger/reader/mapper/KeyboardInputMapper.h
+++ b/services/inputflinger/reader/mapper/KeyboardInputMapper.h
@@ -60,7 +60,10 @@
int32_t flags{};
};
- uint32_t mSource{};
+ // The keyboard source for this mapper. Events generated should use the source shared
+ // by all KeyboardInputMappers for this input device.
+ uint32_t mMapperSource{};
+
std::optional<KeyboardLayoutInfo> mKeyboardLayoutInfo;
std::vector<KeyDown> mKeyDowns{}; // keys that are down
@@ -106,6 +109,7 @@
std::optional<DisplayViewport> findViewport(const InputReaderConfiguration& readerConfig);
[[nodiscard]] std::list<NotifyArgs> cancelAllDownKeys(nsecs_t when);
void onKeyDownProcessed(nsecs_t downTime);
+ uint32_t getEventSource() const;
};
} // namespace android
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 3ea3c20..fd8224a 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -189,10 +189,14 @@
void MultiTouchInputMapper::configureRawPointerAxes() {
TouchInputMapper::configureRawPointerAxes();
- // We can safely assume that ABS_MT_POSITION_X and _Y axes will be available, as EventHub won't
- // classify a device as multitouch if they're not present.
- mRawPointerAxes.x = getAbsoluteAxisInfo(ABS_MT_POSITION_X).value();
- mRawPointerAxes.y = getAbsoluteAxisInfo(ABS_MT_POSITION_Y).value();
+ // TODO(b/351870641): Investigate why we are sometime not getting valid axis infos for the x/y
+ // axes, even though those axes are required to be supported.
+ if (const auto xInfo = getAbsoluteAxisInfo(ABS_MT_POSITION_X); xInfo.has_value()) {
+ mRawPointerAxes.x = *xInfo;
+ }
+ if (const auto yInfo = getAbsoluteAxisInfo(ABS_MT_POSITION_Y); yInfo.has_value()) {
+ mRawPointerAxes.y = *yInfo;
+ }
mRawPointerAxes.touchMajor = getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR);
mRawPointerAxes.touchMinor = getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR);
mRawPointerAxes.toolMajor = getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR);
diff --git a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
index 869feb4..cef1837 100644
--- a/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/SingleTouchInputMapper.cpp
@@ -72,10 +72,14 @@
void SingleTouchInputMapper::configureRawPointerAxes() {
TouchInputMapper::configureRawPointerAxes();
- // We can safely assume that ABS_X and _Y axes will be available, as EventHub won't classify a
- // device as a touch device if they're not present.
- mRawPointerAxes.x = getAbsoluteAxisInfo(ABS_X).value();
- mRawPointerAxes.y = getAbsoluteAxisInfo(ABS_Y).value();
+ // TODO(b/351870641): Investigate why we are sometime not getting valid axis infos for the x/y
+ // axes, even though those axes are required to be supported.
+ if (const auto xInfo = getAbsoluteAxisInfo(ABS_X); xInfo.has_value()) {
+ mRawPointerAxes.x = *xInfo;
+ }
+ if (const auto yInfo = getAbsoluteAxisInfo(ABS_Y); yInfo.has_value()) {
+ mRawPointerAxes.y = *yInfo;
+ }
mRawPointerAxes.pressure = getAbsoluteAxisInfo(ABS_PRESSURE);
mRawPointerAxes.toolMajor = getAbsoluteAxisInfo(ABS_TOOL_WIDTH);
mRawPointerAxes.distance = getAbsoluteAxisInfo(ABS_DISTANCE);
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 65e0429..95283ba 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -70,6 +70,7 @@
"InputTraceSession.cpp",
"InputTracingTest.cpp",
"InstrumentedInputReader.cpp",
+ "JoystickInputMapper_test.cpp",
"LatencyTracker_test.cpp",
"MultiTouchMotionAccumulator_test.cpp",
"NotifyArgs_test.cpp",
@@ -78,10 +79,12 @@
"PropertyProvider_test.cpp",
"RotaryEncoderInputMapper_test.cpp",
"SlopController_test.cpp",
+ "SwitchInputMapper_test.cpp",
"SyncQueue_test.cpp",
"TimerProvider_test.cpp",
"TestInputListener.cpp",
"TouchpadInputMapper_test.cpp",
+ "VibratorInputMapper_test.cpp",
"MultiTouchInputMapper_test.cpp",
"KeyboardInputMapper_test.cpp",
"UinputDevice.cpp",
@@ -109,7 +112,6 @@
},
},
static_libs: [
- "android.companion.virtualdevice.flags-aconfig-cc-test",
"libflagtest",
"libgmock",
],
diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp
index 727237f..b27d02d 100644
--- a/services/inputflinger/tests/CursorInputMapper_test.cpp
+++ b/services/inputflinger/tests/CursorInputMapper_test.cpp
@@ -17,6 +17,7 @@
#include "CursorInputMapper.h"
#include <list>
+#include <optional>
#include <string>
#include <tuple>
#include <variant>
@@ -93,38 +94,6 @@
return v;
}
-/**
- * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper.
- *
- * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates
- * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input
- * device doesn't set its associated viewport when it's configured.
- *
- * TODO(b/319217713): work out a way to avoid this fake.
- */
-class ViewportFakingInputDeviceContext : public InputDeviceContext {
-public:
- ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
- std::optional<DisplayViewport> viewport)
- : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {}
-
- ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
- ui::Rotation orientation)
- : ViewportFakingInputDeviceContext(device, eventHubId,
- createPrimaryViewport(orientation)) {}
-
- std::optional<DisplayViewport> getAssociatedViewport() const override {
- return mAssociatedViewport;
- }
-
- void setViewport(const std::optional<DisplayViewport>& viewport) {
- mAssociatedViewport = viewport;
- }
-
-private:
- std::optional<DisplayViewport> mAssociatedViewport;
-};
-
} // namespace
namespace input_flags = com::android::input::flags;
@@ -163,7 +132,6 @@
}
void createMapper() {
- createDevice();
mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
}
@@ -542,9 +510,9 @@
// need to be rotated.
mPropertyMap.addProperty("cursor.mode", "navigation");
mPropertyMap.addProperty("cursor.orientationAware", "1");
- createDevice();
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation90);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport)
+ .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90)));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, 1));
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1, 1, 1, 1));
@@ -560,9 +528,9 @@
// Since InputReader works in the un-rotated coordinate space, only devices that are not
// orientation-aware are affected by display rotation.
mPropertyMap.addProperty("cursor.mode", "navigation");
- createDevice();
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation0);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport)
+ .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation0)));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, 1));
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1, 1, 1, 1));
@@ -573,7 +541,8 @@
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, -1, 0));
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, -1, 1));
- deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation90));
+ EXPECT_CALL((*mDevice), getAssociatedViewport)
+ .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90)));
std::list<NotifyArgs> args =
mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
InputReaderConfiguration::Change::DISPLAY_INFO);
@@ -586,7 +555,8 @@
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, 0, -1));
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, -1, -1));
- deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation180));
+ EXPECT_CALL((*mDevice), getAssociatedViewport)
+ .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation180)));
args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
InputReaderConfiguration::Change::DISPLAY_INFO);
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 0, -1));
@@ -598,7 +568,8 @@
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 0, 1, 0));
ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1, 1, 1, -1));
- deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation270));
+ EXPECT_CALL((*mDevice), getAssociatedViewport)
+ .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation270)));
args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
InputReaderConfiguration::Change::DISPLAY_INFO);
ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0, 1, 1, 0));
@@ -652,9 +623,8 @@
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
// Set up the secondary display as the display on which the pointer should be shown.
// The InputDevice is not associated with any display.
- createDevice();
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
// Ensure input events are generated for the secondary display.
@@ -673,10 +643,9 @@
DisplayViewport secondaryViewport = createSecondaryViewport();
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
// Set up the primary display as the display on which the pointer should be shown.
- createDevice();
// Associate the InputDevice with the secondary display.
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
// With PointerChoreographer enabled, there could be a PointerController for the associated
// display even if it is different from the pointer display. So the mapper should generate an
@@ -1032,9 +1001,8 @@
mPropertyMap.addProperty("cursor.mode", "pointer");
DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0);
mReaderConfiguration.setDisplayViewports({primaryViewport});
- createDevice();
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, primaryViewport);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -1070,12 +1038,10 @@
mReaderConfiguration.setDisplayViewports({primaryViewport});
// Disable acceleration for the display.
mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID);
- createDevice();
// Don't associate the device with the display yet.
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID,
- /*viewport=*/std::nullopt);
- mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(std::nullopt));
+ mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -1089,7 +1055,7 @@
ASSERT_GT(coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y), 20.f);
// Now associate the device with the display, and verify that acceleration is disabled.
- deviceContext.setViewport(primaryViewport);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport));
args += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
InputReaderConfiguration::Change::DISPLAY_INFO);
args.clear();
diff --git a/services/inputflinger/tests/EventHub_test.cpp b/services/inputflinger/tests/EventHub_test.cpp
index 2e296da..0e3d15a 100644
--- a/services/inputflinger/tests/EventHub_test.cpp
+++ b/services/inputflinger/tests/EventHub_test.cpp
@@ -48,9 +48,6 @@
case EventHubInterface::DEVICE_REMOVED:
ALOGI("Device removed: %i", event.deviceId);
break;
- case EventHubInterface::FINISHED_DEVICE_SCAN:
- ALOGI("Finished device scan.");
- break;
}
} else {
ALOGI("Device %" PRId32 " : time = %" PRId64 ", type %i, code %i, value %i",
@@ -145,15 +142,13 @@
// None of the existing system devices should be changing while this test is run.
// Check that the returned device ids are unique for all of the existing devices.
EXPECT_EQ(existingDevices.size(), events.size() - 1);
- // The last event should be "finished device scan"
- EXPECT_EQ(EventHubInterface::FINISHED_DEVICE_SCAN, events[events.size() - 1].type);
}
int32_t EventHubTest::waitForDeviceCreation() {
// Wait a little longer than usual, to ensure input device has time to be created
std::vector<RawEvent> events = getEvents(2);
- if (events.size() != 2) {
- ADD_FAILURE() << "Instead of 2 events, received " << events.size();
+ if (events.size() != 1) {
+ ADD_FAILURE() << "Instead of 1 event, received " << events.size();
return 0; // this value is unused
}
const RawEvent& deviceAddedEvent = events[0];
@@ -161,21 +156,15 @@
InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceAddedEvent.deviceId);
const int32_t deviceId = deviceAddedEvent.deviceId;
EXPECT_EQ(identifier.name, mKeyboard->getName());
- const RawEvent& finishedDeviceScanEvent = events[1];
- EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
- finishedDeviceScanEvent.type);
return deviceId;
}
void EventHubTest::waitForDeviceClose(int32_t deviceId) {
std::vector<RawEvent> events = getEvents(2);
- ASSERT_EQ(2U, events.size());
+ ASSERT_EQ(1U, events.size());
const RawEvent& deviceRemovedEvent = events[0];
EXPECT_EQ(static_cast<int32_t>(EventHubInterface::DEVICE_REMOVED), deviceRemovedEvent.type);
EXPECT_EQ(deviceId, deviceRemovedEvent.deviceId);
- const RawEvent& finishedDeviceScanEvent = events[1];
- EXPECT_EQ(static_cast<int32_t>(EventHubInterface::FINISHED_DEVICE_SCAN),
- finishedDeviceScanEvent.type);
}
void EventHubTest::assertNoMoreEvents() {
diff --git a/services/inputflinger/tests/FakeEventHub.cpp b/services/inputflinger/tests/FakeEventHub.cpp
index 7079278..31fbf20 100644
--- a/services/inputflinger/tests/FakeEventHub.cpp
+++ b/services/inputflinger/tests/FakeEventHub.cpp
@@ -88,10 +88,6 @@
return device->disable();
}
-void FakeEventHub::finishDeviceScan() {
- enqueueEvent(ARBITRARY_TIME, READ_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
-}
-
void FakeEventHub::addConfigurationProperty(int32_t deviceId, const char* key, const char* value) {
getDevice(deviceId)->configuration.addProperty(key, value);
}
diff --git a/services/inputflinger/tests/FakeEventHub.h b/services/inputflinger/tests/FakeEventHub.h
index c2c875f..3d8dddd 100644
--- a/services/inputflinger/tests/FakeEventHub.h
+++ b/services/inputflinger/tests/FakeEventHub.h
@@ -112,8 +112,6 @@
status_t enableDevice(int32_t deviceId) override;
status_t disableDevice(int32_t deviceId) override;
- void finishDeviceScan();
-
void addConfigurationProperty(int32_t deviceId, const char* key, const char* value);
void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration);
diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
index 3df05f4..db68d8a 100644
--- a/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
+++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
@@ -54,13 +54,6 @@
ASSERT_EQ(nullptr, mFilteredEvent);
}
-void FakeInputDispatcherPolicy::assertNotifyConfigurationChangedWasCalled(nsecs_t when) {
- std::scoped_lock lock(mLock);
- ASSERT_TRUE(mConfigurationChangedTime) << "Timed out waiting for configuration changed call";
- ASSERT_EQ(*mConfigurationChangedTime, when);
- mConfigurationChangedTime = std::nullopt;
-}
-
void FakeInputDispatcherPolicy::assertNotifySwitchWasCalled(const NotifySwitchArgs& args) {
std::scoped_lock lock(mLock);
ASSERT_TRUE(mLastNotifySwitch);
@@ -342,11 +335,6 @@
return std::make_optional(item);
}
-void FakeInputDispatcherPolicy::notifyConfigurationChanged(nsecs_t when) {
- std::scoped_lock lock(mLock);
- mConfigurationChangedTime = when;
-}
-
void FakeInputDispatcherPolicy::notifyWindowUnresponsive(const sp<IBinder>& connectionToken,
std::optional<gui::Pid> pid,
const std::string&) {
diff --git a/services/inputflinger/tests/FakeInputDispatcherPolicy.h b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
index a0f3ea9..a9e39d1 100644
--- a/services/inputflinger/tests/FakeInputDispatcherPolicy.h
+++ b/services/inputflinger/tests/FakeInputDispatcherPolicy.h
@@ -66,7 +66,6 @@
void assertFilterInputEventWasCalled(const NotifyKeyArgs& args);
void assertFilterInputEventWasCalled(const NotifyMotionArgs& args, vec2 point);
void assertFilterInputEventWasNotCalled();
- void assertNotifyConfigurationChangedWasCalled(nsecs_t when);
void assertNotifySwitchWasCalled(const NotifySwitchArgs& args);
void assertOnPointerDownEquals(const sp<IBinder>& touchedToken);
void assertOnPointerDownWasNotCalled();
@@ -121,7 +120,6 @@
private:
std::mutex mLock;
std::unique_ptr<InputEvent> mFilteredEvent GUARDED_BY(mLock);
- std::optional<nsecs_t> mConfigurationChangedTime GUARDED_BY(mLock);
sp<IBinder> mOnPointerDownToken GUARDED_BY(mLock);
std::optional<NotifySwitchArgs> mLastNotifySwitch GUARDED_BY(mLock);
@@ -173,7 +171,6 @@
std::condition_variable& condition)
REQUIRES(mLock);
- void notifyConfigurationChanged(nsecs_t when) override;
void notifyWindowUnresponsive(const sp<IBinder>& connectionToken, std::optional<gui::Pid> pid,
const std::string&) override;
void notifyWindowResponsive(const sp<IBinder>& connectionToken,
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 04ed670..e505850 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -411,16 +411,6 @@
<< "Should reject motion events with duplicate pointer ids.";
}
-/* Test InputDispatcher for notifyConfigurationChanged and notifySwitch events */
-
-TEST_F(InputDispatcherTest, NotifyConfigurationChanged_CallsPolicy) {
- constexpr nsecs_t eventTime = 20;
- mDispatcher->notifyConfigurationChanged({/*id=*/10, eventTime});
- ASSERT_TRUE(mDispatcher->waitForIdle());
-
- mFakePolicy->assertNotifyConfigurationChangedWasCalled(eventTime);
-}
-
TEST_F(InputDispatcherTest, NotifySwitch_CallsPolicy) {
NotifySwitchArgs args(InputEvent::nextId(), /*eventTime=*/20, /*policyFlags=*/0,
/*switchValues=*/1,
@@ -4178,6 +4168,7 @@
* the event routing because the first window prevents splitting.
*/
TEST_F(InputDispatcherTest, SplitTouchesSendCorrectActionDownTimeForNewWindow) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window1 =
sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID);
@@ -4235,6 +4226,7 @@
* (and the touch occurred outside of the bounds of window1).
*/
TEST_F(InputDispatcherTest, SplitTouchesDropsEventForNonSplittableSecondWindow) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window1 =
sp<FakeWindowHandle>::make(application, mDispatcher, "Window1", DISPLAY_ID);
@@ -4491,6 +4483,202 @@
window->assertNoEvents();
}
+/**
+ * A spy window sits above a window with NO_INPUT_CHANNEL. Ensure that the spy receives events even
+ * though the window underneath should not get any events.
+ */
+TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowSinglePointer) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+ sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+ ui::LogicalDisplayId::DEFAULT);
+ spyWindow->setFrame(Rect(0, 0, 100, 100));
+ spyWindow->setTrustedOverlay(true);
+ spyWindow->setPreventSplitting(true);
+ spyWindow->setSpy(true);
+ // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+ sp<FakeWindowHandle> inputSinkWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+ ui::LogicalDisplayId::DEFAULT);
+ inputSinkWindow->setFrame(Rect(0, 0, 100, 100));
+ inputSinkWindow->setTrustedOverlay(true);
+ inputSinkWindow->setPreventSplitting(true);
+ inputSinkWindow->setNoInputChannel(true);
+
+ mDispatcher->onWindowInfosChanged(
+ {{*spyWindow->getInfo(), *inputSinkWindow->getInfo()}, {}, 0, 0});
+
+ // Tap the spy window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(51))
+ .build());
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+ .build());
+
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP)));
+ inputSinkWindow->assertNoEvents();
+}
+
+/**
+ * A spy window sits above a window with NO_INPUT_CHANNEL. Ensure that the spy receives events even
+ * though the window underneath should not get any events.
+ * Same test as above, but with two pointers touching instead of one.
+ */
+TEST_F(InputDispatcherTest, NonSplittableSpyAboveNoInputChannelWindowTwoPointers) {
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+ sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+ ui::LogicalDisplayId::DEFAULT);
+ spyWindow->setFrame(Rect(0, 0, 100, 100));
+ spyWindow->setTrustedOverlay(true);
+ spyWindow->setPreventSplitting(true);
+ spyWindow->setSpy(true);
+ // Another window below spy that would have both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+ sp<FakeWindowHandle> inputSinkWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+ ui::LogicalDisplayId::DEFAULT);
+ inputSinkWindow->setFrame(Rect(0, 0, 100, 100));
+ inputSinkWindow->setTrustedOverlay(true);
+ inputSinkWindow->setPreventSplitting(true);
+ inputSinkWindow->setNoInputChannel(true);
+
+ mDispatcher->onWindowInfosChanged(
+ {{*spyWindow->getInfo(), *inputSinkWindow->getInfo()}, {}, 0, 0});
+
+ // Both fingers land into the spy window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(51))
+ .build());
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(11))
+ .build());
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(10).y(11))
+ .build());
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(50).y(51))
+ .build());
+
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+ spyWindow->consumeMotionPointerDown(1, WithPointerCount(2));
+ spyWindow->consumeMotionPointerUp(1, WithPointerCount(2));
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP)));
+ inputSinkWindow->assertNoEvents();
+}
+
+/** Check the behaviour for cases where input sink prevents or doesn't prevent splitting. */
+class SpyThatPreventsSplittingWithApplicationFixture : public InputDispatcherTest,
+ public ::testing::WithParamInterface<bool> {
+};
+
+/**
+ * Three windows:
+ * - An application window (app window)
+ * - A spy window that does not overlap the app window. Has PREVENT_SPLITTING flag
+ * - A window below the spy that has NO_INPUT_CHANNEL (call it 'inputSink')
+ *
+ * The spy window is side-by-side with the app window. The inputSink is below the spy.
+ * We first touch the area outside of the appWindow, but inside spyWindow.
+ * Only the SPY window should get the DOWN event.
+ * The spy pilfers after receiving the first DOWN event.
+ * Next, we touch the app window.
+ * The spy should receive POINTER_DOWN(1) (since spy is preventing splits).
+ * Also, since the spy is already pilfering the first pointer, it will be sent the remaining new
+ * pointers automatically, as well.
+ * Next, the first pointer (from the spy) is lifted.
+ * Spy should get POINTER_UP(0).
+ * This event should not go to the app because the app never received this pointer to begin with.
+ * Now, lift the remaining pointer and check that the spy receives UP event.
+ *
+ * Finally, send a new ACTION_DOWN event to the spy and check that it's received.
+ * This test attempts to reproduce a crash in the dispatcher.
+ */
+TEST_P(SpyThatPreventsSplittingWithApplicationFixture, SpyThatPreventsSplittingWithApplication) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+
+ sp<FakeWindowHandle> spyWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "Spy",
+ ui::LogicalDisplayId::DEFAULT);
+ spyWindow->setFrame(Rect(100, 100, 200, 200));
+ spyWindow->setTrustedOverlay(true);
+ spyWindow->setPreventSplitting(true);
+ spyWindow->setSpy(true);
+ // Another window below spy that has both NO_INPUT_CHANNEL and PREVENT_SPLITTING
+ sp<FakeWindowHandle> inputSinkWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Input sink below spy",
+ ui::LogicalDisplayId::DEFAULT);
+ inputSinkWindow->setFrame(Rect(100, 100, 200, 200)); // directly below the spy
+ inputSinkWindow->setTrustedOverlay(true);
+ inputSinkWindow->setPreventSplitting(GetParam());
+ inputSinkWindow->setNoInputChannel(true);
+
+ sp<FakeWindowHandle> appWindow = sp<FakeWindowHandle>::make(application, mDispatcher, "App",
+ ui::LogicalDisplayId::DEFAULT);
+ appWindow->setFrame(Rect(0, 0, 100, 100));
+
+ mDispatcher->setFocusedApplication(ui::LogicalDisplayId::DEFAULT, application);
+ mDispatcher->onWindowInfosChanged(
+ {{*spyWindow->getInfo(), *inputSinkWindow->getInfo(), *appWindow->getInfo()},
+ {},
+ 0,
+ 0});
+
+ // First finger lands outside of the appWindow, but inside of the spy window
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(150))
+ .build());
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+
+ mDispatcher->pilferPointers(spyWindow->getToken());
+
+ // Second finger lands in the app, and goes to the spy window. It doesn't go to the app because
+ // the spy is already pilfering the first pointer, and this automatically grants the remaining
+ // new pointers to the spy, as well.
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+ .build());
+
+ spyWindow->consumeMotionPointerDown(1, WithPointerCount(2));
+
+ // Now lift up the first pointer
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(POINTER_0_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/0, ToolType::FINGER).x(150).y(150))
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+ .build());
+ spyWindow->consumeMotionPointerUp(0, WithPointerCount(2));
+
+ // And lift the remaining pointer!
+ mDispatcher->notifyMotion(
+ MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(/*id=*/1, ToolType::FINGER).x(50).y(50))
+ .build());
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithPointerCount(1)));
+
+ // Now send a new DOWN, which should again go to spy.
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(150))
+ .build());
+ spyWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN)));
+ // The app window doesn't get any events this entire time because the spy received the events
+ // first and pilfered, which makes all new pointers go to it as well.
+ appWindow->assertNoEvents();
+}
+
+// Behaviour should be the same regardless of whether inputSink supports splitting.
+INSTANTIATE_TEST_SUITE_P(SpyThatPreventsSplittingWithApplication,
+ SpyThatPreventsSplittingWithApplicationFixture, testing::Bool());
+
TEST_F(InputDispatcherTest, HoverWithSpyWindows) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
@@ -5398,6 +5586,7 @@
}
TEST_F(InputDispatcherTest, NonSplitTouchableWindowReceivesMultiTouch) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window =
sp<FakeWindowHandle>::make(application, mDispatcher, "Fake Window",
@@ -5443,6 +5632,7 @@
* "incomplete" gestures.
*/
TEST_F(InputDispatcherTest, SplittableAndNonSplittableWindows) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> leftWindow =
sp<FakeWindowHandle>::make(application, mDispatcher, "Left splittable Window",
@@ -5472,6 +5662,73 @@
rightWindow->assertNoEvents();
}
+/**
+ * Two windows: left and right. The left window has PREVENT_SPLITTING input config. Device A sends a
+ * down event to the right window. Device B sends a down event to the left window, and then a
+ * POINTER_DOWN event to the right window. However, since the left window prevents splitting, the
+ * POINTER_DOWN event should only go to the left window, and not to the right window.
+ * This test attempts to reproduce a crash.
+ */
+TEST_F(InputDispatcherTest, MultiDeviceTwoWindowsPreventSplitting) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
+ std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
+ sp<FakeWindowHandle> leftWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Left window (prevent splitting)",
+ ui::LogicalDisplayId::DEFAULT);
+ leftWindow->setFrame(Rect(0, 0, 100, 100));
+ leftWindow->setPreventSplitting(true);
+
+ sp<FakeWindowHandle> rightWindow =
+ sp<FakeWindowHandle>::make(application, mDispatcher, "Right window",
+ ui::LogicalDisplayId::DEFAULT);
+ rightWindow->setFrame(Rect(100, 0, 200, 100));
+
+ mDispatcher->onWindowInfosChanged(
+ {{*leftWindow->getInfo(), *rightWindow->getInfo()}, {}, 0, 0});
+
+ const DeviceId deviceA = 9;
+ const DeviceId deviceB = 3;
+ // Touch the right window with device A
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+ .deviceId(deviceA)
+ .build());
+ rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceA)));
+ // Touch the left window with device B
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .deviceId(deviceB)
+ .build());
+ leftWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_DOWN), WithDeviceId(deviceB)));
+ // Send a second pointer from device B to the right window. It shouldn't go to the right window
+ // because the left window prevents splitting.
+ mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
+ .deviceId(deviceB)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+ .build());
+ leftWindow->consumeMotionPointerDown(1, WithDeviceId(deviceB));
+
+ // Finish the gesture for both devices
+ mDispatcher->notifyMotion(MotionArgsBuilder(POINTER_1_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .deviceId(deviceB)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .pointer(PointerBuilder(1, ToolType::FINGER).x(120).y(120))
+ .build());
+ leftWindow->consumeMotionPointerUp(1, WithDeviceId(deviceB));
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(50).y(50))
+ .deviceId(deviceB)
+ .build());
+ leftWindow->consumeMotionEvent(
+ AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceB), WithPointerId(0, 0)));
+ mDispatcher->notifyMotion(MotionArgsBuilder(ACTION_UP, AINPUT_SOURCE_TOUCHSCREEN)
+ .pointer(PointerBuilder(0, ToolType::FINGER).x(150).y(50))
+ .deviceId(deviceA)
+ .build());
+ rightWindow->consumeMotionEvent(AllOf(WithMotionAction(ACTION_UP), WithDeviceId(deviceA)));
+}
+
TEST_F(InputDispatcherTest, TouchpadThreeFingerSwipeOnlySentToTrustedOverlays) {
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window",
@@ -8160,6 +8417,7 @@
* the previous window should receive this event and not be dropped.
*/
TEST_F(InputDispatcherMultiDeviceTest, SingleDevicePointerDownEventRetentionWithoutWindowTarget) {
+ SCOPED_FLAG_OVERRIDE(split_all_touches, false);
std::shared_ptr<FakeApplicationHandle> application = std::make_shared<FakeApplicationHandle>();
sp<FakeWindowHandle> window = sp<FakeWindowHandle>::make(application, mDispatcher, "Window",
ui::LogicalDisplayId::DEFAULT);
diff --git a/services/inputflinger/tests/InputMapperTest.cpp b/services/inputflinger/tests/InputMapperTest.cpp
index 5722444..7dff144 100644
--- a/services/inputflinger/tests/InputMapperTest.cpp
+++ b/services/inputflinger/tests/InputMapperTest.cpp
@@ -26,7 +26,9 @@
namespace android {
using testing::_;
+using testing::NiceMock;
using testing::Return;
+using testing::ReturnRef;
void InputMapperUnitTest::SetUpWithBus(int bus) {
mFakePolicy = sp<FakeInputReaderPolicy>::make();
@@ -43,16 +45,11 @@
EXPECT_CALL(mMockEventHub, getConfiguration(EVENTHUB_ID)).WillRepeatedly([&](int32_t) {
return mPropertyMap;
});
-}
-void InputMapperUnitTest::createDevice() {
- mDevice = std::make_unique<InputDevice>(&mMockInputReaderContext, DEVICE_ID,
- /*generation=*/2, mIdentifier);
- mDevice->addEmptyEventHubDevice(EVENTHUB_ID);
+ mDevice = std::make_unique<NiceMock<MockInputDevice>>(&mMockInputReaderContext, DEVICE_ID,
+ /*generation=*/2, mIdentifier);
+ ON_CALL((*mDevice), getConfiguration).WillByDefault(ReturnRef(mPropertyMap));
mDeviceContext = std::make_unique<InputDeviceContext>(*mDevice, EVENTHUB_ID);
- std::list<NotifyArgs> args =
- mDevice->configure(systemTime(), mReaderConfiguration, /*changes=*/{});
- ASSERT_THAT(args, testing::ElementsAre(testing::VariantWith<NotifyDeviceResetArgs>(_)));
}
void InputMapperUnitTest::setupAxis(int axis, bool valid, int32_t min, int32_t max,
@@ -89,6 +86,13 @@
}
}
+void InputMapperUnitTest::setSwitchState(int32_t state, std::set<int32_t> switchCodes) {
+ for (const auto& switchCode : switchCodes) {
+ EXPECT_CALL(mMockEventHub, getSwitchState(EVENTHUB_ID, switchCode))
+ .WillRepeatedly(testing::Return(static_cast<int>(state)));
+ }
+}
+
std::list<NotifyArgs> InputMapperUnitTest::process(int32_t type, int32_t code, int32_t value) {
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
return process(when, type, code, value);
diff --git a/services/inputflinger/tests/InputMapperTest.h b/services/inputflinger/tests/InputMapperTest.h
index 5bd8cda..fc27e4f 100644
--- a/services/inputflinger/tests/InputMapperTest.h
+++ b/services/inputflinger/tests/InputMapperTest.h
@@ -43,13 +43,6 @@
virtual void SetUp() override { SetUpWithBus(0); }
virtual void SetUpWithBus(int bus);
- /**
- * Initializes mDevice and mDeviceContext. When this happens, mDevice takes a copy of
- * mPropertyMap, so tests that need to set configuration properties should do so before calling
- * this. Others will most likely want to call it in their SetUp method.
- */
- void createDevice();
-
void setupAxis(int axis, bool valid, int32_t min, int32_t max, int32_t resolution);
void expectScanCodes(bool present, std::set<int> scanCodes);
@@ -58,6 +51,8 @@
void setKeyCodeState(KeyState state, std::set<int> keyCodes);
+ void setSwitchState(int32_t state, std::set<int32_t> switchCodes);
+
std::list<NotifyArgs> process(int32_t type, int32_t code, int32_t value);
std::list<NotifyArgs> process(nsecs_t when, int32_t type, int32_t code, int32_t value);
@@ -65,7 +60,7 @@
MockEventHubInterface mMockEventHub;
sp<FakeInputReaderPolicy> mFakePolicy;
MockInputReaderContext mMockInputReaderContext;
- std::unique_ptr<InputDevice> mDevice;
+ std::unique_ptr<MockInputDevice> mDevice;
std::unique_ptr<InputDeviceContext> mDeviceContext;
InputReaderConfiguration mReaderConfiguration;
@@ -121,11 +116,12 @@
T& constructAndAddMapper(Args... args) {
// ensure a device entry exists for this eventHubId
mDevice->addEmptyEventHubDevice(EVENTHUB_ID);
- // configure the empty device
- configureDevice(/*changes=*/{});
- return mDevice->constructAndAddMapper<T>(EVENTHUB_ID, mFakePolicy->getReaderConfiguration(),
- args...);
+ auto& mapper =
+ mDevice->constructAndAddMapper<T>(EVENTHUB_ID,
+ mFakePolicy->getReaderConfiguration(), args...);
+ configureDevice(/*changes=*/{});
+ return mapper;
}
void setDisplayInfoAndReconfigure(ui::LogicalDisplayId displayId, int32_t width, int32_t height,
diff --git a/services/inputflinger/tests/InputProcessor_test.cpp b/services/inputflinger/tests/InputProcessor_test.cpp
index f7e5e67..d4c5a00 100644
--- a/services/inputflinger/tests/InputProcessor_test.cpp
+++ b/services/inputflinger/tests/InputProcessor_test.cpp
@@ -63,20 +63,6 @@
void SetUp() override { mProcessor = std::make_unique<InputProcessor>(mTestListener); }
};
-/**
- * Create a basic configuration change and send it to input processor.
- * Expect that the event is received by the next input stage, unmodified.
- */
-TEST_F(InputProcessorTest, SendToNextStage_NotifyConfigurationChangedArgs) {
- // Create a basic configuration change and send to processor
- NotifyConfigurationChangedArgs args(/*sequenceNum=*/1, /*eventTime=*/2);
-
- mProcessor->notifyConfigurationChanged(args);
- NotifyConfigurationChangedArgs outArgs;
- ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyConfigurationChangedWasCalled(&outArgs));
- ASSERT_EQ(args, outArgs);
-}
-
TEST_F(InputProcessorTest, SendToNextStage_NotifyKeyArgs) {
// Create a basic key event and send to processor
NotifyKeyArgs args(/*sequenceNum=*/1, /*eventTime=*/2, /*readTime=*/21, /*deviceId=*/3,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 8cc34e9..48fd717 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -24,19 +24,16 @@
#include <InputReader.h>
#include <InputReaderBase.h>
#include <InputReaderFactory.h>
-#include <JoystickInputMapper.h>
#include <KeyboardInputMapper.h>
#include <MultiTouchInputMapper.h>
#include <NotifyArgsBuilders.h>
#include <PeripheralController.h>
#include <SensorInputMapper.h>
#include <SingleTouchInputMapper.h>
-#include <SwitchInputMapper.h>
#include <TestEventMatchers.h>
#include <TestInputListener.h>
#include <TouchInputMapper.h>
#include <UinputDevice.h>
-#include <VibratorInputMapper.h>
#include <android-base/thread_annotations.h>
#include <com_android_input_flags.h>
#include <ftl/enum.h>
@@ -624,7 +621,6 @@
if (configuration) {
mFakeEventHub->addConfigurationMap(eventHubId, configuration);
}
- mFakeEventHub->finishDeviceScan();
mReader->loopOnce();
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
@@ -758,8 +754,6 @@
mReader->pushNextDevice(device);
ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
-
NotifyDeviceResetArgs resetArgs;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_EQ(deviceId, resetArgs.deviceId);
@@ -775,7 +769,6 @@
disableDevice(deviceId);
mReader->loopOnce();
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasNotCalled());
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasNotCalled());
ASSERT_EQ(device->isEnabled(), false);
enableDevice(deviceId);
@@ -960,16 +953,6 @@
ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
}
-TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
- constexpr int32_t eventHubId = 1;
- addDevice(eventHubId, "ignored", InputDeviceClass::KEYBOARD, nullptr);
-
- NotifyConfigurationChangedArgs args;
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
- ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-}
-
TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
constexpr int32_t deviceId = END_RESERVED_ID + 1000;
constexpr ftl::Flags<InputDeviceClass> deviceClass = InputDeviceClass::KEYBOARD;
@@ -1074,7 +1057,6 @@
// The device is added after the input port associations are processed since
// we do not yet support dynamic device-to-display associations.
ASSERT_NO_FATAL_FAILURE(addDevice(eventHubId, "fake", deviceClass, nullptr));
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled());
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled());
ASSERT_NO_FATAL_FAILURE(mapper.assertConfigureWasCalled());
@@ -1104,8 +1086,6 @@
ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[0], "fake1", deviceClass, nullptr));
ASSERT_NO_FATAL_FAILURE(addDevice(eventHubIds[1], "fake2", deviceClass, nullptr));
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(nullptr));
-
NotifyDeviceResetArgs resetArgs;
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
ASSERT_EQ(deviceId, resetArgs.deviceId);
@@ -1477,9 +1457,8 @@
// Since this test is run on a real device, all the input devices connected
// to the test device will show up in mReader. We wait for those input devices to
// show up before beginning the tests.
- ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyInputDevicesChangedWasCalled());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
+ ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
}
};
@@ -1499,12 +1478,10 @@
// consider it as a valid device.
std::unique_ptr<UinputDevice> invalidDevice = createUinputDevice<InvalidUinputDevice>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
invalidDevice.reset();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesNotChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasNotCalled());
ASSERT_EQ(numDevices, mFakePolicy->getInputDevices().size());
}
@@ -1513,7 +1490,6 @@
std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
ASSERT_EQ(initialNumDevices + 1, mFakePolicy->getInputDevices().size());
const auto device = waitForDevice(keyboard->getName());
@@ -1524,7 +1500,6 @@
keyboard.reset();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
ASSERT_EQ(initialNumDevices, mFakePolicy->getInputDevices().size());
}
@@ -1532,21 +1507,14 @@
std::unique_ptr<UinputHomeKey> keyboard = createUinputDevice<UinputHomeKey>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- NotifyConfigurationChangedArgs configChangedArgs;
- ASSERT_NO_FATAL_FAILURE(
- mTestListener->assertNotifyConfigurationChangedWasCalled(&configChangedArgs));
- int32_t prevId = configChangedArgs.id;
- nsecs_t prevTimestamp = configChangedArgs.eventTime;
-
NotifyKeyArgs keyArgs;
keyboard->pressAndReleaseHomeKey();
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
- ASSERT_NE(prevId, keyArgs.id);
- prevId = keyArgs.id;
- ASSERT_LE(prevTimestamp, keyArgs.eventTime);
ASSERT_LE(keyArgs.eventTime, keyArgs.readTime);
- prevTimestamp = keyArgs.eventTime;
+
+ int32_t prevId = keyArgs.id;
+ nsecs_t prevTimestamp = keyArgs.eventTime;
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyKeyWasCalled(&keyArgs));
ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
@@ -1669,7 +1637,6 @@
mDevice = createUinputDevice<UinputTouchScreen>(Rect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT));
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto info = waitForDevice(mDevice->getName());
ASSERT_TRUE(info);
mDeviceInfo = *info;
@@ -1738,7 +1705,6 @@
UNIQUE_ID, isInputPortAssociation ? DISPLAY_PORT : NO_PORT,
ViewportType::INTERNAL);
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto info = waitForDevice(mDevice->getName());
ASSERT_TRUE(info);
mDeviceInfo = *info;
@@ -2071,7 +2037,6 @@
// Connecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
auto externalStylus = createUinputDevice<UinputExternalStylus>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto stylusInfo = waitForDevice(externalStylus->getName());
ASSERT_TRUE(stylusInfo);
@@ -2084,7 +2049,6 @@
// Disconnecting an external stylus mid-gesture should not interrupt the ongoing gesture stream.
externalStylus.reset();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyMotionWasNotCalled());
// Up
@@ -2142,7 +2106,6 @@
mStylusDeviceLifecycleTracker = createUinputDevice<T>();
mStylus = mStylusDeviceLifecycleTracker.get();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto info = waitForDevice(mStylus->getName());
ASSERT_TRUE(info);
mStylusInfo = *info;
@@ -2412,7 +2375,6 @@
std::unique_ptr<UinputExternalStylusWithPressure> stylus =
createUinputDevice<UinputExternalStylusWithPressure>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto stylusInfo = waitForDevice(stylus->getName());
ASSERT_TRUE(stylusInfo);
@@ -2430,7 +2392,6 @@
std::unique_ptr<UinputExternalStylusWithPressure> stylus =
createUinputDevice<UinputExternalStylusWithPressure>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto stylusInfo = waitForDevice(stylus->getName());
ASSERT_TRUE(stylusInfo);
@@ -2476,7 +2437,6 @@
std::unique_ptr<UinputExternalStylusWithPressure> stylus =
createUinputDevice<UinputExternalStylusWithPressure>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto stylusInfo = waitForDevice(stylus->getName());
ASSERT_TRUE(stylusInfo);
@@ -2556,7 +2516,6 @@
// touch pointers.
std::unique_ptr<UinputExternalStylus> stylus = createUinputDevice<UinputExternalStylus>();
ASSERT_NO_FATAL_FAILURE(mFakePolicy->assertInputDevicesChanged());
- ASSERT_NO_FATAL_FAILURE(mTestListener->assertNotifyConfigurationChangedWasCalled());
const auto stylusInfo = waitForDevice(stylus->getName());
ASSERT_TRUE(stylusInfo);
@@ -3058,106 +3017,6 @@
mapper.assertProcessWasCalled();
}
-// --- SwitchInputMapperTest ---
-
-class SwitchInputMapperTest : public InputMapperTest {
-protected:
-};
-
-TEST_F(SwitchInputMapperTest, GetSources) {
- SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
-
- ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper.getSources());
-}
-
-TEST_F(SwitchInputMapperTest, GetSwitchState) {
- SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
-
- mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 1);
- ASSERT_EQ(1, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-
- mFakeEventHub->setSwitchState(EVENTHUB_ID, SW_LID, 0);
- ASSERT_EQ(0, mapper.getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-}
-
-TEST_F(SwitchInputMapperTest, Process) {
- SwitchInputMapper& mapper = constructAndAddMapper<SwitchInputMapper>();
- std::list<NotifyArgs> out;
- out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_LID, 1);
- ASSERT_TRUE(out.empty());
- out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
- ASSERT_TRUE(out.empty());
- out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
- ASSERT_TRUE(out.empty());
- out = process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
-
- ASSERT_EQ(1u, out.size());
- const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
- ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
- ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
- ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
- args.switchMask);
- ASSERT_EQ(uint32_t(0), args.policyFlags);
-}
-
-// --- VibratorInputMapperTest ---
-class VibratorInputMapperTest : public InputMapperTest {
-protected:
- void SetUp() override { InputMapperTest::SetUp(DEVICE_CLASSES | InputDeviceClass::VIBRATOR); }
-};
-
-TEST_F(VibratorInputMapperTest, GetSources) {
- VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
- ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mapper.getSources());
-}
-
-TEST_F(VibratorInputMapperTest, GetVibratorIds) {
- VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
- ASSERT_EQ(mapper.getVibratorIds().size(), 2U);
-}
-
-TEST_F(VibratorInputMapperTest, Vibrate) {
- constexpr uint8_t DEFAULT_AMPLITUDE = 192;
- constexpr int32_t VIBRATION_TOKEN = 100;
- VibratorInputMapper& mapper = constructAndAddMapper<VibratorInputMapper>();
-
- VibrationElement pattern(2);
- VibrationSequence sequence(2);
- pattern.duration = std::chrono::milliseconds(200);
- pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
- {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
- sequence.addElement(pattern);
- pattern.duration = std::chrono::milliseconds(500);
- pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
- {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
- sequence.addElement(pattern);
-
- std::vector<int64_t> timings = {0, 1};
- std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
-
- ASSERT_FALSE(mapper.isVibrating());
- // Start vibrating
- std::list<NotifyArgs> out = mapper.vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
- ASSERT_TRUE(mapper.isVibrating());
- // Verify vibrator state listener was notified.
- mReader->loopOnce();
- ASSERT_EQ(1u, out.size());
- const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
- ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
- ASSERT_TRUE(vibrateArgs.isOn);
- // Stop vibrating
- out = mapper.cancelVibrate(VIBRATION_TOKEN);
- ASSERT_FALSE(mapper.isVibrating());
- // Verify vibrator state listener was notified.
- mReader->loopOnce();
- ASSERT_EQ(1u, out.size());
- const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
- ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
- ASSERT_FALSE(cancelArgs.isOn);
-}
-
// --- SensorInputMapperTest ---
class SensorInputMapperTest : public InputMapperTest {
@@ -4180,6 +4039,51 @@
ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_KEEP_TOUCH_MODE, args.flags);
}
+/**
+ * When there is more than one KeyboardInputMapper for an InputDevice, each mapper should produce
+ * events that use the shared keyboard source across all mappers. This is to ensure that each
+ * input device generates key events in a consistent manner, regardless of which mapper produces
+ * the event.
+ */
+TEST_F(KeyboardInputMapperTest, UsesSharedKeyboardSource) {
+ mFakeEventHub->addKey(EVENTHUB_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+
+ // Add a mapper with SOURCE_KEYBOARD
+ KeyboardInputMapper& keyboardMapper =
+ constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD);
+
+ process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
+ ASSERT_NO_FATAL_FAILURE(
+ mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD)));
+ process(keyboardMapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
+ ASSERT_NO_FATAL_FAILURE(
+ mFakeListener->assertNotifyKeyWasCalled(WithSource(AINPUT_SOURCE_KEYBOARD)));
+
+ // Add a mapper with SOURCE_DPAD
+ KeyboardInputMapper& dpadMapper =
+ constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_DPAD);
+ for (auto* mapper : {&keyboardMapper, &dpadMapper}) {
+ process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
+ WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD)));
+ process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
+ WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD)));
+ }
+
+ // Add a mapper with SOURCE_GAMEPAD
+ KeyboardInputMapper& gamepadMapper =
+ constructAndAddMapper<KeyboardInputMapper>(AINPUT_SOURCE_GAMEPAD);
+ for (auto* mapper : {&keyboardMapper, &dpadMapper, &gamepadMapper}) {
+ process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 1);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
+ WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD)));
+ process(*mapper, ARBITRARY_TIME, 0, EV_KEY, KEY_HOME, 0);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(
+ WithSource(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_DPAD | AINPUT_SOURCE_GAMEPAD)));
+ }
+}
+
// --- KeyboardInputMapperTest_ExternalAlphabeticDevice ---
class KeyboardInputMapperTest_ExternalAlphabeticDevice : public InputMapperTest {
@@ -10158,67 +10062,6 @@
ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
}
-// --- JoystickInputMapperTest ---
-
-class JoystickInputMapperTest : public InputMapperTest {
-protected:
- static const int32_t RAW_X_MIN;
- static const int32_t RAW_X_MAX;
- static const int32_t RAW_Y_MIN;
- static const int32_t RAW_Y_MAX;
-
- void SetUp() override {
- InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
- }
- void prepareAxes() {
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
- mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
- }
-
- void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
- }
-
- void processSync(JoystickInputMapper& mapper) {
- process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
- }
-
- void prepareVirtualDisplay(ui::Rotation orientation) {
- setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, VIRTUAL_DISPLAY_WIDTH,
- VIRTUAL_DISPLAY_HEIGHT, orientation, VIRTUAL_DISPLAY_UNIQUE_ID,
- NO_PORT, ViewportType::VIRTUAL);
- }
-};
-
-const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
-const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
-const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
-const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
-
-TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
- prepareAxes();
- JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
-
- mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);
-
- prepareVirtualDisplay(ui::ROTATION_0);
-
- // Send an axis event
- processAxis(mapper, ABS_X, 100);
- processSync(mapper);
-
- NotifyMotionArgs args;
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
-
- // Send another axis event
- processAxis(mapper, ABS_Y, 100);
- processSync(mapper);
-
- ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
- ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
-}
-
// --- PeripheralControllerTest ---
class PeripheralControllerTest : public testing::Test {
diff --git a/services/inputflinger/tests/InterfaceMocks.h b/services/inputflinger/tests/InterfaceMocks.h
index 48e0b4f..5a3d79d 100644
--- a/services/inputflinger/tests/InterfaceMocks.h
+++ b/services/inputflinger/tests/InterfaceMocks.h
@@ -26,6 +26,7 @@
#include <vector>
#include <EventHub.h>
+#include <InputDevice.h>
#include <InputReaderBase.h>
#include <InputReaderContext.h>
#include <NotifyArgs.h>
@@ -59,7 +60,7 @@
MOCK_METHOD(void, requestTimeoutAtTime, (nsecs_t when), (override));
int32_t bumpGeneration() override { return ++mGeneration; }
- MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo> & outDevices),
+ MOCK_METHOD(void, getExternalStylusDevices, (std::vector<InputDeviceInfo>& outDevices),
(override));
MOCK_METHOD(std::list<NotifyArgs>, dispatchExternalStylusState, (const StylusState& outState),
(override));
@@ -172,7 +173,7 @@
MOCK_METHOD(void, requestReopenDevices, (), (override));
MOCK_METHOD(void, wake, (), (override));
- MOCK_METHOD(void, dump, (std::string & dump), (const, override));
+ MOCK_METHOD(void, dump, (std::string& dump), (const, override));
MOCK_METHOD(void, monitor, (), (const, override));
MOCK_METHOD(bool, isDeviceEnabled, (int32_t deviceId), (const, override));
MOCK_METHOD(status_t, enableDevice, (int32_t deviceId), (override));
@@ -190,4 +191,76 @@
MOCK_METHOD(void, notifyMouseCursorFadedOnTyping, (), (override));
};
+class MockInputDevice : public InputDevice {
+public:
+ MockInputDevice(InputReaderContext* context, int32_t id, int32_t generation,
+ const InputDeviceIdentifier& identifier)
+ : InputDevice(context, id, generation, identifier) {}
+
+ MOCK_METHOD(uint32_t, getSources, (), (const, override));
+ MOCK_METHOD(std::optional<DisplayViewport>, getAssociatedViewport, (), (const));
+ MOCK_METHOD(bool, isEnabled, (), ());
+
+ MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ());
+ MOCK_METHOD(void, addEmptyEventHubDevice, (int32_t eventHubId), ());
+ MOCK_METHOD(std::list<NotifyArgs>, addEventHubDevice,
+ (nsecs_t when, int32_t eventHubId, const InputReaderConfiguration& readerConfig),
+ ());
+ MOCK_METHOD(void, removeEventHubDevice, (int32_t eventHubId), ());
+ MOCK_METHOD(std::list<NotifyArgs>, configure,
+ (nsecs_t when, const InputReaderConfiguration& readerConfig,
+ ConfigurationChanges changes),
+ ());
+ MOCK_METHOD(std::list<NotifyArgs>, reset, (nsecs_t when), ());
+ MOCK_METHOD(std::list<NotifyArgs>, process, (const RawEvent* rawEvents, size_t count), ());
+ MOCK_METHOD(std::list<NotifyArgs>, timeoutExpired, (nsecs_t when), ());
+ MOCK_METHOD(std::list<NotifyArgs>, updateExternalStylusState, (const StylusState& state), ());
+
+ MOCK_METHOD(InputDeviceInfo, getDeviceInfo, (), ());
+ MOCK_METHOD(int32_t, getKeyCodeState, (uint32_t sourceMask, int32_t keyCode), ());
+ MOCK_METHOD(int32_t, getScanCodeState, (uint32_t sourceMask, int32_t scanCode), ());
+ MOCK_METHOD(int32_t, getSwitchState, (uint32_t sourceMask, int32_t switchCode), ());
+ MOCK_METHOD(int32_t, getKeyCodeForKeyLocation, (int32_t locationKeyCode), (const));
+ MOCK_METHOD(bool, markSupportedKeyCodes,
+ (uint32_t sourceMask, const std::vector<int32_t>& keyCodes, uint8_t* outFlags), ());
+ MOCK_METHOD(std::list<NotifyArgs>, vibrate,
+ (const VibrationSequence& sequence, ssize_t repeat, int32_t token), ());
+ MOCK_METHOD(std::list<NotifyArgs>, cancelVibrate, (int32_t token), ());
+ MOCK_METHOD(bool, isVibrating, (), ());
+ MOCK_METHOD(std::vector<int32_t>, getVibratorIds, (), ());
+ MOCK_METHOD(std::list<NotifyArgs>, cancelTouch, (nsecs_t when, nsecs_t readTime), ());
+ MOCK_METHOD(bool, enableSensor,
+ (InputDeviceSensorType sensorType, std::chrono::microseconds samplingPeriod,
+ std::chrono::microseconds maxBatchReportLatency),
+ ());
+
+ MOCK_METHOD(void, disableSensor, (InputDeviceSensorType sensorType), ());
+ MOCK_METHOD(void, flushSensor, (InputDeviceSensorType sensorType), ());
+
+ MOCK_METHOD(std::optional<int32_t>, getBatteryEventHubId, (), (const));
+
+ MOCK_METHOD(bool, setLightColor, (int32_t lightId, int32_t color), ());
+ MOCK_METHOD(bool, setLightPlayerId, (int32_t lightId, int32_t playerId), ());
+ MOCK_METHOD(std::optional<int32_t>, getLightColor, (int32_t lightId), ());
+ MOCK_METHOD(std::optional<int32_t>, getLightPlayerId, (int32_t lightId), ());
+
+ MOCK_METHOD(int32_t, getMetaState, (), ());
+ MOCK_METHOD(void, updateMetaState, (int32_t keyCode), ());
+
+ MOCK_METHOD(void, addKeyRemapping, (int32_t fromKeyCode, int32_t toKeyCode), ());
+
+ MOCK_METHOD(void, setKeyboardType, (KeyboardType keyboardType), ());
+
+ MOCK_METHOD(void, bumpGeneration, (), ());
+
+ MOCK_METHOD(const PropertyMap&, getConfiguration, (), (const, override));
+
+ MOCK_METHOD(NotifyDeviceResetArgs, notifyReset, (nsecs_t when), ());
+
+ MOCK_METHOD(std::optional<ui::LogicalDisplayId>, getAssociatedDisplayId, (), ());
+
+ MOCK_METHOD(void, updateLedState, (bool reset), ());
+
+ MOCK_METHOD(size_t, getMapperCount, (), ());
+};
} // namespace android
diff --git a/services/inputflinger/tests/JoystickInputMapper_test.cpp b/services/inputflinger/tests/JoystickInputMapper_test.cpp
new file mode 100644
index 0000000..adebd72
--- /dev/null
+++ b/services/inputflinger/tests/JoystickInputMapper_test.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2024 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 "JoystickInputMapper.h"
+
+#include <list>
+#include <optional>
+
+#include <EventHub.h>
+#include <NotifyArgs.h>
+#include <ftl/flags.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <input/DisplayViewport.h>
+#include <linux/input-event-codes.h>
+#include <ui/LogicalDisplayId.h>
+
+#include "InputMapperTest.h"
+#include "TestConstants.h"
+#include "TestEventMatchers.h"
+
+namespace android {
+
+using namespace ftl::flag_operators;
+using testing::ElementsAre;
+using testing::IsEmpty;
+using testing::Return;
+using testing::VariantWith;
+
+class JoystickInputMapperTest : public InputMapperUnitTest {
+protected:
+ void SetUp() override {
+ InputMapperUnitTest::SetUp();
+ EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
+ .WillRepeatedly(Return(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL));
+
+ // The mapper requests info on all ABS axis IDs, including ones which aren't actually used
+ // (e.g. in the range from 0x0b (ABS_BRAKE) to 0x0f (ABS_HAT0X)), so just return nullopt for
+ // all axes we don't explicitly set up below.
+ EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_))
+ .WillRepeatedly(Return(std::nullopt));
+
+ setupAxis(ABS_X, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0);
+ setupAxis(ABS_Y, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0);
+ }
+};
+
+TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
+ DisplayViewport viewport;
+ viewport.displayId = ui::LogicalDisplayId{1};
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(viewport));
+ mMapper = createInputMapper<JoystickInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
+
+ std::list<NotifyArgs> out;
+
+ // Send an axis event
+ out = process(EV_ABS, ABS_X, 100);
+ ASSERT_THAT(out, IsEmpty());
+ out = process(EV_SYN, SYN_REPORT, 0);
+ ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId))));
+
+ // Send another axis event
+ out = process(EV_ABS, ABS_Y, 100);
+ ASSERT_THAT(out, IsEmpty());
+ out = process(EV_SYN, SYN_REPORT, 0);
+ ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId))));
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/KeyboardInputMapper_test.cpp b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
index d3e8dee..88c25d3 100644
--- a/services/inputflinger/tests/KeyboardInputMapper_test.cpp
+++ b/services/inputflinger/tests/KeyboardInputMapper_test.cpp
@@ -55,7 +55,6 @@
void SetUp() override {
InputMapperUnitTest::SetUp();
- createDevice();
// set key-codes expected in tests
for (const auto& [scanCode, outKeycode] : mKeyCodeMap) {
@@ -66,6 +65,8 @@
mFakePolicy = sp<FakeInputReaderPolicy>::make();
EXPECT_CALL(mMockInputReaderContext, getPolicy).WillRepeatedly(Return(mFakePolicy.get()));
+ ON_CALL((*mDevice), getSources).WillByDefault(Return(AINPUT_SOURCE_KEYBOARD));
+
mMapper = createInputMapper<KeyboardInputMapper>(*mDeviceContext, mReaderConfiguration,
AINPUT_SOURCE_KEYBOARD);
}
diff --git a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
index d4d3c38..9a6b266 100644
--- a/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
+++ b/services/inputflinger/tests/MultiTouchInputMapper_test.cpp
@@ -109,7 +109,6 @@
mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
/*isActive=*/true, "local:0", NO_PORT,
ViewportType::INTERNAL);
- createDevice();
mMapper = createInputMapper<MultiTouchInputMapper>(*mDeviceContext,
mFakePolicy->getReaderConfiguration());
}
diff --git a/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
index b441a23..9ddb8c1 100644
--- a/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
+++ b/services/inputflinger/tests/MultiTouchMotionAccumulator_test.cpp
@@ -23,10 +23,7 @@
protected:
static constexpr size_t SLOT_COUNT = 8;
- void SetUp() override {
- InputMapperUnitTest::SetUp();
- createDevice();
- }
+ void SetUp() override { InputMapperUnitTest::SetUp(); }
MultiTouchMotionAccumulator mMotionAccumulator;
diff --git a/services/inputflinger/tests/PointerChoreographer_test.cpp b/services/inputflinger/tests/PointerChoreographer_test.cpp
index 144e723..18222dd 100644
--- a/services/inputflinger/tests/PointerChoreographer_test.cpp
+++ b/services/inputflinger/tests/PointerChoreographer_test.cpp
@@ -196,7 +196,6 @@
TEST_F(PointerChoreographerTest, ForwardsArgsToInnerListener) {
const std::vector<NotifyArgs>
allArgs{NotifyInputDevicesChangedArgs{},
- NotifyConfigurationChangedArgs{},
KeyArgsBuilder(AKEY_EVENT_ACTION_DOWN, AINPUT_SOURCE_KEYBOARD).build(),
MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN)
.pointer(FIRST_TOUCH_POINTER)
@@ -214,9 +213,6 @@
[&](const NotifyInputDevicesChangedArgs& args) {
mTestListener.assertNotifyInputDevicesChangedWasCalled();
},
- [&](const NotifyConfigurationChangedArgs& args) {
- mTestListener.assertNotifyConfigurationChangedWasCalled();
- },
[&](const NotifyKeyArgs& args) {
mTestListener.assertNotifyKeyWasCalled();
},
@@ -830,15 +826,20 @@
pc->assertSpotCount(DISPLAY_ID, 0);
}
+/**
+ * In this test, we simulate the complete event of the stylus approaching and clicking on the
+ * screen, and then leaving the screen. We should ensure that spots are displayed correctly.
+ */
TEST_F(PointerChoreographerTest, TouchSetsSpotsForStylusEvent) {
mChoreographer.setShowTouchesEnabled(true);
+ mChoreographer.setStylusPointerIconEnabled(false);
mChoreographer.notifyInputDevicesChanged(
{/*id=*/0,
{generateTestDeviceInfo(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS,
DISPLAY_ID)}});
- // Emit down event with stylus properties.
- mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
+ // First, the stylus begin to approach the screen.
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
.pointer(STYLUS_POINTER)
.deviceId(DEVICE_ID)
@@ -846,6 +847,72 @@
.build());
auto pc = assertPointerControllerCreated(ControllerType::TOUCH);
pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 0);
+
+ // Now, use stylus touch the screen.
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_DOWN,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_MOVE,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_UP,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 0);
+
+ // Then, the stylus start leave from the screen.
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_ENTER,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_MOVE,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 1);
+
+ mChoreographer.notifyMotion(MotionArgsBuilder(AMOTION_EVENT_ACTION_HOVER_EXIT,
+ AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_STYLUS)
+ .pointer(STYLUS_POINTER)
+ .deviceId(DEVICE_ID)
+ .displayId(DISPLAY_ID)
+ .build());
+ pc->assertSpotCount(DISPLAY_ID, 0);
}
TEST_F(PointerChoreographerTest, TouchSetsSpotsForTwoDisplays) {
diff --git a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
index 366b3dc..6607bc7 100644
--- a/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
+++ b/services/inputflinger/tests/RotaryEncoderInputMapper_test.cpp
@@ -78,36 +78,6 @@
return v;
}
-/**
- * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper.
- *
- * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates
- * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input
- * device doesn't set its associated viewport when it's configured.
- *
- * TODO(b/319217713): work out a way to avoid this fake.
- */
-class ViewportFakingInputDeviceContext : public InputDeviceContext {
-public:
- ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
- std::optional<DisplayViewport> viewport)
- : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {}
-
- ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId)
- : ViewportFakingInputDeviceContext(device, eventHubId, createPrimaryViewport()) {}
-
- std::optional<DisplayViewport> getAssociatedViewport() const override {
- return mAssociatedViewport;
- }
-
- void setViewport(const std::optional<DisplayViewport>& viewport) {
- mAssociatedViewport = viewport;
- }
-
-private:
- std::optional<DisplayViewport> mAssociatedViewport;
-};
-
} // namespace
namespace vd_flags = android::companion::virtualdevice::flags;
@@ -138,9 +108,8 @@
mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
// Set up the secondary display as the associated viewport of the mapper.
- createDevice();
- ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
- mMapper = createInputMapper<RotaryEncoderInputMapper>(deviceContext, mReaderConfiguration);
+ EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
+ mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
// Ensure input events are generated for the secondary display.
@@ -159,7 +128,6 @@
mFakePolicy->addDisplayViewport(createPrimaryViewport());
// Set up the mapper with no associated viewport.
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
// Ensure input events are generated without display ID
@@ -174,7 +142,6 @@
}
TEST_F(RotaryEncoderInputMapperTest, ProcessRegularScroll) {
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -191,7 +158,6 @@
vd_flags::high_resolution_scroll(true);
EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
.WillRepeatedly(Return(true));
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
@@ -208,7 +174,6 @@
vd_flags::high_resolution_scroll(true);
EXPECT_CALL(mMockEventHub, hasRelativeAxis(EVENTHUB_ID, REL_WHEEL_HI_RES))
.WillRepeatedly(Return(true));
- createDevice();
mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);
std::list<NotifyArgs> args;
diff --git a/services/inputflinger/tests/SwitchInputMapper_test.cpp b/services/inputflinger/tests/SwitchInputMapper_test.cpp
new file mode 100644
index 0000000..ebbf10b
--- /dev/null
+++ b/services/inputflinger/tests/SwitchInputMapper_test.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2024 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 "SwitchInputMapper.h"
+
+#include <list>
+#include <variant>
+
+#include <NotifyArgs.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+#include <linux/input-event-codes.h>
+
+#include "InputMapperTest.h"
+#include "TestConstants.h"
+
+namespace android {
+
+class SwitchInputMapperTest : public InputMapperUnitTest {
+protected:
+ void SetUp() override {
+ InputMapperUnitTest::SetUp();
+ mMapper = createInputMapper<SwitchInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
+ }
+};
+
+TEST_F(SwitchInputMapperTest, GetSources) {
+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mMapper->getSources());
+}
+
+TEST_F(SwitchInputMapperTest, GetSwitchState) {
+ setSwitchState(1, {SW_LID});
+ ASSERT_EQ(1, mMapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+
+ setSwitchState(0, {SW_LID});
+ ASSERT_EQ(0, mMapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+}
+
+TEST_F(SwitchInputMapperTest, Process) {
+ std::list<NotifyArgs> out;
+ out = process(ARBITRARY_TIME, EV_SW, SW_LID, 1);
+ ASSERT_TRUE(out.empty());
+ out = process(ARBITRARY_TIME, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
+ ASSERT_TRUE(out.empty());
+ out = process(ARBITRARY_TIME, EV_SW, SW_HEADPHONE_INSERT, 0);
+ ASSERT_TRUE(out.empty());
+ out = process(ARBITRARY_TIME, EV_SYN, SYN_REPORT, 0);
+
+ ASSERT_EQ(1u, out.size());
+ const NotifySwitchArgs& args = std::get<NotifySwitchArgs>(*out.begin());
+ ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+ ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT), args.switchValues);
+ ASSERT_EQ((1U << SW_LID) | (1U << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
+ args.switchMask);
+ ASSERT_EQ(uint32_t(0), args.policyFlags);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
index f8e3c22..cfedc6e 100644
--- a/services/inputflinger/tests/TestEventMatchers.h
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -609,10 +609,33 @@
return arg.getRepeatCount() == repeatCount;
}
-MATCHER_P2(WithPointerId, index, id, "MotionEvent with specified pointer ID for pointer index") {
- const auto argPointerId = arg.pointerProperties[index].id;
- *result_listener << "expected pointer with index " << index << " to have ID " << argPointerId;
- return argPointerId == id;
+class WithPointerIdMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithPointerIdMatcher(size_t index, int32_t pointerId)
+ : mIndex(index), mPointerId(pointerId) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return args.pointerProperties[mIndex].id == mPointerId;
+ }
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+ return event.getPointerId(mIndex) == mPointerId;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with pointer[" << mIndex << "] id = " << mPointerId;
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointerId"; }
+
+private:
+ const size_t mIndex;
+ const int32_t mPointerId;
+};
+
+inline WithPointerIdMatcher WithPointerId(size_t index, int32_t pointerId) {
+ return WithPointerIdMatcher(index, pointerId);
}
MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 41e250f..369f9cc 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -37,19 +37,6 @@
"to have been called."));
}
-void TestInputListener::assertNotifyConfigurationChangedWasCalled(
- NotifyConfigurationChangedArgs* outEventArgs) {
- ASSERT_NO_FATAL_FAILURE(
- assertCalled<NotifyConfigurationChangedArgs>(outEventArgs,
- "Expected notifyConfigurationChanged() "
- "to have been called."));
-}
-
-void TestInputListener::assertNotifyConfigurationChangedWasNotCalled() {
- ASSERT_NO_FATAL_FAILURE(assertNotCalled<NotifyConfigurationChangedArgs>(
- "notifyConfigurationChanged() should not be called."));
-}
-
void TestInputListener::assertNotifyDeviceResetWasCalled(NotifyDeviceResetArgs* outEventArgs) {
ASSERT_NO_FATAL_FAILURE(
assertCalled<
@@ -192,10 +179,6 @@
addToQueue<NotifyInputDevicesChangedArgs>(args);
}
-void TestInputListener::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
- addToQueue<NotifyConfigurationChangedArgs>(args);
-}
-
void TestInputListener::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
addToQueue<NotifyDeviceResetArgs>(args);
}
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index 3c5e014..47eae4d 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -38,11 +38,6 @@
void assertNotifyInputDevicesChangedWasCalled(
NotifyInputDevicesChangedArgs* outEventArgs = nullptr);
- void assertNotifyConfigurationChangedWasCalled(
- NotifyConfigurationChangedArgs* outEventArgs = nullptr);
-
- void assertNotifyConfigurationChangedWasNotCalled();
-
void clearNotifyDeviceResetCalls();
void assertNotifyDeviceResetWasCalled(const ::testing::Matcher<NotifyDeviceResetArgs>& matcher);
@@ -85,8 +80,6 @@
virtual void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
- virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
-
virtual void notifyDeviceReset(const NotifyDeviceResetArgs& args) override;
virtual void notifyKey(const NotifyKeyArgs& args) override;
@@ -107,7 +100,6 @@
const std::chrono::milliseconds mEventDidNotHappenTimeout;
std::tuple<std::vector<NotifyInputDevicesChangedArgs>, //
- std::vector<NotifyConfigurationChangedArgs>, //
std::vector<NotifyDeviceResetArgs>, //
std::vector<NotifyKeyArgs>, //
std::vector<NotifyMotionArgs>, //
diff --git a/services/inputflinger/tests/TouchpadInputMapper_test.cpp b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
index 1afb4f0..fc8a7da 100644
--- a/services/inputflinger/tests/TouchpadInputMapper_test.cpp
+++ b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
@@ -109,7 +109,6 @@
.WillRepeatedly([]() -> base::Result<std::vector<int32_t>> {
return base::ResultError("Axis not supported", NAME_NOT_FOUND);
});
- createDevice();
mMapper = createInputMapper<TouchpadInputMapper>(*mDeviceContext, mReaderConfiguration);
}
};
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 853f628..bbb2fc8 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -414,20 +414,6 @@
};
/**
- * Create a basic configuration change and send it to input processor.
- * Expect that the event is received by the next input stage, unmodified.
- */
-TEST_F(UnwantedInteractionBlockerTest, ConfigurationChangedIsPassedToNextListener) {
- // Create a basic configuration change and send to blocker
- NotifyConfigurationChangedArgs args(/*sequenceNum=*/1, /*eventTime=*/2);
-
- mBlocker->notifyConfigurationChanged(args);
- NotifyConfigurationChangedArgs outArgs;
- ASSERT_NO_FATAL_FAILURE(mTestListener.assertNotifyConfigurationChangedWasCalled(&outArgs));
- ASSERT_EQ(args, outArgs);
-}
-
-/**
* Keys are not handled in 'UnwantedInteractionBlocker' and should be passed
* to next stage unmodified.
*/
diff --git a/services/inputflinger/tests/VibratorInputMapper_test.cpp b/services/inputflinger/tests/VibratorInputMapper_test.cpp
new file mode 100644
index 0000000..6e3344c
--- /dev/null
+++ b/services/inputflinger/tests/VibratorInputMapper_test.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2024 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 "VibratorInputMapper.h"
+
+#include <chrono>
+#include <list>
+#include <variant>
+#include <vector>
+
+#include <EventHub.h>
+#include <NotifyArgs.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+
+#include "InputMapperTest.h"
+#include "VibrationElement.h"
+
+namespace android {
+
+class VibratorInputMapperTest : public InputMapperUnitTest {
+protected:
+ void SetUp() override {
+ InputMapperUnitTest::SetUp();
+ EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
+ .WillRepeatedly(testing::Return(InputDeviceClass::VIBRATOR));
+ EXPECT_CALL(mMockEventHub, getVibratorIds(EVENTHUB_ID))
+ .WillRepeatedly(testing::Return<std::vector<int32_t>>({0, 1}));
+ mMapper = createInputMapper<VibratorInputMapper>(*mDeviceContext,
+ mFakePolicy->getReaderConfiguration());
+ }
+};
+
+TEST_F(VibratorInputMapperTest, GetSources) {
+ ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mMapper->getSources());
+}
+
+TEST_F(VibratorInputMapperTest, GetVibratorIds) {
+ ASSERT_EQ(mMapper->getVibratorIds().size(), 2U);
+}
+
+TEST_F(VibratorInputMapperTest, Vibrate) {
+ constexpr uint8_t DEFAULT_AMPLITUDE = 192;
+ constexpr int32_t VIBRATION_TOKEN = 100;
+
+ VibrationElement pattern(2);
+ VibrationSequence sequence(2);
+ pattern.duration = std::chrono::milliseconds(200);
+ pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 2},
+ {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
+ sequence.addElement(pattern);
+ pattern.duration = std::chrono::milliseconds(500);
+ pattern.channels = {{/*vibratorId=*/0, DEFAULT_AMPLITUDE / 4},
+ {/*vibratorId=*/1, DEFAULT_AMPLITUDE}};
+ sequence.addElement(pattern);
+
+ std::vector<int64_t> timings = {0, 1};
+ std::vector<uint8_t> amplitudes = {DEFAULT_AMPLITUDE, DEFAULT_AMPLITUDE / 2};
+
+ ASSERT_FALSE(mMapper->isVibrating());
+ // Start vibrating
+ std::list<NotifyArgs> out = mMapper->vibrate(sequence, /*repeat=*/-1, VIBRATION_TOKEN);
+ ASSERT_TRUE(mMapper->isVibrating());
+ // Verify vibrator state listener was notified.
+ ASSERT_EQ(1u, out.size());
+ const NotifyVibratorStateArgs& vibrateArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
+ ASSERT_EQ(DEVICE_ID, vibrateArgs.deviceId);
+ ASSERT_TRUE(vibrateArgs.isOn);
+ // Stop vibrating
+ out = mMapper->cancelVibrate(VIBRATION_TOKEN);
+ ASSERT_FALSE(mMapper->isVibrating());
+ // Verify vibrator state listener was notified.
+ ASSERT_EQ(1u, out.size());
+ const NotifyVibratorStateArgs& cancelArgs = std::get<NotifyVibratorStateArgs>(*out.begin());
+ ASSERT_EQ(DEVICE_ID, cancelArgs.deviceId);
+ ASSERT_FALSE(cancelArgs.isOn);
+}
+
+} // namespace android
\ No newline at end of file
diff --git a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
index 0b4ac1f..46a6189 100644
--- a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
@@ -39,12 +39,6 @@
while (fdp.remaining_bytes() > 0) {
fdp.PickValueInArray<std::function<void()>>({
[&]() -> void {
- // SendToNextStage_NotifyConfigurationChangedArgs
- mClassifier->notifyConfigurationChanged(
- {/*sequenceNum=*/fdp.ConsumeIntegral<int32_t>(),
- /*eventTime=*/fdp.ConsumeIntegral<nsecs_t>()});
- },
- [&]() -> void {
// SendToNextStage_NotifyKeyArgs
const nsecs_t eventTime =
fdp.ConsumeIntegralInRange<nsecs_t>(0,
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
index c4465b6..fea0d9a 100644
--- a/services/inputflinger/tests/fuzzers/MapperHelpers.h
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -32,8 +32,7 @@
EV_MSC,
EV_REL,
android::EventHubInterface::DEVICE_ADDED,
- android::EventHubInterface::DEVICE_REMOVED,
- android::EventHubInterface::FINISHED_DEVICE_SCAN};
+ android::EventHubInterface::DEVICE_REMOVED};
constexpr size_t kValidCodes[] = {
SYN_REPORT,
@@ -306,7 +305,6 @@
class FuzzInputListener : public virtual InputListenerInterface {
public:
void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override {}
- void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override {}
void notifyKey(const NotifyKeyArgs& args) override {}
void notifyMotion(const NotifyMotionArgs& args) override {}
void notifySwitch(const NotifySwitchArgs& args) override {}
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index a37433c..c2a9880 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -47,6 +47,7 @@
"libtimestats_deps",
"libsurfaceflinger_common_deps",
"surfaceflinger_defaults",
+ "libsurfaceflinger_proto_deps",
],
cflags: [
"-DLOG_TAG=\"SurfaceFlinger\"",
@@ -93,7 +94,6 @@
"libcompositionengine",
"libframetimeline",
"libgui_aidl_static",
- "liblayers_proto",
"libperfetto_client_experimental",
"librenderengine",
"libscheduler",
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 7fa58df..b826466 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -17,6 +17,7 @@
"librenderengine_deps",
"libtimestats_deps",
"surfaceflinger_defaults",
+ "libsurfaceflinger_proto_deps",
],
cflags: [
"-DLOG_TAG=\"CompositionEngine\"",
@@ -41,7 +42,6 @@
"libutils",
],
static_libs: [
- "liblayers_proto",
"libmath",
"librenderengine",
"libtimestats",
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
index 6be6735..9c0e072 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/Predictor.h
@@ -92,15 +92,15 @@
}
private:
- std::vector<const LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
- std::vector<const LayerState> copiedLayers;
+ std::vector<LayerState> copyLayers(const std::vector<const LayerState*>& layers) {
+ std::vector<LayerState> copiedLayers;
copiedLayers.reserve(layers.size());
std::transform(layers.cbegin(), layers.cend(), std::back_inserter(copiedLayers),
[](const LayerState* layerState) { return *layerState; });
return copiedLayers;
}
- std::vector<const LayerState> mLayers;
+ std::vector<LayerState> mLayers;
// TODO(b/180976743): Tune kMaxDifferingFields
constexpr static int kMaxDifferingFields = 6;
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index f339d41..4424a04 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -260,10 +260,6 @@
void DisplayColorProfile::populateColorModes(
const DisplayColorProfileCreationArgs::HwcColorModes& hwcColorModes) {
- if (!hasWideColorGamut()) {
- return;
- }
-
// collect all known SDR render intents
std::unordered_set<RenderIntent> sdrRenderIntents(sSdrRenderIntents.begin(),
sSdrRenderIntents.end());
@@ -352,13 +348,9 @@
*outMode = iter->second.colorMode;
*outIntent = iter->second.renderIntent;
} else {
- // this is unexpected on a WCG display
- if (hasWideColorGamut()) {
- ALOGE("map unknown (%s)/(%s) to default color mode",
- dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
- decodeRenderIntent(intent).c_str());
- }
-
+ ALOGI("map unknown (%s)/(%s) to default color mode",
+ dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(),
+ decodeRenderIntent(intent).c_str());
*outDataspace = Dataspace::UNKNOWN;
*outMode = ColorMode::NATIVE;
*outIntent = RenderIntent::COLORIMETRIC;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
index 03a97dc..c354e4a 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
@@ -123,10 +123,10 @@
.build();
}
- static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport() {
+ static impl::DisplayColorProfile createProfileWithSRGBColorModeSupport(bool wcg = true) {
return ProfileFactory()
- .setHasWideColorGamut(true)
.addHdrType(Hdr::HDR10)
+ .setHasWideColorGamut(wcg)
.addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
.addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
.addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
@@ -289,7 +289,7 @@
TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasNoSupport) {
auto profile = ProfileFactory::createProfileWithNoColorModeSupport();
- EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
@@ -306,6 +306,16 @@
EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
}
+TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport_NoWCG) {
+ auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
+
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
+ EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+ EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
+ EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
+ EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
+}
+
TEST_F(DisplayColorProfileTest, hasRenderIntentReturnsExpectedValueWhenOutputHasSRGBSupport) {
auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
@@ -476,6 +486,40 @@
checkGetBestColorMode(profile, expectedResults);
}
+TEST_F(DisplayColorProfileTest,
+ getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport_NoWCG) {
+ auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport(false);
+
+ // Note: This table of expected values goes with the table of arguments
+ // used in checkGetBestColorMode.
+ using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
+ std::array<Result, 15> expectedResults = {
+ /* clang-format off */
+ /* 0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+ /* 3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+ /* 6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+ /* 8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
+ /* 9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+ /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+ /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+ /* clang-format on */
+ };
+
+ checkGetBestColorMode(profile, expectedResults);
+}
+
TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasSRGBSupport) {
auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 8288b99..75b07a8 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -468,6 +468,12 @@
return false;
}
+void DisplayDevice::onVrrIdle(bool idle) {
+ if (mRefreshRateOverlay) {
+ mRefreshRateOverlay->onVrrIdle(idle);
+ }
+}
+
void DisplayDevice::animateOverlay() {
if (mRefreshRateOverlay) {
mRefreshRateOverlay->animate();
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 3cc8cf5..1b8a3a8 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -196,6 +196,7 @@
bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
void animateOverlay();
bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
+ void onVrrIdle(bool idle);
// Enables an overlay to be display with the hdr/sdr ratio
void enableHdrSdrRatioOverlay(bool enable) REQUIRES(kMainThreadContext);
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 4e09381..47fd700 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -320,11 +320,8 @@
void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerState& requested,
const LayerSnapshotBuilder::Args& args,
const LayerSnapshot& parentSnapshot) {
- if (snapshot.changes.test(RequestedLayerState::Changes::GameMode)) {
- snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE)
- ? requested.gameMode
- : parentSnapshot.gameMode;
- }
+ snapshot.gameMode = requested.metadata.has(gui::METADATA_GAME_MODE) ? requested.gameMode
+ : parentSnapshot.gameMode;
updateMetadata(snapshot, requested, args);
if (args.includeMetadata) {
snapshot.layerMetadata = parentSnapshot.layerMetadata;
@@ -780,7 +777,8 @@
}
if (forceUpdate ||
(args.includeMetadata &&
- snapshot.changes.test(RequestedLayerState::Changes::Metadata))) {
+ snapshot.changes.any(RequestedLayerState::Changes::Metadata |
+ RequestedLayerState::Changes::Geometry))) {
updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
}
return;
@@ -848,7 +846,9 @@
}
}
- if (forceUpdate || snapshot.changes.test(RequestedLayerState::Changes::Metadata)) {
+ if (forceUpdate ||
+ snapshot.changes.any(RequestedLayerState::Changes::Metadata |
+ RequestedLayerState::Changes::Hierarchy)) {
updateMetadataAndGameMode(snapshot, requested, args, parentSnapshot);
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a6d2b15..1258509 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1314,7 +1314,7 @@
}
void Layer::setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info,
- nsecs_t postTime) {
+ nsecs_t postTime, gui::GameMode gameMode) {
mDrawingState.postTime = postTime;
// Check if one of the bufferlessSurfaceFramesTX contains the same vsyncId. This can happen if
@@ -1330,14 +1330,15 @@
mDrawingState.bufferSurfaceFrameTX->setActualQueueTime(postTime);
} else {
mDrawingState.bufferSurfaceFrameTX =
- createSurfaceFrameForBuffer(info, postTime, mTransactionName);
+ createSurfaceFrameForBuffer(info, postTime, mTransactionName, gameMode);
}
- setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
+ setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
}
void Layer::setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
- nsecs_t postTime) {
+ nsecs_t postTime,
+ gui::GameMode gameMode) {
mDrawingState.frameTimelineInfo = info;
mDrawingState.postTime = postTime;
mDrawingState.modified = true;
@@ -1356,17 +1357,17 @@
// targeting different vsyncs).
auto it = mDrawingState.bufferlessSurfaceFramesTX.find(info.vsyncId);
if (it == mDrawingState.bufferlessSurfaceFramesTX.end()) {
- auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime);
+ auto surfaceFrame = createSurfaceFrameForTransaction(info, postTime, gameMode);
mDrawingState.bufferlessSurfaceFramesTX[info.vsyncId] = surfaceFrame;
} else {
if (it->second->getPresentState() == PresentState::Presented) {
// If the SurfaceFrame was already presented, its safe to overwrite it since it must
// have been from previous vsync.
- it->second = createSurfaceFrameForTransaction(info, postTime);
+ it->second = createSurfaceFrameForTransaction(info, postTime, gameMode);
}
}
- setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName);
+ setFrameTimelineVsyncForSkippedFrames(info, postTime, mTransactionName, gameMode);
}
void Layer::addSurfaceFrameDroppedForBuffer(
@@ -1386,12 +1387,12 @@
}
std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForTransaction(
- const FrameTimelineInfo& info, nsecs_t postTime) {
+ const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode) {
auto surfaceFrame =
mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
getSequence(), mName,
mTransactionName,
- /*isBuffer*/ false, getGameMode());
+ /*isBuffer*/ false, gameMode);
surfaceFrame->setActualStartTime(info.startTimeNanos);
// For Transactions, the post time is considered to be both queue and acquire fence time.
surfaceFrame->setActualQueueTime(postTime);
@@ -1404,11 +1405,12 @@
}
std::shared_ptr<frametimeline::SurfaceFrame> Layer::createSurfaceFrameForBuffer(
- const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName) {
+ const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
+ gui::GameMode gameMode) {
auto surfaceFrame =
mFlinger->mFrameTimeline->createSurfaceFrameForToken(info, mOwnerPid, mOwnerUid,
getSequence(), mName, debugName,
- /*isBuffer*/ true, getGameMode());
+ /*isBuffer*/ true, gameMode);
surfaceFrame->setActualStartTime(info.startTimeNanos);
// For buffers, acquire fence time will set during latch.
surfaceFrame->setActualQueueTime(queueTime);
@@ -1420,7 +1422,7 @@
}
void Layer::setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
- std::string debugName) {
+ std::string debugName, gui::GameMode gameMode) {
if (info.skippedFrameVsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
return;
}
@@ -1432,7 +1434,7 @@
mFlinger->mFrameTimeline->createSurfaceFrameForToken(skippedFrameTimelineInfo,
mOwnerPid, mOwnerUid,
getSequence(), mName, debugName,
- /*isBuffer*/ false, getGameMode());
+ /*isBuffer*/ false, gameMode);
surfaceFrame->setActualStartTime(skippedFrameTimelineInfo.skippedFrameStartTimeNanos);
// For Transactions, the post time is considered to be both queue and acquire fence time.
surfaceFrame->setActualQueueTime(postTime);
@@ -1671,25 +1673,12 @@
return count;
}
-void Layer::setGameModeForTree(GameMode gameMode) {
- const auto& currentState = getDrawingState();
- if (currentState.metadata.has(gui::METADATA_GAME_MODE)) {
- gameMode =
- static_cast<GameMode>(currentState.metadata.getInt32(gui::METADATA_GAME_MODE, 0));
- }
- setGameMode(gameMode);
- for (const sp<Layer>& child : mCurrentChildren) {
- child->setGameModeForTree(gameMode);
- }
-}
-
void Layer::addChild(const sp<Layer>& layer) {
mFlinger->mSomeChildrenChanged = true;
setTransactionFlags(eTransactionNeeded);
mCurrentChildren.add(layer);
layer->setParent(sp<Layer>::fromExisting(this));
- layer->setGameModeForTree(mGameMode);
updateTreeHasFrameRateVote();
}
@@ -1701,7 +1690,6 @@
const auto removeResult = mCurrentChildren.remove(layer);
updateTreeHasFrameRateVote();
- layer->setGameModeForTree(GameMode::Unsupported);
layer->updateTreeHasFrameRateVote();
return removeResult;
@@ -2540,10 +2528,6 @@
compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
const DisplayDevice* display) const {
if (!display) return nullptr;
- if (!mFlinger->mLayerLifecycleManagerEnabled) {
- return display->getCompositionDisplay()->getOutputLayerForLayer(
- getCompositionEngineLayerFE());
- }
sp<LayerFE> layerFE;
frontend::LayerHierarchy::TraversalPath path{.id = static_cast<uint32_t>(sequence)};
for (auto& [p, layer] : mLayerFEs) {
@@ -2559,10 +2543,6 @@
compositionengine::OutputLayer* Layer::findOutputLayerForDisplay(
const DisplayDevice* display, const frontend::LayerHierarchy::TraversalPath& path) const {
if (!display) return nullptr;
- if (!mFlinger->mLayerLifecycleManagerEnabled) {
- return display->getCompositionDisplay()->getOutputLayerForLayer(
- getCompositionEngineLayerFE());
- }
sp<LayerFE> layerFE;
for (auto& [p, layer] : mLayerFEs) {
if (p == path) {
@@ -3090,7 +3070,7 @@
bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
- bool isAutoTimestamp, const FrameTimelineInfo& info) {
+ bool isAutoTimestamp, const FrameTimelineInfo& info, gui::GameMode gameMode) {
SFTRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
const bool frameNumberChanged =
@@ -3116,12 +3096,12 @@
resetDrawingStateBufferInfo();
setTransactionFlags(eTransactionNeeded);
mDrawingState.bufferSurfaceFrameTX = nullptr;
- setFrameTimelineVsyncForBufferlessTransaction(info, postTime);
+ setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
return true;
} else {
// release sideband stream if it exists and a non null buffer is being set
if (mDrawingState.sidebandStream != nullptr) {
- setSidebandStream(nullptr, info, postTime);
+ setSidebandStream(nullptr, info, postTime, gameMode);
}
}
@@ -3160,9 +3140,9 @@
const int32_t layerId = getSequence();
mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
- mOwnerUid, postTime, getGameMode());
+ mOwnerUid, postTime, gameMode);
- setFrameTimelineVsyncForBufferTransaction(info, postTime);
+ setFrameTimelineVsyncForBufferTransaction(info, postTime, gameMode);
if (bufferData.dequeueTime > 0) {
const uint64_t bufferId = mDrawingState.buffer->getId();
@@ -3317,7 +3297,7 @@
}
bool Layer::setSidebandStream(const sp<NativeHandle>& sidebandStream, const FrameTimelineInfo& info,
- nsecs_t postTime) {
+ nsecs_t postTime, gui::GameMode gameMode) {
if (mDrawingState.sidebandStream == sidebandStream) return false;
if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
@@ -3332,7 +3312,7 @@
releasePreviousBuffer();
resetDrawingStateBufferInfo();
mDrawingState.bufferSurfaceFrameTX = nullptr;
- setFrameTimelineVsyncForBufferlessTransaction(info, postTime);
+ setFrameTimelineVsyncForBufferlessTransaction(info, postTime, gameMode);
}
setTransactionFlags(eTransactionNeeded);
if (!mSidebandStreamChanged.exchange(true)) {
@@ -3990,7 +3970,8 @@
void Layer::onCompositionPresented(const DisplayDevice* display,
const std::shared_ptr<FenceTime>& glDoneFence,
const std::shared_ptr<FenceTime>& presentFence,
- const CompositorTiming& compositorTiming) {
+ const CompositorTiming& compositorTiming,
+ gui::GameMode gameMode) {
// mFrameLatencyNeeded is true when a new frame was latched for the
// composition.
if (!mBufferInfo.mFrameLatencyNeeded) return;
@@ -4037,7 +4018,6 @@
mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());
const auto vote = frameRateToSetFrameRateVotePayload(getFrameRateForLayerTree());
- const auto gameMode = getGameMode();
if (presentFence->isValid()) {
mFlinger->mTimeStats->setPresentFence(layerId, mCurrentFrameNumber, presentFence,
@@ -4321,38 +4301,6 @@
}
}
-void Layer::updateMetadataSnapshot(const LayerMetadata& parentMetadata) {
- mSnapshot->layerMetadata = parentMetadata;
- mSnapshot->layerMetadata.merge(mDrawingState.metadata);
- for (const sp<Layer>& child : mDrawingChildren) {
- child->updateMetadataSnapshot(mSnapshot->layerMetadata);
- }
-}
-
-void Layer::updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
- std::unordered_set<Layer*>& visited) {
- if (visited.find(this) != visited.end()) {
- ALOGW("Cycle containing layer %s detected in z-order relatives", getDebugName());
- return;
- }
- visited.insert(this);
-
- mSnapshot->relativeLayerMetadata = relativeLayerMetadata;
-
- if (mDrawingState.zOrderRelatives.empty()) {
- return;
- }
- LayerMetadata childRelativeLayerMetadata = mSnapshot->relativeLayerMetadata;
- childRelativeLayerMetadata.merge(mSnapshot->layerMetadata);
- for (wp<Layer> weakRelative : mDrawingState.zOrderRelatives) {
- sp<Layer> relative = weakRelative.promote();
- if (!relative) {
- continue;
- }
- relative->updateRelativeMetadataSnapshot(childRelativeLayerMetadata, visited);
- }
-}
-
bool Layer::setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
TrustedPresentationListener const& listener) {
bool hadTrustedPresentationListener = hasTrustedPresentationListener();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 52f169e..c838b97 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -312,7 +312,7 @@
bool setBuffer(std::shared_ptr<renderengine::ExternalTexture>& /* buffer */,
const BufferData& /* bufferData */, nsecs_t /* postTime */,
nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
- const FrameTimelineInfo& /*info*/);
+ const FrameTimelineInfo& /*info*/, gui::GameMode gameMode);
void setDesiredPresentTime(nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/);
bool setDataspace(ui::Dataspace /*dataspace*/);
bool setExtendedRangeBrightness(float currentBufferRatio, float desiredRatio);
@@ -322,7 +322,8 @@
bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/);
bool setApi(int32_t /*api*/);
bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/,
- const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */);
+ const FrameTimelineInfo& /* info*/, nsecs_t /* postTime */,
+ gui::GameMode gameMode);
bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& /*handles*/,
bool willPresent);
virtual bool setBackgroundColor(const half3& color, float alpha, ui::Dataspace dataspace)
@@ -439,7 +440,7 @@
void onCompositionPresented(const DisplayDevice*,
const std::shared_ptr<FenceTime>& /*glDoneFence*/,
const std::shared_ptr<FenceTime>& /*presentFence*/,
- const CompositorTiming&);
+ const CompositorTiming&, gui::GameMode gameMode);
// If a buffer was replaced this frame, release the former buffer
void releasePendingBuffer(nsecs_t /*dequeueReadyTime*/);
@@ -794,9 +795,10 @@
bool setFrameRateSelectionStrategy(FrameRateSelectionStrategy);
virtual void setFrameTimelineInfoForBuffer(const FrameTimelineInfo& /*info*/) {}
- void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime);
+ void setFrameTimelineVsyncForBufferTransaction(const FrameTimelineInfo& info, nsecs_t postTime,
+ gui::GameMode gameMode);
void setFrameTimelineVsyncForBufferlessTransaction(const FrameTimelineInfo& info,
- nsecs_t postTime);
+ nsecs_t postTime, gui::GameMode gameMode);
void addSurfaceFrameDroppedForBuffer(std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame,
nsecs_t dropTime);
@@ -805,11 +807,12 @@
nsecs_t currentLatchTime);
std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForTransaction(
- const FrameTimelineInfo& info, nsecs_t postTime);
+ const FrameTimelineInfo& info, nsecs_t postTime, gui::GameMode gameMode);
std::shared_ptr<frametimeline::SurfaceFrame> createSurfaceFrameForBuffer(
- const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName);
+ const FrameTimelineInfo& info, nsecs_t queueTime, std::string debugName,
+ gui::GameMode gameMode);
void setFrameTimelineVsyncForSkippedFrames(const FrameTimelineInfo& info, nsecs_t postTime,
- std::string debugName);
+ std::string debugName, gui::GameMode gameMode);
bool setTrustedPresentationInfo(TrustedPresentationThresholds const& thresholds,
TrustedPresentationListener const& listener);
@@ -832,13 +835,6 @@
*/
bool hasInputInfo() const;
- // Sets the gui::GameMode for the tree rooted at this layer. A layer in the tree inherits this
- // gui::GameMode unless it (or an ancestor) has GAME_MODE_METADATA.
- void setGameModeForTree(gui::GameMode);
-
- void setGameMode(gui::GameMode gameMode) { mGameMode = gameMode; }
- gui::GameMode getGameMode() const { return mGameMode; }
-
virtual uid_t getOwnerUid() const { return mOwnerUid; }
pid_t getOwnerPid() { return mOwnerPid; }
@@ -899,9 +895,6 @@
// CompositionEngine to create a single path for composing layers.
void updateSnapshot(bool updateGeometry);
void updateChildrenSnapshots(bool updateGeometry);
- void updateMetadataSnapshot(const LayerMetadata& parentMetadata);
- void updateRelativeMetadataSnapshot(const LayerMetadata& relativeLayerMetadata,
- std::unordered_set<Layer*>& visited);
sp<Layer> getClonedFrom() const {
return mClonedFrom != nullptr ? mClonedFrom.promote() : nullptr;
}
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 496033b..0d2987c 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -266,6 +266,7 @@
perfetto::protos::LayersProto LayerProtoFromSnapshotGenerator::generate(
const frontend::LayerHierarchy& root) {
mLayersProto.clear_layers();
+ mVisitedLayers.clear();
std::unordered_set<uint64_t> stackIdsToSkip;
if ((mTraceFlags & LayerTracing::TRACE_VIRTUAL_DISPLAYS) == 0) {
for (const auto& [layerStack, displayInfo] : mDisplayInfos) {
@@ -326,6 +327,11 @@
perfetto::protos::LayerProto* layerProto = mLayersProto.add_layers();
const frontend::RequestedLayerState& layer = *root.getLayer();
frontend::LayerSnapshot* snapshot = getSnapshot(path, layer);
+ if (mVisitedLayers.find(snapshot->uniqueSequence) != mVisitedLayers.end()) {
+ TransactionTraceWriter::getInstance().invoke("DuplicateLayer", /* overwrite= */ false);
+ return;
+ }
+ mVisitedLayers.insert(snapshot->uniqueSequence);
LayerProtoHelper::writeSnapshotToProto(layerProto, layer, *snapshot, mTraceFlags);
for (const auto& [child, variant] : root.mChildren) {
diff --git a/services/surfaceflinger/LayerProtoHelper.h b/services/surfaceflinger/LayerProtoHelper.h
index 20c2260..d672012 100644
--- a/services/surfaceflinger/LayerProtoHelper.h
+++ b/services/surfaceflinger/LayerProtoHelper.h
@@ -101,6 +101,8 @@
const frontend::DisplayInfos& mDisplayInfos;
uint32_t mTraceFlags;
perfetto::protos::LayersProto mLayersProto;
+ std::unordered_set<uint32_t> mVisitedLayers;
+
// winscope expects all the layers, so provide a snapshot even if it not currently drawing
std::unordered_map<frontend::LayerHierarchy::TraversalPath, frontend::LayerSnapshot,
frontend::LayerHierarchy::TraversalPathHash>
diff --git a/services/surfaceflinger/LocklessQueue.h b/services/surfaceflinger/LocklessQueue.h
index 6b63360..4d0b261 100644
--- a/services/surfaceflinger/LocklessQueue.h
+++ b/services/surfaceflinger/LocklessQueue.h
@@ -15,11 +15,11 @@
*/
#pragma once
+
#include <atomic>
#include <optional>
-template <typename T>
-// Single consumer multi producer stack. We can understand the two operations independently to see
+// Single consumer multi producer queue. We can understand the two operations independently to see
// why they are without race condition.
//
// push is responsible for maintaining a linked list stored in mPush, and called from multiple
@@ -36,33 +36,27 @@
// then store the list and pop one element.
//
// If we already had something in the pop list we just pop directly.
+template <typename T>
class LocklessQueue {
public:
- class Entry {
- public:
- T mValue;
- std::atomic<Entry*> mNext;
- Entry(T value) : mValue(value) {}
- };
- std::atomic<Entry*> mPush = nullptr;
- std::atomic<Entry*> mPop = nullptr;
bool isEmpty() { return (mPush.load() == nullptr) && (mPop.load() == nullptr); }
void push(T value) {
- Entry* entry = new Entry(value);
+ Entry* entry = new Entry(std::move(value));
Entry* previousHead = mPush.load(/*std::memory_order_relaxed*/);
do {
entry->mNext = previousHead;
} while (!mPush.compare_exchange_weak(previousHead, entry)); /*std::memory_order_release*/
}
+
std::optional<T> pop() {
Entry* popped = mPop.load(/*std::memory_order_acquire*/);
if (popped) {
// Single consumer so this is fine
mPop.store(popped->mNext /* , std::memory_order_release */);
- auto value = popped->mValue;
+ auto value = std::move(popped->mValue);
delete popped;
- return std::move(value);
+ return value;
} else {
Entry* grabbedList = mPush.exchange(nullptr /* , std::memory_order_acquire */);
if (!grabbedList) return std::nullopt;
@@ -74,9 +68,19 @@
grabbedList = next;
}
mPop.store(popped /* , std::memory_order_release */);
- auto value = grabbedList->mValue;
+ auto value = std::move(grabbedList->mValue);
delete grabbedList;
- return std::move(value);
+ return value;
}
}
+
+private:
+ class Entry {
+ public:
+ T mValue;
+ std::atomic<Entry*> mNext;
+ Entry(T value) : mValue(value) {}
+ };
+ std::atomic<Entry*> mPush = nullptr;
+ std::atomic<Entry*> mPop = nullptr;
};
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 9527a99..35f12a0 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -28,10 +28,11 @@
namespace android {
-auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color,
+auto RefreshRateOverlay::draw(int refreshRate, int renderFps, bool idle, SkColor color,
ui::Transform::RotationFlags rotation, ftl::Flags<Features> features)
-> Buffers {
const size_t loopCount = features.test(Features::Spinner) ? 6 : 1;
+ const bool isSetByHwc = features.test(Features::SetByHwc);
Buffers buffers;
buffers.reserve(loopCount);
@@ -71,7 +72,11 @@
canvas->setMatrix(canvasTransform);
int left = 0;
- drawNumber(refreshRate, left, color, *canvas);
+ if (idle && !isSetByHwc) {
+ drawDash(left, *canvas);
+ } else {
+ drawNumber(refreshRate, left, color, *canvas);
+ }
left += 3 * (kDigitWidth + kDigitSpace);
if (features.test(Features::Spinner)) {
switch (i) {
@@ -104,7 +109,11 @@
left += kDigitWidth + kDigitSpace;
if (features.test(Features::RenderRate)) {
- drawNumber(renderFps, left, color, *canvas);
+ if (idle) {
+ drawDash(left, *canvas);
+ } else {
+ drawNumber(renderFps, left, color, *canvas);
+ }
}
left += 3 * (kDigitWidth + kDigitSpace);
@@ -138,6 +147,14 @@
SegmentDrawer::drawDigit(number % 10, left, color, canvas);
}
+void RefreshRateOverlay::drawDash(int left, SkCanvas& canvas) {
+ left += kDigitWidth + kDigitSpace;
+ SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas);
+
+ left += kDigitWidth + kDigitSpace;
+ SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas);
+}
+
std::unique_ptr<RefreshRateOverlay> RefreshRateOverlay::create(FpsRange range,
ftl::Flags<Features> features) {
std::unique_ptr<RefreshRateOverlay> overlay =
@@ -171,7 +188,8 @@
return mSurfaceControl != nullptr;
}
-auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> const Buffers& {
+auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps, bool idle)
+ -> const Buffers& {
static const Buffers kNoBuffers;
if (!mSurfaceControl) return kNoBuffers;
@@ -197,8 +215,8 @@
createTransaction().setTransform(mSurfaceControl->get(), transform).apply();
- BufferCache::const_iterator it =
- mBufferCache.find({refreshRate.getIntValue(), renderFps.getIntValue(), transformHint});
+ BufferCache::const_iterator it = mBufferCache.find(
+ {refreshRate.getIntValue(), renderFps.getIntValue(), transformHint, idle});
if (it == mBufferCache.end()) {
const int maxFps = mFpsRange.max.getIntValue();
@@ -222,10 +240,10 @@
const SkColor color = colorBase.toSkColor();
- auto buffers = draw(refreshIntFps, renderIntFps, color, transformHint, mFeatures);
+ auto buffers = draw(refreshIntFps, renderIntFps, idle, color, transformHint, mFeatures);
it = mBufferCache
- .try_emplace({refreshIntFps, renderIntFps, transformHint}, std::move(buffers))
- .first;
+ .try_emplace({refreshIntFps, renderIntFps, transformHint, idle},
+ std::move(buffers)).first;
}
return it->second;
@@ -257,7 +275,15 @@
void RefreshRateOverlay::changeRefreshRate(Fps refreshRate, Fps renderFps) {
mRefreshRate = refreshRate;
mRenderFps = renderFps;
- const auto buffer = getOrCreateBuffers(refreshRate, renderFps)[mFrame];
+ const auto buffer = getOrCreateBuffers(refreshRate, renderFps, mIsVrrIdle)[mFrame];
+ createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
+}
+
+void RefreshRateOverlay::onVrrIdle(bool idle) {
+ mIsVrrIdle = idle;
+ if (!mRefreshRate || !mRenderFps) return;
+
+ const auto buffer = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle)[mFrame];
createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
}
@@ -265,7 +291,7 @@
if (mFeatures.test(Features::RenderRate) && mRefreshRate &&
FlagManager::getInstance().misc1()) {
mRenderFps = renderFps;
- const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps)[mFrame];
+ const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps, mIsVrrIdle)[mFrame];
createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
}
}
@@ -273,7 +299,7 @@
void RefreshRateOverlay::animate() {
if (!mFeatures.test(Features::Spinner) || !mRefreshRate) return;
- const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps);
+ const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle);
mFrame = (mFrame + 1) % buffers.size();
const auto buffer = buffers[mFrame];
createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply();
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index b2896f0..d8aa048 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -57,6 +57,7 @@
void changeRenderRate(Fps);
void animate();
bool isSetByHwc() const { return mFeatures.test(RefreshRateOverlay::Features::SetByHwc); }
+ void onVrrIdle(bool idle);
RefreshRateOverlay(ConstructorTag, FpsRange, ftl::Flags<Features>);
@@ -65,11 +66,12 @@
using Buffers = std::vector<sp<GraphicBuffer>>;
- static Buffers draw(int refreshRate, int renderFps, SkColor, ui::Transform::RotationFlags,
- ftl::Flags<Features>);
+ static Buffers draw(int refreshRate, int renderFps, bool idle, SkColor,
+ ui::Transform::RotationFlags, ftl::Flags<Features>);
static void drawNumber(int number, int left, SkColor, SkCanvas&);
+ static void drawDash(int left, SkCanvas&);
- const Buffers& getOrCreateBuffers(Fps, Fps);
+ const Buffers& getOrCreateBuffers(Fps, Fps, bool);
SurfaceComposerClient::Transaction createTransaction() const;
@@ -77,10 +79,11 @@
int refreshRate;
int renderFps;
ui::Transform::RotationFlags flags;
+ bool idle;
bool operator==(Key other) const {
return refreshRate == other.refreshRate && renderFps == other.renderFps &&
- flags == other.flags;
+ flags == other.flags && idle == other.idle;
}
};
@@ -89,6 +92,7 @@
std::optional<Fps> mRefreshRate;
std::optional<Fps> mRenderFps;
+ bool mIsVrrIdle = false;
size_t mFrame = 0;
const FpsRange mFpsRange; // For color interpolation.
diff --git a/services/surfaceflinger/Scheduler/ISchedulerCallback.h b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
index 43cdb5e..2b9e88c 100644
--- a/services/surfaceflinger/Scheduler/ISchedulerCallback.h
+++ b/services/surfaceflinger/Scheduler/ISchedulerCallback.h
@@ -28,11 +28,11 @@
virtual void requestHardwareVsync(PhysicalDisplayId, bool enabled) = 0;
virtual void requestDisplayModes(std::vector<display::DisplayModeRequest>) = 0;
virtual void kernelTimerChanged(bool expired) = 0;
- virtual void triggerOnFrameRateOverridesChanged() = 0;
virtual void onChoreographerAttached() = 0;
virtual void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>,
Fps renderRate) = 0;
virtual void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) = 0;
+ virtual void vrrDisplayIdle(bool idle) = 0;
protected:
~ISchedulerCallback() = default;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 6a67ac5..2e1f938 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -188,12 +188,13 @@
postMessage(sp<ConfigureHandler>::make(mCompositor));
}
-void MessageQueue::scheduleFrame() {
+void MessageQueue::scheduleFrame(Duration workDurationSlack) {
SFTRACE_CALL();
std::lock_guard lock(mVsync.mutex);
+ const auto workDuration = Duration(mVsync.workDuration.get() - workDurationSlack);
mVsync.scheduledFrameTimeOpt =
- mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
+ mVsync.registration->schedule({.workDuration = workDuration.ns(),
.readyDuration = 0,
.lastVsync = mVsync.lastCallbackTime.ns()});
}
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index c5fc371..ba1efbe 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -74,7 +74,7 @@
virtual void postMessage(sp<MessageHandler>&&) = 0;
virtual void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) = 0;
virtual void scheduleConfigure() = 0;
- virtual void scheduleFrame() = 0;
+ virtual void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) = 0;
virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
};
@@ -149,7 +149,7 @@
void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) override;
void scheduleConfigure() override;
- void scheduleFrame() override;
+ void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) override;
std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
};
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index a20cf9a..9f6eab2 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -634,11 +634,12 @@
// If all layers are category NoPreference, use the current config.
if (noPreferenceLayers + noVoteLayers == layers.size()) {
ALOGV("All layers NoPreference");
- const auto ascendingWithPreferred =
- rankFrameRates(anchorGroup, RefreshRateOrder::Ascending, activeMode.getId());
+ constexpr float kScore = std::numeric_limits<float>::max();
+ FrameRateRanking currentMode;
+ currentMode.emplace_back(ScoredFrameRate{getActiveModeLocked(), kScore});
SFTRACE_FORMAT_INSTANT("%s (All layers NoPreference)",
- to_string(ascendingWithPreferred.front().frameRateMode.fps).c_str());
- return {ascendingWithPreferred, kNoSignals};
+ to_string(currentMode.front().frameRateMode.fps).c_str());
+ return {currentMode, kNoSignals};
}
const bool smoothSwitchOnly = categorySmoothSwitchOnlyLayers > 0;
@@ -1500,7 +1501,7 @@
return str;
};
ALOGV("%s render rates: %s, isVrrDevice? %d", rangeName, stringifyModes().c_str(),
- mIsVrrDevice);
+ mIsVrrDevice.load());
return frameRateModes;
};
@@ -1510,7 +1511,6 @@
}
bool RefreshRateSelector::isVrrDevice() const {
- std::lock_guard lock(mLock);
return mIsVrrDevice;
}
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index 4f491d9..998b1b8 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -321,7 +321,10 @@
RefreshRateSelector(const RefreshRateSelector&) = delete;
RefreshRateSelector& operator=(const RefreshRateSelector&) = delete;
- const DisplayModes& displayModes() const { return mDisplayModes; }
+ DisplayModes displayModes() const {
+ std::lock_guard lock(mLock);
+ return mDisplayModes;
+ }
// Returns whether switching modes (refresh rate or resolution) is possible.
// TODO(b/158780872): Consider HAL support, and skip frame rate detection if the modes only
@@ -383,6 +386,7 @@
Callbacks platform;
Callbacks kernel;
+ Callbacks vrr;
};
void setIdleTimerCallbacks(IdleTimerCallbacks callbacks) EXCLUDES(mIdleTimerCallbacksMutex) {
@@ -501,6 +505,9 @@
std::optional<IdleTimerCallbacks::Callbacks> getIdleTimerCallbacks() const
REQUIRES(mIdleTimerCallbacksMutex) {
if (!mIdleTimerCallbacks) return {};
+
+ if (mIsVrrDevice) return mIdleTimerCallbacks->vrr;
+
return mConfig.kernelIdleTimerController.has_value() ? mIdleTimerCallbacks->kernel
: mIdleTimerCallbacks->platform;
}
@@ -536,7 +543,7 @@
std::vector<FrameRateMode> mAppRequestFrameRates GUARDED_BY(mLock);
// Caches whether the device is VRR-compatible based on the active display mode.
- bool mIsVrrDevice GUARDED_BY(mLock) = false;
+ std::atomic_bool mIsVrrDevice = false;
Policy mDisplayManagerPolicy GUARDED_BY(mLock);
std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index c43e942..84584a4 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -82,7 +82,7 @@
mTouchTimer.reset();
// Stop idle timer and clear callbacks, as the RefreshRateSelector may outlive the Scheduler.
- demotePacesetterDisplay();
+ demotePacesetterDisplay({.toggleIdleTimer = true});
}
void Scheduler::initVsync(frametimeline::TokenManager& tokenManager,
@@ -117,10 +117,11 @@
}
}
-void Scheduler::setPacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
- demotePacesetterDisplay();
+void Scheduler::setPacesetterDisplay(PhysicalDisplayId pacesetterId) {
+ constexpr PromotionParams kPromotionParams = {.toggleIdleTimer = true};
- promotePacesetterDisplay(pacesetterIdOpt);
+ demotePacesetterDisplay(kPromotionParams);
+ promotePacesetterDisplay(pacesetterId, kPromotionParams);
}
void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
@@ -139,16 +140,22 @@
RefreshRateSelectorPtr selectorPtr,
VsyncSchedulePtr schedulePtr,
PhysicalDisplayId activeDisplayId) {
- demotePacesetterDisplay();
+ const bool isPrimary = (ftl::FakeGuard(mDisplayLock), !mPacesetterDisplayId);
- auto [pacesetterVsyncSchedule, isNew] = [&]() FTL_FAKE_GUARD(kMainThreadContext) {
+ // Start the idle timer for the first registered (i.e. primary) display.
+ const PromotionParams promotionParams = {.toggleIdleTimer = isPrimary};
+
+ demotePacesetterDisplay(promotionParams);
+
+ auto [pacesetterVsyncSchedule, isNew] = [&]() REQUIRES(kMainThreadContext) {
std::scoped_lock lock(mDisplayLock);
const bool isNew = mDisplays
.emplace_or_replace(displayId, displayId, std::move(selectorPtr),
std::move(schedulePtr), mFeatures)
.second;
- return std::make_pair(promotePacesetterDisplayLocked(activeDisplayId), isNew);
+ return std::make_pair(promotePacesetterDisplayLocked(activeDisplayId, promotionParams),
+ isNew);
}();
applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
@@ -166,7 +173,8 @@
dispatchHotplug(displayId, Hotplug::Disconnected);
- demotePacesetterDisplay();
+ constexpr PromotionParams kPromotionParams = {.toggleIdleTimer = false};
+ demotePacesetterDisplay(kPromotionParams);
std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
{
@@ -178,7 +186,7 @@
// headless virtual display.)
LOG_ALWAYS_FATAL_IF(mDisplays.empty(), "Cannot unregister all displays!");
- pacesetterVsyncSchedule = promotePacesetterDisplayLocked(activeDisplayId);
+ pacesetterVsyncSchedule = promotePacesetterDisplayLocked(activeDisplayId, kPromotionParams);
}
applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
@@ -395,14 +403,20 @@
eventThreadFor(Cycle::Render).enableSyntheticVsync(enable);
}
-void Scheduler::onFrameRateOverridesChanged(Cycle cycle, PhysicalDisplayId displayId) {
- const bool supportsFrameRateOverrideByContent =
- pacesetterSelectorPtr()->supportsAppFrameRateOverrideByContent();
+void Scheduler::onFrameRateOverridesChanged() {
+ const auto [pacesetterId, supportsFrameRateOverrideByContent] = [this] {
+ std::scoped_lock lock(mDisplayLock);
+ const auto pacesetterOpt = pacesetterDisplayLocked();
+ LOG_ALWAYS_FATAL_IF(!pacesetterOpt);
+ const Display& pacesetter = *pacesetterOpt;
+ return std::make_pair(FTL_FAKE_GUARD(kMainThreadContext, *mPacesetterDisplayId),
+ pacesetter.selectorPtr->supportsAppFrameRateOverrideByContent());
+ }();
std::vector<FrameRateOverride> overrides =
mFrameRateOverrideMappings.getAllFrameRateOverrides(supportsFrameRateOverrideByContent);
- eventThreadFor(cycle).onFrameRateOverridesChanged(displayId, std::move(overrides));
+ eventThreadFor(Cycle::Render).onFrameRateOverridesChanged(pacesetterId, std::move(overrides));
}
void Scheduler::onHdcpLevelsChanged(Cycle cycle, PhysicalDisplayId displayId,
@@ -899,9 +913,13 @@
}
}
-bool Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps displayRefreshRate) {
- std::scoped_lock lock(mPolicyLock);
- return updateFrameRateOverridesLocked(consideredSignals, displayRefreshRate);
+void Scheduler::updateFrameRateOverrides(GlobalSignals consideredSignals, Fps displayRefreshRate) {
+ const bool changed = (std::scoped_lock(mPolicyLock),
+ updateFrameRateOverridesLocked(consideredSignals, displayRefreshRate));
+
+ if (changed) {
+ onFrameRateOverridesChanged();
+ }
}
bool Scheduler::updateFrameRateOverridesLocked(GlobalSignals consideredSignals,
@@ -917,35 +935,38 @@
return mFrameRateOverrideMappings.updateFrameRateOverridesByContent(frameRateOverrides);
}
-void Scheduler::promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt) {
+void Scheduler::promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams params) {
std::shared_ptr<VsyncSchedule> pacesetterVsyncSchedule;
-
{
std::scoped_lock lock(mDisplayLock);
- pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterIdOpt);
+ pacesetterVsyncSchedule = promotePacesetterDisplayLocked(pacesetterId, params);
}
applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));
}
std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
- std::optional<PhysicalDisplayId> pacesetterIdOpt) {
- // TODO(b/241286431): Choose the pacesetter display.
- mPacesetterDisplayId = pacesetterIdOpt.value_or(mDisplays.begin()->first);
- ALOGI("Display %s is the pacesetter", to_string(*mPacesetterDisplayId).c_str());
+ PhysicalDisplayId pacesetterId, PromotionParams params) {
+ // TODO: b/241286431 - Choose the pacesetter among mDisplays.
+ mPacesetterDisplayId = pacesetterId;
+ ALOGI("Display %s is the pacesetter", to_string(pacesetterId).c_str());
std::shared_ptr<VsyncSchedule> newVsyncSchedulePtr;
if (const auto pacesetterOpt = pacesetterDisplayLocked()) {
const Display& pacesetter = *pacesetterOpt;
- pacesetter.selectorPtr->setIdleTimerCallbacks(
- {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
- .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
- .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
- .onExpired =
- [this] { kernelIdleTimerCallback(TimerState::Expired); }}});
+ if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) {
+ pacesetter.selectorPtr->setIdleTimerCallbacks(
+ {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
+ .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
+ .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
+ .onExpired =
+ [this] { kernelIdleTimerCallback(TimerState::Expired); }},
+ .vrr = {.onReset = [this] { mSchedulerCallback.vrrDisplayIdle(false); },
+ .onExpired = [this] { mSchedulerCallback.vrrDisplayIdle(true); }}});
- pacesetter.selectorPtr->startIdleTimer();
+ pacesetter.selectorPtr->startIdleTimer();
+ }
newVsyncSchedulePtr = pacesetter.schedulePtr;
@@ -965,11 +986,14 @@
}
}
-void Scheduler::demotePacesetterDisplay() {
- // No need to lock for reads on kMainThreadContext.
- if (const auto pacesetterPtr = FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
- pacesetterPtr->stopIdleTimer();
- pacesetterPtr->clearIdleTimerCallbacks();
+void Scheduler::demotePacesetterDisplay(PromotionParams params) {
+ if (!FlagManager::getInstance().connected_display() || params.toggleIdleTimer) {
+ // No need to lock for reads on kMainThreadContext.
+ if (const auto pacesetterPtr =
+ FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
+ pacesetterPtr->stopIdleTimer();
+ pacesetterPtr->clearIdleTimerCallbacks();
+ }
}
// Clear state that depends on the pacesetter's RefreshRateSelector.
@@ -1143,7 +1167,7 @@
updateFrameRateOverridesLocked(consideredSignals, mPolicy.modeOpt->fps);
}
if (frameRateOverridesChanged) {
- mSchedulerCallback.triggerOnFrameRateOverridesChanged();
+ onFrameRateOverridesChanged();
}
return consideredSignals;
}
@@ -1243,6 +1267,8 @@
} else {
mFrameRateOverrideMappings.setGameModeRefreshRateForUid(frameRateOverride);
}
+
+ onFrameRateOverridesChanged();
}
void Scheduler::setGameDefaultFrameRateForUid(FrameRateOverride frameRateOverride) {
@@ -1261,6 +1287,7 @@
}
mFrameRateOverrideMappings.setPreferredRefreshRateForUid(frameRateOverride);
+ onFrameRateOverridesChanged();
}
void Scheduler::updateSmallAreaDetection(
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 1a4aa79..e1f4d20 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -92,8 +92,8 @@
void startTimers();
- // TODO(b/241285191): Remove this API by promoting pacesetter in onScreen{Acquired,Released}.
- void setPacesetterDisplay(std::optional<PhysicalDisplayId>) REQUIRES(kMainThreadContext)
+ // TODO: b/241285191 - Remove this API by promoting pacesetter in onScreen{Acquired,Released}.
+ void setPacesetterDisplay(PhysicalDisplayId) REQUIRES(kMainThreadContext)
EXCLUDES(mDisplayLock);
using RefreshRateSelectorPtr = std::shared_ptr<RefreshRateSelector>;
@@ -159,8 +159,6 @@
void enableSyntheticVsync(bool = true) REQUIRES(kMainThreadContext);
- void onFrameRateOverridesChanged(Cycle, PhysicalDisplayId);
-
void onHdcpLevelsChanged(Cycle, PhysicalDisplayId, int32_t, int32_t);
// Modifies work duration in the event thread.
@@ -326,7 +324,7 @@
return mLayerHistory.getLayerFramerate(now, id);
}
- bool updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) EXCLUDES(mPolicyLock);
+ void updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) EXCLUDES(mPolicyLock);
// Returns true if the small dirty detection is enabled for the appId.
bool supportSmallDirtyDetection(int32_t appId) {
@@ -377,9 +375,16 @@
void resyncAllToHardwareVsync(bool allowToEnable) EXCLUDES(mDisplayLock);
void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod);
- // Chooses a pacesetter among the registered displays, unless `pacesetterIdOpt` is specified.
- // The new `mPacesetterDisplayId` is never `std::nullopt`.
- void promotePacesetterDisplay(std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
+ // TODO: b/241286431 - Remove this option, which assumes that the pacesetter does not change
+ // when a (secondary) display is registered or unregistered. In the short term, this avoids
+ // a deadlock where the main thread joins with the timer thread as the timer thread waits to
+ // lock a mutex held by the main thread.
+ struct PromotionParams {
+ // Whether to stop and start the idle timer. Ignored unless connected_display flag is set.
+ bool toggleIdleTimer;
+ };
+
+ void promotePacesetterDisplay(PhysicalDisplayId pacesetterId, PromotionParams)
REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock);
// Changes to the displays (e.g. registering and unregistering) must be made
@@ -388,14 +393,16 @@
// MessageQueue and EventThread need to use the new pacesetter's
// VsyncSchedule, and this must happen while mDisplayLock is *not* locked,
// or else we may deadlock with EventThread.
- std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(
- std::optional<PhysicalDisplayId> pacesetterIdOpt = std::nullopt)
+ std::shared_ptr<VsyncSchedule> promotePacesetterDisplayLocked(PhysicalDisplayId pacesetterId,
+ PromotionParams)
REQUIRES(kMainThreadContext, mDisplayLock);
void applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule>) EXCLUDES(mDisplayLock);
- // Blocks until the pacesetter's idle timer thread exits. `mDisplayLock` must not be locked by
- // the caller on the main thread to avoid deadlock, since the timer thread locks it before exit.
- void demotePacesetterDisplay() REQUIRES(kMainThreadContext) EXCLUDES(mDisplayLock, mPolicyLock);
+ // If toggleIdleTimer is true, the calling thread blocks until the pacesetter's idle timer
+ // thread exits, in which case mDisplayLock must not be locked by the caller to avoid deadlock,
+ // since the timer thread locks it before exit.
+ void demotePacesetterDisplay(PromotionParams) REQUIRES(kMainThreadContext)
+ EXCLUDES(mDisplayLock, mPolicyLock);
void registerDisplayInternal(PhysicalDisplayId, RefreshRateSelectorPtr, VsyncSchedulePtr,
PhysicalDisplayId activeDisplayId) REQUIRES(kMainThreadContext)
@@ -441,6 +448,9 @@
bool updateFrameRateOverridesLocked(GlobalSignals, Fps displayRefreshRate)
REQUIRES(mPolicyLock);
+
+ void onFrameRateOverridesChanged();
+
void updateAttachedChoreographers(const surfaceflinger::frontend::LayerHierarchy&,
Fps displayRefreshRate);
int updateAttachedChoreographersInternal(const surfaceflinger::frontend::LayerHierarchy&,
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
index 16799bd..04491a2 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.cpp
@@ -400,8 +400,9 @@
} else {
if (FlagManager::getInstance().vrr_bugfix_24q4()) {
- // We need to freeze the timeline at the committed vsync so that we don't
- // overshoot the deadline.
+ // We need to freeze the timeline at the committed vsync, and
+ // then use with threshold adjustments when required to avoid
+ // marginal errors when checking the vsync on the timeline.
mTimelines.back().freeze(mLastCommittedVsync);
} else {
mTimelines.back().freeze(
@@ -451,7 +452,7 @@
const auto currentPeriod = mRateMap.find(idealPeriod())->second.slope;
const auto threshold = currentPeriod / 2;
- const auto minFramePeriod = minFramePeriodLocked().ns();
+ const auto minFramePeriod = minFramePeriodLocked();
auto prev = lastConfirmedPresentTime.ns();
for (auto& current : mPastExpectedPresentTimes) {
@@ -462,10 +463,10 @@
1e6f);
}
- const auto minPeriodViolation = current.ns() - prev + threshold < minFramePeriod;
+ const auto minPeriodViolation = current.ns() - prev + threshold < minFramePeriod.ns();
if (minPeriodViolation) {
SFTRACE_NAME("minPeriodViolation");
- current = TimePoint::fromNs(prev + minFramePeriod);
+ current = TimePoint::fromNs(prev + minFramePeriod.ns());
prev = current.ns();
} else {
break;
@@ -476,7 +477,7 @@
const auto phase = Duration(mPastExpectedPresentTimes.back() - expectedPresentTime);
if (phase > 0ns) {
for (auto& timeline : mTimelines) {
- timeline.shiftVsyncSequence(phase);
+ timeline.shiftVsyncSequence(phase, minFramePeriod);
}
mPastExpectedPresentTimes.clear();
return phase;
@@ -486,13 +487,13 @@
return 0ns;
}
-void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime,
- TimePoint lastConfirmedPresentTime) {
+void VSyncPredictor::onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) {
SFTRACE_NAME("VSyncPredictor::onFrameBegin");
std::lock_guard lock(mMutex);
if (!mDisplayModePtr->getVrrConfig()) return;
+ const auto [lastConfirmedPresentTime, lastConfirmedExpectedPresentTime] = lastSignaledFrameTime;
if (CC_UNLIKELY(mTraceOn)) {
SFTRACE_FORMAT_INSTANT("vsync is %.2f past last signaled fence",
static_cast<float>(expectedPresentTime.ns() -
@@ -518,6 +519,11 @@
}
}
+ if (lastConfirmedExpectedPresentTime.ns() - lastConfirmedPresentTime.ns() > threshold) {
+ SFTRACE_FORMAT_INSTANT("lastFramePresentedEarly");
+ return;
+ }
+
const auto phase = ensureMinFrameDurationIsKept(expectedPresentTime, lastConfirmedPresentTime);
if (phase > 0ns) {
mMissedVsync = {expectedPresentTime, minFramePeriodLocked()};
@@ -772,13 +778,34 @@
return vsyncSequence.seq % divisor == 0;
}
-void VSyncPredictor::VsyncTimeline::shiftVsyncSequence(Duration phase) {
+void VSyncPredictor::VsyncTimeline::shiftVsyncSequence(Duration phase, Period minFramePeriod) {
if (mLastVsyncSequence) {
+ const auto renderRate = mRenderRateOpt.value_or(Fps::fromPeriodNsecs(mIdealPeriod.ns()));
+ const auto threshold = mIdealPeriod.ns() / 2;
+ if (renderRate.getPeriodNsecs() - phase.ns() + threshold >= minFramePeriod.ns()) {
+ SFTRACE_FORMAT_INSTANT("Not-Adjusting vsync by %.2f",
+ static_cast<float>(phase.ns()) / 1e6f);
+ return;
+ }
SFTRACE_FORMAT_INSTANT("adjusting vsync by %.2f", static_cast<float>(phase.ns()) / 1e6f);
mLastVsyncSequence->vsyncTime += phase.ns();
}
}
+VSyncPredictor::VsyncTimeline::VsyncOnTimeline VSyncPredictor::VsyncTimeline::isWithin(
+ TimePoint vsync) {
+ const auto threshold = mIdealPeriod.ns() / 2;
+ if (!mValidUntil || vsync.ns() < mValidUntil->ns() - threshold) {
+ // if mValidUntil is absent then timeline is not frozen and
+ // vsync should be unique to that timeline.
+ return VsyncOnTimeline::Unique;
+ }
+ if (vsync.ns() > mValidUntil->ns() + threshold) {
+ return VsyncOnTimeline::Outside;
+ }
+ return VsyncOnTimeline::Shared;
+}
+
} // namespace android::scheduler
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index 66a7d71..6c8a2f2 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -22,6 +22,7 @@
#include <vector>
#include <android-base/thread_annotations.h>
+#include <scheduler/FrameTime.h>
#include <scheduler/TimeKeeper.h>
#include <ui/DisplayId.h>
@@ -77,7 +78,7 @@
void setRenderRate(Fps, bool applyImmediately) final EXCLUDES(mMutex);
- void onFrameBegin(TimePoint expectedPresentTime, TimePoint lastConfirmedPresentTime) final
+ void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) final
EXCLUDES(mMutex);
void onFrameMissed(TimePoint expectedPresentTime) final EXCLUDES(mMutex);
@@ -103,7 +104,7 @@
void freeze(TimePoint lastVsync);
std::optional<TimePoint> validUntil() const { return mValidUntil; }
bool isVSyncInPhase(Model, nsecs_t vsync, Fps frameRate);
- void shiftVsyncSequence(Duration phase);
+ void shiftVsyncSequence(Duration phase, Period minFramePeriod);
void setRenderRate(std::optional<Fps> renderRateOpt) { mRenderRateOpt = renderRateOpt; }
enum class VsyncOnTimeline {
@@ -111,18 +112,7 @@
Shared, // Within timeline, shared with next timeline.
Outside, // Outside of the timeline.
};
- VsyncOnTimeline isWithin(TimePoint vsync) {
- const auto threshold = mIdealPeriod.ns() / 2;
- if (!mValidUntil || vsync.ns() < mValidUntil->ns() - threshold) {
- // if mValidUntil is absent then timeline is not frozen and
- // vsync should be unique to that timeline.
- return VsyncOnTimeline::Unique;
- }
- if (vsync.ns() > mValidUntil->ns() + threshold) {
- return VsyncOnTimeline::Outside;
- }
- return VsyncOnTimeline::Shared;
- }
+ VsyncOnTimeline isWithin(TimePoint vsync);
private:
nsecs_t snapToVsyncAlignedWithRenderRate(Model model, nsecs_t vsync);
diff --git a/services/surfaceflinger/Scheduler/VSyncTracker.h b/services/surfaceflinger/Scheduler/VSyncTracker.h
index 134d28e..3376fad 100644
--- a/services/surfaceflinger/Scheduler/VSyncTracker.h
+++ b/services/surfaceflinger/Scheduler/VSyncTracker.h
@@ -21,6 +21,7 @@
#include <scheduler/Fps.h>
#include <scheduler/FrameRateMode.h>
+#include <scheduler/FrameTime.h>
#include "VSyncDispatch.h"
@@ -112,8 +113,7 @@
*/
virtual void setRenderRate(Fps, bool applyImmediately) = 0;
- virtual void onFrameBegin(TimePoint expectedPresentTime,
- TimePoint lastConfirmedPresentTime) = 0;
+ virtual void onFrameBegin(TimePoint expectedPresentTime, FrameTime lastSignaledFrameTime) = 0;
virtual void onFrameMissed(TimePoint expectedPresentTime) = 0;
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
index d37d2dc..2185bb0 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h
@@ -26,6 +26,7 @@
#include <ui/FenceTime.h>
#include <scheduler/Features.h>
+#include <scheduler/FrameTime.h>
#include <scheduler/Time.h>
#include <scheduler/VsyncId.h>
#include <scheduler/interface/CompositeResult.h>
@@ -54,31 +55,20 @@
std::optional<TimePoint> earliestPresentTime() const { return mEarliestPresentTime; }
- // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details.
- TimePoint pastVsyncTime(Period minFramePeriod) const;
-
- // The present fence for the frame that had targeted the most recent VSYNC before this frame.
- // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
- // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
- // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
- // signaled by now (unless that frame missed).
- FenceTimePtr presentFenceForPastVsync(Period minFramePeriod) const;
-
- // Equivalent to `presentFenceForPastVsync` unless running N VSYNCs ahead.
- const FenceTimePtr& presentFenceForPreviousFrame() const {
- return mPresentFences.front().fenceTime;
- }
+ // Equivalent to `expectedSignaledPresentFence` unless running N VSYNCs ahead.
+ const FenceTimePtr& presentFenceForPreviousFrame() const;
bool isFramePending() const { return mFramePending; }
+ bool wouldBackpressureHwc() const { return mWouldBackpressureHwc; }
bool didMissFrame() const { return mFrameMissed; }
bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; }
- TimePoint lastSignaledFrameTime() const { return mLastSignaledFrameTime; };
+ FrameTime lastSignaledFrameTime() const { return mLastSignaledFrameTime; }
protected:
explicit FrameTarget(const std::string& displayLabel);
~FrameTarget() = default;
- bool wouldPresentEarly(Period minFramePeriod) const;
+ bool wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) const;
// Equivalent to `pastVsyncTime` unless running N VSYNCs ahead.
TimePoint previousFrameVsyncTime(Period minFramePeriod) const {
@@ -87,8 +77,7 @@
void addFence(sp<Fence> presentFence, FenceTimePtr presentFenceTime,
TimePoint expectedPresentTime) {
- mFenceWithFenceTimes.next() = {std::move(presentFence), presentFenceTime,
- expectedPresentTime};
+ mPresentFences.next() = {std::move(presentFence), presentFenceTime, expectedPresentTime};
}
VsyncId mVsyncId;
@@ -100,16 +89,25 @@
TracedOrdinal<bool> mFrameMissed;
TracedOrdinal<bool> mHwcFrameMissed;
TracedOrdinal<bool> mGpuFrameMissed;
+ bool mWouldBackpressureHwc = false;
- struct FenceWithFenceTime {
+ struct PresentFence {
sp<Fence> fence = Fence::NO_FENCE;
FenceTimePtr fenceTime = FenceTime::NO_FENCE;
TimePoint expectedPresentTime = TimePoint();
};
- std::array<FenceWithFenceTime, 2> mPresentFences;
- utils::RingBuffer<FenceWithFenceTime, 5> mFenceWithFenceTimes;
- TimePoint mLastSignaledFrameTime;
+ // The present fence for the frame that had targeted the most recent VSYNC before this frame.
+ // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the
+ // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the
+ // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been
+ // signaled by now (unless that frame missed).
+ std::pair<bool /* wouldBackpressure */, PresentFence> expectedSignaledPresentFence(
+ Period vsyncPeriod, Period minFramePeriod) const;
+ std::array<PresentFence, 2> mPresentFencesLegacy;
+ utils::RingBuffer<PresentFence, 5> mPresentFences;
+
+ FrameTime mLastSignaledFrameTime;
private:
friend class FrameTargeterTestBase;
@@ -119,18 +117,6 @@
static_assert(N > 1);
return expectedFrameDuration() > (N - 1) * minFramePeriod;
}
-
- const FenceTimePtr pastVsyncTimePtr() const {
- auto pastFenceTimePtr = FenceTime::NO_FENCE;
- for (size_t i = 0; i < mFenceWithFenceTimes.size(); i++) {
- const auto& [_, fenceTimePtr, expectedPresentTime] = mFenceWithFenceTimes[i];
- if (expectedPresentTime > mFrameBeginTime) {
- return pastFenceTimePtr;
- }
- pastFenceTimePtr = fenceTimePtr;
- }
- return pastFenceTimePtr;
- }
};
// Computes a display's per-frame metrics about past/upcoming targeting of present deadlines.
@@ -153,7 +139,7 @@
void beginFrame(const BeginFrameArgs&, const IVsyncSource&);
- std::optional<TimePoint> computeEarliestPresentTime(Period minFramePeriod,
+ std::optional<TimePoint> computeEarliestPresentTime(Period vsyncPeriod, Period minFramePeriod,
Duration hwcMinWorkDuration);
// TODO(b/241285191): Merge with FrameTargeter::endFrame.
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h
new file mode 100644
index 0000000..ed5c899
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/include/scheduler/FrameTime.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024 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.
+ */
+
+#pragma once
+
+#include <scheduler/Time.h>
+
+namespace android::scheduler {
+struct FrameTime {
+ TimePoint signalTime;
+ TimePoint expectedPresentTime;
+};
+} // namespace android::scheduler
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
index 60694b9..8adf2a6 100644
--- a/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
+++ b/services/surfaceflinger/Scheduler/src/FrameTargeter.cpp
@@ -18,8 +18,10 @@
#include <common/trace.h>
#include <scheduler/FrameTargeter.h>
#include <scheduler/IVsyncSource.h>
+#include <utils/Log.h>
namespace android::scheduler {
+using namespace std::chrono_literals;
FrameTarget::FrameTarget(const std::string& displayLabel)
: mFramePending("PrevFramePending " + displayLabel, false),
@@ -27,32 +29,50 @@
mHwcFrameMissed("PrevHwcFrameMissed " + displayLabel, false),
mGpuFrameMissed("PrevGpuFrameMissed " + displayLabel, false) {}
-TimePoint FrameTarget::pastVsyncTime(Period minFramePeriod) const {
- // TODO(b/267315508): Generalize to N VSYNCs.
- const int shift = static_cast<int>(targetsVsyncsAhead<2>(minFramePeriod));
- return mExpectedPresentTime - Period::fromNs(minFramePeriod.ns() << shift);
-}
-
-FenceTimePtr FrameTarget::presentFenceForPastVsync(Period minFramePeriod) const {
- if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
- return pastVsyncTimePtr();
+std::pair<bool /* wouldBackpressure */, FrameTarget::PresentFence>
+FrameTarget::expectedSignaledPresentFence(Period vsyncPeriod, Period minFramePeriod) const {
+ if (!FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
+ const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod));
+ return {true, mPresentFencesLegacy[i]};
}
- const size_t i = static_cast<size_t>(targetsVsyncsAhead<2>(minFramePeriod));
- return mPresentFences[i].fenceTime;
+
+ bool wouldBackpressure = true;
+ auto expectedPresentTime = mExpectedPresentTime;
+ for (size_t i = mPresentFences.size(); i != 0; --i) {
+ const auto& fence = mPresentFences[i - 1];
+
+ if (fence.expectedPresentTime + minFramePeriod < expectedPresentTime - vsyncPeriod / 2) {
+ wouldBackpressure = false;
+ }
+
+ if (fence.expectedPresentTime <= mFrameBeginTime) {
+ return {wouldBackpressure, fence};
+ }
+
+ expectedPresentTime = fence.expectedPresentTime;
+ }
+ return {wouldBackpressure, PresentFence{}};
}
-bool FrameTarget::wouldPresentEarly(Period minFramePeriod) const {
- // TODO(b/241285475): Since this is called during `composite`, the calls to `targetsVsyncsAhead`
- // should use `TimePoint::now()` in case of delays since `mFrameBeginTime`.
-
- // TODO(b/267315508): Generalize to N VSYNCs.
- const bool allowNVsyncs = FlagManager::getInstance().allow_n_vsyncs_in_targeter();
- if (!allowNVsyncs && targetsVsyncsAhead<3>(minFramePeriod)) {
+bool FrameTarget::wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) const {
+ if (targetsVsyncsAhead<3>(minFramePeriod)) {
return true;
}
- const auto fence = presentFenceForPastVsync(minFramePeriod);
- return fence->isValid() && fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
+ const auto [wouldBackpressure, fence] =
+ expectedSignaledPresentFence(vsyncPeriod, minFramePeriod);
+
+ return !wouldBackpressure ||
+ (fence.fenceTime->isValid() &&
+ fence.fenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING);
+}
+
+const FenceTimePtr& FrameTarget::presentFenceForPreviousFrame() const {
+ if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
+ return mPresentFences.back().fenceTime;
+ }
+
+ return mPresentFencesLegacy.front().fenceTime;
}
void FrameTargeter::beginFrame(const BeginFrameArgs& args, const IVsyncSource& vsyncSource) {
@@ -86,27 +106,39 @@
}
if (!mSupportsExpectedPresentTime) {
- mEarliestPresentTime = computeEarliestPresentTime(minFramePeriod, args.hwcMinWorkDuration);
+ mEarliestPresentTime =
+ computeEarliestPresentTime(vsyncPeriod, minFramePeriod, args.hwcMinWorkDuration);
}
SFTRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, ftl::to_underlying(args.vsyncId),
ticks<std::milli, float>(mExpectedPresentTime - TimePoint::now()),
mExpectedPresentTime == args.expectedVsyncTime ? "" : " (adjusted)");
- const FenceTimePtr& pastPresentFence = presentFenceForPastVsync(minFramePeriod);
+ const auto [wouldBackpressure, fence] =
+ expectedSignaledPresentFence(vsyncPeriod, minFramePeriod);
// In cases where the present fence is about to fire, give it a small grace period instead of
// giving up on the frame.
- //
- // TODO(b/280667110): The grace period should depend on `sfWorkDuration` and `vsyncPeriod` being
- // approximately equal, not whether backpressure propagation is enabled.
- const int graceTimeForPresentFenceMs = static_cast<int>(
- mBackpressureGpuComposition || !mCompositionCoverage.test(CompositionCoverage::Gpu));
+ const int graceTimeForPresentFenceMs = [&] {
+ const bool considerBackpressure =
+ mBackpressureGpuComposition || !mCompositionCoverage.test(CompositionCoverage::Gpu);
+
+ if (!FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
+ return static_cast<int>(considerBackpressure);
+ }
+
+ if (!wouldBackpressure || !considerBackpressure) {
+ return 0;
+ }
+
+ return static_cast<int>((std::abs(fence.expectedPresentTime.ns() - mFrameBeginTime.ns()) <=
+ Duration(1ms).ns()));
+ }();
// Pending frames may trigger backpressure propagation.
const auto& isFencePending = *isFencePendingFuncPtr;
- mFramePending = pastPresentFence != FenceTime::NO_FENCE &&
- isFencePending(pastPresentFence, graceTimeForPresentFenceMs);
+ mFramePending = fence.fenceTime != FenceTime::NO_FENCE &&
+ isFencePending(fence.fenceTime, graceTimeForPresentFenceMs);
// A frame is missed if the prior frame is still pending. If no longer pending, then we still
// count the frame as missed if the predicted present time was further in the past than when the
@@ -114,9 +146,10 @@
// than a typical frame duration, but should not be so small that it reports reasonable drift as
// a missed frame.
mFrameMissed = mFramePending || [&] {
- const nsecs_t pastPresentTime = pastPresentFence->getSignalTime();
+ const nsecs_t pastPresentTime = fence.fenceTime->getSignalTime();
if (pastPresentTime < 0) return false;
- mLastSignaledFrameTime = TimePoint::fromNs(pastPresentTime);
+ mLastSignaledFrameTime = {.signalTime = TimePoint::fromNs(pastPresentTime),
+ .expectedPresentTime = fence.expectedPresentTime};
const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2;
return lastScheduledPresentTime.ns() < pastPresentTime - frameMissedSlop;
}();
@@ -127,11 +160,14 @@
if (mFrameMissed) mFrameMissedCount++;
if (mHwcFrameMissed) mHwcFrameMissedCount++;
if (mGpuFrameMissed) mGpuFrameMissedCount++;
+
+ mWouldBackpressureHwc = mFramePending && wouldBackpressure;
}
-std::optional<TimePoint> FrameTargeter::computeEarliestPresentTime(Period minFramePeriod,
+std::optional<TimePoint> FrameTargeter::computeEarliestPresentTime(Period vsyncPeriod,
+ Period minFramePeriod,
Duration hwcMinWorkDuration) {
- if (wouldPresentEarly(minFramePeriod)) {
+ if (wouldPresentEarly(vsyncPeriod, minFramePeriod)) {
return previousFrameVsyncTime(minFramePeriod) - hwcMinWorkDuration;
}
return {};
@@ -150,8 +186,8 @@
if (FlagManager::getInstance().allow_n_vsyncs_in_targeter()) {
addFence(std::move(presentFence), presentFenceTime, mExpectedPresentTime);
} else {
- mPresentFences[1] = mPresentFences[0];
- mPresentFences[0] = {std::move(presentFence), presentFenceTime, mExpectedPresentTime};
+ mPresentFencesLegacy[1] = mPresentFencesLegacy[0];
+ mPresentFencesLegacy[0] = {std::move(presentFence), presentFenceTime, mExpectedPresentTime};
}
return presentFenceTime;
}
diff --git a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
index 5448eec..6f4e1f1 100644
--- a/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
+++ b/services/surfaceflinger/Scheduler/tests/FrameTargeterTest.cpp
@@ -53,8 +53,13 @@
const auto& target() const { return mTargeter.target(); }
- bool wouldPresentEarly(Period minFramePeriod) const {
- return target().wouldPresentEarly(minFramePeriod);
+ bool wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) const {
+ return target().wouldPresentEarly(vsyncPeriod, minFramePeriod);
+ }
+
+ std::pair<bool /*wouldBackpressure*/, FrameTarget::PresentFence> expectedSignaledPresentFence(
+ Period vsyncPeriod, Period minFramePeriod) const {
+ return target().expectedSignaledPresentFence(vsyncPeriod, minFramePeriod);
}
struct Frame {
@@ -169,7 +174,6 @@
}
TEST_F(FrameTargeterTest, recallsPastVsync) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{111};
TimePoint frameBeginTime(1000ms);
constexpr Fps kRefreshRate = 60_Hz;
@@ -177,16 +181,72 @@
constexpr Duration kFrameDuration = 13ms;
for (int n = 5; n-- > 0;) {
- Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
- const auto fence = frame.end();
+ FenceTimePtr fence;
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate,
+ kRefreshRate);
+ fence = frame.end();
+ }
- EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - kPeriod);
- EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), fence);
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+ const auto [wouldBackpressure, presentFence] =
+ expectedSignaledPresentFence(kPeriod, kPeriod);
+ ASSERT_TRUE(wouldBackpressure);
+ EXPECT_EQ(presentFence.fenceTime, fence);
+ }
+}
+
+TEST_F(FrameTargeterTest, wouldBackpressureAfterTime) {
+ SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
+ VsyncId vsyncId{111};
+ TimePoint frameBeginTime(1000ms);
+ constexpr Fps kRefreshRate = 60_Hz;
+ constexpr Period kPeriod = kRefreshRate.getPeriod();
+ constexpr Duration kFrameDuration = 13ms;
+
+ { Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate); }
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+
+ const auto [wouldBackpressure, presentFence] =
+ expectedSignaledPresentFence(kPeriod, kPeriod);
+ EXPECT_TRUE(wouldBackpressure);
+ }
+ {
+ frameBeginTime += kPeriod;
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+ const auto [wouldBackpressure, presentFence] =
+ expectedSignaledPresentFence(kPeriod, kPeriod);
+ EXPECT_FALSE(wouldBackpressure);
+ }
+}
+
+TEST_F(FrameTargeterTest, wouldBackpressureAfterTimeLegacy) {
+ SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
+ VsyncId vsyncId{111};
+ TimePoint frameBeginTime(1000ms);
+ constexpr Fps kRefreshRate = 60_Hz;
+ constexpr Period kPeriod = kRefreshRate.getPeriod();
+ constexpr Duration kFrameDuration = 13ms;
+
+ { Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate); }
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+
+ const auto [wouldBackpressure, presentFence] =
+ expectedSignaledPresentFence(kPeriod, kPeriod);
+ EXPECT_TRUE(wouldBackpressure);
+ }
+ {
+ frameBeginTime += kPeriod;
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+ const auto [wouldBackpressure, presentFence] =
+ expectedSignaledPresentFence(kPeriod, kPeriod);
+ EXPECT_TRUE(wouldBackpressure);
}
}
TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAhead) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{222};
TimePoint frameBeginTime(2000ms);
constexpr Fps kRefreshRate = 120_Hz;
@@ -194,101 +254,66 @@
constexpr Duration kFrameDuration = 10ms;
FenceTimePtr previousFence = FenceTime::NO_FENCE;
-
+ FenceTimePtr currentFence = FenceTime::NO_FENCE;
for (int n = 5; n-- > 0;) {
Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
- const auto fence = frame.end();
-
- EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod);
- EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence);
-
- previousFence = fence;
+ EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, previousFence);
+ previousFence = currentFence;
+ currentFence = frame.end();
}
}
-TEST_F(FrameTargeterTest, recallsPastNVsyncTwoVsyncsAhead) {
+TEST_F(FrameTargeterTest, recallsPastVsyncFiveVsyncsAhead) {
SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
+
VsyncId vsyncId{222};
TimePoint frameBeginTime(2000ms);
constexpr Fps kRefreshRate = 120_Hz;
constexpr Period kPeriod = kRefreshRate.getPeriod();
- constexpr Duration kFrameDuration = 10ms;
+ constexpr Duration kFrameDuration = 40ms;
- FenceTimePtr previousFence = FenceTime::NO_FENCE;
-
+ FenceTimePtr firstFence = FenceTime::NO_FENCE;
for (int n = 5; n-- > 0;) {
Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
const auto fence = frame.end();
-
- const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod;
- EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime);
- EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence);
-
- frameBeginTime += kPeriod;
- previousFence = fence;
+ if (firstFence == FenceTime::NO_FENCE) {
+ firstFence = fence;
+ }
}
+
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+ EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, firstFence);
}
TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAheadVrr) {
SET_FLAG_FOR_TEST(flags::vrr_config, true);
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{222};
TimePoint frameBeginTime(2000ms);
constexpr Fps kRefreshRate = 120_Hz;
- constexpr Fps kPeakRefreshRate = 240_Hz;
+ constexpr Fps kVsyncRate = 240_Hz;
constexpr Period kPeriod = kRefreshRate.getPeriod();
+ constexpr Period kVsyncPeriod = kVsyncRate.getPeriod();
constexpr Duration kFrameDuration = 10ms;
FenceTimePtr previousFence = FenceTime::NO_FENCE;
-
+ FenceTimePtr currentFence = FenceTime::NO_FENCE;
for (int n = 5; n-- > 0;) {
- Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate,
- kPeakRefreshRate);
- const auto fence = frame.end();
-
- EXPECT_EQ(target().pastVsyncTime(kPeriod), frameBeginTime + kFrameDuration - 2 * kPeriod);
- EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), previousFence);
-
- previousFence = fence;
- }
-}
-
-TEST_F(FrameTargeterTest, recallsPastNVsyncTwoVsyncsAheadVrr) {
- SET_FLAG_FOR_TEST(flags::vrr_config, true);
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
-
- VsyncId vsyncId{222};
- TimePoint frameBeginTime(2000ms);
- constexpr Fps kRefreshRate = 120_Hz;
- constexpr Fps kPeakRefreshRate = 240_Hz;
- constexpr Period kPeriod = kRefreshRate.getPeriod();
- constexpr Duration kFrameDuration = 10ms;
-
- FenceTimePtr previousFence = FenceTime::NO_FENCE;
-
- for (int n = 5; n-- > 0;) {
- Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate,
- kPeakRefreshRate);
- const auto fence = frame.end();
-
- const auto pastVsyncTime = frameBeginTime + kFrameDuration - 2 * kPeriod;
- EXPECT_EQ(target().pastVsyncTime(kPeriod), pastVsyncTime);
- EXPECT_EQ(target().presentFenceForPastVsync(kFrameDuration), previousFence);
-
- frameBeginTime += kPeriod;
- previousFence = fence;
+ Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
+ EXPECT_EQ(expectedSignaledPresentFence(kVsyncPeriod, kPeriod).second.fenceTime,
+ previousFence);
+ previousFence = currentFence;
+ currentFence = frame.end();
}
}
TEST_F(FrameTargeterTest, doesNotDetectEarlyPresentIfNoFence) {
constexpr Period kPeriod = (60_Hz).getPeriod();
- EXPECT_EQ(target().presentFenceForPastVsync(kPeriod), FenceTime::NO_FENCE);
- EXPECT_FALSE(wouldPresentEarly(kPeriod));
+ EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, FenceTime::NO_FENCE);
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
}
TEST_F(FrameTargeterTest, detectsEarlyPresent) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{333};
TimePoint frameBeginTime(3000ms);
constexpr Fps kRefreshRate = 60_Hz;
@@ -296,20 +321,57 @@
// The target is not early while past present fences are pending.
for (int n = 3; n-- > 0;) {
- const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- EXPECT_FALSE(wouldPresentEarly(kPeriod));
+ {
+ const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ }
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
EXPECT_FALSE(target().earliestPresentTime());
}
// The target is early if the past present fence was signaled.
- Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- const auto fence = frame.end();
- fence->signalForTest(frameBeginTime.ns());
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ const auto fence = frame.end();
+ fence->signalForTest(frameBeginTime.ns());
+ }
Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
// `finalFrame` would present early, so it has an earliest present time.
- EXPECT_TRUE(wouldPresentEarly(kPeriod));
+ EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
+ ASSERT_NE(std::nullopt, target().earliestPresentTime());
+ EXPECT_EQ(*target().earliestPresentTime(),
+ target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
+}
+
+TEST_F(FrameTargeterTest, detectsEarlyPresentAfterLongPeriod) {
+ VsyncId vsyncId{333};
+ TimePoint frameBeginTime(3000ms);
+ constexpr Fps kRefreshRate = 60_Hz;
+ constexpr Period kPeriod = kRefreshRate.getPeriod();
+
+ // The target is not early while past present fences are pending.
+ for (int n = 3; n-- > 0;) {
+ {
+ const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ }
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
+ EXPECT_FALSE(target().earliestPresentTime());
+ }
+
+ // The target is early if the past present fence was signaled.
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ const auto fence = frame.end();
+ fence->signalForTest(frameBeginTime.ns());
+ }
+
+ frameBeginTime += 10 * kPeriod;
+
+ Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+
+ // `finalFrame` would present early, so it has an earliest present time.
+ EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
ASSERT_NE(std::nullopt, target().earliestPresentTime());
EXPECT_EQ(*target().earliestPresentTime(),
target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
@@ -318,7 +380,6 @@
// Same as `detectsEarlyPresent`, above, but verifies that we do not set an earliest present time
// when there is expected present time support.
TEST_F(FrameTargeterWithExpectedPresentSupportTest, detectsEarlyPresent) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{333};
TimePoint frameBeginTime(3000ms);
constexpr Fps kRefreshRate = 60_Hz;
@@ -326,26 +387,30 @@
// The target is not early while past present fences are pending.
for (int n = 3; n-- > 0;) {
- const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- EXPECT_FALSE(wouldPresentEarly(kPeriod));
+ {
+ const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ }
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
EXPECT_FALSE(target().earliestPresentTime());
}
// The target is early if the past present fence was signaled.
- Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- const auto fence = frame.end();
- fence->signalForTest(frameBeginTime.ns());
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+
+ const auto fence = frame.end();
+ fence->signalForTest(frameBeginTime.ns());
+ }
Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
// `finalFrame` would present early, but we have expected present time support, so it has no
// earliest present time.
- EXPECT_TRUE(wouldPresentEarly(kPeriod));
+ EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
ASSERT_EQ(std::nullopt, target().earliestPresentTime());
}
TEST_F(FrameTargeterTest, detectsEarlyPresentTwoVsyncsAhead) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
VsyncId vsyncId{444};
TimePoint frameBeginTime(4000ms);
constexpr Fps kRefreshRate = 120_Hz;
@@ -353,17 +418,21 @@
// The target is not early while past present fences are pending.
for (int n = 3; n-- > 0;) {
- const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- EXPECT_FALSE(wouldPresentEarly(kPeriod));
+ {
+ const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
+ }
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
EXPECT_FALSE(target().earliestPresentTime());
}
+ {
+ Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
- const auto fence = frame.end();
- fence->signalForTest(frameBeginTime.ns());
+ const auto fence = frame.end();
+ fence->signalForTest(frameBeginTime.ns());
+ }
// The target is two VSYNCs ahead, so the past present fence is still pending.
- EXPECT_FALSE(wouldPresentEarly(kPeriod));
+ EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
EXPECT_FALSE(target().earliestPresentTime());
{ const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); }
@@ -371,66 +440,21 @@
Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
// The target is early if the past present fence was signaled.
- EXPECT_TRUE(wouldPresentEarly(kPeriod));
+ EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
ASSERT_NE(std::nullopt, target().earliestPresentTime());
EXPECT_EQ(*target().earliestPresentTime(),
target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
}
-TEST_F(FrameTargeterTest, detectsEarlyPresentNVsyncsAhead) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
- VsyncId vsyncId{444};
- TimePoint frameBeginTime(4000ms);
- Fps refreshRate = 120_Hz;
- Period period = refreshRate.getPeriod();
-
- // The target is not early while past present fences are pending.
- for (int n = 5; n-- > 0;) {
- const Frame frame(this, vsyncId++, frameBeginTime, 10ms, refreshRate, refreshRate);
- EXPECT_FALSE(wouldPresentEarly(period));
- EXPECT_FALSE(target().earliestPresentTime());
- }
-
- Frame frame(this, vsyncId++, frameBeginTime, 10ms, refreshRate, refreshRate);
- auto fence = frame.end();
- frameBeginTime += period;
- fence->signalForTest(frameBeginTime.ns());
-
- // The target is two VSYNCs ahead, so the past present fence is still pending.
- EXPECT_FALSE(wouldPresentEarly(period));
- EXPECT_FALSE(target().earliestPresentTime());
-
- { const Frame frame(this, vsyncId++, frameBeginTime, 10ms, refreshRate, refreshRate); }
-
- Frame oneEarlyPresentFrame(this, vsyncId++, frameBeginTime, 10ms, refreshRate, refreshRate);
- // The target is early if the past present fence was signaled.
- EXPECT_TRUE(wouldPresentEarly(period));
- ASSERT_NE(std::nullopt, target().earliestPresentTime());
- EXPECT_EQ(*target().earliestPresentTime(),
- target().expectedPresentTime() - period - kHwcMinWorkDuration);
-
- fence = oneEarlyPresentFrame.end();
- frameBeginTime += period;
- fence->signalForTest(frameBeginTime.ns());
-
- // Change rate to track frame more than 2 vsyncs ahead
- refreshRate = 144_Hz;
- period = refreshRate.getPeriod();
- Frame onePresentEarlyFrame(this, vsyncId++, frameBeginTime, 16ms, refreshRate, refreshRate);
- // The target is not early as last frame as the past frame is tracked for pending.
- EXPECT_FALSE(wouldPresentEarly(period));
-}
-
TEST_F(FrameTargeterTest, detectsEarlyPresentThreeVsyncsAhead) {
- SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
TimePoint frameBeginTime(5000ms);
constexpr Fps kRefreshRate = 144_Hz;
constexpr Period kPeriod = kRefreshRate.getPeriod();
- const Frame frame(this, VsyncId{555}, frameBeginTime, 16ms, kRefreshRate, kRefreshRate);
+ { const Frame frame(this, VsyncId{555}, frameBeginTime, 16ms, kRefreshRate, kRefreshRate); }
// The target is more than two VSYNCs ahead, but present fences are not tracked that far back.
- EXPECT_TRUE(wouldPresentEarly(kPeriod));
+ EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
EXPECT_TRUE(target().earliestPresentTime());
EXPECT_EQ(*target().earliestPresentTime(),
target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c75c9f5..2275165 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -73,7 +73,7 @@
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <hidl/ServiceManagement.h>
-#include <layerproto/LayerProtoParser.h>
+#include <layerproto/LayerProtoHeader.h>
#include <linux/sched/types.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -534,9 +534,6 @@
mIgnoreHdrCameraLayers = ignore_hdr_camera_layers(false);
- mLayerLifecycleManagerEnabled =
- base::GetBoolProperty("persist.debug.sf.enable_layer_lifecycle_manager"s, true);
-
// These are set by the HWC implementation to indicate that they will use the workarounds.
mIsHotplugErrViaNegVsync =
base::GetBoolProperty("debug.sf.hwc_hotplug_error_via_neg_vsync"s, false);
@@ -729,6 +726,7 @@
mBootFinished = true;
FlagManager::getMutableInstance().markBootCompleted();
+ ::tracing_perfetto::registerWithPerfetto();
mInitBootPropsFuture.wait();
mRenderEnginePrimeCacheFuture.wait();
@@ -913,9 +911,11 @@
LOG_ALWAYS_FATAL_IF(!configureLocked(),
"Initial display configuration failed: HWC did not hotplug");
+ mActiveDisplayId = getPrimaryDisplayIdLocked();
+
// Commit primary display.
sp<const DisplayDevice> display;
- if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
+ if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
const auto& displays = mCurrentState.displays;
const auto& token = displays.keyAt(*indexOpt);
@@ -1415,6 +1415,8 @@
return future.get();
}
+// TODO: b/241285876 - Restore thread safety analysis once mStateLock below is unconditional.
+[[clang::no_thread_safety_analysis]]
void SurfaceFlinger::finalizeDisplayModeChange(PhysicalDisplayId displayId) {
SFTRACE_NAME(ftl::Concat(__func__, ' ', displayId.value).c_str());
@@ -1430,7 +1432,7 @@
if (const auto oldResolution =
mDisplayModeController.getActiveMode(displayId).modePtr->getResolution();
oldResolution != activeMode.modePtr->getResolution()) {
- Mutex::Autolock lock(mStateLock);
+ ConditionalLock lock(mStateLock, !FlagManager::getInstance().connected_display());
auto& state = mCurrentState.displays.editValueFor(getPhysicalDisplayTokenLocked(displayId));
// We need to generate new sequenceId in order to recreate the display (and this
@@ -1482,7 +1484,7 @@
void SurfaceFlinger::initiateDisplayModeChanges() {
SFTRACE_CALL();
- for (const auto& [displayId, physical] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) {
+ for (const auto& [displayId, physical] : mPhysicalDisplays) {
auto desiredModeOpt = mDisplayModeController.getDesiredMode(displayId);
if (!desiredModeOpt) {
continue;
@@ -2161,12 +2163,12 @@
return mScheduler->createDisplayEventConnection(cycle, eventRegistration, layerHandle);
}
-void SurfaceFlinger::scheduleCommit(FrameHint hint) {
+void SurfaceFlinger::scheduleCommit(FrameHint hint, Duration workDurationSlack) {
if (hint == FrameHint::kActive) {
mScheduler->resetIdleTimer();
}
mPowerAdvisor->notifyDisplayUpdateImminentAndCpuReset();
- mScheduler->scheduleFrame();
+ mScheduler->scheduleFrame(workDurationSlack);
}
void SurfaceFlinger::scheduleComposite(FrameHint hint) {
@@ -2306,37 +2308,6 @@
}
}
-bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs,
- bool flushTransactions,
- bool& outTransactionsAreEmpty) {
- SFTRACE_CALL();
- frontend::Update update;
- if (flushTransactions) {
- update = flushLifecycleUpdates();
- if (mTransactionTracing) {
- mTransactionTracing->addCommittedTransactions(ftl::to_underlying(vsyncId), frameTimeNs,
- update, mFrontEndDisplayInfos,
- mFrontEndDisplayInfosChanged);
- }
- }
-
- bool needsTraversal = false;
- if (flushTransactions) {
- needsTraversal |= commitMirrorDisplays(vsyncId);
- needsTraversal |= commitCreatedLayers(vsyncId, update.layerCreatedStates);
- needsTraversal |= applyTransactions(update.transactions, vsyncId);
- }
- outTransactionsAreEmpty = !needsTraversal;
- const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
- if (shouldCommit) {
- commitTransactionsLegacy();
- }
-
- bool mustComposite = latchBuffers() || shouldCommit;
- updateLayerGeometry();
- return mustComposite;
-}
-
void SurfaceFlinger::updateLayerHistory(nsecs_t now) {
for (const auto& snapshot : mLayerSnapshotBuilder.getSnapshots()) {
using Changes = frontend::RequestedLayerState::Changes;
@@ -2552,7 +2523,9 @@
it->second->latchBufferImpl(unused, latchTime, bgColorOnly);
newDataLatched = true;
- mLayersWithQueuedFrames.emplace(it->second);
+ frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
+ gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
+ mLayersWithQueuedFrames.emplace(it->second, gameMode);
mLayersIdsWithQueuedFrames.emplace(it->second->sequence);
}
@@ -2610,19 +2583,26 @@
return false;
}
- for (const auto [displayId, _] : frameTargets) {
- if (mDisplayModeController.isModeSetPending(displayId)) {
- finalizeDisplayModeChange(displayId);
+ {
+ ConditionalLock lock(mStateLock, FlagManager::getInstance().connected_display());
+
+ for (const auto [displayId, _] : frameTargets) {
+ if (mDisplayModeController.isModeSetPending(displayId)) {
+ finalizeDisplayModeChange(displayId);
+ }
}
}
- if (pacesetterFrameTarget.isFramePending()) {
+ if (pacesetterFrameTarget.wouldBackpressureHwc()) {
if (mBackpressureGpuComposition || pacesetterFrameTarget.didMissHwcFrame()) {
if (FlagManager::getInstance().vrr_config()) {
mScheduler->getVsyncSchedule()->getTracker().onFrameMissed(
pacesetterFrameTarget.expectedPresentTime());
}
- scheduleCommit(FrameHint::kNone);
+ const Duration slack = FlagManager::getInstance().allow_n_vsyncs_in_targeter()
+ ? TimePoint::now() - pacesetterFrameTarget.frameBeginTime()
+ : Duration::fromNs(0);
+ scheduleCommit(FrameHint::kNone, slack);
return false;
}
}
@@ -2669,11 +2649,8 @@
const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
bool transactionsAreEmpty = false;
- if (mLayerLifecycleManagerEnabled) {
- mustComposite |=
- updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
- flushTransactions, transactionsAreEmpty);
- }
+ mustComposite |= updateLayerSnapshots(vsyncId, pacesetterFrameTarget.frameBeginTime().ns(),
+ flushTransactions, transactionsAreEmpty);
// Tell VsyncTracker that we are going to present this frame before scheduling
// setTransactionFlags which will schedule another SF frame. This was if the tracker
@@ -2707,13 +2684,18 @@
mUpdateAttachedChoreographer = false;
Mutex::Autolock lock(mStateLock);
- mScheduler->chooseRefreshRateForContent(mLayerLifecycleManagerEnabled
- ? &mLayerHierarchyBuilder.getHierarchy()
- : nullptr,
+ mScheduler->chooseRefreshRateForContent(&mLayerHierarchyBuilder.getHierarchy(),
updateAttachedChoreographer);
+
+ if (FlagManager::getInstance().connected_display()) {
+ initiateDisplayModeChanges();
+ }
}
- initiateDisplayModeChanges();
+ if (!FlagManager::getInstance().connected_display()) {
+ ftl::FakeGuard guard(mStateLock);
+ initiateDisplayModeChanges();
+ }
updateCursorAsync();
if (!mustComposite) {
@@ -2772,16 +2754,12 @@
const bool updateTaskMetadata = mCompositionEngine->getFeatureFlags().test(
compositionengine::Feature::kSnapshotLayerMetadata);
- if (updateTaskMetadata && (mVisibleRegionsDirty || mLayerMetadataSnapshotNeeded)) {
- updateLayerMetadataSnapshot();
- mLayerMetadataSnapshotNeeded = false;
- }
refreshArgs.bufferIdsToUncache = std::move(mBufferIdsToUncache);
if (!FlagManager::getInstance().ce_fence_promise()) {
refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
- for (auto& layer : mLayersWithQueuedFrames) {
+ for (auto& [layer, _] : mLayersWithQueuedFrames) {
if (const auto& layerFE = layer->getCompositionEngineLayerFE())
refreshArgs.layersWithQueuedFrames.push_back(layerFE);
}
@@ -2823,7 +2801,7 @@
constexpr bool kCursorOnly = false;
const auto layers = moveSnapshotsToCompositionArgs(refreshArgs, kCursorOnly);
- if (mLayerLifecycleManagerEnabled && !mVisibleRegionsDirty) {
+ if (!mVisibleRegionsDirty) {
for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
auto compositionDisplay = display->getCompositionDisplay();
if (!compositionDisplay->getState().isEnabled) continue;
@@ -2857,7 +2835,7 @@
}
refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
- for (auto& layer : mLayersWithQueuedFrames) {
+ for (auto& [layer, _] : mLayersWithQueuedFrames) {
if (const auto& layerFE = layer->getCompositionEngineLayerFE()) {
refreshArgs.layersWithQueuedFrames.push_back(layerFE);
// Some layers are not displayed and do not yet have a future release fence
@@ -2907,6 +2885,9 @@
// Now that the current frame has been presented above, PowerAdvisor needs the present time
// of the previous frame (whose fence is signaled by now) to determine how long the HWC had
// waited on that fence to retire before presenting.
+ // TODO(b/355238809) `presentFenceForPreviousFrame` might not always be signaled (e.g. on
+ // devices
+ // where HWC does not block on the previous present fence). Revise this assumtion.
const auto& previousPresentFence = pacesetterTarget.presentFenceForPreviousFrame();
mPowerAdvisor->setSfPresentTiming(TimePoint::fromNs(previousPresentFence->getSignalTime()),
@@ -2994,21 +2975,6 @@
return resultsPerDisplay;
}
-void SurfaceFlinger::updateLayerGeometry() {
- SFTRACE_CALL();
-
- if (mVisibleRegionsDirty) {
- computeLayerBounds();
- }
-
- for (auto& layer : mLayersPendingRefresh) {
- Region visibleReg;
- visibleReg.set(layer->getScreenBounds());
- invalidateLayerStack(layer->getOutputFilter(), visibleReg);
- }
- mLayersPendingRefresh.clear();
-}
-
bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const {
// Even though the camera layer may be using an HDR transfer function or otherwise be "HDR"
// the device may need to avoid boosting the brightness as a result of these layers to
@@ -3175,10 +3141,10 @@
}
mLayersWithBuffersRemoved.clear();
- for (const auto& layer: mLayersWithQueuedFrames) {
+ for (const auto& [layer, gameMode] : mLayersWithQueuedFrames) {
layer->onCompositionPresented(pacesetterDisplay.get(),
pacesetterGpuCompositionDoneFenceTime,
- pacesetterPresentFenceTime, compositorTiming);
+ pacesetterPresentFenceTime, compositorTiming, gameMode);
layer->releasePendingBuffer(presentTime.ns());
}
@@ -3239,28 +3205,20 @@
}
};
- if (mLayerLifecycleManagerEnabled) {
- mLayerSnapshotBuilder.forEachVisibleSnapshot(
- [&, compositionDisplay = compositionDisplay](
- std::unique_ptr<frontend::LayerSnapshot>&
- snapshot) FTL_FAKE_GUARD(kMainThreadContext) {
- auto it = mLegacyLayers.find(snapshot->sequence);
- LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
- "Couldnt find layer object for %s",
- snapshot->getDebugString().c_str());
- auto& legacyLayer = it->second;
- sp<LayerFE> layerFe =
- legacyLayer->getCompositionEngineLayerFE(snapshot->path);
+ mLayerSnapshotBuilder.forEachVisibleSnapshot(
+ [&, compositionDisplay = compositionDisplay](
+ std::unique_ptr<frontend::LayerSnapshot>& snapshot)
+ FTL_FAKE_GUARD(kMainThreadContext) {
+ auto it = mLegacyLayers.find(snapshot->sequence);
+ LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
+ "Couldnt find layer object for %s",
+ snapshot->getDebugString().c_str());
+ auto& legacyLayer = it->second;
+ sp<LayerFE> layerFe =
+ legacyLayer->getCompositionEngineLayerFE(snapshot->path);
- updateInfoFn(compositionDisplay, *snapshot, layerFe);
- });
- } else {
- mDrawingState.traverse([&, compositionDisplay = compositionDisplay](Layer* layer) {
- const auto layerFe = layer->getCompositionEngineLayerFE();
- const frontend::LayerSnapshot& snapshot = *layer->getLayerSnapshot();
- updateInfoFn(compositionDisplay, snapshot, layerFe);
- });
- }
+ updateInfoFn(compositionDisplay, *snapshot, layerFe);
+ });
listener->dispatchHdrLayerInfo(info);
}
}
@@ -3306,9 +3264,8 @@
if (!layer->hasTrustedPresentationListener()) {
return;
}
- const frontend::LayerSnapshot* snapshot = mLayerLifecycleManagerEnabled
- ? mLayerSnapshotBuilder.getSnapshot(layer->sequence)
- : layer->getLayerSnapshot();
+ const frontend::LayerSnapshot* snapshot =
+ mLayerSnapshotBuilder.getSnapshot(layer->sequence);
std::optional<const DisplayDevice*> displayOpt = std::nullopt;
if (snapshot) {
displayOpt = layerStackToDisplay.get(snapshot->outputFilter.layerStack);
@@ -3330,36 +3287,6 @@
logFrameStats(presentTime);
}
-FloatRect SurfaceFlinger::getMaxDisplayBounds() {
- const ui::Size maxSize = [this] {
- ftl::FakeGuard guard(mStateLock);
-
- // The LayerTraceGenerator tool runs without displays.
- if (mDisplays.empty()) return ui::Size{5000, 5000};
-
- return std::accumulate(mDisplays.begin(), mDisplays.end(), ui::kEmptySize,
- [](ui::Size size, const auto& pair) -> ui::Size {
- const auto& display = pair.second;
- return {std::max(size.getWidth(), display->getWidth()),
- std::max(size.getHeight(), display->getHeight())};
- });
- }();
-
- // Ignore display bounds for now since they will be computed later. Use a large Rect bound
- // to ensure it's bigger than an actual display will be.
- const float xMax = maxSize.getWidth() * 10.f;
- const float yMax = maxSize.getHeight() * 10.f;
-
- return {-xMax, -yMax, xMax, yMax};
-}
-
-void SurfaceFlinger::computeLayerBounds() {
- const FloatRect maxBounds = getMaxDisplayBounds();
- for (const auto& layer : mDrawingState.layersSortedByZ) {
- layer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
- }
-}
-
void SurfaceFlinger::commitTransactions() {
SFTRACE_CALL();
mDebugInTransaction = systemTime();
@@ -3373,28 +3300,6 @@
mDebugInTransaction = 0;
}
-void SurfaceFlinger::commitTransactionsLegacy() {
- SFTRACE_CALL();
-
- // Keep a copy of the drawing state (that is going to be overwritten
- // by commitTransactionsLocked) outside of mStateLock so that the side
- // effects of the State assignment don't happen with mStateLock held,
- // which can cause deadlocks.
- State drawingState(mDrawingState);
-
- Mutex::Autolock lock(mStateLock);
- mDebugInTransaction = systemTime();
-
- // Here we're guaranteed that some transaction flags are set
- // so we can call commitTransactionsLocked unconditionally.
- // We clear the flags with mStateLock held to guarantee that
- // mCurrentState won't change until the transaction is committed.
- mScheduler->modulateVsync({}, &VsyncModulator::onTransactionCommit);
- commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
-
- mDebugInTransaction = 0;
-}
-
std::pair<DisplayModes, DisplayModePtr> SurfaceFlinger::loadDisplayModes(
PhysicalDisplayId displayId) const {
std::vector<HWComposer::HWCDisplayMode> hwcModes;
@@ -3653,7 +3558,12 @@
state.physical = {.id = displayId,
.hwcDisplayId = hwcDisplayId,
.activeMode = std::move(activeMode)};
- state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
+ if (mIsHdcpViaNegVsync) {
+ state.isSecure = connectionType == ui::DisplayConnectionType::Internal;
+ } else {
+ // TODO(b/349703362): Remove this when HDCP aidl API becomes ready
+ state.isSecure = true; // All physical displays are currently considered secure.
+ }
state.isProtected = true;
state.displayName = std::move(info.name);
@@ -3762,7 +3672,7 @@
if (const auto& physical = state.physical) {
const auto& mode = *physical->activeMode;
mDisplayModeController.setActiveMode(physical->id, mode.getId(), mode.getVsyncRate(),
- mode.getVsyncRate());
+ mode.getPeakFps());
}
display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack));
@@ -4028,13 +3938,6 @@
// Commit display transactions.
const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
mFrontEndDisplayInfosChanged = displayTransactionNeeded;
- if (displayTransactionNeeded && !mLayerLifecycleManagerEnabled) {
- processDisplayChangesLocked();
- mFrontEndDisplayInfos.clear();
- for (const auto& [_, display] : mDisplays) {
- mFrontEndDisplayInfos.try_emplace(display->getLayerStack(), display->getFrontEndInfo());
- }
- }
mForceTransactionDisplayChange = displayTransactionNeeded;
if (mSomeChildrenChanged) {
@@ -4215,23 +4118,10 @@
outWindowInfos.reserve(sNumWindowInfos);
sNumWindowInfos = 0;
- if (mLayerLifecycleManagerEnabled) {
- mLayerSnapshotBuilder.forEachInputSnapshot(
- [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
- outWindowInfos.push_back(snapshot.inputInfo);
- });
- } else {
- mDrawingState.traverseInReverseZOrder([&](Layer* layer) FTL_FAKE_GUARD(kMainThreadContext) {
- if (!layer->needsInputInfo()) return;
- const auto opt =
- mFrontEndDisplayInfos.get(layer->getLayerStack())
- .transform([](const frontend::DisplayInfo& info) {
- return Layer::InputDisplayArgs{&info.transform, info.isSecure};
- });
-
- outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
- });
- }
+ mLayerSnapshotBuilder.forEachInputSnapshot(
+ [&outWindowInfos](const frontend::LayerSnapshot& snapshot) {
+ outWindowInfos.push_back(snapshot.inputInfo);
+ });
sNumWindowInfos = outWindowInfos.size();
@@ -4259,11 +4149,6 @@
getHwComposer().setVsyncEnabled(displayId, enable ? hal::Vsync::ENABLE : hal::Vsync::DISABLE);
}
-// This callback originates from Scheduler::applyPolicy, whose thread context may be the main thread
-// (via Scheduler::chooseRefreshRateForContent) or a OneShotTimer thread. The latter case imposes a
-// deadlock prevention rule: If the main thread is processing hotplug, then mStateLock is locked as
-// the main thread stops the OneShotTimer and joins with its thread. Hence, the OneShotTimer thread
-// must not lock mStateLock in this callback, which would deadlock with the join.
void SurfaceFlinger::requestDisplayModes(std::vector<display::DisplayModeRequest> modeRequests) {
if (mBootStage != BootStage::FINISHED) {
ALOGV("Currently in the boot stage, skipping display mode changes");
@@ -4272,14 +4157,21 @@
SFTRACE_CALL();
+ // If this is called from the main thread mStateLock must be locked before
+ // Currently the only way to call this function from the main thread is from
+ // Scheduler::chooseRefreshRateForContent
+
+ ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
+
for (auto& request : modeRequests) {
const auto& modePtr = request.mode.modePtr;
+
const auto displayId = modePtr->getPhysicalDisplayId();
+ const auto display = getDisplayDeviceLocked(displayId);
- const auto selectorPtr = mDisplayModeController.selectorPtrFor(displayId);
- if (!selectorPtr) continue;
+ if (!display) continue;
- if (selectorPtr->isModeAllowed(request.mode)) {
+ if (display->refreshRateSelector().isModeAllowed(request.mode)) {
setDesiredMode(std::move(request));
} else {
ALOGV("%s: Mode %d is disallowed for display %s", __func__,
@@ -4288,25 +4180,14 @@
}
}
-void SurfaceFlinger::triggerOnFrameRateOverridesChanged() {
- PhysicalDisplayId displayId = [&]() {
- ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId);
- return getDefaultDisplayDeviceLocked()->getPhysicalId();
- }();
-
- mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
-}
-
void SurfaceFlinger::notifyCpuLoadUp() {
mPowerAdvisor->notifyCpuLoadUp();
}
void SurfaceFlinger::onChoreographerAttached() {
SFTRACE_CALL();
- if (mLayerLifecycleManagerEnabled) {
- mUpdateAttachedChoreographer = true;
- scheduleCommit(FrameHint::kNone);
- }
+ mUpdateAttachedChoreographer = true;
+ scheduleCommit(FrameHint::kNone);
}
void SurfaceFlinger::onExpectedPresentTimePosted(TimePoint expectedPresentTime,
@@ -4610,97 +4491,6 @@
}
}
-bool SurfaceFlinger::latchBuffers() {
- SFTRACE_CALL();
-
- const nsecs_t latchTime = systemTime();
-
- bool visibleRegions = false;
- bool frameQueued = false;
- bool newDataLatched = false;
-
- // Store the set of layers that need updates. This set must not change as
- // buffers are being latched, as this could result in a deadlock.
- // Example: Two producers share the same command stream and:
- // 1.) Layer 0 is latched
- // 2.) Layer 0 gets a new frame
- // 2.) Layer 1 gets a new frame
- // 3.) Layer 1 is latched.
- // Display is now waiting on Layer 1's frame, which is behind layer 0's
- // second frame. But layer 0's second frame could be waiting on display.
- mDrawingState.traverse([&](Layer* layer) {
- if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange) {
- const uint32_t flags = layer->doTransaction(0);
- if (flags & Layer::eVisibleRegion) {
- mVisibleRegionsDirty = true;
- }
- }
-
- if (layer->hasReadyFrame() || layer->willReleaseBufferOnLatch()) {
- frameQueued = true;
- mLayersWithQueuedFrames.emplace(sp<Layer>::fromExisting(layer));
- } else {
- layer->useEmptyDamage();
- if (!layer->hasBuffer()) {
- // The last latch time is used to classify a missed frame as buffer stuffing
- // instead of a missed frame. This is used to identify scenarios where we
- // could not latch a buffer or apply a transaction due to backpressure.
- // We only update the latch time for buffer less layers here, the latch time
- // is updated for buffer layers when the buffer is latched.
- layer->updateLastLatchTime(latchTime);
- }
- }
- });
- mForceTransactionDisplayChange = false;
-
- // The client can continue submitting buffers for offscreen layers, but they will not
- // be shown on screen. Therefore, we need to latch and release buffers of offscreen
- // layers to ensure dequeueBuffer doesn't block indefinitely.
- for (Layer* offscreenLayer : mOffscreenLayers) {
- offscreenLayer->traverse(LayerVector::StateSet::Drawing,
- [&](Layer* l) { l->latchAndReleaseBuffer(); });
- }
-
- if (!mLayersWithQueuedFrames.empty()) {
- // mStateLock is needed for latchBuffer as LayerRejecter::reject()
- // writes to Layer current state. See also b/119481871
- Mutex::Autolock lock(mStateLock);
-
- for (const auto& layer : mLayersWithQueuedFrames) {
- if (layer->willReleaseBufferOnLatch()) {
- mLayersWithBuffersRemoved.emplace(layer);
- }
- if (layer->latchBuffer(visibleRegions, latchTime)) {
- mLayersPendingRefresh.push_back(layer);
- newDataLatched = true;
- }
- layer->useSurfaceDamage();
- }
- }
-
- mVisibleRegionsDirty |= visibleRegions;
-
- // If we will need to wake up at some time in the future to deal with a
- // queued frame that shouldn't be displayed during this vsync period, wake
- // up during the next vsync period to check again.
- if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) {
- scheduleCommit(FrameHint::kNone);
- }
-
- // enter boot animation on first buffer latch
- if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
- ALOGI("Enter boot animation");
- mBootStage = BootStage::BOOTANIMATION;
- }
-
- if (mLayerMirrorRoots.size() > 0) {
- mDrawingState.traverse([&](Layer* layer) { layer->updateCloneBufferInfo(); });
- }
-
- // Only continue with the refresh if there is actually new work to do
- return !mLayersWithQueuedFrames.empty() && newDataLatched;
-}
-
status_t SurfaceFlinger::addClientLayer(LayerCreationArgs& args, const sp<IBinder>& handle,
const sp<Layer>& layer, const wp<Layer>& parent,
uint32_t* outTransformHint) {
@@ -4850,101 +4640,6 @@
return TransactionReadiness::Ready;
}
-TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheckLegacy(
- const TransactionHandler::TransactionFlushState& flushState) {
- using TransactionReadiness = TransactionHandler::TransactionReadiness;
- auto ready = TransactionReadiness::Ready;
- flushState.transaction->traverseStatesWithBuffersWhileTrue([&](const ResolvedComposerState&
- resolvedState) -> bool {
- sp<Layer> layer = LayerHandle::getLayer(resolvedState.state.surface);
-
- const auto& transaction = *flushState.transaction;
- const auto& s = resolvedState.state;
- // check for barrier frames
- if (s.bufferData->hasBarrier) {
- // The current producerId is already a newer producer than the buffer that has a
- // barrier. This means the incoming buffer is older and we can release it here. We
- // don't wait on the barrier since we know that's stale information.
- if (layer->getDrawingState().barrierProducerId > s.bufferData->producerId) {
- layer->callReleaseBufferCallback(s.bufferData->releaseBufferListener,
- resolvedState.externalTexture->getBuffer(),
- s.bufferData->frameNumber,
- s.bufferData->acquireFence);
- // Delete the entire state at this point and not just release the buffer because
- // everything associated with the Layer in this Transaction is now out of date.
- SFTRACE_FORMAT("DeleteStaleBuffer %s barrierProducerId:%d > %d",
- layer->getDebugName(), layer->getDrawingState().barrierProducerId,
- s.bufferData->producerId);
- return TraverseBuffersReturnValues::DELETE_AND_CONTINUE_TRAVERSAL;
- }
-
- if (layer->getDrawingState().barrierFrameNumber < s.bufferData->barrierFrameNumber) {
- const bool willApplyBarrierFrame =
- flushState.bufferLayersReadyToPresent.contains(s.surface.get()) &&
- ((flushState.bufferLayersReadyToPresent.get(s.surface.get()) >=
- s.bufferData->barrierFrameNumber));
- if (!willApplyBarrierFrame) {
- SFTRACE_FORMAT("NotReadyBarrier %s barrierFrameNumber:%" PRId64 " > %" PRId64,
- layer->getDebugName(),
- layer->getDrawingState().barrierFrameNumber,
- s.bufferData->barrierFrameNumber);
- ready = TransactionReadiness::NotReadyBarrier;
- return TraverseBuffersReturnValues::STOP_TRAVERSAL;
- }
- }
- }
-
- // If backpressure is enabled and we already have a buffer to commit, keep
- // the transaction in the queue.
- const bool hasPendingBuffer =
- flushState.bufferLayersReadyToPresent.contains(s.surface.get());
- if (layer->backpressureEnabled() && hasPendingBuffer && transaction.isAutoTimestamp) {
- SFTRACE_FORMAT("hasPendingBuffer %s", layer->getDebugName());
- ready = TransactionReadiness::NotReady;
- return TraverseBuffersReturnValues::STOP_TRAVERSAL;
- }
-
- const bool acquireFenceAvailable = s.bufferData &&
- s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
- s.bufferData->acquireFence;
- const bool fenceSignaled = !acquireFenceAvailable ||
- s.bufferData->acquireFence->getStatus() != Fence::Status::Unsignaled;
- if (!fenceSignaled) {
- // check fence status
- const bool allowLatchUnsignaled = shouldLatchUnsignaled(s, transaction.states.size(),
- flushState.firstTransaction) &&
- layer->isSimpleBufferUpdate(s);
-
- if (allowLatchUnsignaled) {
- SFTRACE_FORMAT("fence unsignaled try allowLatchUnsignaled %s",
- layer->getDebugName());
- ready = TransactionReadiness::NotReadyUnsignaled;
- } else {
- ready = TransactionReadiness::NotReady;
- auto& listener = s.bufferData->releaseBufferListener;
- if (listener &&
- (flushState.queueProcessTime - transaction.postTime) >
- std::chrono::nanoseconds(4s).count()) {
- // Used to add a stalled transaction which uses an internal lock.
- ftl::FakeGuard guard(kMainThreadContext);
- mTransactionHandler
- .onTransactionQueueStalled(transaction.id,
- {.pid = layer->getOwnerPid(),
- .layerId = static_cast<uint32_t>(
- layer->getSequence()),
- .layerName = layer->getDebugName(),
- .bufferId = s.bufferData->getId(),
- .frameNumber = s.bufferData->frameNumber});
- }
- SFTRACE_FORMAT("fence unsignaled %s", layer->getDebugName());
- return TraverseBuffersReturnValues::STOP_TRAVERSAL;
- }
- }
- return TraverseBuffersReturnValues::CONTINUE_TRAVERSAL;
- });
- return ready;
-}
-
TransactionHandler::TransactionReadiness SurfaceFlinger::transactionReadyBufferCheck(
const TransactionHandler::TransactionFlushState& flushState) {
using TransactionReadiness = TransactionHandler::TransactionReadiness;
@@ -5056,15 +4751,8 @@
void SurfaceFlinger::addTransactionReadyFilters() {
mTransactionHandler.addTransactionReadyFilter(
std::bind(&SurfaceFlinger::transactionReadyTimelineCheck, this, std::placeholders::_1));
- if (mLayerLifecycleManagerEnabled) {
- mTransactionHandler.addTransactionReadyFilter(
- std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this,
- std::placeholders::_1));
- } else {
- mTransactionHandler.addTransactionReadyFilter(
- std::bind(&SurfaceFlinger::transactionReadyBufferCheckLegacy, this,
- std::placeholders::_1));
- }
+ mTransactionHandler.addTransactionReadyFilter(
+ std::bind(&SurfaceFlinger::transactionReadyBufferCheck, this, std::placeholders::_1));
}
// For tests only
@@ -5296,11 +4984,6 @@
const std::vector<ListenerCallbacks>& listenerCallbacks,
int originPid, int originUid, uint64_t transactionId) {
uint32_t transactionFlags = 0;
- if (!mLayerLifecycleManagerEnabled) {
- for (DisplayState& display : displays) {
- transactionFlags |= setDisplayStateLocked(display);
- }
- }
// start and end registration for listeners w/ no surface so they can get their callback. Note
// that listeners with SurfaceControls will start registration during setClientStateLocked
@@ -5308,27 +4991,11 @@
for (const auto& listener : listenerCallbacks) {
mTransactionCallbackInvoker.addEmptyTransaction(listener);
}
- nsecs_t now = systemTime();
uint32_t clientStateFlags = 0;
for (auto& resolvedState : states) {
clientStateFlags |=
updateLayerCallbacksAndStats(frameTimelineInfo, resolvedState, desiredPresentTime,
isAutoTimestamp, postTime, transactionId);
- if (!mLayerLifecycleManagerEnabled) {
- if ((flags & eAnimation) && resolvedState.state.surface) {
- if (const auto layer = LayerHandle::getLayer(resolvedState.state.surface)) {
- const auto layerProps = scheduler::LayerProps{
- .visible = layer->isVisible(),
- .bounds = layer->getBounds(),
- .transform = layer->getTransform(),
- .setFrameRateVote = layer->getFrameRateForLayerTree(),
- .frameRateSelectionPriority = layer->getFrameRateSelectionPriority(),
- .isFrontBuffered = layer->isFrontBuffered(),
- };
- layer->recordLayerHistoryAnimationTx(layerProps, now);
- }
- }
- }
}
transactionFlags |= clientStateFlags;
@@ -5463,364 +5130,6 @@
return true;
}
-uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,
- ResolvedComposerState& composerState,
- int64_t desiredPresentTime, bool isAutoTimestamp,
- int64_t postTime, uint64_t transactionId) {
- layer_state_t& s = composerState.state;
-
- std::vector<ListenerCallbacks> filteredListeners;
- for (auto& listener : s.listeners) {
- // Starts a registration but separates the callback ids according to callback type. This
- // allows the callback invoker to send on latch callbacks earlier.
- // note that startRegistration will not re-register if the listener has
- // already be registered for a prior surface control
-
- ListenerCallbacks onCommitCallbacks = listener.filter(CallbackId::Type::ON_COMMIT);
- if (!onCommitCallbacks.callbackIds.empty()) {
- filteredListeners.push_back(onCommitCallbacks);
- }
-
- ListenerCallbacks onCompleteCallbacks = listener.filter(CallbackId::Type::ON_COMPLETE);
- if (!onCompleteCallbacks.callbackIds.empty()) {
- filteredListeners.push_back(onCompleteCallbacks);
- }
- }
-
- const uint64_t what = s.what;
- uint32_t flags = 0;
- sp<Layer> layer = nullptr;
- if (s.surface) {
- layer = LayerHandle::getLayer(s.surface);
- } else {
- // The client may provide us a null handle. Treat it as if the layer was removed.
- ALOGW("Attempt to set client state with a null layer handle");
- }
- if (layer == nullptr) {
- for (auto& [listener, callbackIds] : s.listeners) {
- mTransactionCallbackInvoker.addCallbackHandle(
- sp<CallbackHandle>::make(listener, callbackIds, s.surface));
- }
- return 0;
- }
- MUTEX_ALIAS(mStateLock, layer->mFlinger->mStateLock);
-
- ui::LayerStack oldLayerStack = layer->getLayerStack(LayerVector::StateSet::Current);
-
- // Only set by BLAST adapter layers
- if (what & layer_state_t::eProducerDisconnect) {
- layer->onDisconnect();
- }
-
- if (what & layer_state_t::ePositionChanged) {
- if (layer->setPosition(s.x, s.y)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eLayerChanged) {
- // NOTE: index needs to be calculated before we update the state
- const auto& p = layer->getParent();
- if (p == nullptr) {
- ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
- if (layer->setLayer(s.z) && idx >= 0) {
- mCurrentState.layersSortedByZ.removeAt(idx);
- mCurrentState.layersSortedByZ.add(layer);
- // we need traversal (state changed)
- // AND transaction (list changed)
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- } else {
- if (p->setChildLayer(layer, s.z)) {
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- }
- }
- if (what & layer_state_t::eRelativeLayerChanged) {
- // NOTE: index needs to be calculated before we update the state
- const auto& p = layer->getParent();
- const auto& relativeHandle = s.relativeLayerSurfaceControl ?
- s.relativeLayerSurfaceControl->getHandle() : nullptr;
- if (p == nullptr) {
- ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
- if (layer->setRelativeLayer(relativeHandle, s.z) &&
- idx >= 0) {
- mCurrentState.layersSortedByZ.removeAt(idx);
- mCurrentState.layersSortedByZ.add(layer);
- // we need traversal (state changed)
- // AND transaction (list changed)
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- } else {
- if (p->setChildRelativeLayer(layer, relativeHandle, s.z)) {
- flags |= eTransactionNeeded|eTraversalNeeded;
- }
- }
- }
- if (what & layer_state_t::eAlphaChanged) {
- if (layer->setAlpha(s.color.a)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eColorChanged) {
- if (layer->setColor(s.color.rgb)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eColorTransformChanged) {
- if (layer->setColorTransform(s.colorTransform)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eBackgroundColorChanged) {
- if (layer->setBackgroundColor(s.bgColor.rgb, s.bgColor.a, s.bgColorDataspace)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eMatrixChanged) {
- if (layer->setMatrix(s.matrix)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eTransparentRegionChanged) {
- if (layer->setTransparentRegionHint(s.transparentRegion))
- flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eFlagsChanged) {
- if (layer->setFlags(s.flags, s.mask)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eCornerRadiusChanged) {
- if (layer->setCornerRadius(s.cornerRadius))
- flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eBackgroundBlurRadiusChanged && mSupportsBlur) {
- if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eBlurRegionsChanged) {
- if (layer->setBlurRegions(s.blurRegions)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eLayerStackChanged) {
- ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
- // We only allow setting layer stacks for top level layers,
- // everything else inherits layer stack from its parent.
- if (layer->hasParent()) {
- ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
- layer->getDebugName());
- } else if (idx < 0) {
- ALOGE("Attempt to set layer stack on layer without parent (%s) that "
- "that also does not appear in the top level layer list. Something"
- " has gone wrong.",
- layer->getDebugName());
- } else if (layer->setLayerStack(s.layerStack)) {
- mCurrentState.layersSortedByZ.removeAt(idx);
- mCurrentState.layersSortedByZ.add(layer);
- // we need traversal (state changed)
- // AND transaction (list changed)
- flags |= eTransactionNeeded | eTraversalNeeded | eTransformHintUpdateNeeded;
- }
- }
- if (what & layer_state_t::eBufferTransformChanged) {
- if (layer->setTransform(s.bufferTransform)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eTransformToDisplayInverseChanged) {
- if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse))
- flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eCropChanged) {
- if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eDataspaceChanged) {
- if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eSurfaceDamageRegionChanged) {
- if (layer->setSurfaceDamageRegion(s.surfaceDamageRegion)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eApiChanged) {
- if (layer->setApi(s.api)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eSidebandStreamChanged) {
- if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime))
- flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eInputInfoChanged) {
- layer->setInputInfo(*s.windowInfoHandle->getInfo());
- flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eMetadataChanged) {
- if (const int32_t gameMode = s.metadata.getInt32(gui::METADATA_GAME_MODE, -1);
- gameMode != -1) {
- // The transaction will be received on the Task layer and needs to be applied to all
- // child layers. Child layers that are added at a later point will obtain the game mode
- // info through addChild().
- layer->setGameModeForTree(static_cast<GameMode>(gameMode));
- }
-
- if (layer->setMetadata(s.metadata)) {
- flags |= eTraversalNeeded;
- mLayerMetadataSnapshotNeeded = true;
- }
- }
- if (what & layer_state_t::eColorSpaceAgnosticChanged) {
- if (layer->setColorSpaceAgnostic(s.colorSpaceAgnostic)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eShadowRadiusChanged) {
- if (layer->setShadowRadius(s.shadowRadius)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eDefaultFrameRateCompatibilityChanged) {
- const auto compatibility =
- Layer::FrameRate::convertCompatibility(s.defaultFrameRateCompatibility);
-
- if (layer->setDefaultFrameRateCompatibility(compatibility)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eFrameRateSelectionPriority) {
- if (layer->setFrameRateSelectionPriority(s.frameRateSelectionPriority)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eFrameRateChanged) {
- const auto compatibility =
- Layer::FrameRate::convertCompatibility(s.frameRateCompatibility);
- const auto strategy =
- Layer::FrameRate::convertChangeFrameRateStrategy(s.changeFrameRateStrategy);
-
- if (layer->setFrameRate(Layer::FrameRate::FrameRateVote(Fps::fromValue(s.frameRate),
- compatibility, strategy))) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eFrameRateCategoryChanged) {
- const FrameRateCategory category = Layer::FrameRate::convertCategory(s.frameRateCategory);
- if (layer->setFrameRateCategory(category, s.frameRateCategorySmoothSwitchOnly)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eFrameRateSelectionStrategyChanged) {
- const scheduler::LayerInfo::FrameRateSelectionStrategy strategy =
- scheduler::LayerInfo::convertFrameRateSelectionStrategy(
- s.frameRateSelectionStrategy);
- if (layer->setFrameRateSelectionStrategy(strategy)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eFixedTransformHintChanged) {
- if (layer->setFixedTransformHint(s.fixedTransformHint)) {
- flags |= eTraversalNeeded | eTransformHintUpdateNeeded;
- }
- }
- if (what & layer_state_t::eAutoRefreshChanged) {
- layer->setAutoRefresh(s.autoRefresh);
- }
- if (what & layer_state_t::eDimmingEnabledChanged) {
- if (layer->setDimmingEnabled(s.dimmingEnabled)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eExtendedRangeBrightnessChanged) {
- if (layer->setExtendedRangeBrightness(s.currentHdrSdrRatio, s.desiredHdrSdrRatio)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eDesiredHdrHeadroomChanged) {
- if (layer->setDesiredHdrHeadroom(s.desiredHdrSdrRatio)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eCachingHintChanged) {
- if (layer->setCachingHint(s.cachingHint)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eHdrMetadataChanged) {
- if (layer->setHdrMetadata(s.hdrMetadata)) flags |= eTraversalNeeded;
- }
- if (what & layer_state_t::eTrustedOverlayChanged) {
- if (layer->setTrustedOverlay(s.trustedOverlay == gui::TrustedOverlay::ENABLED)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eStretchChanged) {
- if (layer->setStretchEffect(s.stretchEffect)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eBufferCropChanged) {
- if (layer->setBufferCrop(s.bufferCrop)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eDestinationFrameChanged) {
- if (layer->setDestinationFrame(s.destinationFrame)) {
- flags |= eTraversalNeeded;
- }
- }
- if (what & layer_state_t::eDropInputModeChanged) {
- if (layer->setDropInputMode(s.dropInputMode)) {
- flags |= eTraversalNeeded;
- mUpdateInputInfo = true;
- }
- }
- // This has to happen after we reparent children because when we reparent to null we remove
- // child layers from current state and remove its relative z. If the children are reparented in
- // the same transaction, then we have to make sure we reparent the children first so we do not
- // lose its relative z order.
- if (what & layer_state_t::eReparent) {
- bool hadParent = layer->hasParent();
- auto parentHandle = (s.parentSurfaceControlForChild)
- ? s.parentSurfaceControlForChild->getHandle()
- : nullptr;
- if (layer->reparent(parentHandle)) {
- if (!hadParent) {
- layer->setIsAtRoot(false);
- mCurrentState.layersSortedByZ.remove(layer);
- }
- flags |= eTransactionNeeded | eTraversalNeeded;
- }
- }
- std::vector<sp<CallbackHandle>> callbackHandles;
- if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!filteredListeners.empty())) {
- for (auto& [listener, callbackIds] : filteredListeners) {
- callbackHandles.emplace_back(
- sp<CallbackHandle>::make(listener, callbackIds, s.surface));
- }
- }
-
- if (what & layer_state_t::eBufferChanged) {
- if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
- desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) {
- flags |= eTraversalNeeded;
- }
- } else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
- layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
- }
-
- if ((what & layer_state_t::eBufferChanged) == 0) {
- layer->setDesiredPresentTime(desiredPresentTime, isAutoTimestamp);
- }
-
- if (what & layer_state_t::eTrustedPresentationInfoChanged) {
- if (layer->setTrustedPresentationInfo(s.trustedPresentationThresholds,
- s.trustedPresentationListener)) {
- flags |= eTraversalNeeded;
- }
- }
-
- if (what & layer_state_t::eFlushJankData) {
- // Do nothing. Processing the transaction completed listeners currently cause the flush.
- }
-
- if (layer->setTransactionCompletedListeners(callbackHandles,
- layer->willPresentCurrentTransaction() ||
- layer->willReleaseBufferOnLatch())) {
- flags |= eTraversalNeeded;
- }
-
- // Do not put anything that updates layer state or modifies flags after
- // setTransactionCompletedListener
-
- // if the layer has been parented on to a new display, update its transform hint.
- if (((flags & eTransformHintUpdateNeeded) == 0) &&
- oldLayerStack != layer->getLayerStack(LayerVector::StateSet::Current)) {
- flags |= eTransformHintUpdateNeeded;
- }
-
- return flags;
-}
-
uint32_t SurfaceFlinger::updateLayerCallbacksAndStats(const FrameTimelineInfo& frameTimelineInfo,
ResolvedComposerState& composerState,
int64_t desiredPresentTime,
@@ -5873,6 +5182,17 @@
sp<CallbackHandle>::make(listener, callbackIds, s.surface));
}
}
+
+ frontend::LayerSnapshot* snapshot = nullptr;
+ gui::GameMode gameMode = gui::GameMode::Unsupported;
+ if (what & (layer_state_t::eSidebandStreamChanged | layer_state_t::eBufferChanged) ||
+ frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
+ snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
+ if (snapshot) {
+ gameMode = snapshot->gameMode;
+ }
+ }
+
// TODO(b/238781169) remove after screenshot refactor, currently screenshots
// requires to read drawing state from binder thread. So we need to fix that
// before removing this.
@@ -5887,7 +5207,7 @@
if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eSidebandStreamChanged) {
- if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime))
+ if (layer->setSidebandStream(s.sidebandStream, frameTimelineInfo, postTime, gameMode))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eDataspaceChanged) {
@@ -5905,18 +5225,17 @@
}
if (what & layer_state_t::eBufferChanged) {
std::optional<ui::Transform::RotationFlags> transformHint = std::nullopt;
- frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(layer->sequence);
if (snapshot) {
transformHint = snapshot->transformHint;
}
layer->setTransformHint(transformHint);
if (layer->setBuffer(composerState.externalTexture, *s.bufferData, postTime,
- desiredPresentTime, isAutoTimestamp, frameTimelineInfo)) {
+ desiredPresentTime, isAutoTimestamp, frameTimelineInfo, gameMode)) {
flags |= eTraversalNeeded;
}
- mLayersWithQueuedFrames.emplace(layer);
+ mLayersWithQueuedFrames.emplace(layer, gameMode);
} else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
- layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime, gameMode);
}
if ((what & layer_state_t::eBufferChanged) == 0) {
@@ -6640,53 +5959,35 @@
}
void SurfaceFlinger::dumpVisibleFrontEnd(std::string& result) {
- if (!mLayerLifecycleManagerEnabled) {
- StringAppendF(&result, "Composition layers\n");
- mDrawingState.traverseInZOrder([&](Layer* layer) {
- auto* compositionState = layer->getCompositionState();
- if (!compositionState || !compositionState->isVisible) return;
- android::base::StringAppendF(&result, "* Layer %p (%s)\n", layer,
- layer->getDebugName() ? layer->getDebugName()
- : "<unknown>");
- compositionState->dump(result);
- });
-
- StringAppendF(&result, "Offscreen Layers\n");
- for (Layer* offscreenLayer : mOffscreenLayers) {
- offscreenLayer->traverse(LayerVector::StateSet::Drawing,
- [&](Layer* layer) { layer->dumpOffscreenDebugInfo(result); });
- }
- } else {
- std::ostringstream out;
- out << "\nComposition list\n";
- ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
- mLayerSnapshotBuilder.forEachVisibleSnapshot(
- [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
- if (snapshot->hasSomethingToDraw()) {
- if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
- lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
- out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
- }
- out << " " << *snapshot << "\n";
+ std::ostringstream out;
+ out << "\nComposition list\n";
+ ui::LayerStack lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
+ mLayerSnapshotBuilder.forEachVisibleSnapshot(
+ [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) {
+ if (snapshot->hasSomethingToDraw()) {
+ if (lastPrintedLayerStackHeader != snapshot->outputFilter.layerStack) {
+ lastPrintedLayerStackHeader = snapshot->outputFilter.layerStack;
+ out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
}
- });
+ out << " " << *snapshot << "\n";
+ }
+ });
- out << "\nInput list\n";
- lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
- mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
- if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
- lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
- out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
- }
- out << " " << snapshot << "\n";
- });
+ out << "\nInput list\n";
+ lastPrintedLayerStackHeader = ui::INVALID_LAYER_STACK;
+ mLayerSnapshotBuilder.forEachInputSnapshot([&](const frontend::LayerSnapshot& snapshot) {
+ if (lastPrintedLayerStackHeader != snapshot.outputFilter.layerStack) {
+ lastPrintedLayerStackHeader = snapshot.outputFilter.layerStack;
+ out << "LayerStack=" << lastPrintedLayerStackHeader.id << "\n";
+ }
+ out << " " << snapshot << "\n";
+ });
- out << "\nLayer Hierarchy\n"
- << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
- << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
- result = out.str();
- dumpHwcLayersMinidump(result);
- }
+ out << "\nLayer Hierarchy\n"
+ << mLayerHierarchyBuilder.getHierarchy() << "\nOffscreen Hierarchy\n"
+ << mLayerHierarchyBuilder.getOffscreenHierarchy() << "\n\n";
+ result = out.str();
+ dumpHwcLayersMinidump(result);
}
perfetto::protos::LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
@@ -6747,14 +6048,24 @@
rootProto->set_name("Offscreen Root");
rootProto->set_parent(-1);
- for (Layer* offscreenLayer : mOffscreenLayers) {
- // Add layer as child of the fake root
- rootProto->add_children(offscreenLayer->sequence);
+ perfetto::protos::LayersProto offscreenLayers =
+ LayerProtoFromSnapshotGenerator(mLayerSnapshotBuilder, mFrontEndDisplayInfos,
+ mLegacyLayers, traceFlags)
+ .generate(mLayerHierarchyBuilder.getOffscreenHierarchy());
- // Add layer
- auto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);
- layerProto->set_parent(offscreenRootLayerId);
+ for (int i = 0; i < offscreenLayers.layers_size(); i++) {
+ perfetto::protos::LayerProto* layerProto = offscreenLayers.mutable_layers()->Mutable(i);
+ if (layerProto->parent() == -1) {
+ layerProto->set_parent(offscreenRootLayerId);
+ // Add layer as child of the fake root
+ rootProto->add_children(layerProto->id());
+ }
}
+
+ layersProto.mutable_layers()->Reserve(layersProto.layers_size() +
+ offscreenLayers.layers_size());
+ std::copy(offscreenLayers.layers().begin(), offscreenLayers.layers().end(),
+ RepeatedFieldBackInserter(layersProto.mutable_layers()));
}
perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
@@ -6779,28 +6090,8 @@
result.append(future.get());
}
-void SurfaceFlinger::dumpHwcLayersMinidumpLockedLegacy(std::string& result) const {
- for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
- const auto displayId = HalDisplayId::tryCast(display->getId());
- if (!displayId) {
- continue;
- }
-
- StringAppendF(&result, "Display %s (%s) HWC layers:\n", to_string(*displayId).c_str(),
- displayId == mActiveDisplayId ? "active" : "inactive");
- Layer::miniDumpHeader(result);
-
- const DisplayDevice& ref = *display;
- mDrawingState.traverseInZOrder([&](Layer* layer) { layer->miniDumpLegacy(result, ref); });
- result.append("\n");
- }
-}
-
void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
- if (!mLayerLifecycleManagerEnabled) {
- return dumpHwcLayersMinidumpLockedLegacy(result);
- }
- for (const auto& [token, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
+ for (const auto& [token, display] : mDisplays) {
const auto displayId = HalDisplayId::tryCast(display->getId());
if (!displayId) {
continue;
@@ -6879,8 +6170,7 @@
* Dump the visible layer list
*/
colorizer.bold(result);
- StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n",
- mLayerLifecycleManagerEnabled ? "true" : "false");
+ StringAppendF(&result, "SurfaceFlinger New Frontend Enabled:%s\n", "true");
StringAppendF(&result, "Active Layers - layers with client handles (count = %zu)\n",
mNumLayers.load());
colorizer.reset(result);
@@ -7472,15 +6762,9 @@
return NO_ERROR;
}
case 1039: {
- PhysicalDisplayId displayId = [&]() {
- Mutex::Autolock lock(mStateLock);
- return getDefaultDisplayDeviceLocked()->getPhysicalId();
- }();
-
- auto inUid = static_cast<uid_t>(data.readInt32());
+ const auto uid = static_cast<uid_t>(data.readInt32());
const auto refreshRate = data.readFloat();
- mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{inUid, refreshRate});
- mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
+ mScheduler->setPreferredRefreshRateForUid(FrameRateOverride{uid, refreshRate});
return NO_ERROR;
}
// Toggle caching feature
@@ -7691,6 +6975,22 @@
}));
}
+void SurfaceFlinger::vrrDisplayIdle(bool idle) {
+ // Update the overlay on the main thread to avoid race conditions with
+ // RefreshRateSelector::getActiveMode
+ static_cast<void>(mScheduler->schedule([=, this] {
+ const auto display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked());
+ if (!display) {
+ ALOGW("%s: default display is null", __func__);
+ return;
+ }
+ if (!display->isRefreshRateOverlayEnabled()) return;
+
+ display->onVrrIdle(idle);
+ mScheduler->scheduleFrame();
+ }));
+}
+
std::pair<std::optional<KernelIdleTimerController>, std::chrono::milliseconds>
SurfaceFlinger::getKernelIdleTimerProperties(PhysicalDisplayId displayId) {
const bool isKernelIdleTimerHwcSupported = getHwComposer().getComposer()->isSupported(
@@ -8588,12 +7888,8 @@
}
void SurfaceFlinger::traverseLegacyLayers(const LayerVector::Visitor& visitor) const {
- if (mLayerLifecycleManagerEnabled) {
- for (auto& layer : mLegacyLayers) {
- visitor(layer.second.get());
- }
- } else {
- mDrawingState.traverse(visitor);
+ for (auto& layer : mLegacyLayers) {
+ visitor(layer.second.get());
}
}
@@ -8611,42 +7907,6 @@
layersSortedByZ.traverseInReverseZOrder(stateSet, visitor);
}
-void SurfaceFlinger::traverseLayersInLayerStack(ui::LayerStack layerStack, const int32_t uid,
- std::unordered_set<uint32_t> excludeLayerIds,
- const LayerVector::Visitor& visitor) {
- // We loop through the first level of layers without traversing,
- // as we need to determine which layers belong to the requested display.
- for (const auto& layer : mDrawingState.layersSortedByZ) {
- if (layer->getLayerStack() != layerStack) {
- continue;
- }
- // relative layers are traversed in Layer::traverseInZOrder
- layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
- if (layer->isInternalDisplayOverlay()) {
- return;
- }
- if (!layer->isVisible()) {
- return;
- }
- if (uid != CaptureArgs::UNSET_UID && layer->getOwnerUid() != uid) {
- return;
- }
-
- if (!excludeLayerIds.empty()) {
- auto p = sp<Layer>::fromExisting(layer);
- while (p != nullptr) {
- if (excludeLayerIds.count(p->sequence) != 0) {
- return;
- }
- p = p->getParent();
- }
- }
-
- visitor(layer);
- });
- }
-}
-
ftl::Optional<scheduler::FrameRateMode> SurfaceFlinger::getPreferredDisplayMode(
PhysicalDisplayId displayId, DisplayModeId defaultModeId) const {
if (const auto schedulerMode = mScheduler->getPreferredDisplayMode();
@@ -8727,10 +7987,7 @@
setDesiredMode({std::move(preferredMode), .emitEvent = true});
// Update the frameRateOverride list as the display render rate might have changed
- if (mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps)) {
- triggerOnFrameRateOverridesChanged();
- }
-
+ mScheduler->updateFrameRateOverrides(scheduler::GlobalSignals{}, preferredFps);
return NO_ERROR;
}
@@ -8890,13 +8147,7 @@
}
status_t SurfaceFlinger::setGameModeFrameRateOverride(uid_t uid, float frameRate) {
- PhysicalDisplayId displayId = [&]() {
- Mutex::Autolock lock(mStateLock);
- return getDefaultDisplayDeviceLocked()->getPhysicalId();
- }();
-
- mScheduler->setGameModeFrameRateForUid(FrameRateOverride{static_cast<uid_t>(uid), frameRate});
- mScheduler->onFrameRateOverridesChanged(scheduler::Cycle::Render, displayId);
+ mScheduler->setGameModeFrameRateForUid(FrameRateOverride{uid, frameRate});
return NO_ERROR;
}
@@ -9221,178 +8472,52 @@
return nullptr;
}
-bool SurfaceFlinger::commitMirrorDisplays(VsyncId vsyncId) {
- std::vector<MirrorDisplayState> mirrorDisplays;
- {
- std::scoped_lock<std::mutex> lock(mMirrorDisplayLock);
- mirrorDisplays = std::move(mMirrorDisplays);
- mMirrorDisplays.clear();
- if (mirrorDisplays.size() == 0) {
- return false;
- }
- }
-
- sp<IBinder> unused;
- for (const auto& mirrorDisplay : mirrorDisplays) {
- // Set mirror layer's default layer stack to -1 so it doesn't end up rendered on a display
- // accidentally.
- sp<Layer> rootMirrorLayer = LayerHandle::getLayer(mirrorDisplay.rootHandle);
- ssize_t idx = mCurrentState.layersSortedByZ.indexOf(rootMirrorLayer);
- bool ret = rootMirrorLayer->setLayerStack(ui::LayerStack::fromValue(-1));
- if (idx >= 0 && ret) {
- mCurrentState.layersSortedByZ.removeAt(idx);
- mCurrentState.layersSortedByZ.add(rootMirrorLayer);
- }
-
- for (const auto& layer : mDrawingState.layersSortedByZ) {
- if (layer->getLayerStack() != mirrorDisplay.layerStack ||
- layer->isInternalDisplayOverlay()) {
- continue;
- }
-
- LayerCreationArgs mirrorArgs(this, mirrorDisplay.client, "MirrorLayerParent",
- ISurfaceComposerClient::eNoColorFill,
- gui::LayerMetadata());
- sp<Layer> childMirror;
- {
- Mutex::Autolock lock(mStateLock);
- createEffectLayer(mirrorArgs, &unused, &childMirror);
- MUTEX_ALIAS(mStateLock, childMirror->mFlinger->mStateLock);
- childMirror->setClonedChild(layer->createClone());
- childMirror->reparent(mirrorDisplay.rootHandle);
- }
- // lock on mStateLock needs to be released before binder handle gets destroyed
- unused.clear();
- }
- }
- return true;
-}
-
-bool SurfaceFlinger::commitCreatedLayers(VsyncId vsyncId,
- std::vector<LayerCreatedState>& createdLayers) {
- if (createdLayers.size() == 0) {
- return false;
- }
-
- Mutex::Autolock _l(mStateLock);
- for (const auto& createdLayer : createdLayers) {
- handleLayerCreatedLocked(createdLayer, vsyncId);
- }
- mLayersAdded = true;
- return mLayersAdded;
-}
-
-void SurfaceFlinger::updateLayerMetadataSnapshot() {
- LayerMetadata parentMetadata;
- for (const auto& layer : mDrawingState.layersSortedByZ) {
- layer->updateMetadataSnapshot(parentMetadata);
- }
-
- std::unordered_set<Layer*> visited;
- mDrawingState.traverse([&visited](Layer* layer) {
- if (visited.find(layer) != visited.end()) {
- return;
- }
-
- // If the layer isRelativeOf, then either it's relative metadata will be set
- // recursively when updateRelativeMetadataSnapshot is called on its relative parent or
- // it's relative parent has been deleted. Clear the layer's relativeLayerMetadata to ensure
- // that layers with deleted relative parents don't hold stale relativeLayerMetadata.
- if (layer->getDrawingState().isRelativeOf) {
- layer->editLayerSnapshot()->relativeLayerMetadata = {};
- return;
- }
-
- layer->updateRelativeMetadataSnapshot({}, visited);
- });
-}
-
void SurfaceFlinger::moveSnapshotsFromCompositionArgs(
compositionengine::CompositionRefreshArgs& refreshArgs,
const std::vector<std::pair<Layer*, LayerFE*>>& layers) {
- if (mLayerLifecycleManagerEnabled) {
- std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
- mLayerSnapshotBuilder.getSnapshots();
- for (auto [_, layerFE] : layers) {
- auto i = layerFE->mSnapshot->globalZ;
- snapshots[i] = std::move(layerFE->mSnapshot);
- }
- }
- if (!mLayerLifecycleManagerEnabled) {
- for (auto [layer, layerFE] : layers) {
- layer->updateLayerSnapshot(std::move(layerFE->mSnapshot));
- }
+ std::vector<std::unique_ptr<frontend::LayerSnapshot>>& snapshots =
+ mLayerSnapshotBuilder.getSnapshots();
+ for (auto [_, layerFE] : layers) {
+ auto i = layerFE->mSnapshot->globalZ;
+ snapshots[i] = std::move(layerFE->mSnapshot);
}
}
std::vector<std::pair<Layer*, LayerFE*>> SurfaceFlinger::moveSnapshotsToCompositionArgs(
compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly) {
std::vector<std::pair<Layer*, LayerFE*>> layers;
- if (mLayerLifecycleManagerEnabled) {
- nsecs_t currentTime = systemTime();
- const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
- compositionengine::Feature::kSnapshotLayerMetadata);
- mLayerSnapshotBuilder.forEachSnapshot(
- [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
- kMainThreadContext) {
- if (cursorOnly &&
- snapshot->compositionType !=
- aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
- return;
- }
-
- if (!snapshot->hasSomethingToDraw()) {
- return;
- }
-
- auto it = mLegacyLayers.find(snapshot->sequence);
- LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
- "Couldnt find layer object for %s",
- snapshot->getDebugString().c_str());
- auto& legacyLayer = it->second;
- sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
- snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
- layerFE->mSnapshot = std::move(snapshot);
- refreshArgs.layers.push_back(layerFE);
- layers.emplace_back(legacyLayer.get(), layerFE.get());
- },
- [needsMetadata](const frontend::LayerSnapshot& snapshot) {
- return snapshot.isVisible ||
- (needsMetadata &&
- snapshot.changes.test(
- frontend::RequestedLayerState::Changes::Metadata));
- });
- }
- if (!mLayerLifecycleManagerEnabled) {
- auto moveSnapshots = [&layers, &refreshArgs, cursorOnly](Layer* layer) {
- if (const auto& layerFE = layer->getCompositionEngineLayerFE()) {
+ nsecs_t currentTime = systemTime();
+ const bool needsMetadata = mCompositionEngine->getFeatureFlags().test(
+ compositionengine::Feature::kSnapshotLayerMetadata);
+ mLayerSnapshotBuilder.forEachSnapshot(
+ [&](std::unique_ptr<frontend::LayerSnapshot>& snapshot) FTL_FAKE_GUARD(
+ kMainThreadContext) {
if (cursorOnly &&
- layer->getLayerSnapshot()->compositionType !=
- aidl::android::hardware::graphics::composer3::Composition::CURSOR)
+ snapshot->compositionType !=
+ aidl::android::hardware::graphics::composer3::Composition::CURSOR) {
return;
- layer->updateSnapshot(refreshArgs.updatingGeometryThisFrame);
- layerFE->mSnapshot = layer->stealLayerSnapshot();
+ }
+
+ if (!snapshot->hasSomethingToDraw()) {
+ return;
+ }
+
+ auto it = mLegacyLayers.find(snapshot->sequence);
+ LLOG_ALWAYS_FATAL_WITH_TRACE_IF(it == mLegacyLayers.end(),
+ "Couldnt find layer object for %s",
+ snapshot->getDebugString().c_str());
+ auto& legacyLayer = it->second;
+ sp<LayerFE> layerFE = legacyLayer->getCompositionEngineLayerFE(snapshot->path);
+ snapshot->fps = getLayerFramerate(currentTime, snapshot->sequence);
+ layerFE->mSnapshot = std::move(snapshot);
refreshArgs.layers.push_back(layerFE);
- layers.emplace_back(layer, layerFE.get());
- }
- };
-
- if (cursorOnly || !mVisibleRegionsDirty) {
- // for hot path avoid traversals by walking though the previous composition list
- for (sp<Layer> layer : mPreviouslyComposedLayers) {
- moveSnapshots(layer.get());
- }
- } else {
- mPreviouslyComposedLayers.clear();
- mDrawingState.traverseInZOrder(
- [&moveSnapshots](Layer* layer) { moveSnapshots(layer); });
- mPreviouslyComposedLayers.reserve(layers.size());
- for (auto [layer, _] : layers) {
- mPreviouslyComposedLayers.push_back(sp<Layer>::fromExisting(layer));
- }
- }
- }
-
+ layers.emplace_back(legacyLayer.get(), layerFE.get());
+ },
+ [needsMetadata](const frontend::LayerSnapshot& snapshot) {
+ return snapshot.isVisible ||
+ (needsMetadata &&
+ snapshot.changes.test(frontend::RequestedLayerState::Changes::Metadata));
+ });
return layers;
}
@@ -9519,33 +8644,6 @@
};
}
-frontend::Update SurfaceFlinger::flushLifecycleUpdates() {
- frontend::Update update;
- SFTRACE_NAME("TransactionHandler:flushTransactions");
- // Locking:
- // 1. to prevent onHandleDestroyed from being called while the state lock is held,
- // we must keep a copy of the transactions (specifically the composer
- // states) around outside the scope of the lock.
- // 2. Transactions and created layers do not share a lock. To prevent applying
- // transactions with layers still in the createdLayer queue, flush the transactions
- // before committing the created layers.
- mTransactionHandler.collectTransactions();
- update.transactions = mTransactionHandler.flushTransactions();
- {
- // TODO(b/238781169) lockless queue this and keep order.
- std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
- update.layerCreatedStates = std::move(mCreatedLayers);
- mCreatedLayers.clear();
- update.newLayers = std::move(mNewLayers);
- mNewLayers.clear();
- update.layerCreationArgs = std::move(mNewLayerArgs);
- mNewLayerArgs.clear();
- update.destroyedHandles = std::move(mDestroyedHandles);
- mDestroyedHandles.clear();
- }
- return update;
-}
-
void SurfaceFlinger::doActiveLayersTracingIfNeeded(bool isCompositionComputed,
bool visibleRegionDirty, TimePoint time,
VsyncId vsyncId) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 65bfce2..9b2dea2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -273,7 +273,7 @@
enum class FrameHint { kNone, kActive };
// Schedule commit of transactions on the main thread ahead of the next VSYNC.
- void scheduleCommit(FrameHint);
+ void scheduleCommit(FrameHint, Duration workDurationSlack = Duration::fromNs(0));
// As above, but also force composite regardless if transactions were committed.
void scheduleComposite(FrameHint);
// As above, but also force dirty geometry to repaint.
@@ -313,7 +313,6 @@
// Disables expensive rendering for all displays
// This is scheduled on the main thread
void disableExpensiveRendering();
- FloatRect getMaxDisplayBounds();
// If set, composition engine tries to predict the composition strategy provided by HWC
// based on the previous frame. If the strategy can be predicted, gpu composition will
@@ -698,12 +697,12 @@
void requestHardwareVsync(PhysicalDisplayId, bool) override;
void requestDisplayModes(std::vector<display::DisplayModeRequest>) override;
void kernelTimerChanged(bool expired) override;
- void triggerOnFrameRateOverridesChanged() override;
void onChoreographerAttached() override;
void onExpectedPresentTimePosted(TimePoint expectedPresentTime, ftl::NonNull<DisplayModePtr>,
Fps renderRate) override;
void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) override
REQUIRES(kMainThreadContext);
+ void vrrDisplayIdle(bool idle) override;
// ICEPowerCallback overrides:
void notifyCpuLoadUp() override;
@@ -733,14 +732,14 @@
// Show hdr sdr ratio overlay
bool mHdrSdrRatioOverlay = false;
- void setDesiredMode(display::DisplayModeRequest&&);
+ void setDesiredMode(display::DisplayModeRequest&&) REQUIRES(mStateLock);
status_t setActiveModeFromBackdoor(const sp<display::DisplayToken>&, DisplayModeId, Fps minFps,
Fps maxFps);
- void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) EXCLUDES(mStateLock);
+ void initiateDisplayModeChanges() REQUIRES(kMainThreadContext) REQUIRES(mStateLock);
void finalizeDisplayModeChange(PhysicalDisplayId) REQUIRES(kMainThreadContext)
- EXCLUDES(mStateLock);
+ REQUIRES(mStateLock);
void dropModeRequest(PhysicalDisplayId) REQUIRES(kMainThreadContext);
void applyActiveMode(PhysicalDisplayId) REQUIRES(kMainThreadContext);
@@ -763,17 +762,11 @@
const scheduler::RefreshRateSelector&)
REQUIRES(mStateLock, kMainThreadContext);
- void commitTransactionsLegacy() EXCLUDES(mStateLock) REQUIRES(kMainThreadContext);
void commitTransactions() REQUIRES(kMainThreadContext, mStateLock);
void commitTransactionsLocked(uint32_t transactionFlags)
REQUIRES(mStateLock, kMainThreadContext);
void doCommitTransactions() REQUIRES(mStateLock);
- // Returns whether a new buffer has been latched.
- bool latchBuffers();
-
- void updateLayerGeometry();
- void updateLayerMetadataSnapshot();
std::vector<std::pair<Layer*, LayerFE*>> moveSnapshotsToCompositionArgs(
compositionengine::CompositionRefreshArgs& refreshArgs, bool cursorOnly)
REQUIRES(kMainThreadContext);
@@ -781,13 +774,9 @@
const std::vector<std::pair<Layer*, LayerFE*>>& layers)
REQUIRES(kMainThreadContext);
// Return true if we must composite this frame
- bool updateLayerSnapshotsLegacy(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed,
- bool& out) REQUIRES(kMainThreadContext);
- // Return true if we must composite this frame
bool updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs, bool transactionsFlushed,
bool& out) REQUIRES(kMainThreadContext);
void updateLayerHistory(nsecs_t now) REQUIRES(kMainThreadContext);
- frontend::Update flushLifecycleUpdates() REQUIRES(kMainThreadContext);
void updateInputFlinger(VsyncId vsyncId, TimePoint frameTime) REQUIRES(kMainThreadContext);
void persistDisplayBrightness(bool needsComposite) REQUIRES(kMainThreadContext);
@@ -826,16 +815,10 @@
TransactionHandler::TransactionReadiness transactionReadyTimelineCheck(
const TransactionHandler::TransactionFlushState& flushState)
REQUIRES(kMainThreadContext);
- TransactionHandler::TransactionReadiness transactionReadyBufferCheckLegacy(
- const TransactionHandler::TransactionFlushState& flushState)
- REQUIRES(kMainThreadContext);
TransactionHandler::TransactionReadiness transactionReadyBufferCheck(
const TransactionHandler::TransactionFlushState& flushState)
REQUIRES(kMainThreadContext);
- uint32_t setClientStateLocked(const FrameTimelineInfo&, ResolvedComposerState&,
- int64_t desiredPresentTime, bool isAutoTimestamp,
- int64_t postTime, uint64_t transactionId) REQUIRES(mStateLock);
uint32_t updateLayerCallbacksAndStats(const FrameTimelineInfo&, ResolvedComposerState&,
int64_t desiredPresentTime, bool isAutoTimestamp,
int64_t postTime, uint64_t transactionId)
@@ -885,9 +868,6 @@
const sp<Layer>& layer, const wp<Layer>& parentLayer,
uint32_t* outTransformHint);
- // Traverse through all the layers and compute and cache its bounds.
- void computeLayerBounds();
-
// Creates a promise for a future release fence for a layer. This allows for
// the layer to keep track of when its buffer can be released.
void attachReleaseFenceFutureToLayer(Layer* layer, LayerFE* layerFE, ui::LayerStack layerStack);
@@ -934,12 +914,6 @@
std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
std::vector<sp<LayerFE>>& layerFEs);
- // If the uid provided is not UNSET_UID, the traverse will skip any layers that don't have a
- // matching ownerUid
- void traverseLayersInLayerStack(ui::LayerStack, const int32_t uid,
- std::unordered_set<uint32_t> excludeLayerIds,
- const LayerVector::Visitor&);
-
void readPersistentProperties();
uint32_t getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;
@@ -988,18 +962,12 @@
return nullptr;
}
- // Returns the primary display or (for foldables) the active display, assuming that the inner
- // and outer displays have mutually exclusive power states.
+ // Returns the primary display or (for foldables) the active display.
sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const REQUIRES(mStateLock) {
return const_cast<SurfaceFlinger*>(this)->getDefaultDisplayDeviceLocked();
}
sp<DisplayDevice> getDefaultDisplayDeviceLocked() REQUIRES(mStateLock) {
- if (const auto display = getDisplayDeviceLocked(mActiveDisplayId)) {
- return display;
- }
- // The active display is outdated, so fall back to the primary display.
- mActiveDisplayId = getPrimaryDisplayIdLocked();
return getDisplayDeviceLocked(mActiveDisplayId);
}
@@ -1156,7 +1124,6 @@
void dumpAll(const DumpArgs& args, const std::string& compositionLayers,
std::string& result) const EXCLUDES(mStateLock);
void dumpHwcLayersMinidump(std::string& result) const REQUIRES(mStateLock, kMainThreadContext);
- void dumpHwcLayersMinidumpLockedLegacy(std::string& result) const REQUIRES(mStateLock);
void appendSfConfigString(std::string& result) const;
void listLayers(std::string& result) const REQUIRES(kMainThreadContext);
@@ -1183,7 +1150,8 @@
perfetto::protos::LayersProto dumpDrawingStateProto(uint32_t traceFlags) const
REQUIRES(kMainThreadContext);
void dumpOffscreenLayersProto(perfetto::protos::LayersProto& layersProto,
- uint32_t traceFlags = LayerTracing::TRACE_ALL) const;
+ uint32_t traceFlags = LayerTracing::TRACE_ALL) const
+ REQUIRES(kMainThreadContext);
google::protobuf::RepeatedPtrField<perfetto::protos::DisplayProto> dumpDisplayProto() const;
void doActiveLayersTracingIfNeeded(bool isCompositionComputed, bool visibleRegionDirty,
TimePoint, VsyncId) REQUIRES(kMainThreadContext);
@@ -1299,18 +1267,20 @@
bool mForceTransactionDisplayChange = false;
bool mUpdateAttachedChoreographer = false;
- // Set if LayerMetadata has changed since the last LayerMetadata snapshot.
- bool mLayerMetadataSnapshotNeeded = false;
+ struct LayerIntHash {
+ size_t operator()(const std::pair<sp<Layer>, gui::GameMode>& k) const {
+ return std::hash<Layer*>()(k.first.get()) ^
+ std::hash<int32_t>()(static_cast<int32_t>(k.second));
+ }
+ };
// TODO(b/238781169) validate these on composition
// Tracks layers that have pending frames which are candidates for being
// latched.
- std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithQueuedFrames;
+ std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames;
std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved;
std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames;
- // Tracks layers that need to update a display's dirty region.
- std::vector<sp<Layer>> mLayersPendingRefresh;
// Sorted list of layers that were composed during previous frame. This is used to
// avoid an expensive traversal of the layer hierarchy when there are no
// visible region changes. Because this is a list of strong pointers, this will
@@ -1338,7 +1308,7 @@
display::PhysicalDisplays mPhysicalDisplays GUARDED_BY(mStateLock);
- // The inner or outer display for foldables, assuming they have mutually exclusive power states.
+ // The inner or outer display for foldables, while unfolded or folded, respectively.
std::atomic<PhysicalDisplayId> mActiveDisplayId;
display::DisplayModeController mDisplayModeController;
@@ -1455,22 +1425,8 @@
// A temporay pool that store the created layers and will be added to current state in main
// thread.
std::vector<LayerCreatedState> mCreatedLayers GUARDED_BY(mCreatedLayersLock);
- bool commitCreatedLayers(VsyncId, std::vector<LayerCreatedState>& createdLayers);
void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock);
- mutable std::mutex mMirrorDisplayLock;
- struct MirrorDisplayState {
- MirrorDisplayState(ui::LayerStack layerStack, sp<IBinder>& rootHandle,
- const sp<Client>& client)
- : layerStack(layerStack), rootHandle(rootHandle), client(client) {}
-
- ui::LayerStack layerStack;
- sp<IBinder> rootHandle;
- const sp<Client> client;
- };
- std::vector<MirrorDisplayState> mMirrorDisplays GUARDED_BY(mMirrorDisplayLock);
- bool commitMirrorDisplays(VsyncId);
-
std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;
// Must only be accessed on the main thread.
@@ -1504,8 +1460,6 @@
}
bool mPowerHintSessionEnabled;
-
- bool mLayerLifecycleManagerEnabled = false;
// Whether a display should be turned on when initialized
bool mSkipPowerOnForQuiescent;
diff --git a/services/surfaceflinger/TimeStats/Android.bp b/services/surfaceflinger/TimeStats/Android.bp
index ea86911..a6a0152 100644
--- a/services/surfaceflinger/TimeStats/Android.bp
+++ b/services/surfaceflinger/TimeStats/Android.bp
@@ -20,6 +20,7 @@
"libtimestats_atoms_proto",
"libui",
"libutils",
+ "libtracing_perfetto",
],
static_libs: [
diff --git a/services/surfaceflinger/Tracing/tools/Android.bp b/services/surfaceflinger/Tracing/tools/Android.bp
index 8afca41..63c1b37 100644
--- a/services/surfaceflinger/Tracing/tools/Android.bp
+++ b/services/surfaceflinger/Tracing/tools/Android.bp
@@ -28,6 +28,7 @@
"libsurfaceflinger_mocks_defaults",
"librenderengine_deps",
"surfaceflinger_defaults",
+ "libsurfaceflinger_common_deps",
],
srcs: [
":libsurfaceflinger_sources",
diff --git a/services/surfaceflinger/Utils/RingBuffer.h b/services/surfaceflinger/Utils/RingBuffer.h
index 198e7b2..215472b 100644
--- a/services/surfaceflinger/Utils/RingBuffer.h
+++ b/services/surfaceflinger/Utils/RingBuffer.h
@@ -43,8 +43,10 @@
}
T& front() { return (*this)[0]; }
+ const T& front() const { return (*this)[0]; }
T& back() { return (*this)[size() - 1]; }
+ const T& back() const { return (*this)[size() - 1]; }
T& operator[](size_t index) {
return mBuffer[(static_cast<size_t>(mHead + 1) + index) % mCount];
diff --git a/services/surfaceflinger/common/Android.bp b/services/surfaceflinger/common/Android.bp
index bcf1886..f9c99bf 100644
--- a/services/surfaceflinger/common/Android.bp
+++ b/services/surfaceflinger/common/Android.bp
@@ -18,6 +18,7 @@
"libSurfaceFlingerProp",
"server_configurable_flags",
"libaconfig_storage_read_api_cc",
+ "libtracing_perfetto",
],
static_libs: [
"librenderengine_includes",
@@ -27,6 +28,7 @@
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
+ export_shared_lib_headers: ["libtracing_perfetto"],
}
cc_library_static {
@@ -60,6 +62,7 @@
shared_libs: [
"server_configurable_flags",
"libaconfig_storage_read_api_cc",
+ "libtracing_perfetto",
],
static_libs: [
"libsurfaceflinger_common",
@@ -75,6 +78,7 @@
shared_libs: [
"server_configurable_flags",
"libaconfig_storage_read_api_cc",
+ "libtracing_perfetto",
],
static_libs: [
"libsurfaceflinger_common_test",
diff --git a/services/surfaceflinger/common/include/common/trace.h b/services/surfaceflinger/common/include/common/trace.h
index 344359e..0d7ac9b 100644
--- a/services/surfaceflinger/common/include/common/trace.h
+++ b/services/surfaceflinger/common/include/common/trace.h
@@ -17,43 +17,57 @@
#pragma once
-#include <cutils/trace.h>
-#include <stdint.h>
-
#ifndef ATRACE_TAG
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#endif
-#define SFTRACE_ENABLED() ATRACE_ENABLED()
-#define SFTRACE_BEGIN(name) ATRACE_BEGIN(name)
-#define SFTRACE_END() ATRACE_END()
-#define SFTRACE_ASYNC_BEGIN(name, cookie) ATRACE_ASYNC_BEGIN(name, cookie)
-#define SFTRACE_ASYNC_END(name, cookie) ATRACE_ASYNC_END(name, cookie)
+#include <cutils/trace.h>
+#include <tracing_perfetto.h>
+
+// prevent using atrace directly, calls should go through tracing_perfetto lib
+#undef ATRACE_ENABLED
+#undef ATRACE_BEGIN
+#undef ATRACE_END
+#undef ATRACE_ASYNC_BEGIN
+#undef ATRACE_ASYNC_END
+#undef ATRACE_ASYNC_FOR_TRACK_BEGIN
+#undef ATRACE_ASYNC_FOR_TRACK_END
+#undef ATRACE_INSTANT
+#undef ATRACE_INSTANT_FOR_TRACK
+#undef ATRACE_INT
+#undef ATRACE_INT64
+#undef ATRACE_CALL
+#undef ATRACE_NAME
+#undef ATRACE_FORMAT
+#undef ATRACE_FORMAT_INSTANT
+
+#define SFTRACE_ENABLED() ::tracing_perfetto::isTagEnabled(ATRACE_TAG)
+#define SFTRACE_BEGIN(name) ::tracing_perfetto::traceBegin(ATRACE_TAG, name)
+#define SFTRACE_END() ::tracing_perfetto::traceEnd(ATRACE_TAG)
+#define SFTRACE_ASYNC_BEGIN(name, cookie) \
+ ::tracing_perfetto::traceAsyncBegin(ATRACE_TAG, name, cookie)
+#define SFTRACE_ASYNC_END(name, cookie) ::tracing_perfetto::traceAsyncEnd(ATRACE_TAG, name, cookie)
#define SFTRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie) \
- ATRACE_ASYNC_FOR_TRACK_BEGIN(track_name, name, cookie)
+ ::tracing_perfetto::traceAsyncBeginForTrack(ATRACE_TAG, track_name, name, cookie)
#define SFTRACE_ASYNC_FOR_TRACK_END(track_name, cookie) \
- ATRACE_ASYNC_FOR_TRACK_END(track_name, cookie)
-#define SFTRACE_INSTANT(name) ATRACE_INSTANT(name)
-#define SFTRACE_INSTANT_FOR_TRACK(trackName, name) ATRACE_INSTANT_FOR_TRACK(trackName, name)
-#define SFTRACE_INT(name, value) ATRACE_INT(name, value)
-#define SFTRACE_INT64(name, value) ATRACE_INT64(name, value)
+ ::tracing_perfetto::traceAsyncEndForTrack(ATRACE_TAG, track_name, cookie)
+#define SFTRACE_INSTANT(name) ::tracing_perfetto::traceInstant(ATRACE_TAG, name)
+#define SFTRACE_FORMAT_INSTANT(fmt, ...) \
+ ::tracing_perfetto::traceFormatInstant(ATRACE_TAG, fmt, ##__VA_ARGS__)
+#define SFTRACE_INSTANT_FOR_TRACK(trackName, name) \
+ ::tracing_perfetto::traceInstantForTrack(ATRACE_TAG, trackName, name)
+#define SFTRACE_INT(name, value) ::tracing_perfetto::traceCounter32(ATRACE_TAG, name, value)
+#define SFTRACE_INT64(name, value) ::tracing_perfetto::traceCounter(ATRACE_TAG, name, value)
// SFTRACE_NAME traces from its location until the end of its enclosing scope.
#define _PASTE(x, y) x##y
#define PASTE(x, y) _PASTE(x, y)
-#define SFTRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(ATRACE_TAG, name)
-
-// SFTRACE_CALL is an ATRACE_NAME that uses the current function name.
+#define SFTRACE_NAME(name) ::android::ScopedTrace PASTE(___tracer, __LINE__)(name)
+// SFTRACE_CALL is an SFTRACE_NAME that uses the current function name.
#define SFTRACE_CALL() SFTRACE_NAME(__FUNCTION__)
-#define SFTRACE_FORMAT(fmt, ...) \
- TraceUtils::TraceEnder traceEnder = \
- (CC_UNLIKELY(ATRACE_ENABLED()) && \
- (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), true), \
- TraceUtils::TraceEnder())
-
-#define SFTRACE_FORMAT_INSTANT(fmt, ...) \
- (CC_UNLIKELY(ATRACE_ENABLED()) && (TraceUtils::instantFormat(fmt, ##__VA_ARGS__), true))
+#define SFTRACE_FORMAT(fmt, ...) \
+ ::android::ScopedTrace PASTE(___tracer, __LINE__)(fmt, ##__VA_ARGS__)
#define ALOGE_AND_TRACE(fmt, ...) \
do { \
@@ -63,46 +77,14 @@
namespace android {
-class TraceUtils {
-public:
- class TraceEnder {
- public:
- ~TraceEnder() { ATRACE_END(); }
- };
-
- static void atraceFormatBegin(const char* fmt, ...) {
- const int BUFFER_SIZE = 256;
- va_list ap;
- char buf[BUFFER_SIZE];
-
- va_start(ap, fmt);
- vsnprintf(buf, BUFFER_SIZE, fmt, ap);
- va_end(ap);
-
- SFTRACE_BEGIN(buf);
- }
-
- static void instantFormat(const char* fmt, ...) {
- const int BUFFER_SIZE = 256;
- va_list ap;
- char buf[BUFFER_SIZE];
-
- va_start(ap, fmt);
- vsnprintf(buf, BUFFER_SIZE, fmt, ap);
- va_end(ap);
-
- SFTRACE_INSTANT(buf);
- }
-};
-
class ScopedTrace {
public:
- inline ScopedTrace(uint64_t tag, const char* name) : mTag(tag) { atrace_begin(mTag, name); }
-
- inline ~ScopedTrace() { atrace_end(mTag); }
-
-private:
- uint64_t mTag;
+ template <typename... Args>
+ inline ScopedTrace(const char* fmt, Args&&... args) {
+ ::tracing_perfetto::traceFormatBegin(ATRACE_TAG, fmt, std::forward<Args>(args)...);
+ }
+ inline ScopedTrace(const char* name) { SFTRACE_BEGIN(name); }
+ inline ~ScopedTrace() { SFTRACE_END(); }
};
} // namespace android
diff --git a/services/surfaceflinger/layerproto/Android.bp b/services/surfaceflinger/layerproto/Android.bp
index f77b137..0a69a72 100644
--- a/services/surfaceflinger/layerproto/Android.bp
+++ b/services/surfaceflinger/layerproto/Android.bp
@@ -8,14 +8,9 @@
default_team: "trendy_team_android_core_graphics_stack",
}
-cc_library {
- name: "liblayers_proto",
+cc_defaults {
+ name: "libsurfaceflinger_proto_deps",
export_include_dirs: ["include"],
-
- srcs: [
- "LayerProtoParser.cpp",
- ],
-
static_libs: [
"libperfetto_client_experimental",
],
@@ -31,24 +26,15 @@
],
shared_libs: [
- "android.hardware.graphics.common@1.1",
- "libgui",
- "libui",
"libprotobuf-cpp-lite",
- "libbase",
],
- cppflags: [
- "-Werror",
- "-Wno-unused-parameter",
- "-Wno-format",
- "-Wno-c++98-compat-pedantic",
- "-Wno-float-conversion",
- "-Wno-disabled-macro-expansion",
- "-Wno-float-equal",
- "-Wno-sign-conversion",
- "-Wno-padded",
- "-Wno-old-style-cast",
- "-Wno-undef",
+ header_libs: [
+ "libsurfaceflinger_proto_headers",
],
}
+
+cc_library_headers {
+ name: "libsurfaceflinger_proto_headers",
+ export_include_dirs: ["include"],
+}
diff --git a/services/surfaceflinger/layerproto/LayerProtoParser.cpp b/services/surfaceflinger/layerproto/LayerProtoParser.cpp
deleted file mode 100644
index c3d0a40..0000000
--- a/services/surfaceflinger/layerproto/LayerProtoParser.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <android-base/stringprintf.h>
-#include <layerproto/LayerProtoParser.h>
-#include <ui/DebugUtils.h>
-
-using android::base::StringAppendF;
-using android::base::StringPrintf;
-
-namespace android {
-namespace surfaceflinger {
-
-bool sortLayers(LayerProtoParser::Layer* lhs, const LayerProtoParser::Layer* rhs) {
- uint32_t ls = lhs->layerStack;
- uint32_t rs = rhs->layerStack;
- if (ls != rs) return ls < rs;
-
- int32_t lz = lhs->z;
- int32_t rz = rhs->z;
- if (lz != rz) {
- return lz < rz;
- }
-
- return lhs->id < rhs->id;
-}
-
-LayerProtoParser::LayerTree LayerProtoParser::generateLayerTree(
- const perfetto::protos::LayersProto& layersProto) {
- LayerTree layerTree;
- layerTree.allLayers = generateLayerList(layersProto);
-
- // find and sort the top-level layers
- for (Layer& layer : layerTree.allLayers) {
- if (layer.parent == nullptr) {
- layerTree.topLevelLayers.push_back(&layer);
- }
- }
- std::sort(layerTree.topLevelLayers.begin(), layerTree.topLevelLayers.end(), sortLayers);
-
- return layerTree;
-}
-
-std::vector<LayerProtoParser::Layer> LayerProtoParser::generateLayerList(
- const perfetto::protos::LayersProto& layersProto) {
- std::vector<Layer> layerList;
- std::unordered_map<int32_t, Layer*> layerMap;
-
- // build the layer list and the layer map
- layerList.reserve(layersProto.layers_size());
- layerMap.reserve(layersProto.layers_size());
- for (int i = 0; i < layersProto.layers_size(); i++) {
- layerList.emplace_back(generateLayer(layersProto.layers(i)));
- // this works because layerList never changes capacity
- layerMap[layerList.back().id] = &layerList.back();
- }
-
- // fix up children and relatives
- for (int i = 0; i < layersProto.layers_size(); i++) {
- updateChildrenAndRelative(layersProto.layers(i), layerMap);
- }
-
- return layerList;
-}
-
-LayerProtoParser::Layer LayerProtoParser::generateLayer(
- const perfetto::protos::LayerProto& layerProto) {
- Layer layer;
- layer.id = layerProto.id();
- layer.name = layerProto.name();
- layer.type = layerProto.type();
- layer.transparentRegion = generateRegion(layerProto.transparent_region());
- layer.visibleRegion = generateRegion(layerProto.visible_region());
- layer.damageRegion = generateRegion(layerProto.damage_region());
- layer.layerStack = layerProto.layer_stack();
- layer.z = layerProto.z();
- layer.position = {layerProto.position().x(), layerProto.position().y()};
- layer.requestedPosition = {layerProto.requested_position().x(),
- layerProto.requested_position().y()};
- layer.size = {layerProto.size().w(), layerProto.size().h()};
- layer.crop = generateRect(layerProto.crop());
- layer.isOpaque = layerProto.is_opaque();
- layer.invalidate = layerProto.invalidate();
- layer.dataspace = layerProto.dataspace();
- layer.pixelFormat = layerProto.pixel_format();
- layer.color = {layerProto.color().r(), layerProto.color().g(), layerProto.color().b(),
- layerProto.color().a()};
- layer.requestedColor = {layerProto.requested_color().r(), layerProto.requested_color().g(),
- layerProto.requested_color().b(), layerProto.requested_color().a()};
- layer.flags = layerProto.flags();
- layer.transform = generateTransform(layerProto.transform());
- layer.requestedTransform = generateTransform(layerProto.requested_transform());
- layer.activeBuffer = generateActiveBuffer(layerProto.active_buffer());
- layer.bufferTransform = generateTransform(layerProto.buffer_transform());
- layer.queuedFrames = layerProto.queued_frames();
- layer.refreshPending = layerProto.refresh_pending();
- layer.isProtected = layerProto.is_protected();
- layer.isTrustedOverlay = layerProto.is_trusted_overlay();
- layer.cornerRadius = layerProto.corner_radius();
- layer.backgroundBlurRadius = layerProto.background_blur_radius();
- for (const auto& entry : layerProto.metadata()) {
- const std::string& dataStr = entry.second;
- std::vector<uint8_t>& outData = layer.metadata.mMap[entry.first];
- outData.resize(dataStr.size());
- memcpy(outData.data(), dataStr.data(), dataStr.size());
- }
- layer.cornerRadiusCrop = generateFloatRect(layerProto.corner_radius_crop());
- layer.shadowRadius = layerProto.shadow_radius();
- layer.ownerUid = layerProto.owner_uid();
- return layer;
-}
-
-LayerProtoParser::Region LayerProtoParser::generateRegion(
- const perfetto::protos::RegionProto& regionProto) {
- LayerProtoParser::Region region;
- for (int i = 0; i < regionProto.rect_size(); i++) {
- const perfetto::protos::RectProto& rectProto = regionProto.rect(i);
- region.rects.push_back(generateRect(rectProto));
- }
-
- return region;
-}
-
-LayerProtoParser::Rect LayerProtoParser::generateRect(
- const perfetto::protos::RectProto& rectProto) {
- LayerProtoParser::Rect rect;
- rect.left = rectProto.left();
- rect.top = rectProto.top();
- rect.right = rectProto.right();
- rect.bottom = rectProto.bottom();
-
- return rect;
-}
-
-LayerProtoParser::FloatRect LayerProtoParser::generateFloatRect(
- const perfetto::protos::FloatRectProto& rectProto) {
- LayerProtoParser::FloatRect rect;
- rect.left = rectProto.left();
- rect.top = rectProto.top();
- rect.right = rectProto.right();
- rect.bottom = rectProto.bottom();
-
- return rect;
-}
-
-LayerProtoParser::Transform LayerProtoParser::generateTransform(
- const perfetto::protos::TransformProto& transformProto) {
- LayerProtoParser::Transform transform;
- transform.dsdx = transformProto.dsdx();
- transform.dtdx = transformProto.dtdx();
- transform.dsdy = transformProto.dsdy();
- transform.dtdy = transformProto.dtdy();
-
- return transform;
-}
-
-LayerProtoParser::ActiveBuffer LayerProtoParser::generateActiveBuffer(
- const perfetto::protos::ActiveBufferProto& activeBufferProto) {
- LayerProtoParser::ActiveBuffer activeBuffer;
- activeBuffer.width = activeBufferProto.width();
- activeBuffer.height = activeBufferProto.height();
- activeBuffer.stride = activeBufferProto.stride();
- activeBuffer.format = activeBufferProto.format();
-
- return activeBuffer;
-}
-
-void LayerProtoParser::updateChildrenAndRelative(const perfetto::protos::LayerProto& layerProto,
- std::unordered_map<int32_t, Layer*>& layerMap) {
- auto currLayer = layerMap[layerProto.id()];
-
- for (int i = 0; i < layerProto.children_size(); i++) {
- if (layerMap.count(layerProto.children(i)) > 0) {
- currLayer->children.push_back(layerMap[layerProto.children(i)]);
- }
- }
-
- for (int i = 0; i < layerProto.relatives_size(); i++) {
- if (layerMap.count(layerProto.relatives(i)) > 0) {
- currLayer->relatives.push_back(layerMap[layerProto.relatives(i)]);
- }
- }
-
- if (layerProto.has_parent()) {
- if (layerMap.count(layerProto.parent()) > 0) {
- currLayer->parent = layerMap[layerProto.parent()];
- }
- }
-
- if (layerProto.has_z_order_relative_of()) {
- if (layerMap.count(layerProto.z_order_relative_of()) > 0) {
- currLayer->zOrderRelativeOf = layerMap[layerProto.z_order_relative_of()];
- }
- }
-}
-
-std::string LayerProtoParser::layerTreeToString(const LayerTree& layerTree) {
- std::string result;
- for (const LayerProtoParser::Layer* layer : layerTree.topLevelLayers) {
- if (layer->zOrderRelativeOf != nullptr) {
- continue;
- }
- result.append(layerToString(layer));
- }
-
- return result;
-}
-
-std::string LayerProtoParser::layerToString(const LayerProtoParser::Layer* layer) {
- std::string result;
-
- std::vector<Layer*> traverse(layer->relatives);
- for (LayerProtoParser::Layer* child : layer->children) {
- if (child->zOrderRelativeOf != nullptr) {
- continue;
- }
-
- traverse.push_back(child);
- }
-
- std::sort(traverse.begin(), traverse.end(), sortLayers);
-
- size_t i = 0;
- for (; i < traverse.size(); i++) {
- auto& relative = traverse[i];
- if (relative->z >= 0) {
- break;
- }
- result.append(layerToString(relative));
- }
- result.append(layer->to_string());
- result.append("\n");
- for (; i < traverse.size(); i++) {
- auto& relative = traverse[i];
- result.append(layerToString(relative));
- }
-
- return result;
-}
-
-std::string LayerProtoParser::ActiveBuffer::to_string() const {
- return StringPrintf("[%4ux%4u:%4u,%s]", width, height, stride,
- decodePixelFormat(format).c_str());
-}
-
-std::string LayerProtoParser::Transform::to_string() const {
- return StringPrintf("[%.2f, %.2f][%.2f, %.2f]", static_cast<double>(dsdx),
- static_cast<double>(dtdx), static_cast<double>(dsdy),
- static_cast<double>(dtdy));
-}
-
-std::string LayerProtoParser::Rect::to_string() const {
- return StringPrintf("[%3d, %3d, %3d, %3d]", left, top, right, bottom);
-}
-
-std::string LayerProtoParser::FloatRect::to_string() const {
- return StringPrintf("[%.2f, %.2f, %.2f, %.2f]", left, top, right, bottom);
-}
-
-std::string LayerProtoParser::Region::to_string(const char* what) const {
- std::string result =
- StringPrintf(" Region %s (this=%lx count=%d)\n", what, static_cast<unsigned long>(id),
- static_cast<int>(rects.size()));
-
- for (auto& rect : rects) {
- StringAppendF(&result, " %s\n", rect.to_string().c_str());
- }
-
- return result;
-}
-
-std::string LayerProtoParser::Layer::to_string() const {
- std::string result;
- StringAppendF(&result, "+ %s (%s) uid=%d\n", type.c_str(), name.c_str(), ownerUid);
- result.append(transparentRegion.to_string("TransparentRegion").c_str());
- result.append(visibleRegion.to_string("VisibleRegion").c_str());
- result.append(damageRegion.to_string("SurfaceDamageRegion").c_str());
-
- StringAppendF(&result, " layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ", layerStack,
- z, static_cast<double>(position.x), static_cast<double>(position.y), size.x,
- size.y);
-
- StringAppendF(&result, "crop=%s, ", crop.to_string().c_str());
- StringAppendF(&result, "cornerRadius=%f, ", cornerRadius);
- StringAppendF(&result, "isProtected=%1d, ", isProtected);
- StringAppendF(&result, "isTrustedOverlay=%1d, ", isTrustedOverlay);
- StringAppendF(&result, "isOpaque=%1d, invalidate=%1d, ", isOpaque, invalidate);
- StringAppendF(&result, "dataspace=%s, ", dataspace.c_str());
- StringAppendF(&result, "defaultPixelFormat=%s, ", pixelFormat.c_str());
- StringAppendF(&result, "backgroundBlurRadius=%1d, ", backgroundBlurRadius);
- StringAppendF(&result, "color=(%.3f,%.3f,%.3f,%.3f), flags=0x%08x, ",
- static_cast<double>(color.r), static_cast<double>(color.g),
- static_cast<double>(color.b), static_cast<double>(color.a), flags);
- StringAppendF(&result, "tr=%s", transform.to_string().c_str());
- result.append("\n");
- StringAppendF(&result, " parent=%s\n", parent == nullptr ? "none" : parent->name.c_str());
- StringAppendF(&result, " zOrderRelativeOf=%s\n",
- zOrderRelativeOf == nullptr ? "none" : zOrderRelativeOf->name.c_str());
- StringAppendF(&result, " activeBuffer=%s,", activeBuffer.to_string().c_str());
- StringAppendF(&result, " tr=%s", bufferTransform.to_string().c_str());
- StringAppendF(&result, " queued-frames=%d", queuedFrames);
- StringAppendF(&result, " metadata={");
- bool first = true;
- for (const auto& entry : metadata.mMap) {
- if (!first) result.append(", ");
- first = false;
- result.append(metadata.itemToString(entry.first, ":"));
- }
- result.append("},");
- StringAppendF(&result, " cornerRadiusCrop=%s, ", cornerRadiusCrop.to_string().c_str());
- StringAppendF(&result, " shadowRadius=%.3f, ", shadowRadius);
- return result;
-}
-
-} // namespace surfaceflinger
-} // namespace android
diff --git a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h b/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
deleted file mode 100644
index 79c3982..0000000
--- a/services/surfaceflinger/layerproto/include/layerproto/LayerProtoParser.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <layerproto/LayerProtoHeader.h>
-
-#include <gui/LayerMetadata.h>
-#include <math/vec4.h>
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-using android::gui::LayerMetadata;
-
-namespace android {
-namespace surfaceflinger {
-
-class LayerProtoParser {
-public:
- class ActiveBuffer {
- public:
- uint32_t width;
- uint32_t height;
- uint32_t stride;
- int32_t format;
-
- std::string to_string() const;
- };
-
- class Transform {
- public:
- float dsdx;
- float dtdx;
- float dsdy;
- float dtdy;
-
- std::string to_string() const;
- };
-
- class Rect {
- public:
- int32_t left;
- int32_t top;
- int32_t right;
- int32_t bottom;
-
- std::string to_string() const;
- };
-
- class FloatRect {
- public:
- float left;
- float top;
- float right;
- float bottom;
-
- std::string to_string() const;
- };
-
- class Region {
- public:
- uint64_t id;
- std::vector<Rect> rects;
-
- std::string to_string(const char* what) const;
- };
-
- class Layer {
- public:
- int32_t id;
- std::string name;
- std::vector<Layer*> children;
- std::vector<Layer*> relatives;
- std::string type;
- LayerProtoParser::Region transparentRegion;
- LayerProtoParser::Region visibleRegion;
- LayerProtoParser::Region damageRegion;
- uint32_t layerStack;
- int32_t z;
- float2 position;
- float2 requestedPosition;
- int2 size;
- LayerProtoParser::Rect crop;
- bool isOpaque;
- bool invalidate;
- std::string dataspace;
- std::string pixelFormat;
- half4 color;
- half4 requestedColor;
- uint32_t flags;
- Transform transform;
- Transform requestedTransform;
- Layer* parent = 0;
- Layer* zOrderRelativeOf = 0;
- LayerProtoParser::ActiveBuffer activeBuffer;
- Transform bufferTransform;
- int32_t queuedFrames;
- bool refreshPending;
- bool isProtected;
- bool isTrustedOverlay;
- float cornerRadius;
- int backgroundBlurRadius;
- LayerMetadata metadata;
- LayerProtoParser::FloatRect cornerRadiusCrop;
- float shadowRadius;
- uid_t ownerUid;
-
- std::string to_string() const;
- };
-
- class LayerTree {
- public:
- // all layers in LayersProto and in the original order
- std::vector<Layer> allLayers;
-
- // pointers to top-level layers in allLayers
- std::vector<Layer*> topLevelLayers;
- };
-
- static LayerTree generateLayerTree(const perfetto::protos::LayersProto& layersProto);
- static std::string layerTreeToString(const LayerTree& layerTree);
-
-private:
- static std::vector<Layer> generateLayerList(const perfetto::protos::LayersProto& layersProto);
- static LayerProtoParser::Layer generateLayer(const perfetto::protos::LayerProto& layerProto);
- static LayerProtoParser::Region generateRegion(
- const perfetto::protos::RegionProto& regionProto);
- static LayerProtoParser::Rect generateRect(const perfetto::protos::RectProto& rectProto);
- static LayerProtoParser::FloatRect generateFloatRect(
- const perfetto::protos::FloatRectProto& rectProto);
- static LayerProtoParser::Transform generateTransform(
- const perfetto::protos::TransformProto& transformProto);
- static LayerProtoParser::ActiveBuffer generateActiveBuffer(
- const perfetto::protos::ActiveBufferProto& activeBufferProto);
- static void updateChildrenAndRelative(const perfetto::protos::LayerProto& layerProto,
- std::unordered_map<int32_t, Layer*>& layerMap);
-
- static std::string layerToString(const LayerProtoParser::Layer* layer);
-};
-
-} // namespace surfaceflinger
-} // namespace android
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index 39d7bd9..dfdd4aa 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -5,6 +5,3 @@
capabilities SYS_NICE
onrestart restart --only-if-running zygote
task_profiles HighPerformance
- socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
- socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
- socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 38fc977..4d5c0fd 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -28,6 +28,7 @@
"android.hardware.graphics.common-ndk_shared",
"surfaceflinger_defaults",
"libsurfaceflinger_common_test_deps",
+ "libsurfaceflinger_proto_deps",
],
test_suites: ["device-tests"],
srcs: [
@@ -58,14 +59,12 @@
"ScreenCapture_test.cpp",
"SetFrameRate_test.cpp",
"SetGeometry_test.cpp",
- "Stress_test.cpp",
"TextureFiltering_test.cpp",
"VirtualDisplay_test.cpp",
"WindowInfosListener_test.cpp",
],
data: ["SurfaceFlinger_test.filter"],
static_libs: [
- "liblayers_proto",
"android.hardware.graphics.composer@2.1",
"libsurfaceflinger_common",
],
@@ -121,7 +120,6 @@
"libEGL",
"libGLESv2",
"libgui",
- "liblayers_proto",
"liblog",
"libprotobuf-cpp-full",
"libui",
diff --git a/services/surfaceflinger/tests/Stress_test.cpp b/services/surfaceflinger/tests/Stress_test.cpp
deleted file mode 100644
index b30df5e..0000000
--- a/services/surfaceflinger/tests/Stress_test.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wconversion"
-
-#include <gtest/gtest.h>
-
-#include <gui/SurfaceComposerClient.h>
-
-#include <utils/String8.h>
-
-#include <thread>
-#include <functional>
-#include <layerproto/LayerProtoParser.h>
-
-namespace android {
-
-TEST(SurfaceFlingerStress, create_and_destroy) {
- auto do_stress = []() {
- sp<SurfaceComposerClient> client = sp<SurfaceComposerClient>::make();
- ASSERT_EQ(NO_ERROR, client->initCheck());
- for (int j = 0; j < 1000; j++) {
- auto surf = client->createSurface(String8("t"), 100, 100,
- PIXEL_FORMAT_RGBA_8888, 0);
- ASSERT_TRUE(surf != nullptr);
- surf.clear();
- }
- };
-
- std::vector<std::thread> threads;
- for (int i = 0; i < 10; i++) {
- threads.push_back(std::thread(do_stress));
- }
- for (auto& thread : threads) {
- thread.join();
- }
-}
-
-perfetto::protos::LayersProto generateLayerProto() {
- perfetto::protos::LayersProto layersProto;
- std::array<perfetto::protos::LayerProto*, 10> layers = {};
- for (size_t i = 0; i < layers.size(); ++i) {
- layers[i] = layersProto.add_layers();
- layers[i]->set_id(i);
- }
-
- layers[0]->add_children(1);
- layers[1]->set_parent(0);
- layers[0]->add_children(2);
- layers[2]->set_parent(0);
- layers[0]->add_children(3);
- layers[3]->set_parent(0);
- layers[2]->add_children(4);
- layers[4]->set_parent(2);
- layers[3]->add_children(5);
- layers[5]->set_parent(3);
- layers[5]->add_children(6);
- layers[6]->set_parent(5);
- layers[5]->add_children(7);
- layers[7]->set_parent(5);
- layers[6]->add_children(8);
- layers[8]->set_parent(6);
-
- layers[4]->set_z_order_relative_of(3);
- layers[3]->add_relatives(4);
- layers[8]->set_z_order_relative_of(9);
- layers[9]->add_relatives(8);
- layers[3]->set_z_order_relative_of(1);
- layers[1]->add_relatives(3);
-
-/* ----------------------------
- * - 0 - - 9 -
- * / | \
- * 1 2 3(1)
- * | |
- * 4(3) 5
- * / \
- * 6 7
- * |
- * 8(9)
- * -------------------------- */
-
- return layersProto;
-}
-
-TEST(LayerProtoStress, mem_info) {
- std::string cmd = "dumpsys meminfo ";
- cmd += std::to_string(getpid());
- system(cmd.c_str());
- for (int i = 0; i < 100000; i++) {
- perfetto::protos::LayersProto layersProto = generateLayerProto();
- auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
- surfaceflinger::LayerProtoParser::layerTreeToString(layerTree);
- }
- system(cmd.c_str());
-}
-
-}
-
-// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/benchmarks/Android.bp b/services/surfaceflinger/tests/benchmarks/Android.bp
new file mode 100644
index 0000000..1c47be34
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/Android.bp
@@ -0,0 +1,31 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_benchmark {
+ name: "surfaceflinger_microbenchmarks",
+ srcs: [
+ ":libsurfaceflinger_mock_sources",
+ ":libsurfaceflinger_sources",
+ "*.cpp",
+ ],
+ defaults: [
+ "libsurfaceflinger_mocks_defaults",
+ "skia_renderengine_deps",
+ "surfaceflinger_defaults",
+ ],
+ static_libs: [
+ "libgmock",
+ "libgtest",
+ "libc++fs",
+ ],
+ header_libs: [
+ "libsurfaceflinger_mocks_headers",
+ "surfaceflinger_tests_common_headers",
+ ],
+}
diff --git a/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp
new file mode 100644
index 0000000..7641a45
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/LayerLifecycleManager_benchmarks.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2024 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 <memory>
+#include <optional>
+
+#include <benchmark/benchmark.h>
+
+#include <Client.h> // temporarily needed for LayerCreationArgs
+#include <FrontEnd/LayerCreationArgs.h>
+#include <FrontEnd/LayerLifecycleManager.h>
+#include <LayerLifecycleManagerHelper.h>
+
+namespace android::surfaceflinger {
+
+namespace {
+
+using namespace android::surfaceflinger::frontend;
+
+static void addRemoveLayers(benchmark::State& state) {
+ LayerLifecycleManager lifecycleManager;
+ for (auto _ : state) {
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+ layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(2));
+ layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(3));
+ lifecycleManager.addLayers(std::move(layers));
+ lifecycleManager.onHandlesDestroyed({{1, "1"}, {2, "2"}, {3, "3"}});
+ lifecycleManager.commitChanges();
+ }
+}
+BENCHMARK(addRemoveLayers);
+
+static void updateClientStates(benchmark::State& state) {
+ LayerLifecycleManager lifecycleManager;
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+ lifecycleManager.addLayers(std::move(layers));
+ lifecycleManager.commitChanges();
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ auto& transactionState = transactions.back().states.front();
+ transactionState.state.what = layer_state_t::eColorChanged;
+ transactionState.state.color.rgb = {0.f, 0.f, 0.f};
+ transactionState.layerId = 1;
+ lifecycleManager.applyTransactions(transactions);
+ lifecycleManager.commitChanges();
+ int i = 0;
+ for (auto s : state) {
+ if (i++ % 100 == 0) i = 0;
+ transactionState.state.color.b = static_cast<float>(i / 100.f);
+ lifecycleManager.applyTransactions(transactions);
+ lifecycleManager.commitChanges();
+ }
+}
+BENCHMARK(updateClientStates);
+
+static void updateClientStatesNoChanges(benchmark::State& state) {
+ LayerLifecycleManager lifecycleManager;
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(LayerLifecycleManagerHelper::rootLayer(1));
+ lifecycleManager.addLayers(std::move(layers));
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ auto& transactionState = transactions.back().states.front();
+ transactionState.state.what = layer_state_t::eColorChanged;
+ transactionState.state.color.rgb = {0.f, 0.f, 0.f};
+ transactionState.layerId = 1;
+ lifecycleManager.applyTransactions(transactions);
+ lifecycleManager.commitChanges();
+ for (auto _ : state) {
+ lifecycleManager.applyTransactions(transactions);
+ lifecycleManager.commitChanges();
+ }
+}
+BENCHMARK(updateClientStatesNoChanges);
+
+} // namespace
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp b/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp
new file mode 100644
index 0000000..60bd58a
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/LocklessQueue_benchmarks.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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 <memory>
+#include <optional>
+
+#include <benchmark/benchmark.h>
+
+#include <LocklessQueue.h>
+
+namespace android::surfaceflinger {
+
+namespace {
+static void pushPop(benchmark::State& state) {
+ LocklessQueue<std::vector<uint32_t>> queue;
+ for (auto _ : state) {
+ queue.push({10, 5});
+ std::vector<uint32_t> poppedValue = *queue.pop();
+ benchmark::DoNotOptimize(poppedValue);
+ }
+}
+BENCHMARK(pushPop);
+
+} // namespace
+} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/tests/benchmarks/main.cpp b/services/surfaceflinger/tests/benchmarks/main.cpp
new file mode 100644
index 0000000..685c7c6
--- /dev/null
+++ b/services/surfaceflinger/tests/benchmarks/main.cpp
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2024 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 <benchmark/benchmark.h>
+BENCHMARK_MAIN();
diff --git a/libs/vr/Android.bp b/services/surfaceflinger/tests/common/Android.bp
similarity index 76%
rename from libs/vr/Android.bp
rename to services/surfaceflinger/tests/common/Android.bp
index b308895..2dfa8af 100644
--- a/libs/vr/Android.bp
+++ b/services/surfaceflinger/tests/common/Android.bp
@@ -4,11 +4,10 @@
// all of the 'license_kinds' from "frameworks_native_license"
// to get the below license kinds:
// SPDX-license-identifier-Apache-2.0
- // SPDX-license-identifier-BSD
- // legacy_notice
default_applicable_licenses: ["frameworks_native_license"],
}
-subdirs = [
- "*",
-]
+cc_library_headers {
+ name: "surfaceflinger_tests_common_headers",
+ export_include_dirs: ["."],
+}
diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
new file mode 100644
index 0000000..8b9d14b
--- /dev/null
+++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
@@ -0,0 +1,491 @@
+/*
+ * Copyright 2024 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.
+ */
+
+#pragma once
+
+#include <gui/fake/BufferData.h>
+#include <renderengine/mock/FakeExternalTexture.h>
+#include <ui/ShadowSettings.h>
+
+#include <Client.h> // temporarily needed for LayerCreationArgs
+#include <FrontEnd/LayerCreationArgs.h>
+#include <FrontEnd/LayerHierarchy.h>
+#include <FrontEnd/LayerLifecycleManager.h>
+#include <FrontEnd/LayerSnapshotBuilder.h>
+
+namespace android::surfaceflinger::frontend {
+
+class LayerLifecycleManagerHelper {
+public:
+ LayerLifecycleManagerHelper(LayerLifecycleManager& layerLifecycleManager)
+ : mLifecycleManager(layerLifecycleManager) {}
+ ~LayerLifecycleManagerHelper() = default;
+
+ static LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, uint32_t parentId,
+ uint32_t layerIdToMirror) {
+ LayerCreationArgs args(std::make_optional(id));
+ args.name = "testlayer";
+ args.addToRoot = canBeRoot;
+ args.parentId = parentId;
+ args.layerIdToMirror = layerIdToMirror;
+ return args;
+ }
+
+ static LayerCreationArgs createDisplayMirrorArgs(uint32_t id,
+ ui::LayerStack layerStackToMirror) {
+ LayerCreationArgs args(std::make_optional(id));
+ args.name = "testlayer";
+ args.addToRoot = true;
+ args.layerStackToMirror = layerStackToMirror;
+ return args;
+ }
+
+ static std::unique_ptr<RequestedLayerState> rootLayer(uint32_t id) {
+ return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/true,
+ /*parent=*/UNASSIGNED_LAYER_ID,
+ /*mirror=*/UNASSIGNED_LAYER_ID));
+ }
+
+ static std::unique_ptr<RequestedLayerState> childLayer(uint32_t id, uint32_t parentId) {
+ return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/false,
+ parentId,
+ /*mirror=*/UNASSIGNED_LAYER_ID));
+ }
+
+ static std::vector<TransactionState> setZTransaction(uint32_t id, int32_t z) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.z = z;
+ return transactions;
+ }
+
+ void createRootLayer(uint32_t id) {
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(std::make_unique<RequestedLayerState>(
+ createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/UNASSIGNED_LAYER_ID,
+ /*mirror=*/UNASSIGNED_LAYER_ID)));
+ mLifecycleManager.addLayers(std::move(layers));
+ }
+
+ void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack) {
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(std::make_unique<RequestedLayerState>(
+ createDisplayMirrorArgs(/*id=*/id, layerStack)));
+ mLifecycleManager.addLayers(std::move(layers));
+ }
+
+ void createLayer(uint32_t id, uint32_t parentId) {
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(std::make_unique<RequestedLayerState>(
+ createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
+ /*mirror=*/UNASSIGNED_LAYER_ID)));
+ mLifecycleManager.addLayers(std::move(layers));
+ }
+
+ std::vector<TransactionState> reparentLayerTransaction(uint32_t id, uint32_t newParentId) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().parentId = newParentId;
+ transactions.back().states.front().state.what = layer_state_t::eReparent;
+ transactions.back().states.front().relativeParentId = UNASSIGNED_LAYER_ID;
+ transactions.back().states.front().layerId = id;
+ return transactions;
+ }
+
+ void reparentLayer(uint32_t id, uint32_t newParentId) {
+ mLifecycleManager.applyTransactions(reparentLayerTransaction(id, newParentId));
+ }
+
+ std::vector<TransactionState> relativeLayerTransaction(uint32_t id, uint32_t relativeParentId) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().relativeParentId = relativeParentId;
+ transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
+ transactions.back().states.front().layerId = id;
+ return transactions;
+ }
+
+ void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
+ mLifecycleManager.applyTransactions(relativeLayerTransaction(id, relativeParentId));
+ }
+
+ void removeRelativeZ(uint32_t id) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setPosition(uint32_t id, float x, float y) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().state.what = layer_state_t::ePositionChanged;
+ transactions.back().states.front().state.x = x;
+ transactions.back().states.front().state.y = y;
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void mirrorLayer(uint32_t id, uint32_t parentId, uint32_t layerIdToMirror) {
+ std::vector<std::unique_ptr<RequestedLayerState>> layers;
+ layers.emplace_back(std::make_unique<RequestedLayerState>(
+ createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
+ /*mirror=*/layerIdToMirror)));
+ mLifecycleManager.addLayers(std::move(layers));
+ }
+
+ void updateBackgroundColor(uint32_t id, half alpha) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
+ transactions.back().states.front().state.bgColor.a = alpha;
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({{id, "test"}}); }
+
+ void setZ(uint32_t id, int32_t z) {
+ mLifecycleManager.applyTransactions(setZTransaction(id, z));
+ }
+
+ void setCrop(uint32_t id, const Rect& crop) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eCropChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.crop = crop;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setFlags(uint32_t id, uint32_t mask, uint32_t flags) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eFlagsChanged;
+ transactions.back().states.front().state.flags = flags;
+ transactions.back().states.front().state.mask = mask;
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setAlpha(uint32_t id, float alpha) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eAlphaChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.color.a = static_cast<half>(alpha);
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void hideLayer(uint32_t id) {
+ setFlags(id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
+ }
+
+ void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); }
+
+ void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().state.what = layer_state_t::eColorChanged;
+ transactions.back().states.front().state.color.rgb = rgb;
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setLayerStack(uint32_t id, int32_t layerStack) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eLayerStackChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.layerStack = ui::LayerStack::fromValue(layerStack);
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setTouchableRegion(uint32_t id, Region region) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.windowInfoHandle =
+ sp<gui::WindowInfoHandle>::make();
+ auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+ inputInfo->touchableRegion = region;
+ inputInfo->token = sp<BBinder>::make();
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setInputInfo(uint32_t id, std::function<void(gui::WindowInfo&)> configureInput) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.windowInfoHandle =
+ sp<gui::WindowInfoHandle>::make();
+ auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+ if (!inputInfo->token) {
+ inputInfo->token = sp<BBinder>::make();
+ }
+ configureInput(*inputInfo);
+
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId,
+ bool replaceTouchableRegionWithCrop) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.windowInfoHandle =
+ sp<gui::WindowInfoHandle>::make();
+ auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
+ inputInfo->touchableRegion = region;
+ inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop;
+ transactions.back().states.front().touchCropId = touchCropId;
+
+ inputInfo->token = sp<BBinder>::make();
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setBackgroundBlurRadius(uint32_t id, uint32_t backgroundBlurRadius) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eBackgroundBlurRadiusChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.backgroundBlurRadius = backgroundBlurRadius;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setFrameRateSelectionPriority(uint32_t id, int32_t priority) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eFrameRateSelectionPriority;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.frameRateSelectionPriority = priority;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setFrameRate(uint32_t id, float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.frameRate = frameRate;
+ transactions.back().states.front().state.frameRateCompatibility = compatibility;
+ transactions.back().states.front().state.changeFrameRateStrategy = changeFrameRateStrategy;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eFrameRateCategoryChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.frameRateCategory = frameRateCategory;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setFrameRateSelectionStrategy(uint32_t id, int8_t strategy) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what =
+ layer_state_t::eFrameRateSelectionStrategyChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.frameRateSelectionStrategy = strategy;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setDefaultFrameRateCompatibility(uint32_t id, int8_t defaultFrameRateCompatibility) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what =
+ layer_state_t::eDefaultFrameRateCompatibilityChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.defaultFrameRateCompatibility =
+ defaultFrameRateCompatibility;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setRoundedCorners(uint32_t id, float radius) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eCornerRadiusChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.cornerRadius = radius;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setBuffer(uint32_t id, std::shared_ptr<renderengine::ExternalTexture> texture) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eBufferChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().externalTexture = texture;
+ transactions.back().states.front().state.bufferData =
+ std::make_shared<fake::BufferData>(texture->getId(), texture->getWidth(),
+ texture->getHeight(), texture->getPixelFormat(),
+ texture->getUsage());
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setBuffer(uint32_t id) {
+ static uint64_t sBufferId = 1;
+ setBuffer(id,
+ std::make_shared<renderengine::mock::
+ FakeExternalTexture>(1U /*width*/, 1U /*height*/,
+ sBufferId++,
+ HAL_PIXEL_FORMAT_RGBA_8888,
+ GRALLOC_USAGE_PROTECTED /*usage*/));
+ }
+
+ void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.bufferCrop = bufferCrop;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setDamageRegion(uint32_t id, const Region& damageRegion) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.surfaceDamageRegion = damageRegion;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setDataspace(uint32_t id, ui::Dataspace dataspace) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eDataspaceChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.dataspace = dataspace;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) {
+ layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy};
+
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eMatrixChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.matrix = matrix;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setShadowRadius(uint32_t id, float shadowRadius) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eShadowRadiusChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.shadowRadius = shadowRadius;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.trustedOverlay = trustedOverlay;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+
+ transactions.back().states.front().state.what = layer_state_t::eDropInputModeChanged;
+ transactions.back().states.front().layerId = id;
+ transactions.back().states.front().state.dropInputMode = dropInputMode;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+ void setGameMode(uint32_t id, gui::GameMode gameMode) {
+ std::vector<TransactionState> transactions;
+ transactions.emplace_back();
+ transactions.back().states.push_back({});
+ transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
+ transactions.back().states.front().state.metadata = LayerMetadata();
+ transactions.back().states.front().state.metadata.setInt32(METADATA_GAME_MODE,
+ static_cast<int32_t>(gameMode));
+ transactions.back().states.front().layerId = id;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
+private:
+ LayerLifecycleManager& mLifecycleManager;
+};
+
+} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index bc35639..d9d239d 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -58,6 +58,7 @@
],
test_suites: ["device-tests"],
static_libs: ["libc++fs"],
+ header_libs: ["surfaceflinger_tests_common_headers"],
srcs: [
":libsurfaceflinger_mock_sources",
":libsurfaceflinger_sources",
@@ -82,7 +83,6 @@
"FrameRateSelectionPriorityTest.cpp",
"FrameRateSelectionStrategyTest.cpp",
"FrameTimelineTest.cpp",
- "GameModeTest.cpp",
"HWComposerTest.cpp",
"JankTrackerTest.cpp",
"OneShotTimerTest.cpp",
@@ -93,7 +93,6 @@
"LayerHierarchyTest.cpp",
"LayerLifecycleManagerTest.cpp",
"LayerSnapshotTest.cpp",
- "LayerTest.cpp",
"LayerTestUtils.cpp",
"MessageQueueTest.cpp",
"PowerAdvisorTest.cpp",
@@ -116,7 +115,6 @@
"SurfaceFlinger_SetDisplayStateTest.cpp",
"SurfaceFlinger_SetPowerModeInternalTest.cpp",
"SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp",
- "SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp",
"SchedulerTest.cpp",
"SetFrameRateTest.cpp",
"RefreshRateSelectorTest.cpp",
@@ -152,6 +150,7 @@
"android.hardware.power-ndk_static",
"librenderengine_deps",
"libsurfaceflinger_common_test_deps",
+ "libsurfaceflinger_proto_deps",
],
static_libs: [
"android.hardware.common-V2-ndk",
@@ -170,7 +169,6 @@
"libframetimeline",
"libgmock",
"libgui_mocks",
- "liblayers_proto",
"libperfetto_client_experimental",
"librenderengine",
"librenderengine_mocks",
@@ -209,6 +207,7 @@
"libsync",
"libui",
"libutils",
+ "libtracing_perfetto",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index cdd77fe..23d3c16 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -15,7 +15,6 @@
*/
// TODO(b/129481165): remove the #pragma below and fix conversion issues
-#include "renderengine/ExternalTexture.h"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wextra"
@@ -31,6 +30,7 @@
#include <gui/IProducerListener.h>
#include <gui/LayerMetadata.h>
#include <log/log.h>
+#include <renderengine/ExternalTexture.h>
#include <renderengine/mock/FakeExternalTexture.h>
#include <renderengine/mock/RenderEngine.h>
#include <system/window.h>
@@ -149,7 +149,6 @@
sp<compositionengine::mock::DisplaySurface> mDisplaySurface =
sp<compositionengine::mock::DisplaySurface>::make();
sp<mock::NativeWindow> mNativeWindow = sp<mock::NativeWindow>::make();
- std::vector<sp<Layer>> mAuxiliaryLayers;
sp<GraphicBuffer> mBuffer =
sp<GraphicBuffer>::make(1u, 1u, PIXEL_FORMAT_RGBA_8888,
@@ -194,6 +193,7 @@
template <typename LayerCase>
void CompositionTest::captureScreenComposition() {
LayerCase::setupForScreenCapture(this);
+ mFlinger.commit();
const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
constexpr bool regionSampling = false;
@@ -204,13 +204,8 @@
RenderArea::Options::CAPTURE_SECURE_LAYERS |
RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION);
- auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
- return mFlinger.traverseLayersInLayerStack(mDisplay->getLayerStack(),
- CaptureArgs::UNSET_UID, {}, visitor);
- };
-
- // TODO: Use SurfaceFlinger::getLayerSnapshotsForScreenshots instead of this legacy function
- auto getLayerSnapshotsFn = RenderArea::fromTraverseLayersLambda(traverseLayers);
+ auto getLayerSnapshotsFn = mFlinger.getLayerSnapshotsForScreenshotsFn(mDisplay->getLayerStack(),
+ CaptureArgs::UNSET_UID);
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
@@ -462,7 +457,7 @@
static constexpr IComposerClient::BlendMode BLENDMODE =
IComposerClient::BlendMode::PREMULTIPLIED;
- static void setupLatchedBuffer(CompositionTest* test, sp<Layer> layer) {
+ static void setupLatchedBuffer(CompositionTest* test, frontend::RequestedLayerState& layer) {
Mock::VerifyAndClear(test->mRenderEngine);
const auto buffer = std::make_shared<
@@ -472,21 +467,15 @@
LayerProperties::FORMAT,
LayerProperties::USAGE |
GraphicBuffer::USAGE_HW_TEXTURE);
-
- auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
- layerDrawingState.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
- layerDrawingState.buffer = buffer;
- layerDrawingState.acquireFence = Fence::NO_FENCE;
- layerDrawingState.dataspace = ui::Dataspace::UNKNOWN;
- layer->setSurfaceDamageRegion(
- Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH)));
-
- bool ignoredRecomputeVisibleRegions;
- layer->latchBuffer(ignoredRecomputeVisibleRegions, 0);
+ layer.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
+ layer.externalTexture = buffer;
+ layer.bufferData->acquireFence = Fence::NO_FENCE;
+ layer.dataspace = ui::Dataspace::UNKNOWN;
+ layer.surfaceDamageRegion = Region(Rect(LayerProperties::HEIGHT, LayerProperties::WIDTH));
Mock::VerifyAndClear(test->mRenderEngine);
}
- static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+ static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
setupLatchedBuffer(test, layer);
}
@@ -670,14 +659,12 @@
using Base = BaseLayerProperties<SidebandLayerProperties>;
static constexpr IComposerClient::BlendMode BLENDMODE = IComposerClient::BlendMode::NONE;
- static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+ static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
- test->mFlinger.setLayerSidebandStream(layer, stream);
- auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
- layerDrawingState.crop =
- Rect(0, 0, SidebandLayerProperties::HEIGHT, SidebandLayerProperties::WIDTH);
+ layer.sidebandStream = stream;
+ layer.crop = Rect(0, 0, SidebandLayerProperties::HEIGHT, SidebandLayerProperties::WIDTH);
}
static void setupHwcSetSourceCropBufferCallExpectations(CompositionTest* test) {
@@ -755,17 +742,17 @@
struct CursorLayerProperties : public BaseLayerProperties<CursorLayerProperties> {
using Base = BaseLayerProperties<CursorLayerProperties>;
- static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
+ static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
Base::setupLayerState(test, layer);
- test->mFlinger.setLayerPotentialCursor(layer, true);
+ layer.potentialCursor = true;
}
};
struct NoLayerVariant {
- using FlingerLayerType = sp<Layer>;
-
- static FlingerLayerType createLayer(CompositionTest*) { return FlingerLayerType(); }
- static void injectLayer(CompositionTest*, FlingerLayerType) {}
+ static frontend::RequestedLayerState createLayer(CompositionTest*) {
+ return {LayerCreationArgs()};
+ }
+ static void injectLayer(CompositionTest*, frontend::RequestedLayerState&) {}
static void cleanupInjectedLayers(CompositionTest*) {}
static void setupCallExpectationsForDirtyGeometry(CompositionTest*) {}
@@ -775,10 +762,10 @@
template <typename LayerProperties>
struct BaseLayerVariant {
template <typename L, typename F>
- static sp<L> createLayerWithFactory(CompositionTest* test, F factory) {
+ static frontend::RequestedLayerState createLayerWithFactory(CompositionTest* test, F factory) {
EXPECT_CALL(*test->mFlinger.scheduler(), postMessage(_)).Times(0);
- sp<L> layer = factory();
+ auto layer = factory();
// Layer should be registered with scheduler.
EXPECT_EQ(1u, test->mFlinger.scheduler()->layerHistorySize());
@@ -792,27 +779,26 @@
return layer;
}
- template <typename L>
- static void initLayerDrawingStateAndComputeBounds(CompositionTest* test, sp<L> layer) {
- auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
- layerDrawingState.layerStack = LAYER_STACK;
- layerDrawingState.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
- LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
- layer->computeBounds(FloatRect(0, 0, 100, 100), ui::Transform(), 0.f /* shadowRadius */);
+ static void initLayerDrawingStateAndComputeBounds(CompositionTest* test,
+ frontend::RequestedLayerState& layer) {
+ layer.layerStack = LAYER_STACK;
+ layer.color = half4(LayerProperties::COLOR[0], LayerProperties::COLOR[1],
+ LayerProperties::COLOR[2], LayerProperties::COLOR[3]);
}
- static void injectLayer(CompositionTest* test, sp<Layer> layer) {
+ static void injectLayer(CompositionTest* test, frontend::RequestedLayerState& layer) {
EXPECT_CALL(*test->mComposer, createLayer(HWC_DISPLAY, _))
.WillOnce(DoAll(SetArgPointee<1>(HWC_LAYER), Return(Error::NONE)));
-
+ auto legacyLayer = test->mFlinger.getLegacyLayer(layer.id);
auto outputLayer = test->mDisplay->getCompositionDisplay()->injectOutputLayerForTest(
- layer->getCompositionEngineLayerFE());
+ legacyLayer->getCompositionEngineLayerFE({.id = layer.id}));
outputLayer->editState().visibleRegion = Region(Rect(0, 0, 100, 100));
outputLayer->editState().outputSpaceVisibleRegion = Region(Rect(0, 0, 100, 100));
Mock::VerifyAndClear(test->mComposer);
- test->mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
+ auto layerCopy = std::make_unique<frontend::RequestedLayerState>(layer);
+ test->mFlinger.addLayer(layerCopy);
test->mFlinger.mutableVisibleRegionsDirty() = true;
}
@@ -820,10 +806,9 @@
EXPECT_CALL(*test->mComposer, destroyLayer(HWC_DISPLAY, HWC_LAYER))
.WillOnce(Return(Error::NONE));
+ test->mFlinger.destroyAllLayerHandles();
test->mDisplay->getCompositionDisplay()->clearOutputLayers();
- test->mFlinger.mutableDrawingState().layersSortedByZ.clear();
test->mFlinger.mutablePreviouslyComposedLayers().clear();
-
// Layer should be unregistered with scheduler.
test->mFlinger.commit();
EXPECT_EQ(0u, test->mFlinger.scheduler()->layerHistorySize());
@@ -833,17 +818,17 @@
template <typename LayerProperties>
struct EffectLayerVariant : public BaseLayerVariant<LayerProperties> {
using Base = BaseLayerVariant<LayerProperties>;
- using FlingerLayerType = sp<Layer>;
-
- static FlingerLayerType createLayer(CompositionTest* test) {
- FlingerLayerType layer = Base::template createLayerWithFactory<Layer>(test, [test]() {
- return sp<Layer>::make(LayerCreationArgs(test->mFlinger.flinger(), sp<Client>(),
- "test-layer", LayerProperties::LAYER_FLAGS,
- LayerMetadata()));
+ static frontend::RequestedLayerState createLayer(CompositionTest* test) {
+ frontend::RequestedLayerState layer = Base::template createLayerWithFactory<
+ frontend::RequestedLayerState>(test, [test]() {
+ auto args = LayerCreationArgs(test->mFlinger.flinger(), sp<Client>(), "test-layer",
+ LayerProperties::LAYER_FLAGS, LayerMetadata());
+ auto legacyLayer = sp<Layer>::make(args);
+ test->mFlinger.injectLegacyLayer(legacyLayer);
+ return frontend::RequestedLayerState(args);
});
- auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
- layerDrawingState.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
+ layer.crop = Rect(0, 0, LayerProperties::HEIGHT, LayerProperties::WIDTH);
return layer;
}
@@ -869,13 +854,15 @@
template <typename LayerProperties>
struct BufferLayerVariant : public BaseLayerVariant<LayerProperties> {
using Base = BaseLayerVariant<LayerProperties>;
- using FlingerLayerType = sp<Layer>;
- static FlingerLayerType createLayer(CompositionTest* test) {
- FlingerLayerType layer = Base::template createLayerWithFactory<Layer>(test, [test]() {
+ static frontend::RequestedLayerState createLayer(CompositionTest* test) {
+ frontend::RequestedLayerState layer = Base::template createLayerWithFactory<
+ frontend::RequestedLayerState>(test, [test]() {
LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-layer",
LayerProperties::LAYER_FLAGS, LayerMetadata());
- return sp<Layer>::make(args);
+ auto legacyLayer = sp<Layer>::make(args);
+ test->mFlinger.injectLegacyLayer(legacyLayer);
+ return frontend::RequestedLayerState(args);
});
LayerProperties::setupLayerState(test, layer);
@@ -917,13 +904,14 @@
template <typename LayerProperties>
struct ContainerLayerVariant : public BaseLayerVariant<LayerProperties> {
using Base = BaseLayerVariant<LayerProperties>;
- using FlingerLayerType = sp<Layer>;
- static FlingerLayerType createLayer(CompositionTest* test) {
+ static frontend::RequestedLayerState createLayer(CompositionTest* test) {
LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-container-layer",
LayerProperties::LAYER_FLAGS, LayerMetadata());
- FlingerLayerType layer = sp<Layer>::make(args);
- Base::template initLayerDrawingStateAndComputeBounds(test, layer);
+ sp<Layer> legacyLayer = sp<Layer>::make(args);
+ test->mFlinger.injectLegacyLayer(legacyLayer);
+ frontend::RequestedLayerState layer(args);
+ Base::initLayerDrawingStateAndComputeBounds(test, layer);
return layer;
}
};
@@ -931,29 +919,19 @@
template <typename LayerVariant, typename ParentLayerVariant>
struct ChildLayerVariant : public LayerVariant {
using Base = LayerVariant;
- using FlingerLayerType = typename LayerVariant::FlingerLayerType;
using ParentBase = ParentLayerVariant;
- static FlingerLayerType createLayer(CompositionTest* test) {
+ static frontend::RequestedLayerState createLayer(CompositionTest* test) {
// Need to create child layer first. Otherwise layer history size will be 2.
- FlingerLayerType layer = Base::createLayer(test);
-
- typename ParentBase::FlingerLayerType parentLayer = ParentBase::createLayer(test);
- parentLayer->addChild(layer);
- test->mFlinger.setLayerDrawingParent(layer, parentLayer);
-
- test->mAuxiliaryLayers.push_back(parentLayer);
-
+ frontend::RequestedLayerState layer = Base::createLayer(test);
+ frontend::RequestedLayerState parentLayer = ParentBase::createLayer(test);
+ layer.parentId = parentLayer.id;
+ auto layerCopy = std::make_unique<frontend::RequestedLayerState>(parentLayer);
+ test->mFlinger.addLayer(layerCopy);
return layer;
}
- static void cleanupInjectedLayers(CompositionTest* test) {
- // Clear auxiliary layers first so that child layer can be successfully destroyed in the
- // following call.
- test->mAuxiliaryLayers.clear();
-
- Base::cleanupInjectedLayers(test);
- }
+ static void cleanupInjectedLayers(CompositionTest* test) { Base::cleanupInjectedLayers(test); }
};
/* ------------------------------------------------------------------------
@@ -1016,7 +994,7 @@
*/
struct CompositionResultBaseVariant {
- static void setupLayerState(CompositionTest*, sp<Layer>) {}
+ static void setupLayerState(CompositionTest*, frontend::RequestedLayerState&) {}
template <typename Case>
static void setupCallExpectationsForDirtyGeometry(CompositionTest* test) {
@@ -1056,9 +1034,8 @@
};
struct ForcedClientCompositionResultVariant : public CompositionResultBaseVariant {
- static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
- const auto outputLayer =
- TestableSurfaceFlinger::findOutputLayerForDisplay(layer, test->mDisplay);
+ static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState& layer) {
+ const auto outputLayer = test->mFlinger.findOutputLayerForDisplay(layer.id, test->mDisplay);
LOG_FATAL_IF(!outputLayer);
outputLayer->editState().forceClientComposition = true;
}
@@ -1079,7 +1056,7 @@
};
struct ForcedClientCompositionViaDebugOptionResultVariant : public CompositionResultBaseVariant {
- static void setupLayerState(CompositionTest* test, sp<Layer>) {
+ static void setupLayerState(CompositionTest* test, frontend::RequestedLayerState&) {
test->mFlinger.mutableDebugDisableHWC() = true;
}
@@ -1099,7 +1076,7 @@
};
struct EmptyScreenshotResultVariant {
- static void setupLayerState(CompositionTest*, sp<Layer>) {}
+ static void setupLayerState(CompositionTest*, frontend::RequestedLayerState&) {}
template <typename Case>
static void setupCallExpectations(CompositionTest*) {}
@@ -1365,28 +1342,6 @@
* Layers with a parent layer with ISurfaceComposerClient::eSecure, on a non-secure display
*/
-TEST_F(CompositionTest,
- HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyGeometry) {
- displayRefreshCompositionDirtyGeometry<CompositionCase<
- InsecureDisplaySetupVariant,
- ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
- ContainerLayerVariant<SecureLayerProperties>>,
- KeepCompositionTypeVariant<
- aidl::android::hardware::graphics::composer3::Composition::CLIENT>,
- ForcedClientCompositionResultVariant>>();
-}
-
-TEST_F(CompositionTest,
- HWCComposedBufferLayerWithSecureParentLayerOnInsecureDisplayWithDirtyFrame) {
- displayRefreshCompositionDirtyFrame<CompositionCase<
- InsecureDisplaySetupVariant,
- ChildLayerVariant<BufferLayerVariant<ParentSecureLayerProperties>,
- ContainerLayerVariant<SecureLayerProperties>>,
- KeepCompositionTypeVariant<
- aidl::android::hardware::graphics::composer3::Composition::CLIENT>,
- ForcedClientCompositionResultVariant>>();
-}
-
TEST_F(CompositionTest, captureScreenBufferLayerWithSecureParentLayerOnInsecureDisplay) {
captureScreenComposition<
CompositionCase<InsecureDisplaySetupVariant,
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index f26336a..db3c0a1 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -498,9 +498,7 @@
constexpr int PHYSICAL_DISPLAY_FLAGS = 0x1;
template <typename PhysicalDisplay, int width, int height,
- Secure secure = (PhysicalDisplay::CONNECTION_TYPE == ui::DisplayConnectionType::Internal)
- ? Secure::TRUE
- : Secure::FALSE>
+ Secure secure = (PhysicalDisplay::SECURE) ? Secure::TRUE : Secure::FALSE>
struct PhysicalDisplayVariant
: DisplayVariant<PhysicalDisplayIdType<PhysicalDisplay>, width, height, Async::FALSE, secure,
PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY,
@@ -515,16 +513,18 @@
struct PrimaryDisplay {
static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::Internal;
static constexpr Primary PRIMARY = Primary::TRUE;
+ static constexpr bool SECURE = true;
static constexpr uint8_t PORT = 255;
static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
};
-template <ui::DisplayConnectionType connectionType, bool hasIdentificationData>
+template <ui::DisplayConnectionType connectionType, bool hasIdentificationData, bool secure>
struct SecondaryDisplay {
static constexpr auto CONNECTION_TYPE = connectionType;
static constexpr Primary PRIMARY = Primary::FALSE;
+ static constexpr bool SECURE = secure;
static constexpr uint8_t PORT = 254;
static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
@@ -533,9 +533,14 @@
: getExternalEdid;
};
+constexpr bool kSecure = true;
+constexpr bool kNonSecure = false;
+
+template <bool secure>
struct TertiaryDisplay {
static constexpr auto CONNECTION_TYPE = ui::DisplayConnectionType::External;
static constexpr Primary PRIMARY = Primary::FALSE;
+ static constexpr bool SECURE = secure;
static constexpr uint8_t PORT = 253;
static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
@@ -545,14 +550,26 @@
using InnerDisplayVariant = PhysicalDisplayVariant<PrimaryDisplay<true>, 1840, 2208>;
using OuterDisplayVariant =
- PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal, true>, 1080,
- 2092>;
+ PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
+ /*hasIdentificationData=*/true, kSecure>,
+ 1080, 2092>;
+using OuterDisplayNonSecureVariant =
+ PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::Internal,
+ /*hasIdentificationData=*/true, kNonSecure>,
+ 1080, 2092>;
using ExternalDisplayVariant =
- PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External, false>, 1920,
- 1280>;
+ PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
+ /*hasIdentificationData=*/false, kSecure>,
+ 1920, 1280>;
+using ExternalDisplayNonSecureVariant =
+ PhysicalDisplayVariant<SecondaryDisplay<ui::DisplayConnectionType::External,
+ /*hasIdentificationData=*/false, kNonSecure>,
+ 1920, 1280>;
-using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay, 1600, 1200>;
+using TertiaryDisplayVariant = PhysicalDisplayVariant<TertiaryDisplay<kSecure>, 1600, 1200>;
+using TertiaryDisplayNonSecureVariant =
+ PhysicalDisplayVariant<TertiaryDisplay<kNonSecure>, 1600, 1200>;
// A virtual display not supported by the HWC.
constexpr uint32_t GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY = 0;
@@ -750,10 +767,18 @@
Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayVariant>,
HdrNotSupportedVariant<ExternalDisplayVariant>,
NoPerFrameMetadataSupportVariant<ExternalDisplayVariant>>;
+using SimpleExternalDisplayNonSecureCase =
+ Case<ExternalDisplayVariant, WideColorNotSupportedVariant<ExternalDisplayNonSecureVariant>,
+ HdrNotSupportedVariant<ExternalDisplayNonSecureVariant>,
+ NoPerFrameMetadataSupportVariant<ExternalDisplayNonSecureVariant>>;
using SimpleTertiaryDisplayCase =
Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayVariant>,
HdrNotSupportedVariant<TertiaryDisplayVariant>,
NoPerFrameMetadataSupportVariant<TertiaryDisplayVariant>>;
+using SimpleTertiaryDisplayNonSecureCase =
+ Case<TertiaryDisplayVariant, WideColorNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
+ HdrNotSupportedVariant<TertiaryDisplayNonSecureVariant>,
+ NoPerFrameMetadataSupportVariant<TertiaryDisplayNonSecureVariant>>;
using NonHwcVirtualDisplayCase =
Case<NonHwcVirtualDisplayVariant<1024, 768, Secure::FALSE>,
diff --git a/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp b/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp
index 5c742d7..866eb08 100644
--- a/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameRateSelectionStrategyTest.cpp
@@ -28,6 +28,7 @@
namespace android {
+using testing::_;
using testing::DoAll;
using testing::Mock;
using testing::SetArgPointee;
@@ -91,7 +92,7 @@
PrintToStringParamName);
TEST_P(FrameRateSelectionStrategyTest, SetAndGet) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
auto layer = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -104,7 +105,7 @@
}
TEST_P(FrameRateSelectionStrategyTest, SetChildOverrideChildren) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
auto parent = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -128,7 +129,7 @@
}
TEST_P(FrameRateSelectionStrategyTest, SetParentOverrideChildren) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
@@ -169,7 +170,7 @@
}
TEST_P(FrameRateSelectionStrategyTest, OverrideChildrenAndSelf) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
auto layer1 = mLayers.emplace_back(layerFactory->createLayer(mFlinger));
diff --git a/services/surfaceflinger/tests/unittests/GameModeTest.cpp b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
deleted file mode 100644
index 1b5c6e7..0000000
--- a/services/surfaceflinger/tests/unittests/GameModeTest.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2021 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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "LibSurfaceFlingerUnittests"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gui/LayerMetadata.h>
-#include <gui/SurfaceComposerClient.h>
-#include <log/log.h>
-
-#include "TestableSurfaceFlinger.h"
-#include "mock/DisplayHardware/MockComposer.h"
-
-namespace android {
-
-using testing::_;
-using testing::Mock;
-using testing::Return;
-
-using gui::GameMode;
-using gui::LayerMetadata;
-
-class GameModeTest : public testing::Test {
-public:
- GameModeTest() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
- mFlinger.setupMockScheduler();
- setupComposer();
- }
-
- ~GameModeTest() {
- const ::testing::TestInfo* const test_info =
- ::testing::UnitTest::GetInstance()->current_test_info();
- ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
- }
-
- sp<Layer> createLayer() {
- sp<Client> client;
- LayerCreationArgs args(mFlinger.flinger(), client, "layer", 0, LayerMetadata());
- return sp<Layer>::make(args);
- }
-
- void setupComposer() {
- mComposer = new Hwc2::mock::Composer();
- mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
-
- Mock::VerifyAndClear(mComposer);
- }
-
- // Mocks the behavior of applying a transaction from WMShell
- void setGameModeMetadata(sp<Layer> layer, GameMode gameMode) {
- mLayerMetadata.setInt32(gui::METADATA_GAME_MODE, static_cast<int32_t>(gameMode));
- layer->setMetadata(mLayerMetadata);
- layer->setGameModeForTree(gameMode);
- }
-
- TestableSurfaceFlinger mFlinger;
- Hwc2::mock::Composer* mComposer = nullptr;
- client_cache_t mClientCache;
- LayerMetadata mLayerMetadata;
-};
-
-TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) {
- sp<Layer> rootLayer = createLayer();
- sp<Layer> childLayer1 = createLayer();
- sp<Layer> childLayer2 = createLayer();
- rootLayer->addChild(childLayer1);
- rootLayer->addChild(childLayer2);
- rootLayer->setGameModeForTree(GameMode::Performance);
-
- EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
- EXPECT_EQ(childLayer1->getGameMode(), GameMode::Performance);
- EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-}
-
-TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) {
- sp<Layer> rootLayer = createLayer();
- sp<Layer> childLayer = createLayer();
- rootLayer->setGameModeForTree(GameMode::Performance);
- rootLayer->addChild(childLayer);
-
- EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
- EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance);
-}
-
-TEST_F(GameModeTest, RemoveChildResetsGameMode) {
- sp<Layer> rootLayer = createLayer();
- sp<Layer> childLayer = createLayer();
- rootLayer->setGameModeForTree(GameMode::Performance);
- rootLayer->addChild(childLayer);
-
- EXPECT_EQ(rootLayer->getGameMode(), GameMode::Performance);
- EXPECT_EQ(childLayer->getGameMode(), GameMode::Performance);
-
- rootLayer->removeChild(childLayer);
- EXPECT_EQ(childLayer->getGameMode(), GameMode::Unsupported);
-}
-
-TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) {
- sp<Layer> rootLayer = createLayer();
- sp<Layer> childLayer1 = createLayer();
- sp<Layer> childLayer2 = createLayer();
- rootLayer->setGameModeForTree(GameMode::Standard);
- rootLayer->addChild(childLayer1);
-
- setGameModeMetadata(childLayer2, GameMode::Performance);
- rootLayer->addChild(childLayer2);
-
- EXPECT_EQ(rootLayer->getGameMode(), GameMode::Standard);
- EXPECT_EQ(childLayer1->getGameMode(), GameMode::Standard);
- EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-
- rootLayer->removeChild(childLayer2);
- EXPECT_EQ(childLayer2->getGameMode(), GameMode::Performance);
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index 8b3303c..37cda3e 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -25,13 +25,15 @@
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerHierarchy.h"
#include "FrontEnd/LayerLifecycleManager.h"
+#include "LayerLifecycleManagerHelper.h"
+
#include "FrontEnd/LayerSnapshotBuilder.h"
namespace android::surfaceflinger::frontend {
-class LayerHierarchyTestBase : public testing::Test {
+class LayerHierarchyTestBase : public testing::Test, public LayerLifecycleManagerHelper {
protected:
- LayerHierarchyTestBase() {
+ LayerHierarchyTestBase() : LayerLifecycleManagerHelper(mLifecycleManager) {
// tree with 3 levels of children
// ROOT
// ├── 1
@@ -55,24 +57,6 @@
createLayer(1221, 122);
}
- LayerCreationArgs createArgs(uint32_t id, bool canBeRoot, uint32_t parentId,
- uint32_t layerIdToMirror) {
- LayerCreationArgs args(std::make_optional(id));
- args.name = "testlayer";
- args.addToRoot = canBeRoot;
- args.parentId = parentId;
- args.layerIdToMirror = layerIdToMirror;
- return args;
- }
-
- LayerCreationArgs createDisplayMirrorArgs(uint32_t id, ui::LayerStack layerStackToMirror) {
- LayerCreationArgs args(std::make_optional(id));
- args.name = "testlayer";
- args.addToRoot = true;
- args.layerStackToMirror = layerStackToMirror;
- return args;
- }
-
std::vector<uint32_t> getTraversalPath(const LayerHierarchy& hierarchy) const {
std::vector<uint32_t> layerIds;
hierarchy.traverse([&layerIds = layerIds](const LayerHierarchy& hierarchy,
@@ -94,98 +78,6 @@
return layerIds;
}
- virtual void createRootLayer(uint32_t id) {
- std::vector<std::unique_ptr<RequestedLayerState>> layers;
- layers.emplace_back(std::make_unique<RequestedLayerState>(
- createArgs(/*id=*/id, /*canBeRoot=*/true, /*parent=*/UNASSIGNED_LAYER_ID,
- /*mirror=*/UNASSIGNED_LAYER_ID)));
- mLifecycleManager.addLayers(std::move(layers));
- }
-
- void createDisplayMirrorLayer(uint32_t id, ui::LayerStack layerStack) {
- std::vector<std::unique_ptr<RequestedLayerState>> layers;
- layers.emplace_back(std::make_unique<RequestedLayerState>(
- createDisplayMirrorArgs(/*id=*/id, layerStack)));
- mLifecycleManager.addLayers(std::move(layers));
- }
-
- virtual void createLayer(uint32_t id, uint32_t parentId) {
- std::vector<std::unique_ptr<RequestedLayerState>> layers;
- layers.emplace_back(std::make_unique<RequestedLayerState>(
- createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
- /*mirror=*/UNASSIGNED_LAYER_ID)));
- mLifecycleManager.addLayers(std::move(layers));
- }
-
- std::vector<TransactionState> reparentLayerTransaction(uint32_t id, uint32_t newParentId) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().parentId = newParentId;
- transactions.back().states.front().state.what = layer_state_t::eReparent;
- transactions.back().states.front().relativeParentId = UNASSIGNED_LAYER_ID;
- transactions.back().states.front().layerId = id;
- return transactions;
- }
-
- void reparentLayer(uint32_t id, uint32_t newParentId) {
- mLifecycleManager.applyTransactions(reparentLayerTransaction(id, newParentId));
- }
-
- std::vector<TransactionState> relativeLayerTransaction(uint32_t id, uint32_t relativeParentId) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().relativeParentId = relativeParentId;
- transactions.back().states.front().state.what = layer_state_t::eRelativeLayerChanged;
- transactions.back().states.front().layerId = id;
- return transactions;
- }
-
- void reparentRelativeLayer(uint32_t id, uint32_t relativeParentId) {
- mLifecycleManager.applyTransactions(relativeLayerTransaction(id, relativeParentId));
- }
-
- void removeRelativeZ(uint32_t id) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
- transactions.back().states.front().layerId = id;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setPosition(uint32_t id, float x, float y) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::ePositionChanged;
- transactions.back().states.front().state.x = x;
- transactions.back().states.front().state.y = y;
- transactions.back().states.front().layerId = id;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- virtual void mirrorLayer(uint32_t id, uint32_t parentId, uint32_t layerIdToMirror) {
- std::vector<std::unique_ptr<RequestedLayerState>> layers;
- layers.emplace_back(std::make_unique<RequestedLayerState>(
- createArgs(/*id=*/id, /*canBeRoot=*/false, /*parent=*/parentId,
- /*mirror=*/layerIdToMirror)));
- mLifecycleManager.addLayers(std::move(layers));
- }
-
- void updateBackgroundColor(uint32_t id, half alpha) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::eBackgroundColorChanged;
- transactions.back().states.front().state.bgColor.a = alpha;
- transactions.back().states.front().layerId = id;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void destroyLayerHandle(uint32_t id) { mLifecycleManager.onHandlesDestroyed({{id, "test"}}); }
-
void updateAndVerify(LayerHierarchyBuilder& hierarchyBuilder) {
hierarchyBuilder.update(mLifecycleManager);
mLifecycleManager.commitChanges();
@@ -201,321 +93,6 @@
mLifecycleManager.getGlobalChanges().test(RequestedLayerState::Changes::Hierarchy));
}
- std::vector<TransactionState> setZTransaction(uint32_t id, int32_t z) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eLayerChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.z = z;
- return transactions;
- }
-
- void setZ(uint32_t id, int32_t z) {
- mLifecycleManager.applyTransactions(setZTransaction(id, z));
- }
-
- void setCrop(uint32_t id, const Rect& crop) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eCropChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.crop = crop;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setFlags(uint32_t id, uint32_t mask, uint32_t flags) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eFlagsChanged;
- transactions.back().states.front().state.flags = flags;
- transactions.back().states.front().state.mask = mask;
- transactions.back().states.front().layerId = id;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setAlpha(uint32_t id, float alpha) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eAlphaChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.color.a = static_cast<half>(alpha);
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void hideLayer(uint32_t id) {
- setFlags(id, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
- }
-
- void showLayer(uint32_t id) { setFlags(id, layer_state_t::eLayerHidden, 0); }
-
- void setColor(uint32_t id, half3 rgb = half3(1._hf, 1._hf, 1._hf)) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::eColorChanged;
- transactions.back().states.front().state.color.rgb = rgb;
- transactions.back().states.front().layerId = id;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setLayerStack(uint32_t id, int32_t layerStack) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eLayerStackChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.layerStack = ui::LayerStack::fromValue(layerStack);
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setTouchableRegion(uint32_t id, Region region) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.windowInfoHandle =
- sp<gui::WindowInfoHandle>::make();
- auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
- inputInfo->touchableRegion = region;
- inputInfo->token = sp<BBinder>::make();
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setInputInfo(uint32_t id, std::function<void(gui::WindowInfo&)> configureInput) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.windowInfoHandle =
- sp<gui::WindowInfoHandle>::make();
- auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
- if (!inputInfo->token) {
- inputInfo->token = sp<BBinder>::make();
- }
- configureInput(*inputInfo);
-
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setTouchableRegionCrop(uint32_t id, Region region, uint32_t touchCropId,
- bool replaceTouchableRegionWithCrop) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eInputInfoChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.windowInfoHandle =
- sp<gui::WindowInfoHandle>::make();
- auto inputInfo = transactions.back().states.front().state.windowInfoHandle->editInfo();
- inputInfo->touchableRegion = region;
- inputInfo->replaceTouchableRegionWithCrop = replaceTouchableRegionWithCrop;
- transactions.back().states.front().touchCropId = touchCropId;
-
- inputInfo->token = sp<BBinder>::make();
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setBackgroundBlurRadius(uint32_t id, uint32_t backgroundBlurRadius) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eBackgroundBlurRadiusChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.backgroundBlurRadius = backgroundBlurRadius;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setFrameRateSelectionPriority(uint32_t id, int32_t priority) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eFrameRateSelectionPriority;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.frameRateSelectionPriority = priority;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setFrameRate(uint32_t id, float frameRate, int8_t compatibility,
- int8_t changeFrameRateStrategy) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eFrameRateChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.frameRate = frameRate;
- transactions.back().states.front().state.frameRateCompatibility = compatibility;
- transactions.back().states.front().state.changeFrameRateStrategy = changeFrameRateStrategy;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setFrameRateCategory(uint32_t id, int8_t frameRateCategory) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eFrameRateCategoryChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.frameRateCategory = frameRateCategory;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setFrameRateSelectionStrategy(uint32_t id, int8_t strategy) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what =
- layer_state_t::eFrameRateSelectionStrategyChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.frameRateSelectionStrategy = strategy;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setDefaultFrameRateCompatibility(uint32_t id, int8_t defaultFrameRateCompatibility) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what =
- layer_state_t::eDefaultFrameRateCompatibilityChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.defaultFrameRateCompatibility =
- defaultFrameRateCompatibility;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setRoundedCorners(uint32_t id, float radius) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eCornerRadiusChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.cornerRadius = radius;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setBuffer(uint32_t id, std::shared_ptr<renderengine::ExternalTexture> texture) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eBufferChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().externalTexture = texture;
- transactions.back().states.front().state.bufferData =
- std::make_shared<fake::BufferData>(texture->getId(), texture->getWidth(),
- texture->getHeight(), texture->getPixelFormat(),
- texture->getUsage());
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setBuffer(uint32_t id) {
- static uint64_t sBufferId = 1;
- setBuffer(id,
- std::make_shared<renderengine::mock::
- FakeExternalTexture>(1U /*width*/, 1U /*height*/,
- sBufferId++,
- HAL_PIXEL_FORMAT_RGBA_8888,
- GRALLOC_USAGE_PROTECTED /*usage*/));
- }
-
- void setBufferCrop(uint32_t id, const Rect& bufferCrop) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eBufferCropChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.bufferCrop = bufferCrop;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setDamageRegion(uint32_t id, const Region& damageRegion) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eSurfaceDamageRegionChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.surfaceDamageRegion = damageRegion;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setDataspace(uint32_t id, ui::Dataspace dataspace) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eDataspaceChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.dataspace = dataspace;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setMatrix(uint32_t id, float dsdx, float dtdx, float dtdy, float dsdy) {
- layer_state_t::matrix22_t matrix{dsdx, dtdx, dtdy, dsdy};
-
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eMatrixChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.matrix = matrix;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setShadowRadius(uint32_t id, float shadowRadius) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eShadowRadiusChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.shadowRadius = shadowRadius;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setTrustedOverlay(uint32_t id, gui::TrustedOverlay trustedOverlay) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eTrustedOverlayChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.trustedOverlay = trustedOverlay;
- mLifecycleManager.applyTransactions(transactions);
- }
-
- void setDropInputMode(uint32_t id, gui::DropInputMode dropInputMode) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eDropInputModeChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.dropInputMode = dropInputMode;
- mLifecycleManager.applyTransactions(transactions);
- }
-
LayerLifecycleManager mLifecycleManager;
};
@@ -523,21 +100,6 @@
protected:
LayerSnapshotTestBase() : LayerHierarchyTestBase() {}
- void createRootLayer(uint32_t id) override {
- LayerHierarchyTestBase::createRootLayer(id);
- setColor(id);
- }
-
- void createLayer(uint32_t id, uint32_t parentId) override {
- LayerHierarchyTestBase::createLayer(id, parentId);
- setColor(parentId);
- }
-
- void mirrorLayer(uint32_t id, uint32_t parent, uint32_t layerToMirror) override {
- LayerHierarchyTestBase::mirrorLayer(id, parent, layerToMirror);
- setColor(id);
- }
-
void update(LayerSnapshotBuilder& snapshotBuilder) {
mHierarchyBuilder.update(mLifecycleManager);
LayerSnapshotBuilder::Args args{.root = mHierarchyBuilder.getHierarchy(),
diff --git a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
index bc15dec..b4efe0f 100644
--- a/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerLifecycleManagerTest.cpp
@@ -61,18 +61,6 @@
class LayerLifecycleManagerTest : public LayerHierarchyTestBase {
protected:
- std::unique_ptr<RequestedLayerState> rootLayer(uint32_t id) {
- return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/true,
- /*parent=*/UNASSIGNED_LAYER_ID,
- /*mirror=*/UNASSIGNED_LAYER_ID));
- }
-
- std::unique_ptr<RequestedLayerState> childLayer(uint32_t id, uint32_t parentId) {
- return std::make_unique<RequestedLayerState>(createArgs(/*id=*/id, /*canBeRoot=*/false,
- parentId,
- /*mirror=*/UNASSIGNED_LAYER_ID));
- }
-
RequestedLayerState* getRequestedLayerState(LayerLifecycleManager& lifecycleManager,
uint32_t layerId) {
return lifecycleManager.getLayerFromId(layerId);
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 54d4659..2bb864a 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -281,22 +281,40 @@
EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eColorChanged);
}
-TEST_F(LayerSnapshotTest, GameMode) {
- std::vector<TransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
- transactions.back().states.front().state.what = layer_state_t::eMetadataChanged;
- transactions.back().states.front().state.metadata = LayerMetadata();
- transactions.back().states.front().state.metadata.setInt32(METADATA_GAME_MODE, 42);
- transactions.back().states.front().layerId = 1;
- transactions.back().states.front().state.layerId = static_cast<int32_t>(1);
- mLifecycleManager.applyTransactions(transactions);
+TEST_F(LayerSnapshotTest, ChildrenInheritGameMode) {
+ setGameMode(1, gui::GameMode::Performance);
EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
- EXPECT_EQ(static_cast<int32_t>(getSnapshot(1)->gameMode), 42);
- EXPECT_EQ(static_cast<int32_t>(getSnapshot(11)->gameMode), 42);
+ EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+ EXPECT_EQ(getSnapshot(11)->gameMode, gui::GameMode::Performance);
+}
+
+TEST_F(LayerSnapshotTest, ChildrenCanOverrideGameMode) {
+ setGameMode(1, gui::GameMode::Performance);
+ setGameMode(11, gui::GameMode::Battery);
+ EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+ RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
+ EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+ EXPECT_EQ(getSnapshot(11)->gameMode, gui::GameMode::Battery);
+}
+
+TEST_F(LayerSnapshotTest, ReparentingUpdatesGameMode) {
+ setGameMode(1, gui::GameMode::Performance);
+ EXPECT_EQ(mLifecycleManager.getGlobalChanges(),
+ RequestedLayerState::Changes::GameMode | RequestedLayerState::Changes::Metadata);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(1)->clientChanges, layer_state_t::eMetadataChanged);
+ EXPECT_EQ(getSnapshot(1)->gameMode, gui::GameMode::Performance);
+ EXPECT_EQ(getSnapshot(2)->gameMode, gui::GameMode::Unsupported);
+
+ reparentLayer(2, 1);
+ setZ(2, 2);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_EQ(getSnapshot(2)->gameMode, gui::GameMode::Performance);
}
TEST_F(LayerSnapshotTest, UpdateMetadata) {
@@ -1539,4 +1557,48 @@
gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
}
+static constexpr const FloatRect LARGE_FLOAT_RECT{std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::min(),
+ std::numeric_limits<float>::max(),
+ std::numeric_limits<float>::max()};
+TEST_F(LayerSnapshotTest, layerVisibleByDefault) {
+ DisplayInfo info;
+ info.info.logicalHeight = 1000000;
+ info.info.logicalWidth = 1000000;
+ mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
+ EXPECT_FALSE(getSnapshot(1)->isHiddenByPolicy());
+}
+
+TEST_F(LayerSnapshotTest, hideLayerWithZeroMatrix) {
+ DisplayInfo info;
+ info.info.logicalHeight = 1000000;
+ info.info.logicalWidth = 1000000;
+ mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
+ setMatrix(1, 0.f, 0.f, 0.f, 0.f);
+ UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+ EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy());
+}
+
+TEST_F(LayerSnapshotTest, hideLayerWithInfMatrix) {
+ DisplayInfo info;
+ info.info.logicalHeight = 1000000;
+ info.info.logicalWidth = 1000000;
+ mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
+ setMatrix(1, std::numeric_limits<float>::infinity(), 0.f, 0.f,
+ std::numeric_limits<float>::infinity());
+ UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+ EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy());
+}
+
+TEST_F(LayerSnapshotTest, hideLayerWithNanMatrix) {
+ DisplayInfo info;
+ info.info.logicalHeight = 1000000;
+ info.info.logicalWidth = 1000000;
+ mFrontEndDisplayInfos.emplace_or_replace(ui::LayerStack::fromValue(1), info);
+ setMatrix(1, std::numeric_limits<float>::quiet_NaN(), 0.f, 0.f,
+ std::numeric_limits<float>::quiet_NaN());
+ UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+ EXPECT_TRUE(getSnapshot(1)->isHiddenByPolicy());
+}
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/LayerTest.cpp b/services/surfaceflinger/tests/unittests/LayerTest.cpp
deleted file mode 100644
index 95e54f6..0000000
--- a/services/surfaceflinger/tests/unittests/LayerTest.cpp
+++ /dev/null
@@ -1,86 +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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "LibSurfaceFlingerUnittests"
-
-#include <gtest/gtest.h>
-#include <ui/FloatRect.h>
-#include <ui/Transform.h>
-#include <limits>
-
-#include "LayerTestUtils.h"
-#include "TestableSurfaceFlinger.h"
-
-namespace android {
-namespace {
-
-class LayerTest : public BaseLayerTest {
-protected:
- static constexpr const float MIN_FLOAT = std::numeric_limits<float>::min();
- static constexpr const float MAX_FLOAT = std::numeric_limits<float>::max();
- static constexpr const FloatRect LARGE_FLOAT_RECT{MIN_FLOAT, MIN_FLOAT, MAX_FLOAT, MAX_FLOAT};
-};
-
-INSTANTIATE_TEST_SUITE_P(PerLayerType, LayerTest,
- testing::Values(std::make_shared<BufferStateLayerFactory>(),
- std::make_shared<EffectLayerFactory>()),
- PrintToStringParamName);
-
-TEST_P(LayerTest, layerVisibleByDefault) {
- sp<Layer> layer = GetParam()->createLayer(mFlinger);
- layer->updateGeometry();
- layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f);
- ASSERT_FALSE(layer->isHiddenByPolicy());
-}
-
-TEST_P(LayerTest, hideLayerWithZeroMatrix) {
- sp<Layer> layer = GetParam()->createLayer(mFlinger);
-
- layer_state_t::matrix22_t matrix{0, 0, 0, 0};
- layer->setMatrix(matrix);
- layer->updateGeometry();
- layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f);
-
- ASSERT_TRUE(layer->isHiddenByPolicy());
-}
-
-TEST_P(LayerTest, hideLayerWithInfMatrix) {
- sp<Layer> layer = GetParam()->createLayer(mFlinger);
-
- constexpr const float INF = std::numeric_limits<float>::infinity();
- layer_state_t::matrix22_t matrix{INF, 0, 0, INF};
- layer->setMatrix(matrix);
- layer->updateGeometry();
- layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f);
-
- ASSERT_TRUE(layer->isHiddenByPolicy());
-}
-
-TEST_P(LayerTest, hideLayerWithNanMatrix) {
- sp<Layer> layer = GetParam()->createLayer(mFlinger);
-
- constexpr const float QUIET_NAN = std::numeric_limits<float>::quiet_NaN();
- layer_state_t::matrix22_t matrix{QUIET_NAN, 0, 0, QUIET_NAN};
- layer->setMatrix(matrix);
- layer->updateGeometry();
- layer->computeBounds(LARGE_FLOAT_RECT, ui::Transform(), 0.f);
-
- ASSERT_TRUE(layer->isHiddenByPolicy());
-}
-
-} // namespace
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
index e74f643..c879280 100644
--- a/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PowerAdvisorTest.cpp
@@ -706,7 +706,7 @@
testGpuScenario(config, res);
EXPECT_EQ(res.gpuDurationNanos, 0L);
EXPECT_EQ(res.cpuDurationNanos, 0L);
- EXPECT_GE(res.durationNanos, toNanos(30ms + getErrorMargin()));
+ EXPECT_GE(res.durationNanos, toNanos(29ms + getErrorMargin()));
EXPECT_LE(res.durationNanos, toNanos(31ms + getErrorMargin()));
}
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index fc54a8b..3df724a 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -34,6 +34,7 @@
#include "mock/MockSchedulerCallback.h"
#include <FrontEnd/LayerHierarchy.h>
+#include <scheduler/FrameTime.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include "FpsOps.h"
@@ -607,7 +608,8 @@
TimePoint::fromNs(2000)));
// Not crossing the min frame period
- vrrTracker->onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500));
+ vrrTracker->onFrameBegin(TimePoint::fromNs(2000),
+ {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
EXPECT_EQ(Fps::fromPeriodNsecs(1000),
scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
TimePoint::fromNs(2500)));
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 9899d42..4705dd1 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -35,7 +35,7 @@
#include "mock/MockVsyncController.h"
namespace android {
-
+using testing::_;
using testing::DoAll;
using testing::Mock;
using testing::SetArgPointee;
@@ -93,7 +93,7 @@
namespace {
TEST_P(SetFrameRateTest, SetAndGet) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -104,7 +104,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetParent) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -129,7 +129,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetParentAllVote) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -168,7 +168,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetChild) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -193,7 +193,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetChildAllVote) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -232,7 +232,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetChildAddAfterVote) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -262,7 +262,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetChildRemoveAfterVote) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -293,7 +293,7 @@
}
TEST_P(SetFrameRateTest, SetAndGetParentNotInTree) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
@@ -352,7 +352,7 @@
}
TEST_P(SetFrameRateTest, addChildForParentWithTreeVote) {
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
const auto& layerFactory = GetParam();
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
index ff7612e..d638024 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_ColorMatrixTest.cpp
@@ -28,7 +28,6 @@
class ColorMatrixTest : public CommitAndCompositeTest {};
TEST_F(ColorMatrixTest, colorMatrixChanged) {
- mFlinger.enableLayerLifecycleManager();
EXPECT_COLOR_MATRIX_CHANGED(true, true);
mFlinger.mutableTransactionFlags() |= eTransactionNeeded;
@@ -46,7 +45,6 @@
}
TEST_F(ColorMatrixTest, colorMatrixChangedAfterDisplayTransaction) {
- mFlinger.enableLayerLifecycleManager();
EXPECT_COLOR_MATRIX_CHANGED(true, true);
mFlinger.mutableTransactionFlags() |= eTransactionNeeded;
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index e5f2a91..2d3ebb4 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -97,7 +97,7 @@
// Cleanup conditions
// Creating the display commits a display transaction.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
}
TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForSecureDisplay) {
@@ -129,7 +129,7 @@
// Cleanup conditions
// Creating the display commits a display transaction.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
}
TEST_F(CreateDisplayTest, createDisplaySetsCurrentStateForUniqueId) {
@@ -159,7 +159,7 @@
// Cleanup conditions
// Creating the display commits a display transaction.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
}
// Requesting 0 tells SF not to do anything, i.e., default to refresh as physical displays
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
index f8ad8e1..df8f68f 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DestroyDisplayTest.cpp
@@ -38,7 +38,7 @@
// Call Expectations
// Destroying the display commits a display transaction.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
// --------------------------------------------------------------------
// Invocation
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
index b620830..9bf344c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
@@ -265,6 +265,13 @@
processesHotplugConnectCommon<SimpleExternalDisplayCase>();
}
+TEST_F(DisplayTransactionCommitTest, processesHotplugConnectNonSecureExternalDisplay) {
+ // Inject a primary display.
+ PrimaryDisplayVariant::injectHwcDisplay(this);
+
+ processesHotplugConnectCommon<SimpleExternalDisplayNonSecureCase>();
+}
+
TEST_F(DisplayTransactionCommitTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
// Inject both a primary and external display.
PrimaryDisplayVariant::injectHwcDisplay(this);
@@ -273,13 +280,29 @@
// TODO: This is an unnecessary call.
EXPECT_CALL(*mComposer,
getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
- .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
- SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
+ .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
+ SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
Return(Error::NONE)));
ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
}
+TEST_F(DisplayTransactionCommitTest,
+ ignoresHotplugConnectNonSecureIfPrimaryAndExternalAlreadyConnected) {
+ // Inject both a primary and external display.
+ PrimaryDisplayVariant::injectHwcDisplay(this);
+ ExternalDisplayVariant::injectHwcDisplay(this);
+
+ // TODO: This is an unnecessary call.
+ EXPECT_CALL(*mComposer,
+ getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
+ .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay<kSecure>::PORT),
+ SetArgPointee<2>(TertiaryDisplay<kSecure>::GET_IDENTIFICATION_DATA()),
+ Return(Error::NONE)));
+
+ ignoresHotplugConnectCommon<SimpleTertiaryDisplayNonSecureCase>();
+}
+
TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectPrimaryDisplay) {
EXPECT_EXIT(processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>(),
testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
@@ -289,6 +312,10 @@
processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
}
+TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectNonSecureExternalDisplay) {
+ processesHotplugDisconnectCommon<SimpleExternalDisplayNonSecureCase>();
+}
+
TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimary) {
EXPECT_EXIT(
[this] {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
index 897f9a0..aef467a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
@@ -48,7 +48,7 @@
TEST_F(HotplugTest, schedulesFrameToCommitDisplayTransaction) {
EXPECT_CALL(*mFlinger.scheduler(), scheduleConfigure()).Times(1);
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
constexpr HWDisplayId displayId1 = 456;
mFlinger.onComposerHalHotplugEvent(displayId1, DisplayHotplugEvent::DISCONNECTED);
@@ -73,7 +73,7 @@
.WillOnce(Return(Error::NONE));
// A single commit should be scheduled for both configure calls.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED);
mFlinger.configure();
@@ -116,7 +116,7 @@
setVsyncEnabled(ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
.WillOnce(Return(Error::NONE));
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
ExternalDisplay::injectPendingHotplugEvent(this, Connection::CONNECTED);
mFlinger.configure();
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
index eaf4684..5231965 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_InitializeDisplaysTest.cpp
@@ -28,7 +28,7 @@
TEST_F(InitializeDisplaysTest, initializesDisplays) {
// Scheduled by the display transaction, and by powering on each display.
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(3);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(3);
EXPECT_CALL(static_cast<mock::VSyncTracker&>(
mFlinger.scheduler()->getVsyncSchedule()->getTracker()),
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index 83e2f98..fed7b2e 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -271,7 +271,7 @@
}
static void setupRepaintEverythingCallExpectations(DisplayTransactionTest* test) {
- EXPECT_CALL(*test->mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*test->mFlinger.scheduler(), scheduleFrame(_)).Times(1);
}
static void setupComposerCallExpectations(DisplayTransactionTest* test, PowerMode mode) {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp
deleted file mode 100644
index 0e5f1ea..0000000
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_UpdateLayerMetadataSnapshotTest.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <gui/LayerMetadata.h>
-
-#include "TestableSurfaceFlinger.h"
-
-namespace android {
-
-using testing::_;
-using testing::Return;
-
-class SurfaceFlingerUpdateLayerMetadataSnapshotTest : public testing::Test {
-public:
- SurfaceFlingerUpdateLayerMetadataSnapshotTest() { mFlinger.setupMockScheduler(); }
-
-protected:
- sp<Layer> createLayer(const char* name, LayerMetadata& inOutlayerMetadata) {
- LayerCreationArgs args =
- LayerCreationArgs{mFlinger.flinger(), nullptr, name, 0, inOutlayerMetadata};
- inOutlayerMetadata = args.metadata;
- return sp<Layer>::make(args);
- }
-
- TestableSurfaceFlinger mFlinger;
-};
-
-class LayerMetadataBuilder {
-public:
- LayerMetadataBuilder(LayerMetadata layerMetadata = {}) : mLayerMetadata(layerMetadata) {}
-
- LayerMetadataBuilder& setInt32(uint32_t key, int32_t value) {
- mLayerMetadata.setInt32(key, value);
- return *this;
- }
-
- LayerMetadata build() { return mLayerMetadata; }
-
-private:
- LayerMetadata mLayerMetadata;
-};
-
-bool operator==(const LayerMetadata& lhs, const LayerMetadata& rhs) {
- return lhs.mMap == rhs.mMap;
-}
-
-std::ostream& operator<<(std::ostream& stream, const LayerMetadata& layerMetadata) {
- stream << "LayerMetadata{";
- for (auto it = layerMetadata.mMap.cbegin(); it != layerMetadata.mMap.cend(); it++) {
- if (it != layerMetadata.mMap.cbegin()) {
- stream << ", ";
- }
- stream << layerMetadata.itemToString(it->first, ":");
- }
- return stream << "}";
-}
-
-// Test that the snapshot's layer metadata is set.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesSnapshotMetadata) {
- auto layerMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
- auto layer = createLayer("layer", layerMetadata);
- mFlinger.mutableDrawingState().layersSortedByZ.add(layer);
-
- mFlinger.updateLayerMetadataSnapshot();
-
- EXPECT_EQ(layer->getLayerSnapshot()->layerMetadata, layerMetadata);
-}
-
-// Test that snapshot layer metadata is set by merging the child's metadata on top of its
-// parent's metadata.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, mergesSnapshotMetadata) {
- auto layerAMetadata = LayerMetadataBuilder()
- .setInt32(METADATA_OWNER_UID, 1)
- .setInt32(METADATA_TASK_ID, 2)
- .build();
- auto layerA = createLayer("parent", layerAMetadata);
- auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 3).build();
- auto layerB = createLayer("child", layerBMetadata);
- layerA->addChild(layerB);
- layerA->commitChildList();
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-
- mFlinger.updateLayerMetadataSnapshot();
-
- EXPECT_EQ(layerA->getLayerSnapshot()->layerMetadata, layerAMetadata);
- auto expectedChildMetadata =
- LayerMetadataBuilder(layerAMetadata).setInt32(METADATA_TASK_ID, 3).build();
- EXPECT_EQ(layerB->getLayerSnapshot()->layerMetadata, expectedChildMetadata);
-}
-
-// Test that snapshot relative layer metadata is set to the parent's layer metadata merged on top of
-// that parent's relative layer metadata.
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadata) {
- auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 1).build();
- auto layerA = createLayer("relative-parent", layerAMetadata);
- auto layerAHandle = layerA->getHandle();
- auto layerBMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 2).build();
- auto layerB = createLayer("relative-child", layerBMetadata);
- layerB->setRelativeLayer(layerAHandle, 1);
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
-
- mFlinger.updateLayerMetadataSnapshot();
-
- EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
- EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
-}
-
-// Test that snapshot relative layer metadata is set correctly when a layer is interleaved within
-// two other layers.
-//
-// Layer
-// A
-// / \
-// B D
-// /
-// C
-//
-// Z-order Relatives
-// B <- D <- C
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest, updatesRelativeMetadataInterleaved) {
- auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
- auto layerA = createLayer("layer-a", layerAMetadata);
- auto layerBMetadata = LayerMetadataBuilder()
- .setInt32(METADATA_TASK_ID, 2)
- .setInt32(METADATA_OWNER_PID, 3)
- .build();
- auto layerB = createLayer("layer-b", layerBMetadata);
- auto layerBHandle = layerB->getHandle();
- LayerMetadata layerCMetadata;
- auto layerC = createLayer("layer-c", layerCMetadata);
- auto layerDMetadata = LayerMetadataBuilder().setInt32(METADATA_TASK_ID, 4).build();
- auto layerD = createLayer("layer-d", layerDMetadata);
- auto layerDHandle = layerD->getHandle();
- layerB->addChild(layerC);
- layerA->addChild(layerB);
- layerA->addChild(layerD);
- layerC->setRelativeLayer(layerDHandle, 1);
- layerD->setRelativeLayer(layerBHandle, 1);
- layerA->commitChildList();
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
-
- mFlinger.updateLayerMetadataSnapshot();
-
- auto expectedLayerDRelativeMetadata =
- LayerMetadataBuilder()
- // From layer A, parent of relative parent
- .setInt32(METADATA_OWNER_UID, 1)
- // From layer B, relative parent
- .setInt32(METADATA_TASK_ID, 2)
- .setInt32(METADATA_OWNER_PID, 3)
- // added by layer creation args
- .setInt32(gui::METADATA_CALLING_UID,
- layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
- .build();
- EXPECT_EQ(layerD->getLayerSnapshot()->relativeLayerMetadata, expectedLayerDRelativeMetadata);
- auto expectedLayerCRelativeMetadata =
- LayerMetadataBuilder()
- // From layer A, parent of relative parent
- .setInt32(METADATA_OWNER_UID, 1)
- // From layer B, relative parent of relative parent
- .setInt32(METADATA_OWNER_PID, 3)
- // From layer D, relative parent
- .setInt32(METADATA_TASK_ID, 4)
- // added by layer creation args
- .setInt32(gui::METADATA_CALLING_UID,
- layerDMetadata.getInt32(gui::METADATA_CALLING_UID, 0))
- .build();
- EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, expectedLayerCRelativeMetadata);
-}
-
-TEST_F(SurfaceFlingerUpdateLayerMetadataSnapshotTest,
- updatesRelativeMetadataMultipleRelativeChildren) {
- auto layerAMetadata = LayerMetadataBuilder().setInt32(METADATA_OWNER_UID, 1).build();
- auto layerA = createLayer("layer-a", layerAMetadata);
- auto layerAHandle = layerA->getHandle();
- LayerMetadata layerBMetadata;
- auto layerB = createLayer("layer-b", layerBMetadata);
- LayerMetadata layerCMetadata;
- auto layerC = createLayer("layer-c", layerCMetadata);
- layerB->setRelativeLayer(layerAHandle, 1);
- layerC->setRelativeLayer(layerAHandle, 2);
- layerA->commitChildList();
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerA);
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerB);
- mFlinger.mutableDrawingState().layersSortedByZ.add(layerC);
-
- mFlinger.updateLayerMetadataSnapshot();
-
- EXPECT_EQ(layerA->getLayerSnapshot()->relativeLayerMetadata, LayerMetadata{});
- EXPECT_EQ(layerB->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
- EXPECT_EQ(layerC->getLayerSnapshot()->relativeLayerMetadata, layerAMetadata);
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index f063809..0814e3d 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -62,7 +62,7 @@
}
MOCK_METHOD(void, scheduleConfigure, (), (override));
- MOCK_METHOD(void, scheduleFrame, (), (override));
+ MOCK_METHOD(void, scheduleFrame, (Duration), (override));
MOCK_METHOD(void, postMessage, (sp<MessageHandler>&&), (override));
void doFrameSignal(ICompositor& compositor, VsyncId vsyncId) {
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index b5b36be..a6a2758 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -326,9 +326,13 @@
auto& mutableStateLock() { return mFlinger->mStateLock; }
- static auto findOutputLayerForDisplay(const sp<Layer>& layer,
- const sp<const DisplayDevice>& display) {
- return layer->findOutputLayerForDisplay(display.get());
+ compositionengine::OutputLayer* findOutputLayerForDisplay(
+ uint32_t layerId, const sp<const DisplayDevice>& display) {
+ ftl::FakeGuard guard(kMainThreadContext);
+ if (mFlinger->mLegacyLayers.find(layerId) == mFlinger->mLegacyLayers.end()) {
+ return nullptr;
+ }
+ return mFlinger->mLegacyLayers[layerId]->findOutputLayerForDisplay(display.get());
}
static void setLayerSidebandStream(const sp<Layer>& layer,
@@ -340,17 +344,14 @@
void setLayerCompositionType(const sp<Layer>& layer,
aidl::android::hardware::graphics::composer3::Composition type) {
- auto outputLayer = findOutputLayerForDisplay(layer, mFlinger->getDefaultDisplayDevice());
+ auto outputLayer = findOutputLayerForDisplay(static_cast<uint32_t>(layer->sequence),
+ mFlinger->getDefaultDisplayDevice());
LOG_ALWAYS_FATAL_IF(!outputLayer);
auto& state = outputLayer->editState();
LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc);
(*state.hwc).hwcCompositionType = type;
}
- static void setLayerPotentialCursor(const sp<Layer>& layer, bool potentialCursor) {
- layer->mPotentialCursor = potentialCursor;
- }
-
static void setLayerDrawingParent(const sp<Layer>& layer, const sp<Layer>& drawingParent) {
layer->mDrawingParent = drawingParent;
}
@@ -395,7 +396,7 @@
targets.try_emplace(id, &frameTargeter.target());
targeters.try_emplace(id, &frameTargeter);
}
-
+ mFlinger->setTransactionFlags(eTransactionFlushNeeded);
mFlinger->commit(displayId, targets);
if (composite) {
@@ -505,10 +506,9 @@
captureResults, displayState, layers, layerFEs);
}
- auto traverseLayersInLayerStack(ui::LayerStack layerStack, int32_t uid,
- std::unordered_set<uint32_t> excludeLayerIds,
- const LayerVector::Visitor& visitor) {
- return mFlinger->traverseLayersInLayerStack(layerStack, uid, excludeLayerIds, visitor);
+ auto getLayerSnapshotsForScreenshotsFn(ui::LayerStack layerStack, uint32_t uid) {
+ return mFlinger->getLayerSnapshotsForScreenshots(layerStack, uid,
+ std::unordered_set<uint32_t>{});
}
auto getDisplayNativePrimaries(const sp<IBinder>& displayToken,
@@ -584,8 +584,6 @@
return mFlinger->mirrorLayer(args, mirrorFromHandle, outResult);
}
- void updateLayerMetadataSnapshot() { mFlinger->updateLayerMetadataSnapshot(); }
-
void getDynamicDisplayInfoFromToken(const sp<IBinder>& displayToken,
ui::DynamicDisplayInfo* dynamicDisplayInfo) {
mFlinger->getDynamicDisplayInfoFromToken(displayToken, dynamicDisplayInfo);
@@ -620,6 +618,18 @@
mFlinger->mNewLayers.emplace_back(std::move(layer));
}
+ // Used to add a layer before updateLayerSnapshots is called.
+ // Must have transactionsFlushed enabled for the new layer to be updated.
+ void addLayer(uint32_t layerId) {
+ std::scoped_lock<std::mutex> lock(mFlinger->mCreatedLayersLock);
+ LayerCreationArgs args(std::make_optional(layerId));
+ args.flinger = this->mFlinger.get();
+ auto layer = std::make_unique<frontend::RequestedLayerState>(args);
+ auto legacyLayer = sp<Layer>::make(args);
+ injectLegacyLayer(legacyLayer);
+ mFlinger->mNewLayers.emplace_back(std::move(layer));
+ }
+
/* ------------------------------------------------------------------------
* Read-only access to private data to assert post-conditions.
*/
@@ -637,12 +647,24 @@
void injectLegacyLayer(sp<Layer> layer) {
FTL_FAKE_GUARD(kMainThreadContext,
mFlinger->mLegacyLayers[static_cast<uint32_t>(layer->sequence)] = layer);
- };
+ }
void releaseLegacyLayer(uint32_t sequence) {
FTL_FAKE_GUARD(kMainThreadContext, mFlinger->mLegacyLayers.erase(sequence));
+ }
+
+ auto getLegacyLayer(uint32_t layerId) {
+ ftl::FakeGuard guard(kMainThreadContext);
+ return mFlinger->mLegacyLayers[layerId];
};
+ void destroyAllLayerHandles() {
+ ftl::FakeGuard guard(kMainThreadContext);
+ for (auto [layerId, legacyLayer] : mFlinger->mLegacyLayers) {
+ mFlinger->onHandleDestroyed(nullptr, legacyLayer, layerId);
+ }
+ }
+
auto setLayerHistoryDisplayArea(uint32_t displayArea) {
return mFlinger->mScheduler->onActiveDisplayAreaChanged(displayArea);
};
@@ -709,10 +731,6 @@
return mFlinger->initTransactionTraceWriter();
}
- // Needed since mLayerLifecycleManagerEnabled is false by default and must
- // be enabled for tests to go through the new front end path.
- void enableLayerLifecycleManager() { mFlinger->mLayerLifecycleManagerEnabled = true; }
-
void notifyExpectedPresentIfRequired(PhysicalDisplayId displayId, Period vsyncPeriod,
TimePoint expectedPresentTime, Fps frameInterval,
std::optional<Period> timeoutOpt) {
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 7fb9247..fab1f6d 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -17,6 +17,7 @@
#undef LOG_TAG
#define LOG_TAG "TransactionApplicationTest"
+#include <binder/Binder.h>
#include <common/test/FlagUtils.h>
#include <compositionengine/Display.h>
#include <compositionengine/mock/DisplaySurface.h>
@@ -26,10 +27,10 @@
#include <gui/SurfaceComposerClient.h>
#include <gui/fake/BufferData.h>
#include <log/log.h>
+#include <renderengine/mock/RenderEngine.h>
#include <ui/MockFence.h>
#include <utils/String8.h>
#include <vector>
-#include <binder/Binder.h>
#include "FrontEnd/TransactionHandler.h"
#include "TestableSurfaceFlinger.h"
@@ -55,6 +56,7 @@
mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
mFlinger.setupMockScheduler();
+ mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
mFlinger.flinger()->addTransactionReadyFilters();
}
@@ -65,6 +67,7 @@
}
TestableSurfaceFlinger mFlinger;
+ renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
struct TransactionInfo {
Vector<ComposerState> states;
@@ -102,7 +105,7 @@
void NotPlacedOnTransactionQueue(uint32_t flags) {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
TransactionInfo transaction;
setupSingle(transaction, flags,
/*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
@@ -126,7 +129,7 @@
void PlaceOnTransactionQueue(uint32_t flags) {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
// first check will see desired present time has not passed,
// but afterwards it will look like the desired present time has passed
@@ -152,7 +155,7 @@
void BlockedByPriorTransaction(uint32_t flags) {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
nsecs_t time = systemTime();
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(2);
// transaction that should go on the pending thread
TransactionInfo transactionA;
@@ -214,7 +217,7 @@
TEST_F(TransactionApplicationTest, AddToPendingQueue) {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
@@ -235,7 +238,7 @@
TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
- EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
@@ -323,15 +326,17 @@
transaction1.states[0].state.bufferData =
std::make_shared<fake::BufferData>(/* bufferId */ 1, /* width */ 1, /* height */ 1,
/* pixelFormat */ 0, /* outUsage */ 0);
+ mFlinger.addLayer(1);
+ bool out;
+ mFlinger.updateLayerSnapshots(VsyncId{1}, 0, /* transactionsFlushed */ true, out);
transaction1.states[0].externalTexture =
std::make_shared<FakeExternalTexture>(*transaction1.states[0].state.bufferData);
- transaction1.states[0].state.surface =
- sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
- ->getHandle();
+ transaction1.states[0].state.surface = mFlinger.getLegacyLayer(1)->getHandle();
auto fence = sp<mock::MockFence>::make();
EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(Fence::Status::Unsignaled));
transaction1.states[0].state.bufferData->acquireFence = std::move(fence);
transaction1.states[0].state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
+ transaction1.states[0].layerId = 1;
transaction1.isAutoTimestamp = true;
// Transaction 2 should be ready to be applied.
@@ -361,8 +366,7 @@
}
mFlinger.getPendingTransactionQueue().clear();
mFlinger.commitTransactionsLocked(eTransactionMask);
- mFlinger.mutableCurrentState().layersSortedByZ.clear();
- mFlinger.mutableDrawingState().layersSortedByZ.clear();
+ mFlinger.destroyAllLayerHandles();
}
static sp<Fence> fence(Fence::Status status) {
@@ -371,8 +375,7 @@
return fence;
}
- ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
- std::optional<sp<IBinder>> layerHandle = std::nullopt) {
+ ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what) {
ComposerState state;
state.state.bufferData =
std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
@@ -380,9 +383,6 @@
/* outUsage */ 0);
state.state.bufferData->acquireFence = std::move(fence);
state.state.layerId = layerId;
- state.state.surface = layerHandle.value_or(
- sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
- ->getHandle());
state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
state.state.what = what;
@@ -418,6 +418,19 @@
size_t expectedTransactionsPending) {
EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
+ std::unordered_set<uint32_t> createdLayers;
+ for (auto transaction : transactions) {
+ for (auto& state : transaction.states) {
+ auto layerId = static_cast<uint32_t>(state.state.layerId);
+ if (createdLayers.find(layerId) == createdLayers.end()) {
+ mFlinger.addLayer(layerId);
+ createdLayers.insert(layerId);
+ }
+ }
+ }
+ bool unused;
+ bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
+ /*transactionsFlushed=*/true, unused);
for (auto transaction : transactions) {
std::vector<ResolvedComposerState> resolvedStates;
@@ -427,6 +440,9 @@
resolvedState.state = std::move(state.state);
resolvedState.externalTexture =
std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
+ resolvedState.layerId = static_cast<uint32_t>(state.state.layerId);
+ resolvedState.state.surface =
+ mFlinger.getLegacyLayer(resolvedState.layerId)->getHandle();
resolvedStates.emplace_back(resolvedState);
}
@@ -458,9 +474,8 @@
TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
const sp<IBinder> kApplyToken =
IInterface::asBinder(TransactionCompletedListener::getIInstance());
- const auto kLayerId = 1;
+ const auto kLayerId = 10;
const auto kExpectedTransactionsPending = 0u;
-
const auto signaledTransaction =
createTransactionInfo(kApplyToken,
{createComposerState(kLayerId, fence(Fence::Status::Signaled),
@@ -773,7 +788,7 @@
TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
const sp<IBinder> kApplyToken =
IInterface::asBinder(TransactionCompletedListener::getIInstance());
- const auto kLayerId = 1;
+ const auto kLayerId = 10;
const auto kExpectedTransactionsPending = 0u;
const auto signaledTransaction =
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index 85b61f8..abfab9a 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -94,7 +94,7 @@
HAL_PIXEL_FORMAT_RGBA_8888,
0ULL /*usage*/);
layer->setBuffer(externalTexture, bufferData, postTime, /*desiredPresentTime*/ 30, false,
- FrameTimelineInfo{});
+ FrameTimelineInfo{}, gui::GameMode::Unsupported);
commitTransaction(layer.get());
nsecs_t latchTime = 25;
@@ -112,7 +112,8 @@
EXPECT_CALL(*mFlinger.getFrameTracer(),
traceFence(layerId, bufferId, frameNumber, presentFence,
FrameTracer::FrameEvent::PRESENT_FENCE, /*startTime*/ 0));
- layer->onCompositionPresented(nullptr, glDoneFence, presentFence, compositorTiming);
+ layer->onCompositionPresented(nullptr, glDoneFence, presentFence, compositorTiming,
+ gui::GameMode::Unsupported);
}
};
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index 0745f87..9a68d75 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -72,7 +72,8 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+ gui::GameMode::Unsupported);
EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_TRUE(layer->mDrawingState.bufferSurfaceFrameTX == nullptr);
const auto surfaceFrame = layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1);
@@ -99,7 +100,8 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
acquireFence->signalForTest(12);
commitTransaction(layer.get());
@@ -134,7 +136,8 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -151,7 +154,8 @@
2ULL /* bufferId */,
HAL_PIXEL_FORMAT_RGBA_8888,
0ULL /*usage*/);
- layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
nsecs_t end = systemTime();
acquireFence2->signalForTest(12);
@@ -180,7 +184,8 @@
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+ gui::GameMode::Unsupported);
EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
@@ -197,7 +202,8 @@
1ULL /* bufferId */,
HAL_PIXEL_FORMAT_RGBA_8888,
0ULL /*usage*/);
- layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
acquireFence->signalForTest(12);
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
@@ -232,11 +238,13 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+ gui::GameMode::Unsupported);
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
}
@@ -246,7 +254,8 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo, 10,
+ gui::GameMode::Unsupported);
EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto bufferlessSurfaceFrame1 =
@@ -255,7 +264,8 @@
FrameTimelineInfo ftInfo2;
ftInfo2.vsyncId = 4;
ftInfo2.inputEventId = 0;
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10,
+ gui::GameMode::Unsupported);
EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto bufferlessSurfaceFrame2 = layer->mDrawingState.bufferlessSurfaceFramesTX[4];
@@ -275,7 +285,8 @@
FrameTimelineInfo ftInfo3;
ftInfo3.vsyncId = 3;
ftInfo3.inputEventId = 0;
- layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo3);
+ layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo3,
+ gui::GameMode::Unsupported);
EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto bufferSurfaceFrameTX = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -320,7 +331,8 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture1, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
const auto droppedSurfaceFrame1 = layer->mDrawingState.bufferSurfaceFrameTX;
@@ -340,7 +352,8 @@
FrameTimelineInfo ftInfoInv;
ftInfoInv.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
ftInfoInv.inputEventId = 0;
- layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfoInv);
+ layer->setBuffer(externalTexture2, bufferData, 10, 20, false, ftInfoInv,
+ gui::GameMode::Unsupported);
auto dropEndTime1 = systemTime();
EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
@@ -361,7 +374,8 @@
FrameTimelineInfo ftInfo2;
ftInfo2.vsyncId = 2;
ftInfo2.inputEventId = 0;
- layer->setBuffer(externalTexture3, bufferData, 10, 20, false, ftInfo2);
+ layer->setBuffer(externalTexture3, bufferData, 10, 20, false, ftInfo2,
+ gui::GameMode::Unsupported);
auto dropEndTime2 = systemTime();
acquireFence3->signalForTest(12);
@@ -409,11 +423,13 @@
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
- layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo);
+ layer->setBuffer(externalTexture, bufferData, 10, 20, false, ftInfo,
+ gui::GameMode::Unsupported);
FrameTimelineInfo ftInfo2;
ftInfo2.vsyncId = 2;
ftInfo2.inputEventId = 0;
- layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10);
+ layer->setFrameTimelineVsyncForBufferlessTransaction(ftInfo2, 10,
+ gui::GameMode::Unsupported);
ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX);
EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size());
diff --git a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
index 1cf14ae..9f6065b 100644
--- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
@@ -127,7 +127,7 @@
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
- layer->setSidebandStream(stream, FrameTimelineInfo{}, 20);
+ layer->setSidebandStream(stream, FrameTimelineInfo{}, 20, gui::GameMode::Unsupported);
mFlinger.mutableCurrentState().layersSortedByZ.add(layer);
mTunnelModeEnabledReporter->updateTunnelModeStatus();
mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener);
@@ -151,7 +151,8 @@
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
- layerWithSidebandStream->setSidebandStream(stream, FrameTimelineInfo{}, 20);
+ layerWithSidebandStream->setSidebandStream(stream, FrameTimelineInfo{}, 20,
+ gui::GameMode::Unsupported);
mFlinger.mutableCurrentState().layersSortedByZ.add(simpleLayer);
mFlinger.mutableCurrentState().layersSortedByZ.add(layerWithSidebandStream);
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
index 3b09554..b63f299 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchRealtimeTest.cpp
@@ -19,6 +19,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <scheduler/FrameTime.h>
#include <scheduler/Timer.h>
#include "Scheduler/VSyncDispatchTimerQueue.h"
@@ -51,7 +52,7 @@
bool isVSyncInPhase(nsecs_t, Fps) final { return false; }
void setDisplayModePtr(ftl::NonNull<DisplayModePtr>) final {}
void setRenderRate(Fps, bool) final {}
- void onFrameBegin(TimePoint, TimePoint) final {}
+ void onFrameBegin(TimePoint, scheduler::FrameTime) final {}
void onFrameMissed(TimePoint) final {}
void dump(std::string&) const final {}
bool isCurrentMode(const ftl::NonNull<DisplayModePtr>&) const final { return false; };
diff --git a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
index f36a8a6..7c678bd 100644
--- a/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncPredictorTest.cpp
@@ -901,17 +901,20 @@
EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000));
- vrrTracker.onFrameBegin(TimePoint::fromNs(2000), TimePoint::fromNs(1500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(2000),
+ {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
EXPECT_EQ(3500, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 2000));
EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(3500, 3500));
// Miss when starting 4500 and expect the next vsync will be at 5000 (next one)
- vrrTracker.onFrameBegin(TimePoint::fromNs(3500), TimePoint::fromNs(2500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(3500),
+ {TimePoint::fromNs(2500), TimePoint::fromNs(2500)});
vrrTracker.onFrameMissed(TimePoint::fromNs(4500));
EXPECT_EQ(5000, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500));
EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000));
- vrrTracker.onFrameBegin(TimePoint::fromNs(7000), TimePoint::fromNs(6500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(7000),
+ {TimePoint::fromNs(6500), TimePoint::fromNs(6500)});
EXPECT_EQ(10500, vrrTracker.nextAnticipatedVSyncTimeFrom(9000, 7000));
}
@@ -943,7 +946,7 @@
// SF starts to catch up
EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2700));
- vrrTracker.onFrameBegin(TimePoint::fromNs(3000), TimePoint::fromNs(0));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(3000), {TimePoint::fromNs(0), TimePoint::fromNs(0)});
// SF misses last frame (3000) and observes that when committing (4000)
EXPECT_EQ(6000, vrrTracker.nextAnticipatedVSyncTimeFrom(5000, 5000));
@@ -952,17 +955,20 @@
// SF wakes up again instead of the (4000) missed frame
EXPECT_EQ(4500, vrrTracker.nextAnticipatedVSyncTimeFrom(4000, 4000));
- vrrTracker.onFrameBegin(TimePoint::fromNs(4500), TimePoint::fromNs(4500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(4500),
+ {TimePoint::fromNs(4500), TimePoint::fromNs(4500)});
// Timeline shifted. The app needs to get the next frame at (7500) as its last frame (6500) will
// be presented at (7500)
EXPECT_EQ(7500, vrrTracker.nextAnticipatedVSyncTimeFrom(6000, 6000));
EXPECT_EQ(5500, vrrTracker.nextAnticipatedVSyncTimeFrom(4500, 4500));
- vrrTracker.onFrameBegin(TimePoint::fromNs(5500), TimePoint::fromNs(4500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(5500),
+ {TimePoint::fromNs(4500), TimePoint::fromNs(4500)});
EXPECT_EQ(8500, vrrTracker.nextAnticipatedVSyncTimeFrom(7500, 7500));
EXPECT_EQ(6500, vrrTracker.nextAnticipatedVSyncTimeFrom(5500, 5500));
- vrrTracker.onFrameBegin(TimePoint::fromNs(6500), TimePoint::fromNs(5500));
+ vrrTracker.onFrameBegin(TimePoint::fromNs(6500),
+ {TimePoint::fromNs(5500), TimePoint::fromNs(5500)});
}
TEST_F(VSyncPredictorTest, renderRateIsPreservedForCommittedVsyncs) {
@@ -1020,6 +1026,65 @@
EXPECT_THAT(tracker.nextAnticipatedVSyncTimeFrom(9001), Eq(13000));
}
+TEST_F(VSyncPredictorTest, timelineNotAdjustedForEarlyPresent) {
+ SET_FLAG_FOR_TEST(flags::vrr_config, true);
+
+ const int32_t kGroup = 0;
+ const auto kResolution = ui::Size(1920, 1080);
+ const auto refreshRate = Fps::fromPeriodNsecs(500);
+ const auto minFrameRate = Fps::fromPeriodNsecs(1000);
+ hal::VrrConfig vrrConfig;
+ vrrConfig.minFrameIntervalNs = minFrameRate.getPeriodNsecs();
+ const ftl::NonNull<DisplayModePtr> kMode =
+ ftl::as_non_null(createDisplayModeBuilder(DisplayModeId(0), refreshRate, kGroup,
+ kResolution, DEFAULT_DISPLAY_ID)
+ .setVrrConfig(std::move(vrrConfig))
+ .build());
+
+ VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), kMode, kHistorySize,
+ kMinimumSamplesForPrediction, kOutlierTolerancePercent};
+
+ vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ false);
+ vrrTracker.addVsyncTimestamp(0);
+ EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
+
+ constexpr auto kLastConfirmedExpectedPresentTime = TimePoint::fromNs(1000);
+ constexpr auto kLastActualSignalTime = TimePoint::fromNs(700); // presented early
+ vrrTracker.onFrameBegin(TimePoint::fromNs(1400),
+ {kLastActualSignalTime, kLastConfirmedExpectedPresentTime});
+ EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1400, 1000));
+ EXPECT_EQ(3000, vrrTracker.nextAnticipatedVSyncTimeFrom(2000, 1000));
+}
+
+TEST_F(VSyncPredictorTest, adjustsOnlyMinFrameViolatingVrrTimeline) {
+ const auto refreshRate = Fps::fromPeriodNsecs(500);
+ auto minFrameRate = Fps::fromPeriodNsecs(1000);
+ hal::VrrConfig vrrConfig{.minFrameIntervalNs =
+ static_cast<int32_t>(minFrameRate.getPeriodNsecs())};
+ ftl::NonNull<DisplayModePtr> mode =
+ ftl::as_non_null(createVrrDisplayMode(DisplayModeId(0), refreshRate, vrrConfig));
+ VSyncPredictor vrrTracker{std::make_unique<ClockWrapper>(mClock), mode, kHistorySize,
+ kMinimumSamplesForPrediction, kOutlierTolerancePercent};
+ vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ false);
+ vrrTracker.addVsyncTimestamp(0);
+
+ EXPECT_EQ(1000, vrrTracker.nextAnticipatedVSyncTimeFrom(700));
+ EXPECT_EQ(2000, vrrTracker.nextAnticipatedVSyncTimeFrom(1000));
+ auto lastConfirmedSignalTime = TimePoint::fromNs(1500);
+ auto lastConfirmedExpectedPresentTime = TimePoint::fromNs(1000);
+ vrrTracker.onFrameBegin(TimePoint::fromNs(2000),
+ {lastConfirmedSignalTime, lastConfirmedExpectedPresentTime});
+ EXPECT_EQ(3500, vrrTracker.nextAnticipatedVSyncTimeFrom(3000, 1500));
+
+ minFrameRate = Fps::fromPeriodNsecs(2000);
+ vrrTracker.setRenderRate(minFrameRate, /*applyImmediately*/ false);
+ lastConfirmedSignalTime = TimePoint::fromNs(2500);
+ lastConfirmedExpectedPresentTime = TimePoint::fromNs(2500);
+ vrrTracker.onFrameBegin(TimePoint::fromNs(3000),
+ {lastConfirmedSignalTime, lastConfirmedExpectedPresentTime});
+ // Enough time without adjusting vsync to present with new rate on time, no need of adjustment
+ EXPECT_EQ(5500, vrrTracker.nextAnticipatedVSyncTimeFrom(4000, 3500));
+}
} // namespace android::scheduler
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
index dec5fa5..d45cc66 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSchedulerCallback.h
@@ -26,21 +26,21 @@
MOCK_METHOD(void, requestHardwareVsync, (PhysicalDisplayId, bool), (override));
MOCK_METHOD(void, requestDisplayModes, (std::vector<display::DisplayModeRequest>), (override));
MOCK_METHOD(void, kernelTimerChanged, (bool), (override));
- MOCK_METHOD(void, triggerOnFrameRateOverridesChanged, (), (override));
MOCK_METHOD(void, onChoreographerAttached, (), (override));
MOCK_METHOD(void, onExpectedPresentTimePosted, (TimePoint, ftl::NonNull<DisplayModePtr>, Fps),
(override));
MOCK_METHOD(void, onCommitNotComposited, (PhysicalDisplayId), (override));
+ MOCK_METHOD(void, vrrDisplayIdle, (bool), (override));
};
struct NoOpSchedulerCallback final : ISchedulerCallback {
void requestHardwareVsync(PhysicalDisplayId, bool) override {}
void requestDisplayModes(std::vector<display::DisplayModeRequest>) override {}
void kernelTimerChanged(bool) override {}
- void triggerOnFrameRateOverridesChanged() override {}
void onChoreographerAttached() override {}
void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>, Fps) override {}
void onCommitNotComposited(PhysicalDisplayId) override {}
+ void vrrDisplayIdle(bool) override {}
};
} // namespace android::scheduler::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
index 4f44d1b..8d6d1d3 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.h
@@ -18,6 +18,8 @@
#include <gmock/gmock.h>
+#include <scheduler/FrameTime.h>
+
#include "Scheduler/VSyncTracker.h"
namespace android::mock {
@@ -37,7 +39,7 @@
MOCK_METHOD(bool, isVSyncInPhase, (nsecs_t, Fps), (override));
MOCK_METHOD(void, setDisplayModePtr, (ftl::NonNull<DisplayModePtr>), (override));
MOCK_METHOD(void, setRenderRate, (Fps, bool), (override));
- MOCK_METHOD(void, onFrameBegin, (TimePoint, TimePoint), (override));
+ MOCK_METHOD(void, onFrameBegin, (TimePoint, scheduler::FrameTime), (override));
MOCK_METHOD(void, onFrameMissed, (TimePoint), (override));
MOCK_METHOD(void, dump, (std::string&), (const, override));
MOCK_METHOD(bool, isCurrentMode, (const ftl::NonNull<DisplayModePtr>&), (const, override));
diff --git a/services/surfaceflinger/tests/utils/ColorUtils.h b/services/surfaceflinger/tests/utils/ColorUtils.h
index 07916b6..253bad7 100644
--- a/services/surfaceflinger/tests/utils/ColorUtils.h
+++ b/services/surfaceflinger/tests/utils/ColorUtils.h
@@ -74,8 +74,8 @@
static void applyMatrix(half3& color, const mat3& mat) {
half3 ret = half3(0);
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
+ for (size_t i = 0; i < 3; i++) {
+ for (size_t j = 0; j < 3; j++) {
ret[i] = ret[i] + color[j] * mat[j][i];
}
}
diff --git a/services/vibratorservice/Android.bp b/services/vibratorservice/Android.bp
index 503587f..4735ae5 100644
--- a/services/vibratorservice/Android.bp
+++ b/services/vibratorservice/Android.bp
@@ -45,7 +45,7 @@
"libhidlbase",
"liblog",
"libutils",
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/VibratorHalWrapper.cpp b/services/vibratorservice/VibratorHalWrapper.cpp
index abe78f0..c97f401 100644
--- a/services/vibratorservice/VibratorHalWrapper.cpp
+++ b/services/vibratorservice/VibratorHalWrapper.cpp
@@ -32,6 +32,7 @@
using aidl::android::hardware::vibrator::Effect;
using aidl::android::hardware::vibrator::EffectStrength;
using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
using std::chrono::milliseconds;
@@ -96,6 +97,11 @@
return mInfoCache.get();
}
+HalResult<void> HalWrapper::performVendorEffect(const VendorEffect&, const std::function<void()>&) {
+ ALOGV("Skipped performVendorEffect because it's not available in Vibrator HAL");
+ return HalResult<void>::unsupported();
+}
+
HalResult<milliseconds> HalWrapper::performComposedEffect(const std::vector<CompositeEffect>&,
const std::function<void()>&) {
ALOGV("Skipped performComposedEffect because it's not available in Vibrator HAL");
@@ -271,6 +277,13 @@
return ret;
}
+HalResult<void> AidlHalWrapper::performVendorEffect(
+ const VendorEffect& effect, const std::function<void()>& completionCallback) {
+ // This method should always support callbacks, so no need to double check.
+ auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
+ return HalResultFactory::fromStatus(getHal()->performVendorEffect(effect, cb));
+}
+
HalResult<milliseconds> AidlHalWrapper::performComposedEffect(
const std::vector<CompositeEffect>& primitives,
const std::function<void()>& completionCallback) {
@@ -351,7 +364,7 @@
}
if (halResult.isFailed()) {
// Fail entire request if one request has failed.
- return HalResult<std::vector<milliseconds>>::failed(status.getMessage());
+ return HalResult<std::vector<milliseconds>>::failed(halResult.errorMessage());
}
durations[primitiveIdx] = milliseconds(duration);
}
diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp
index 5bb8ceb..915d6c7 100644
--- a/services/vibratorservice/benchmarks/Android.bp
+++ b/services/vibratorservice/benchmarks/Android.bp
@@ -33,7 +33,7 @@
"liblog",
"libutils",
"libvibratorservice",
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
index d4f7f1d..20979bd 100644
--- a/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
+++ b/services/vibratorservice/include/vibratorservice/VibratorHalWrapper.h
@@ -349,6 +349,7 @@
public:
using Effect = aidl::android::hardware::vibrator::Effect;
using EffectStrength = aidl::android::hardware::vibrator::EffectStrength;
+ using VendorEffect = aidl::android::hardware::vibrator::VendorEffect;
using CompositePrimitive = aidl::android::hardware::vibrator::CompositePrimitive;
using CompositeEffect = aidl::android::hardware::vibrator::CompositeEffect;
using Braking = aidl::android::hardware::vibrator::Braking;
@@ -380,6 +381,9 @@
Effect effect, EffectStrength strength,
const std::function<void()>& completionCallback) = 0;
+ virtual HalResult<void> performVendorEffect(const VendorEffect& effect,
+ const std::function<void()>& completionCallback);
+
virtual HalResult<std::chrono::milliseconds> performComposedEffect(
const std::vector<CompositeEffect>& primitives,
const std::function<void()>& completionCallback);
@@ -455,6 +459,10 @@
Effect effect, EffectStrength strength,
const std::function<void()>& completionCallback) override final;
+ HalResult<void> performVendorEffect(
+ const VendorEffect& effect,
+ const std::function<void()>& completionCallback) override final;
+
HalResult<std::chrono::milliseconds> performComposedEffect(
const std::vector<CompositeEffect>& primitives,
const std::function<void()>& completionCallback) override final;
diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp
index cd05123..92527eb 100644
--- a/services/vibratorservice/test/Android.bp
+++ b/services/vibratorservice/test/Android.bp
@@ -49,7 +49,7 @@
"liblog",
"libvibratorservice",
"libutils",
- "android.hardware.vibrator-V2-ndk",
+ "android.hardware.vibrator-V3-ndk",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
index 91717f6..7bcc59a 100644
--- a/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperAidlTest.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "VibratorHalWrapperAidlTest"
#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/persistable_bundle_aidl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -38,6 +39,8 @@
using aidl::android::hardware::vibrator::IVibrator;
using aidl::android::hardware::vibrator::IVibratorCallback;
using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
+using aidl::android::os::PersistableBundle;
using namespace android;
using namespace std::chrono_literals;
@@ -489,6 +492,42 @@
ASSERT_EQ(1, *callbackCounter.get());
}
+TEST_F(VibratorHalWrapperAidlTest, TestPerformVendorEffect) {
+ PersistableBundle vendorData;
+ vendorData.putInt("key", 1);
+ VendorEffect vendorEffect;
+ vendorEffect.vendorData = vendorData;
+ vendorEffect.strength = EffectStrength::MEDIUM;
+ vendorEffect.scale = 0.5f;
+
+ {
+ InSequence seq;
+ EXPECT_CALL(*mMockHal.get(), performVendorEffect(_, _))
+ .Times(Exactly(3))
+ .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION)))
+ .WillOnce(Return(ndk::ScopedAStatus::fromExceptionCode(EX_SECURITY)))
+ .WillOnce(DoAll(WithArg<1>(vibrator::TriggerCallback()),
+ Return(ndk::ScopedAStatus::ok())));
+ }
+
+ std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
+ auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
+
+ auto result = mWrapper->performVendorEffect(vendorEffect, callback);
+ ASSERT_TRUE(result.isUnsupported());
+ // Callback not triggered on failure
+ ASSERT_EQ(0, *callbackCounter.get());
+
+ result = mWrapper->performVendorEffect(vendorEffect, callback);
+ ASSERT_TRUE(result.isFailed());
+ // Callback not triggered for unsupported
+ ASSERT_EQ(0, *callbackCounter.get());
+
+ result = mWrapper->performVendorEffect(vendorEffect, callback);
+ ASSERT_TRUE(result.isOk());
+ ASSERT_EQ(1, *callbackCounter.get());
+}
+
TEST_F(VibratorHalWrapperAidlTest, TestPerformComposedEffect) {
std::vector<CompositePrimitive> supportedPrimitives = {CompositePrimitive::CLICK,
CompositePrimitive::SPIN,
diff --git a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
index dd59093..9a7c69d 100644
--- a/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
+++ b/services/vibratorservice/test/VibratorHalWrapperHidlV1_0Test.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "VibratorHalWrapperHidlV1_0Test"
#include <aidl/android/hardware/vibrator/IVibrator.h>
+#include <android/persistable_bundle_aidl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -39,6 +40,8 @@
using aidl::android::hardware::vibrator::EffectStrength;
using aidl::android::hardware::vibrator::IVibrator;
using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
+using aidl::android::os::PersistableBundle;
using namespace android;
using namespace std::chrono_literals;
@@ -317,6 +320,22 @@
ASSERT_EQ(0, *callbackCounter.get());
}
+TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformVendorEffectUnsupported) {
+ PersistableBundle vendorData; // empty
+ VendorEffect vendorEffect;
+ vendorEffect.vendorData = vendorData;
+ vendorEffect.strength = EffectStrength::LIGHT;
+ vendorEffect.scale = 1.0f;
+
+ std::unique_ptr<int32_t> callbackCounter = std::make_unique<int32_t>();
+ auto callback = vibrator::TestFactory::createCountingCallback(callbackCounter.get());
+
+ ASSERT_TRUE(mWrapper->performVendorEffect(vendorEffect, callback).isUnsupported());
+
+ // No callback is triggered.
+ ASSERT_EQ(0, *callbackCounter.get());
+}
+
TEST_F(VibratorHalWrapperHidlV1_0Test, TestPerformComposedEffectUnsupported) {
std::vector<CompositeEffect> emptyEffects, singleEffect, multipleEffects;
singleEffect.push_back(
diff --git a/services/vibratorservice/test/test_mocks.h b/services/vibratorservice/test/test_mocks.h
index 7882186..2f9451e 100644
--- a/services/vibratorservice/test/test_mocks.h
+++ b/services/vibratorservice/test/test_mocks.h
@@ -41,6 +41,7 @@
using aidl::android::hardware::vibrator::IVibrator;
using aidl::android::hardware::vibrator::IVibratorCallback;
using aidl::android::hardware::vibrator::PrimitivePwle;
+using aidl::android::hardware::vibrator::VendorEffect;
// -------------------------------------------------------------------------------------------------
@@ -56,6 +57,8 @@
(Effect e, EffectStrength s, const std::shared_ptr<IVibratorCallback>& cb,
int32_t* ret),
(override));
+ MOCK_METHOD(ndk::ScopedAStatus, performVendorEffect,
+ (const VendorEffect& e, const std::shared_ptr<IVibratorCallback>& cb), (override));
MOCK_METHOD(ndk::ScopedAStatus, getSupportedEffects, (std::vector<Effect> * ret), (override));
MOCK_METHOD(ndk::ScopedAStatus, setAmplitude, (float amplitude), (override));
MOCK_METHOD(ndk::ScopedAStatus, setExternalControl, (bool enabled), (override));
diff --git a/services/vr/.clang-format b/services/vr/.clang-format
deleted file mode 100644
index 04d7970..0000000
--- a/services/vr/.clang-format
+++ /dev/null
@@ -1,5 +0,0 @@
-BasedOnStyle: Google
-DerivePointerAlignment: false
-PointerAlignment: Left
-AllowShortIfStatementsOnASingleLine: false
-AllowShortLoopsOnASingleLine: false
diff --git a/services/vr/Android.bp b/services/vr/Android.bp
deleted file mode 100644
index 980dcf4..0000000
--- a/services/vr/Android.bp
+++ /dev/null
@@ -1,13 +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
- // SPDX-license-identifier-MIT
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-subdirs = [
- "*",
-]
diff --git a/services/vr/bufferhubd/Android.bp b/services/vr/bufferhubd/Android.bp
deleted file mode 100644
index f5491cf..0000000
--- a/services/vr/bufferhubd/Android.bp
+++ /dev/null
@@ -1,74 +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"],
-}
-
-sharedLibraries = [
- "libbase",
- "libcutils",
- "libgui",
- "liblog",
- "libpdx_default_transport",
- "libsync",
- "libui",
- "libutils",
-]
-
-cc_library_static {
- name: "libbufferhubd",
- srcs: [
- "buffer_hub.cpp",
- "consumer_channel.cpp",
- "consumer_queue_channel.cpp",
- "producer_channel.cpp",
- "producer_queue_channel.cpp",
- ],
- cflags: [
- "-DLOG_TAG=\"libbufferhubd\"",
- "-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- ],
- export_include_dirs: ["include"],
- header_libs: ["libdvr_headers"],
- shared_libs: sharedLibraries,
- static_libs: [
- "libbufferhub",
- ],
-}
-
-cc_binary {
- srcs: ["bufferhubd.cpp"],
- system_ext_specific: true,
- cflags: [
- "-DLOG_TAG=\"bufferhubd\"",
- "-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
- ],
- header_libs: ["libdvr_headers"],
- shared_libs: sharedLibraries,
- static_libs: [
- "libbufferhub",
- "libbufferhubd",
- "libperformance",
- ],
- name: "bufferhubd",
- init_rc: ["bufferhubd.rc"],
-}
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
deleted file mode 100644
index 6409265..0000000
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <inttypes.h>
-#include <poll.h>
-
-#include <iomanip>
-#include <memory>
-#include <sstream>
-#include <string>
-#include <thread>
-
-#include <log/log.h>
-#include <pdx/default_transport/service_endpoint.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-#include <utils/Trace.h>
-
-using android::pdx::Channel;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-BufferHubService::BufferHubService()
- : BASE("BufferHub", Endpoint::Create(BufferHubRPC::kClientPath)) {}
-
-BufferHubService::~BufferHubService() {}
-
-bool BufferHubService::IsInitialized() const { return BASE::IsInitialized(); }
-
-std::string BufferHubService::DumpState(size_t /*max_length*/) {
- std::ostringstream stream;
- auto channels = GetChannels<BufferHubChannel>();
-
- std::sort(channels.begin(), channels.end(),
- [](const std::shared_ptr<BufferHubChannel>& a,
- const std::shared_ptr<BufferHubChannel>& b) {
- return a->buffer_id() < b->buffer_id();
- });
-
- stream << "Active Producer Buffers:\n";
- stream << std::right;
- stream << std::setw(6) << "Id";
- stream << " ";
- stream << std::setw(9) << "Consumers";
- stream << " ";
- stream << std::setw(14) << "Geometry";
- stream << " ";
- stream << std::setw(6) << "Format";
- stream << " ";
- stream << std::setw(10) << "Usage";
- stream << " ";
- stream << std::setw(18) << "State";
- stream << " ";
- stream << std::setw(18) << "Signaled";
- stream << " ";
- stream << std::setw(10) << "Index";
- stream << std::endl;
-
- for (const auto& channel : channels) {
- if (channel->channel_type() == BufferHubChannel::kProducerType) {
- BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
- stream << std::right;
- stream << std::setw(6) << info.id;
- stream << " ";
- stream << std::setw(9) << info.consumer_count;
- stream << " ";
- if (info.format == HAL_PIXEL_FORMAT_BLOB) {
- std::string size = std::to_string(info.width) + " B";
- stream << std::setw(14) << size;
- } else {
- std::string dimensions = std::to_string(info.width) + "x" +
- std::to_string(info.height) + "x" +
- std::to_string(info.layer_count);
- stream << std::setw(14) << dimensions;
- }
- stream << " ";
- stream << std::setw(6) << info.format;
- stream << " ";
- stream << "0x" << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage;
- stream << std::dec << std::setfill(' ');
- stream << " ";
- stream << "0x" << std::hex << std::setfill('0');
- stream << std::setw(16) << info.state;
- stream << " ";
- stream << "0x" << std::setw(16) << info.signaled_mask;
- stream << std::dec << std::setfill(' ');
- stream << " ";
- stream << std::setw(8) << info.index;
- stream << std::endl;
- }
-
- if (channel->channel_type() == BufferHubChannel::kDetachedBufferType) {
- BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
- stream << std::right;
- stream << std::setw(6) << info.id;
- stream << " ";
- stream << std::setw(9) << "N/A";
- stream << " ";
- if (info.format == HAL_PIXEL_FORMAT_BLOB) {
- std::string size = std::to_string(info.width) + " B";
- stream << std::setw(14) << size;
- } else {
- std::string dimensions = std::to_string(info.width) + "x" +
- std::to_string(info.height) + "x" +
- std::to_string(info.layer_count);
- stream << std::setw(14) << dimensions;
- }
- stream << " ";
- stream << std::setw(6) << info.format;
- stream << " ";
- stream << "0x" << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage;
- stream << std::dec << std::setfill(' ');
- stream << " ";
- stream << std::setw(9) << "N/A";
- stream << " ";
- stream << std::hex << std::setfill(' ');
- stream << std::setw(18) << "Detached";
- stream << " ";
- stream << std::setw(18) << "N/A";
- stream << " ";
- stream << std::setw(10) << "N/A";
- stream << std::endl;
- }
- }
-
- stream << std::endl;
- stream << "Active Producer Queues:\n";
- stream << std::right << std::setw(6) << "Id";
- stream << std::right << std::setw(12) << " Capacity";
- stream << std::right << std::setw(12) << " Consumers";
- stream << " UsageSetMask";
- stream << " UsageClearMask";
- stream << " UsageDenySetMask";
- stream << " UsageDenyClearMask";
- stream << " ";
- stream << std::endl;
-
- for (const auto& channel : channels) {
- if (channel->channel_type() == BufferHubChannel::kProducerQueueType) {
- BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
- stream << std::dec << std::setfill(' ');
- stream << std::right << std::setw(6) << info.id;
- stream << std::right << std::setw(12) << info.capacity;
- stream << std::right << std::setw(12) << info.consumer_count;
- stream << std::setw(5) << std::setfill(' ') << "0x";
- stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_policy.usage_set_mask;
- stream << std::setw(7) << std::setfill(' ') << "0x";
- stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_policy.usage_clear_mask;
- stream << std::setw(9) << std::setfill(' ') << "0x";
- stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_policy.usage_deny_set_mask;
- stream << std::setw(11) << std::setfill(' ') << "0x";
- stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_policy.usage_deny_clear_mask;
- stream << std::hex << std::setfill('0');
- stream << std::endl;
- }
- }
-
- stream << std::endl;
- stream << "Active Consumer Queues:\n";
- stream << std::dec << std::setfill(' ');
- stream << std::right << std::setw(6) << "Id";
- stream << std::right << std::setw(12) << " Imported";
- stream << " ";
- stream << std::endl;
-
- for (const auto& channel : channels) {
- if (channel->channel_type() == BufferHubChannel::kConsumerQueueType) {
- BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
-
- stream << std::right << std::setw(6) << info.id;
- stream << std::right << std::setw(12) << info.capacity;
- stream << std::endl;
- }
- }
-
- stream << std::endl;
- stream << "Orphaned Consumer Buffers:\n";
- stream << std::right;
- stream << std::setw(6) << "Id";
- stream << " ";
- stream << std::setw(14) << "Info";
- stream << std::endl;
-
- for (const auto& channel : channels) {
- BufferHubChannel::BufferInfo info = channel->GetBufferInfo();
- // consumer_count is tracked by producer. When it's zero, producer must have
- // already hung up and the consumer is orphaned.
- if (channel->channel_type() == BufferHubChannel::kConsumerType &&
- info.consumer_count == 0) {
- stream << std::right;
- stream << std::setw(6) << info.id;
- stream << " ";
-
- stream << std::setw(14) << "Orphaned.";
- stream << (" channel_id=" + std::to_string(channel->channel_id()));
- stream << std::endl;
- }
- }
-
- return stream.str();
-}
-
-void BufferHubService::HandleImpulse(Message& message) {
- ATRACE_NAME("BufferHubService::HandleImpulse");
- if (auto channel = message.GetChannel<BufferHubChannel>())
- channel->HandleImpulse(message);
-}
-
-pdx::Status<void> BufferHubService::HandleMessage(Message& message) {
- ATRACE_NAME("BufferHubService::HandleMessage");
- auto channel = message.GetChannel<BufferHubChannel>();
-
- ALOGD_IF(
- TRACE,
- "BufferHubService::HandleMessage: channel=%p channel_id=%d opcode=%d",
- channel.get(), message.GetChannelId(), message.GetOp());
-
- // If the channel is already set up, let it handle the message.
- if (channel && !channel->HandleMessage(message))
- return DefaultHandleMessage(message);
-
- // This channel has not been set up yet, the following are valid operations.
- switch (message.GetOp()) {
- case BufferHubRPC::CreateBuffer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::CreateBuffer>(
- *this, &BufferHubService::OnCreateBuffer, message);
- return {};
-
- case BufferHubRPC::CreateProducerQueue::Opcode:
- DispatchRemoteMethod<BufferHubRPC::CreateProducerQueue>(
- *this, &BufferHubService::OnCreateProducerQueue, message);
- return {};
-
- default:
- return DefaultHandleMessage(message);
- }
-}
-
-Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
- uint32_t height, uint32_t format,
- uint64_t usage,
- size_t meta_size_bytes) {
- // Use the producer channel id as the global buffer id.
- const int buffer_id = message.GetChannelId();
- ALOGD_IF(TRACE,
- "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
- "format=%u usage=%" PRIx64 " meta_size_bytes=%zu",
- buffer_id, width, height, format, usage, meta_size_bytes);
-
- // See if this channel is already attached to a buffer.
- if (const auto channel = message.GetChannel<BufferHubChannel>()) {
- ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
- buffer_id);
- return ErrorStatus(EALREADY);
- }
- const uint32_t kDefaultLayerCount = 1;
- auto status = ProducerChannel::Create(this, buffer_id, width, height,
- kDefaultLayerCount, format, usage,
- meta_size_bytes);
- if (status) {
- message.SetChannel(status.take());
- return {};
- } else {
- ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
- status.GetErrorMessage().c_str());
- return status.error_status();
- }
-}
-
-Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
- pdx::Message& message, const ProducerQueueConfig& producer_config,
- const UsagePolicy& usage_policy) {
- // Use the producer channel id as the global queue id.
- const int queue_id = message.GetChannelId();
- ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
- queue_id);
-
- // See if this channel is already attached to another object.
- if (const auto channel = message.GetChannel<BufferHubChannel>()) {
- ALOGE("BufferHubService::OnCreateProducerQueue: already created: queue=%d",
- queue_id);
- return ErrorStatus(EALREADY);
- }
-
- auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
- usage_policy);
- if (status) {
- message.SetChannel(status.take());
- return {{producer_config, queue_id}};
- } else {
- ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
- return status.error_status();
- }
-}
-
-void BufferHubChannel::SignalAvailable() {
- ATRACE_NAME("BufferHubChannel::SignalAvailable");
- ALOGD_IF(TRACE,
- "BufferHubChannel::SignalAvailable: channel_id=%d buffer_id=%d",
- channel_id(), buffer_id());
- signaled_ = true;
- const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLIN);
- ALOGE_IF(!status,
- "BufferHubChannel::SignalAvailable: failed to signal availability "
- "channel_id=%d: %s",
- channel_id_, status.GetErrorMessage().c_str());
-}
-
-void BufferHubChannel::ClearAvailable() {
- ATRACE_NAME("BufferHubChannel::ClearAvailable");
- ALOGD_IF(TRACE,
- "BufferHubChannel::ClearAvailable: channel_id=%d buffer_id=%d",
- channel_id(), buffer_id());
- signaled_ = false;
- const auto status = service_->ModifyChannelEvents(channel_id_, POLLIN, 0);
- ALOGE_IF(!status,
- "BufferHubChannel::ClearAvailable: failed to clear availability "
- "channel_id=%d: %s",
- channel_id_, status.GetErrorMessage().c_str());
-}
-
-void BufferHubChannel::Hangup() {
- ATRACE_NAME("BufferHubChannel::Hangup");
- ALOGD_IF(TRACE, "BufferHubChannel::Hangup: channel_id=%d buffer_id=%d",
- channel_id(), buffer_id());
- const auto status = service_->ModifyChannelEvents(channel_id_, 0, POLLHUP);
- ALOGE_IF(
- !status,
- "BufferHubChannel::Hangup: failed to signal hangup channel_id=%d: %s",
- channel_id_, status.GetErrorMessage().c_str());
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/bufferhubd/bufferhubd.cpp b/services/vr/bufferhubd/bufferhubd.cpp
deleted file mode 100644
index 50cb3b7..0000000
--- a/services/vr/bufferhubd/bufferhubd.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <sched.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-#include <dvr/performance_client_api.h>
-#include <log/log.h>
-#include <pdx/service_dispatcher.h>
-#include <private/dvr/buffer_hub.h>
-
-int main(int, char**) {
- int ret = -1;
- std::shared_ptr<android::dvr::BufferHubService> pdx_service;
- std::unique_ptr<android::pdx::ServiceDispatcher> dispatcher;
-
- // We need to be able to create endpoints with full perms.
- umask(0000);
-
- // Bump up the soft limit of open fd to the hard limit.
- struct rlimit64 rlim;
- ret = getrlimit64(RLIMIT_NOFILE, &rlim);
- LOG_ALWAYS_FATAL_IF(ret != 0, "Failed to get nofile limit.");
-
- ALOGI("Current nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
- rlim.rlim_cur = rlim.rlim_max;
- ret = setrlimit64(RLIMIT_NOFILE, &rlim);
- ALOGE_IF(ret < 0, "Failed to set nofile limit, error=%s", strerror(errno));
-
- rlim.rlim_cur = -1;
- rlim.rlim_max = -1;
- if (getrlimit64(RLIMIT_NOFILE, &rlim) < 0)
- ALOGE("Failed to get nofile limit.");
- else
- ALOGI("New nofile limit is %llu/%llu.", rlim.rlim_cur, rlim.rlim_max);
-
- dispatcher = android::pdx::ServiceDispatcher::Create();
- CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher\n");
-
- pdx_service = android::dvr::BufferHubService::Create();
- CHECK_ERROR(!pdx_service, error, "Failed to create bufferhub pdx service\n");
- dispatcher->AddService(pdx_service);
-
- ret = dvrSetSchedulerClass(0, "graphics");
- CHECK_ERROR(ret < 0, error, "Failed to set thread priority");
-
- ALOGI("Entering message loop.");
-
- ret = dispatcher->EnterDispatchLoop();
- CHECK_ERROR(ret < 0, error, "Dispatch loop exited because: %s\n",
- strerror(-ret));
-
-error:
- return -ret;
-}
diff --git a/services/vr/bufferhubd/bufferhubd.rc b/services/vr/bufferhubd/bufferhubd.rc
deleted file mode 100644
index c470de5..0000000
--- a/services/vr/bufferhubd/bufferhubd.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service bufferhubd /system/bin/bufferhubd
- class core
- user system
- group system
- socket pdx/system/buffer_hub/client stream 0660 system system u:object_r:pdx_bufferhub_client_endpoint_socket:s0
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
deleted file mode 100644
index c7695bc..0000000
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-#include <thread>
-
-#include <log/log.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <utils/Trace.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::Channel;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-ConsumerChannel::ConsumerChannel(BufferHubService* service, int buffer_id,
- int channel_id, uint32_t client_state_mask,
- const std::shared_ptr<Channel> producer)
- : BufferHubChannel(service, buffer_id, channel_id, kConsumerType),
- client_state_mask_(client_state_mask),
- producer_(producer) {
- GetProducer()->AddConsumer(this);
-}
-
-ConsumerChannel::~ConsumerChannel() {
- ALOGD_IF(TRACE,
- "ConsumerChannel::~ConsumerChannel: channel_id=%d buffer_id=%d",
- channel_id(), buffer_id());
-
- if (auto producer = GetProducer()) {
- producer->RemoveConsumer(this);
- }
-}
-
-BufferHubChannel::BufferInfo ConsumerChannel::GetBufferInfo() const {
- BufferHubChannel::BufferInfo info;
- if (auto producer = GetProducer()) {
- // If producer has not hung up, copy most buffer info from the producer.
- info = producer->GetBufferInfo();
- } else {
- info.signaled_mask = client_state_mask();
- }
- info.id = buffer_id();
- return info;
-}
-
-std::shared_ptr<ProducerChannel> ConsumerChannel::GetProducer() const {
- return std::static_pointer_cast<ProducerChannel>(producer_.lock());
-}
-
-void ConsumerChannel::HandleImpulse(Message& message) {
- ATRACE_NAME("ConsumerChannel::HandleImpulse");
- switch (message.GetOp()) {
- case BufferHubRPC::ConsumerAcquire::Opcode:
- OnConsumerAcquire(message);
- break;
- case BufferHubRPC::ConsumerRelease::Opcode:
- OnConsumerRelease(message, {});
- break;
- }
-}
-
-bool ConsumerChannel::HandleMessage(Message& message) {
- ATRACE_NAME("ConsumerChannel::HandleMessage");
- auto producer = GetProducer();
- if (!producer)
- REPLY_ERROR_RETURN(message, EPIPE, true);
-
- switch (message.GetOp()) {
- case BufferHubRPC::GetBuffer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
- *this, &ConsumerChannel::OnGetBuffer, message);
- return true;
-
- case BufferHubRPC::NewConsumer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
- *producer, &ProducerChannel::OnNewConsumer, message);
- return true;
-
- case BufferHubRPC::ConsumerAcquire::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ConsumerAcquire>(
- *this, &ConsumerChannel::OnConsumerAcquire, message);
- return true;
-
- case BufferHubRPC::ConsumerRelease::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ConsumerRelease>(
- *this, &ConsumerChannel::OnConsumerRelease, message);
- return true;
-
- default:
- return false;
- }
-}
-
-Status<BufferDescription<BorrowedHandle>> ConsumerChannel::OnGetBuffer(
- Message& /*message*/) {
- ATRACE_NAME("ConsumerChannel::OnGetBuffer");
- ALOGD_IF(TRACE, "ConsumerChannel::OnGetBuffer: buffer=%d", buffer_id());
- if (auto producer = GetProducer()) {
- return {producer->GetBuffer(client_state_mask_)};
- } else {
- return ErrorStatus(EPIPE);
- }
-}
-
-Status<LocalFence> ConsumerChannel::OnConsumerAcquire(Message& message) {
- ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
- auto producer = GetProducer();
- if (!producer)
- return ErrorStatus(EPIPE);
-
- if (acquired_ || released_) {
- ALOGE(
- "ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
- "acquired=%d released=%d channel_id=%d buffer_id=%d",
- acquired_, released_, message.GetChannelId(), producer->buffer_id());
- return ErrorStatus(EBUSY);
- } else {
- auto status = producer->OnConsumerAcquire(message);
- if (status) {
- ClearAvailable();
- acquired_ = true;
- }
- return status;
- }
-}
-
-Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
- LocalFence release_fence) {
- ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
- auto producer = GetProducer();
- if (!producer)
- return ErrorStatus(EPIPE);
-
- if (!acquired_ || released_) {
- ALOGE(
- "ConsumerChannel::OnConsumerRelease: Release when not acquired: "
- "acquired=%d released=%d channel_id=%d buffer_id=%d",
- acquired_, released_, message.GetChannelId(), producer->buffer_id());
- return ErrorStatus(EBUSY);
- } else {
- auto status =
- producer->OnConsumerRelease(message, std::move(release_fence));
- if (status) {
- ClearAvailable();
- acquired_ = false;
- released_ = true;
- }
- return status;
- }
-}
-
-void ConsumerChannel::OnProducerGained() {
- // Clear the signal if exist. There is a possiblity that the signal still
- // exist in consumer client when producer gains the buffer, e.g. newly added
- // consumer fail to acquire the previous posted buffer in time. Then, when
- // producer gains back the buffer, posts the buffer again and signal the
- // consumer later, there won't be an signal change in eventfd, and thus,
- // consumer will miss the posted buffer later. Thus, we need to clear the
- // signal in consumer clients if the signal exist.
- ClearAvailable();
-}
-
-void ConsumerChannel::OnProducerPosted() {
- acquired_ = false;
- released_ = false;
- SignalAvailable();
-}
-
-void ConsumerChannel::OnProducerClosed() {
- producer_.reset();
- Hangup();
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
deleted file mode 100644
index 5d7d4e9..0000000
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-#include <pdx/channel_handle.h>
-#include <private/dvr/consumer_queue_channel.h>
-#include <private/dvr/producer_channel.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::RemoteMethodError;
-
-namespace android {
-namespace dvr {
-
-ConsumerQueueChannel::ConsumerQueueChannel(
- BufferHubService* service, int buffer_id, int channel_id,
- const std::shared_ptr<Channel>& producer, bool silent)
- : BufferHubChannel(service, buffer_id, channel_id, kConsumerQueueType),
- producer_(producer),
- capacity_(0),
- silent_(silent) {
- GetProducer()->AddConsumer(this);
-}
-
-ConsumerQueueChannel::~ConsumerQueueChannel() {
- ALOGD_IF(TRACE, "ConsumerQueueChannel::~ConsumerQueueChannel: channel_id=%d",
- channel_id());
-
- if (auto producer = GetProducer()) {
- producer->RemoveConsumer(this);
- }
-}
-
-bool ConsumerQueueChannel::HandleMessage(Message& message) {
- ATRACE_NAME("ConsumerQueueChannel::HandleMessage");
- auto producer = GetProducer();
- if (!producer) {
- RemoteMethodError(message, EPIPE);
- return true;
- }
-
- switch (message.GetOp()) {
- case BufferHubRPC::CreateConsumerQueue::Opcode:
- DispatchRemoteMethod<BufferHubRPC::CreateConsumerQueue>(
- *producer, &ProducerQueueChannel::OnCreateConsumerQueue, message);
- return true;
-
- case BufferHubRPC::GetQueueInfo::Opcode:
- DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
- *producer, &ProducerQueueChannel::OnGetQueueInfo, message);
- return true;
-
- case BufferHubRPC::ConsumerQueueImportBuffers::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>(
- *this, &ConsumerQueueChannel::OnConsumerQueueImportBuffers, message);
- return true;
-
- default:
- return false;
- }
-}
-
-std::shared_ptr<ProducerQueueChannel> ConsumerQueueChannel::GetProducer()
- const {
- return std::static_pointer_cast<ProducerQueueChannel>(producer_.lock());
-}
-
-void ConsumerQueueChannel::HandleImpulse(Message& /* message */) {
- ATRACE_NAME("ConsumerQueueChannel::HandleImpulse");
-}
-
-BufferHubChannel::BufferInfo ConsumerQueueChannel::GetBufferInfo() const {
- BufferHubChannel::BufferInfo info;
- if (auto producer = GetProducer()) {
- // If producer has not hung up, copy most buffer info from the producer.
- info = producer->GetBufferInfo();
- }
- info.id = buffer_id();
- info.capacity = capacity_;
- return info;
-}
-
-void ConsumerQueueChannel::RegisterNewBuffer(
- const std::shared_ptr<ProducerChannel>& producer_channel,
- size_t producer_slot) {
- ALOGD_IF(TRACE, "%s: queue_id=%d buffer_id=%d slot=%zu silent=%d",
- __FUNCTION__, buffer_id(), producer_channel->buffer_id(),
- producer_slot, silent_);
- // Only register buffers if the queue is not silent.
- if (silent_) {
- return;
- }
-
- auto status = producer_channel->CreateConsumerStateMask();
- if (!status.ok()) {
- ALOGE("%s: Failed to create consumer state mask: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- return;
- }
- uint64_t consumer_state_mask = status.get();
-
- pending_buffer_slots_.emplace(producer_channel, producer_slot,
- consumer_state_mask);
- // Signal the client that there is new buffer available.
- SignalAvailable();
-}
-
-Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ConsumerQueueChannel::OnConsumerQueueImportBuffers(Message& message) {
- std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
- ATRACE_NAME(__FUNCTION__);
- ALOGD_IF(TRACE, "%s: pending_buffer_slots=%zu", __FUNCTION__,
- pending_buffer_slots_.size());
-
- // Indicate this is a silent queue that will not import buffers.
- if (silent_)
- return ErrorStatus(EBADR);
-
- while (!pending_buffer_slots_.empty()) {
- auto producer_channel =
- pending_buffer_slots_.front().producer_channel.lock();
- size_t producer_slot = pending_buffer_slots_.front().producer_slot;
- uint64_t consumer_state_mask =
- pending_buffer_slots_.front().consumer_state_mask;
- pending_buffer_slots_.pop();
-
- // It's possible that the producer channel has expired. When this occurs,
- // ignore the producer channel.
- if (producer_channel == nullptr) {
- ALOGW("%s: producer channel has already been expired.", __FUNCTION__);
- continue;
- }
-
- auto status =
- producer_channel->CreateConsumer(message, consumer_state_mask);
-
- // If no buffers are imported successfully, clear available and return an
- // error. Otherwise, return all consumer handles already imported
- // successfully, but keep available bits on, so that the client can retry
- // importing remaining consumer buffers.
- if (!status) {
- ALOGE("%s: Failed create consumer: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- if (buffer_handles.empty()) {
- ClearAvailable();
- return status.error_status();
- } else {
- return {std::move(buffer_handles)};
- }
- }
-
- buffer_handles.emplace_back(status.take(), producer_slot);
- }
-
- ClearAvailable();
- return {std::move(buffer_handles)};
-}
-
-void ConsumerQueueChannel::OnProducerClosed() {
- ALOGD_IF(TRACE, "ConsumerQueueChannel::OnProducerClosed: queue_id=%d",
- buffer_id());
- producer_.reset();
- Hangup();
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
deleted file mode 100644
index 909d69b..0000000
--- a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
-#define ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include <hardware/gralloc.h>
-#include <pdx/service.h>
-#include <private/dvr/bufferhub_rpc.h>
-
-namespace android {
-namespace dvr {
-
-class BufferHubService;
-class ConsumerChannel;
-class ProducerChannel;
-class ConsumerQueueChannel;
-class ProducerQueueChannel;
-
-class BufferHubChannel : public pdx::Channel {
- public:
- enum ChannelType {
- kProducerType,
- kConsumerType,
- kDetachedBufferType,
- kProducerQueueType,
- kConsumerQueueType,
- };
-
- BufferHubChannel(BufferHubService* service, int buffer_id, int channel_id,
- ChannelType channel_type)
- : service_(service),
- buffer_id_(buffer_id),
- channel_id_(channel_id),
- channel_type_(channel_type) {}
- virtual ~BufferHubChannel() {}
-
- virtual bool HandleMessage(pdx::Message& message) = 0;
- virtual void HandleImpulse(pdx::Message& message) = 0;
-
- // Captures buffer info for use by BufferHubService::DumpState().
- struct BufferInfo {
- // Common data field shared by ProducerBuffer and ProducerQueue.
- int id = -1;
- int type = -1;
- size_t consumer_count = 0;
-
- // Data field for producer buffer.
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t layer_count = 0;
- uint32_t format = 0;
- uint64_t usage = 0;
- uint64_t state = 0;
- uint64_t signaled_mask = 0;
- uint64_t index = 0;
-
- // Data filed for producer queue.
- size_t capacity = 0;
- UsagePolicy usage_policy{0, 0, 0, 0};
-
- BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format, uint64_t usage,
- uint64_t state, uint64_t signaled_mask, uint64_t index)
- : id(id),
- type(kProducerType),
- consumer_count(consumer_count),
- width(width),
- height(height),
- layer_count(layer_count),
- format(format),
- usage(usage),
- state(state),
- signaled_mask(signaled_mask),
- index(index) {}
-
- BufferInfo(int id, size_t consumer_count, size_t capacity,
- const UsagePolicy& usage_policy)
- : id(id),
- type(kProducerQueueType),
- consumer_count(consumer_count),
- capacity(capacity),
- usage_policy(usage_policy) {}
-
- BufferInfo() {}
- };
-
- // Returns the buffer info for this buffer.
- virtual BufferInfo GetBufferInfo() const = 0;
-
- // Signal the client fd that an ownership change occurred using POLLIN.
- void SignalAvailable();
-
- // Clear the ownership change event.
- void ClearAvailable();
-
- // Signal hangup event.
- void Hangup();
-
- BufferHubService* service() const { return service_; }
- ChannelType channel_type() const { return channel_type_; }
- int buffer_id() const { return buffer_id_; }
-
- int channel_id() const { return channel_id_; }
-
- bool signaled() const { return signaled_; }
-
- private:
- BufferHubService* service_;
-
- // Static id of the buffer for logging and informational purposes. This id
- // does not change for the life of the buffer.
- // TODO(eieio): Consider using an id allocator instead of the originating
- // channel id; channel ids wrap after 2^31 ids, but this is not a problem in
- // general because channel ids are not used for any lookup in this service.
- int buffer_id_;
-
- // The channel id of the buffer.
- int channel_id_;
-
- bool signaled_;
-
- ChannelType channel_type_;
-
- BufferHubChannel(const BufferHubChannel&) = delete;
- void operator=(const BufferHubChannel&) = delete;
-};
-
-class BufferHubService : public pdx::ServiceBase<BufferHubService> {
- public:
- BufferHubService();
- ~BufferHubService() override;
-
- pdx::Status<void> HandleMessage(pdx::Message& message) override;
- void HandleImpulse(pdx::Message& message) override;
-
- bool IsInitialized() const override;
- std::string DumpState(size_t max_length) override;
-
- private:
- friend BASE;
-
- pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width,
- uint32_t height, uint32_t format,
- uint64_t usage, size_t meta_size_bytes);
- pdx::Status<QueueInfo> OnCreateProducerQueue(
- pdx::Message& message, const ProducerQueueConfig& producer_config,
- const UsagePolicy& usage_policy);
-
- BufferHubService(const BufferHubService&) = delete;
- void operator=(const BufferHubService&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUBD_BUFFER_HUB_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
deleted file mode 100644
index 5ee551f..0000000
--- a/services/vr/bufferhubd/include/private/dvr/consumer_channel.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
-
-#include <pdx/rpc/buffer_wrapper.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-
-namespace android {
-namespace dvr {
-
-// Consumer channels are attached to a Producer channel
-class ConsumerChannel : public BufferHubChannel {
- public:
- using BorrowedHandle = pdx::BorrowedHandle;
- using Channel = pdx::Channel;
- using Message = pdx::Message;
-
- ConsumerChannel(BufferHubService* service, int buffer_id, int channel_id,
- uint32_t client_state_mask,
- const std::shared_ptr<Channel> producer);
- ~ConsumerChannel() override;
-
- bool HandleMessage(Message& message) override;
- void HandleImpulse(Message& message) override;
-
- uint32_t client_state_mask() const { return client_state_mask_; }
- BufferInfo GetBufferInfo() const override;
-
- void OnProducerGained();
- void OnProducerPosted();
- void OnProducerClosed();
-
- private:
- std::shared_ptr<ProducerChannel> GetProducer() const;
-
- pdx::Status<BufferDescription<BorrowedHandle>> OnGetBuffer(Message& message);
-
- pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
- pdx::Status<void> OnConsumerRelease(Message& message,
- LocalFence release_fence);
-
- uint32_t client_state_mask_{0U};
- bool acquired_{false};
- bool released_{true};
- std::weak_ptr<Channel> producer_;
-
- ConsumerChannel(const ConsumerChannel&) = delete;
- void operator=(const ConsumerChannel&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUBD_CONSUMER_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
deleted file mode 100644
index 3a81b03..0000000
--- a/services/vr/bufferhubd/include/private/dvr/consumer_queue_channel.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
-
-#include <queue>
-
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-
-namespace android {
-namespace dvr {
-
-class ConsumerQueueChannel : public BufferHubChannel {
- public:
- using Message = pdx::Message;
- using RemoteChannelHandle = pdx::RemoteChannelHandle;
-
- ConsumerQueueChannel(BufferHubService* service, int buffer_id, int channel_id,
- const std::shared_ptr<Channel>& producer, bool silent);
- ~ConsumerQueueChannel() override;
-
- bool HandleMessage(Message& message) override;
- void HandleImpulse(Message& message) override;
-
- BufferInfo GetBufferInfo() const override;
-
- // Called by ProdcuerQueueChannel to notify consumer queue that a new
- // buffer has been allocated.
- void RegisterNewBuffer(
- const std::shared_ptr<ProducerChannel>& producer_channel,
- size_t producer_slot);
-
- // Called after clients been signaled by service that new buffer has been
- // allocated. Clients uses kOpConsumerQueueImportBuffers to import new
- // consumer buffers and this handler returns a vector of fd representing
- // BufferConsumers that clients can import.
- pdx::Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
- OnConsumerQueueImportBuffers(Message& message);
-
- void OnProducerClosed();
-
- private:
- // Data structure to store relavant info of a newly allocated producer buffer
- // so that consumer channel and buffer can be created later.
- struct PendingBuffer {
- PendingBuffer(std::shared_ptr<ProducerChannel> channel, size_t slot,
- uint64_t mask) {
- producer_channel = channel;
- producer_slot = slot;
- consumer_state_mask = mask;
- }
- PendingBuffer() = delete;
-
- std::weak_ptr<ProducerChannel> producer_channel;
- size_t producer_slot;
- uint64_t consumer_state_mask;
- };
-
- std::shared_ptr<ProducerQueueChannel> GetProducer() const;
-
- // Pointer to the producer channel.
- std::weak_ptr<Channel> producer_;
-
- // Tracks newly allocated buffer producers along with it's slot number.
- std::queue<PendingBuffer> pending_buffer_slots_;
-
- // Tracks how many buffers have this queue imported.
- size_t capacity_;
-
- // A silent queue does not signal or export buffers. It is only used to spawn
- // another consumer queue.
- bool silent_;
-
- ConsumerQueueChannel(const ConsumerQueueChannel&) = delete;
- void operator=(const ConsumerQueueChannel&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUBD_CONSUMER_QUEUE_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_channel.h
deleted file mode 100644
index 45593ad..0000000
--- a/services/vr/bufferhubd/include/private/dvr/producer_channel.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
-
-#include <functional>
-#include <memory>
-#include <vector>
-
-#include <pdx/channel_handle.h>
-#include <pdx/file_handle.h>
-#include <pdx/rpc/buffer_wrapper.h>
-#include <private/dvr/buffer_hub.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/ion_buffer.h>
-
-namespace android {
-namespace dvr {
-
-// The buffer changes ownership according to the following sequence:
-// POST -> ACQUIRE/RELEASE (all consumers) -> GAIN (producer acquires) -> POST
-
-// The producer channel is owned by a single app that writes into buffers and
-// calls POST when drawing is complete. This channel has a set of consumer
-// channels associated with it that are waiting for notifications.
-class ProducerChannel : public BufferHubChannel {
- public:
- using Message = pdx::Message;
- using BorrowedHandle = pdx::BorrowedHandle;
- using RemoteChannelHandle = pdx::RemoteChannelHandle;
- template <typename T>
- using BufferWrapper = pdx::rpc::BufferWrapper<T>;
-
- static std::unique_ptr<ProducerChannel> Create(BufferHubService* service,
- int buffer_id, int channel_id,
- IonBuffer buffer,
- IonBuffer metadata_buffer,
- size_t user_metadata_size);
-
- static pdx::Status<std::shared_ptr<ProducerChannel>> Create(
- BufferHubService* service, int channel_id, uint32_t width,
- uint32_t height, uint32_t layer_count, uint32_t format, uint64_t usage,
- size_t user_metadata_size);
-
- ~ProducerChannel() override;
-
- uint32_t buffer_state() const {
- return buffer_state_->load(std::memory_order_acquire);
- }
-
- bool HandleMessage(Message& message) override;
- void HandleImpulse(Message& message) override;
-
- BufferInfo GetBufferInfo() const override;
-
- BufferDescription<BorrowedHandle> GetBuffer(uint32_t client_state_mask);
-
- pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message,
- uint32_t consumer_state_mask);
- pdx::Status<uint32_t> CreateConsumerStateMask();
- pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
-
- pdx::Status<LocalFence> OnConsumerAcquire(Message& message);
- pdx::Status<void> OnConsumerRelease(Message& message,
- LocalFence release_fence);
-
- void OnConsumerOrphaned(const uint32_t& consumer_state_mask);
-
- void AddConsumer(ConsumerChannel* channel);
- void RemoveConsumer(ConsumerChannel* channel);
-
- bool CheckParameters(uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage,
- size_t user_metadata_size) const;
-
- private:
- std::vector<ConsumerChannel*> consumer_channels_;
-
- IonBuffer buffer_;
-
- // IonBuffer that is shared between bufferhubd, producer, and consumers.
- IonBuffer metadata_buffer_;
- BufferHubDefs::MetadataHeader* metadata_header_ = nullptr;
- std::atomic<uint32_t>* buffer_state_ = nullptr;
- std::atomic<uint32_t>* fence_state_ = nullptr;
- std::atomic<uint32_t>* active_clients_bit_mask_ = nullptr;
-
- // All orphaned consumer bits. Valid bits are the lower 63 bits, while the
- // highest bit is reserved for the producer and should not be set.
- uint32_t orphaned_consumer_bit_mask_{0U};
-
- LocalFence post_fence_;
- LocalFence returned_fence_;
- size_t user_metadata_size_; // size of user requested buffer buffer size.
- size_t metadata_buf_size_; // size of the ion buffer that holds metadata.
-
- pdx::LocalHandle acquire_fence_fd_;
- pdx::LocalHandle release_fence_fd_;
- pdx::LocalHandle dummy_fence_fd_;
-
- ProducerChannel(BufferHubService* service, int buffer_id, int channel_id,
- IonBuffer buffer, IonBuffer metadata_buffer,
- size_t user_metadata_size, int* error);
- ProducerChannel(BufferHubService* service, int channel, uint32_t width,
- uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t user_metadata_size, int* error);
-
- int InitializeBuffer();
- pdx::Status<BufferDescription<BorrowedHandle>> OnGetBuffer(Message& message);
- pdx::Status<void> OnProducerPost(Message& message, LocalFence acquire_fence);
- pdx::Status<LocalFence> OnProducerGain(Message& message);
-
- // Remove consumer from atomics in shared memory based on consumer_state_mask.
- // This function is used for clean up for failures in CreateConsumer method.
- void RemoveConsumerClientMask(uint32_t consumer_state_mask);
-
- // Checks whether the buffer is released by all active clients, excluding
- // orphaned consumers.
- bool IsBufferReleasedByAllActiveClientsExceptForOrphans() const;
-
- ProducerChannel(const ProducerChannel&) = delete;
- void operator=(const ProducerChannel&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUBD_PRODUCER_CHANNEL_H_
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
deleted file mode 100644
index 0456ad8..0000000
--- a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
-#define ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
-
-#include <pdx/status.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/buffer_hub.h>
-
-namespace android {
-namespace dvr {
-
-class ProducerQueueChannel : public BufferHubChannel {
- public:
- static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
- BufferHubService* service, int channel_id,
- const ProducerQueueConfig& config, const UsagePolicy& usage_policy);
- ~ProducerQueueChannel() override;
-
- bool HandleMessage(pdx::Message& message) override;
- void HandleImpulse(pdx::Message& message) override;
-
- BufferInfo GetBufferInfo() const override;
-
- // Handles client request to create a new consumer queue attached to current
- // producer queue.
- // Returns a handle for the service channel, as well as the size of the
- // metadata associated with the queue.
- pdx::Status<pdx::RemoteChannelHandle> OnCreateConsumerQueue(
- pdx::Message& message, bool silent);
-
- pdx::Status<QueueInfo> OnGetQueueInfo(pdx::Message& message);
-
- // Allocate a new BufferHubProducer according to the input spec. Client may
- // handle this as if a new producer is created through kOpCreateBuffer.
- pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
- OnProducerQueueAllocateBuffers(pdx::Message& message, uint32_t width,
- uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage,
- size_t buffer_count);
-
- // Inserts a ProducerBuffer into the queue. Note that the buffer must be in
- // Gain'ed state for the operation to succeed.
- pdx::Status<size_t> OnProducerQueueInsertBuffer(pdx::Message& message, int buffer_cid);
-
- // Removes a ProducerBuffer indicated by |slot|. Note that the buffer must be
- // in Gain'ed state for the operation to succeed.
- pdx::Status<void> OnProducerQueueRemoveBuffer(pdx::Message& message,
- size_t slot);
-
- void AddConsumer(ConsumerQueueChannel* channel);
- void RemoveConsumer(ConsumerQueueChannel* channel);
-
- private:
- ProducerQueueChannel(BufferHubService* service, int channel_id,
- const ProducerQueueConfig& config,
- const UsagePolicy& usage_policy, int* error);
-
- // Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
- // Note that the newly created buffer's file handle will be pushed to client
- // and our return type is a RemoteChannelHandle.
- // Returns the remote channel handle and the slot number for the newly
- // allocated buffer.
- pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
- pdx::Message& message, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format, uint64_t usage);
-
- // The producer queue's configuration. Now we assume the configuration is
- // immutable once the queue is created.
- ProducerQueueConfig config_;
-
- // A set of variables to control what |usage| bits can this ProducerQueue
- // allocate.
- UsagePolicy usage_policy_;
-
- // Provides access to the |channel_id| of all consumer channels associated
- // with this producer.
- std::vector<ConsumerQueueChannel*> consumer_channels_;
-
- // Tracks how many buffers have this queue allocated.
- size_t capacity_;
-
- // Tracks of all buffer producer allocated through this buffer queue. Once
- // a buffer get allocated, it will take a logical slot in the |buffers_| array
- // and the slot number will stay unchanged during the entire life cycle of the
- // queue.
- std::weak_ptr<ProducerChannel> buffers_[BufferHubRPC::kMaxQueueCapacity];
-
- ProducerQueueChannel(const ProducerQueueChannel&) = delete;
- void operator=(const ProducerQueueChannel&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_BUFFERHUBD_PRODUCER_QUEUE_CHANNEL_H_
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
deleted file mode 100644
index b71964b..0000000
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ /dev/null
@@ -1,673 +0,0 @@
-#include <sys/epoll.h>
-#include <sys/eventfd.h>
-#include <sys/poll.h>
-
-#include <algorithm>
-#include <atomic>
-#include <thread>
-
-#include <log/log.h>
-#include <private/dvr/bufferhub_rpc.h>
-#include <private/dvr/consumer_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <sync/sync.h>
-#include <utils/Trace.h>
-
-using android::pdx::BorrowedHandle;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::BufferWrapper;
-using android::pdx::rpc::DispatchRemoteMethod;
-using android::pdx::rpc::WrapBuffer;
-
-namespace android {
-namespace dvr {
-
-ProducerChannel::ProducerChannel(BufferHubService* service, int buffer_id,
- int channel_id, IonBuffer buffer,
- IonBuffer metadata_buffer,
- size_t user_metadata_size, int* error)
- : BufferHubChannel(service, buffer_id, channel_id, kProducerType),
- buffer_(std::move(buffer)),
- metadata_buffer_(std::move(metadata_buffer)),
- user_metadata_size_(user_metadata_size),
- metadata_buf_size_(BufferHubDefs::kMetadataHeaderSize +
- user_metadata_size) {
- if (!buffer_.IsValid()) {
- ALOGE("ProducerChannel::ProducerChannel: Invalid buffer.");
- *error = -EINVAL;
- return;
- }
- if (!metadata_buffer_.IsValid()) {
- ALOGE("ProducerChannel::ProducerChannel: Invalid metadata buffer.");
- *error = -EINVAL;
- return;
- }
-
- *error = InitializeBuffer();
-}
-
-ProducerChannel::ProducerChannel(BufferHubService* service, int channel_id,
- uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t user_metadata_size,
- int* error)
- : BufferHubChannel(service, channel_id, channel_id, kProducerType),
- user_metadata_size_(user_metadata_size),
- metadata_buf_size_(BufferHubDefs::kMetadataHeaderSize +
- user_metadata_size) {
- if (int ret = buffer_.Alloc(width, height, layer_count, format, usage)) {
- ALOGE("ProducerChannel::ProducerChannel: Failed to allocate buffer: %s",
- strerror(-ret));
- *error = ret;
- return;
- }
-
- if (int ret = metadata_buffer_.Alloc(metadata_buf_size_, /*height=*/1,
- /*layer_count=*/1,
- BufferHubDefs::kMetadataFormat,
- BufferHubDefs::kMetadataUsage)) {
- ALOGE("ProducerChannel::ProducerChannel: Failed to allocate metadata: %s",
- strerror(-ret));
- *error = ret;
- return;
- }
-
- *error = InitializeBuffer();
-}
-
-int ProducerChannel::InitializeBuffer() {
- void* metadata_ptr = nullptr;
- if (int ret = metadata_buffer_.Lock(BufferHubDefs::kMetadataUsage, /*x=*/0,
- /*y=*/0, metadata_buf_size_,
- /*height=*/1, &metadata_ptr)) {
- ALOGE("ProducerChannel::ProducerChannel: Failed to lock metadata.");
- return ret;
- }
- metadata_header_ =
- reinterpret_cast<BufferHubDefs::MetadataHeader*>(metadata_ptr);
-
- // Using placement new here to reuse shared memory instead of new allocation
- // and also initialize the value to zero.
- buffer_state_ = new (&metadata_header_->bufferState) std::atomic<uint32_t>(0);
- fence_state_ = new (&metadata_header_->fenceState) std::atomic<uint32_t>(0);
- active_clients_bit_mask_ =
- new (&metadata_header_->activeClientsBitMask) std::atomic<uint32_t>(0);
-
- // Producer channel is never created after consumer channel, and one buffer
- // only have one fixed producer for now. Thus, it is correct to assume
- // producer state bit is kFirstClientBitMask for now.
- active_clients_bit_mask_->store(BufferHubDefs::kFirstClientBitMask,
- std::memory_order_release);
-
- acquire_fence_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
- release_fence_fd_.Reset(epoll_create1(EPOLL_CLOEXEC));
- if (!acquire_fence_fd_ || !release_fence_fd_) {
- ALOGE("ProducerChannel::ProducerChannel: Failed to create shared fences.");
- return -EIO;
- }
-
- dummy_fence_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
- if (!dummy_fence_fd_) {
- ALOGE("ProducerChannel::ProducerChannel: Failed to create dummy fences.");
- return EIO;
- }
-
- epoll_event event;
- event.events = 0;
- event.data.u32 = 0U;
- if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_ADD, dummy_fence_fd_.Get(),
- &event) < 0) {
- ALOGE(
- "ProducerChannel::ProducerChannel: Failed to modify the shared "
- "release fence to include the dummy fence: %s",
- strerror(errno));
- return -EIO;
- }
-
- // Success.
- return 0;
-}
-
-std::unique_ptr<ProducerChannel> ProducerChannel::Create(
- BufferHubService* service, int buffer_id, int channel_id, IonBuffer buffer,
- IonBuffer metadata_buffer, size_t user_metadata_size) {
- int error = 0;
- std::unique_ptr<ProducerChannel> producer(new ProducerChannel(
- service, buffer_id, channel_id, std::move(buffer),
- std::move(metadata_buffer), user_metadata_size, &error));
-
- if (error < 0)
- return nullptr;
- else
- return producer;
-}
-
-Status<std::shared_ptr<ProducerChannel>> ProducerChannel::Create(
- BufferHubService* service, int channel_id, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format, uint64_t usage,
- size_t user_metadata_size) {
- int error;
- std::shared_ptr<ProducerChannel> producer(
- new ProducerChannel(service, channel_id, width, height, layer_count,
- format, usage, user_metadata_size, &error));
- if (error < 0)
- return ErrorStatus(-error);
- else
- return {std::move(producer)};
-}
-
-ProducerChannel::~ProducerChannel() {
- ALOGD_IF(TRACE,
- "ProducerChannel::~ProducerChannel: channel_id=%d buffer_id=%d "
- "state=%" PRIx32 ".",
- channel_id(), buffer_id(),
- buffer_state_->load(std::memory_order_acquire));
- for (auto consumer : consumer_channels_) {
- consumer->OnProducerClosed();
- }
- Hangup();
-}
-
-BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
- // Derive the mask of signaled buffers in this producer / consumer set.
- uint32_t signaled_mask = signaled() ? BufferHubDefs::kFirstClientBitMask : 0;
- for (const ConsumerChannel* consumer : consumer_channels_) {
- signaled_mask |= consumer->signaled() ? consumer->client_state_mask() : 0;
- }
-
- return BufferInfo(buffer_id(), consumer_channels_.size(), buffer_.width(),
- buffer_.height(), buffer_.layer_count(), buffer_.format(),
- buffer_.usage(),
- buffer_state_->load(std::memory_order_acquire),
- signaled_mask, metadata_header_->queueIndex);
-}
-
-void ProducerChannel::HandleImpulse(Message& message) {
- ATRACE_NAME("ProducerChannel::HandleImpulse");
- switch (message.GetOp()) {
- case BufferHubRPC::ProducerGain::Opcode:
- OnProducerGain(message);
- break;
- case BufferHubRPC::ProducerPost::Opcode:
- OnProducerPost(message, {});
- break;
- }
-}
-
-bool ProducerChannel::HandleMessage(Message& message) {
- ATRACE_NAME("ProducerChannel::HandleMessage");
- switch (message.GetOp()) {
- case BufferHubRPC::GetBuffer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::GetBuffer>(
- *this, &ProducerChannel::OnGetBuffer, message);
- return true;
-
- case BufferHubRPC::NewConsumer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::NewConsumer>(
- *this, &ProducerChannel::OnNewConsumer, message);
- return true;
-
- case BufferHubRPC::ProducerPost::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ProducerPost>(
- *this, &ProducerChannel::OnProducerPost, message);
- return true;
-
- case BufferHubRPC::ProducerGain::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ProducerGain>(
- *this, &ProducerChannel::OnProducerGain, message);
- return true;
-
- default:
- return false;
- }
-}
-
-BufferDescription<BorrowedHandle> ProducerChannel::GetBuffer(
- uint32_t client_state_mask) {
- return {buffer_,
- metadata_buffer_,
- buffer_id(),
- channel_id(),
- client_state_mask,
- acquire_fence_fd_.Borrow(),
- release_fence_fd_.Borrow()};
-}
-
-Status<BufferDescription<BorrowedHandle>> ProducerChannel::OnGetBuffer(
- Message& /*message*/) {
- ATRACE_NAME("ProducerChannel::OnGetBuffer");
- ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d, state=%" PRIx32 ".",
- buffer_id(), buffer_state_->load(std::memory_order_acquire));
- return {GetBuffer(BufferHubDefs::kFirstClientBitMask)};
-}
-
-Status<uint32_t> ProducerChannel::CreateConsumerStateMask() {
- // Try find the next consumer state bit which has not been claimed by any
- // consumer yet.
- // memory_order_acquire is chosen here because all writes in other threads
- // that release active_clients_bit_mask_ need to be visible here.
- uint32_t current_active_clients_bit_mask =
- active_clients_bit_mask_->load(std::memory_order_acquire);
- uint32_t consumer_state_mask =
- BufferHubDefs::findNextAvailableClientStateMask(
- current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
- if (consumer_state_mask == 0U) {
- ALOGE("%s: reached the maximum mumber of consumers per producer: 63.",
- __FUNCTION__);
- return ErrorStatus(E2BIG);
- }
- uint32_t updated_active_clients_bit_mask =
- current_active_clients_bit_mask | consumer_state_mask;
- // Set the updated value only if the current value stays the same as what was
- // read before. If the comparison succeeds, update the value without
- // reordering anything before or after this read-modify-write in the current
- // thread, and the modification will be visible in other threads that acquire
- // active_clients_bit_mask_. If the comparison fails, load the result of
- // all writes from all threads to updated_active_clients_bit_mask.
- // Keep on finding the next available slient state mask until succeed or out
- // of memory.
- while (!active_clients_bit_mask_->compare_exchange_weak(
- current_active_clients_bit_mask, updated_active_clients_bit_mask,
- std::memory_order_acq_rel, std::memory_order_acquire)) {
- ALOGE("%s: Current active clients bit mask is changed to %" PRIx32
- ", which was expected to be %" PRIx32
- ". Trying to generate a new client state mask to resolve race "
- "condition.",
- __FUNCTION__, updated_active_clients_bit_mask,
- current_active_clients_bit_mask);
- consumer_state_mask = BufferHubDefs::findNextAvailableClientStateMask(
- current_active_clients_bit_mask | orphaned_consumer_bit_mask_);
- if (consumer_state_mask == 0U) {
- ALOGE("%s: reached the maximum mumber of consumers per producer: %d.",
- __FUNCTION__, (BufferHubDefs::kMaxNumberOfClients - 1));
- return ErrorStatus(E2BIG);
- }
- updated_active_clients_bit_mask =
- current_active_clients_bit_mask | consumer_state_mask;
- }
-
- return {consumer_state_mask};
-}
-
-void ProducerChannel::RemoveConsumerClientMask(uint32_t consumer_state_mask) {
- // Clear up the buffer state and fence state in case there is already
- // something there due to possible race condition between producer post and
- // consumer failed to create channel.
- buffer_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
- fence_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
- // Restore the consumer state bit and make it visible in other threads that
- // acquire the active_clients_bit_mask_.
- active_clients_bit_mask_->fetch_and(~consumer_state_mask,
- std::memory_order_release);
-}
-
-Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(
- Message& message, uint32_t consumer_state_mask) {
- ATRACE_NAME(__FUNCTION__);
- ALOGD("%s: buffer_id=%d", __FUNCTION__, buffer_id());
-
- int channel_id;
- auto status = message.PushChannel(0, nullptr, &channel_id);
- if (!status) {
- ALOGE("%s: Failed to push consumer channel: %s", __FUNCTION__,
- status.GetErrorMessage().c_str());
- RemoveConsumerClientMask(consumer_state_mask);
- return ErrorStatus(ENOMEM);
- }
-
- auto consumer = std::make_shared<ConsumerChannel>(
- service(), buffer_id(), channel_id, consumer_state_mask,
- shared_from_this());
- const auto channel_status = service()->SetChannel(channel_id, consumer);
- if (!channel_status) {
- ALOGE("%s: failed to set new consumer channel: %s.", __FUNCTION__,
- channel_status.GetErrorMessage().c_str());
- RemoveConsumerClientMask(consumer_state_mask);
- return ErrorStatus(ENOMEM);
- }
-
- uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- // Return the consumer channel handle without signal when adding the new
- // consumer to a buffer that is available to producer (a.k.a a fully-released
- // buffer) or a gained buffer.
- if (current_buffer_state == 0U ||
- BufferHubDefs::isAnyClientGained(current_buffer_state)) {
- return {status.take()};
- }
-
- // Signal the new consumer when adding it to a posted producer.
- bool update_buffer_state = true;
- if (!BufferHubDefs::isClientPosted(current_buffer_state,
- consumer_state_mask)) {
- uint32_t updated_buffer_state =
- current_buffer_state ^
- (consumer_state_mask & BufferHubDefs::kHighBitsMask);
- while (!buffer_state_->compare_exchange_weak(
- current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
- std::memory_order_acquire)) {
- ALOGV(
- "%s: Failed to post to the new consumer. "
- "Current buffer state was changed to %" PRIx32
- " when trying to acquire the buffer and modify the buffer state to "
- "%" PRIx32
- ". About to try again if the buffer is still not gained nor fully "
- "released.",
- __FUNCTION__, current_buffer_state, updated_buffer_state);
- if (current_buffer_state == 0U ||
- BufferHubDefs::isAnyClientGained(current_buffer_state)) {
- ALOGI("%s: buffer is gained or fully released, state=%" PRIx32 ".",
- __FUNCTION__, current_buffer_state);
- update_buffer_state = false;
- break;
- }
- updated_buffer_state =
- current_buffer_state ^
- (consumer_state_mask & BufferHubDefs::kHighBitsMask);
- }
- }
- if (update_buffer_state || BufferHubDefs::isClientPosted(
- buffer_state_->load(std::memory_order_acquire),
- consumer_state_mask)) {
- consumer->OnProducerPosted();
- }
-
- return {status.take()};
-}
-
-Status<RemoteChannelHandle> ProducerChannel::OnNewConsumer(Message& message) {
- ATRACE_NAME("ProducerChannel::OnNewConsumer");
- ALOGD_IF(TRACE, "ProducerChannel::OnNewConsumer: buffer_id=%d", buffer_id());
- auto status = CreateConsumerStateMask();
- if (!status.ok()) {
- return status.error_status();
- }
- return CreateConsumer(message, /*consumer_state_mask=*/status.get());
-}
-
-Status<void> ProducerChannel::OnProducerPost(Message&,
- LocalFence acquire_fence) {
- ATRACE_NAME("ProducerChannel::OnProducerPost");
- ALOGD_IF(TRACE, "%s: buffer_id=%d, state=0x%x", __FUNCTION__, buffer_id(),
- buffer_state_->load(std::memory_order_acquire));
-
- epoll_event event;
- event.events = 0;
- event.data.u32 = 0U;
- int ret = epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
- dummy_fence_fd_.Get(), &event);
- ALOGE_IF(ret < 0,
- "ProducerChannel::OnProducerPost: Failed to modify the shared "
- "release fence to include the dummy fence: %s",
- strerror(errno));
-
- eventfd_t dummy_fence_count = 0U;
- if (eventfd_read(dummy_fence_fd_.Get(), &dummy_fence_count) < 0) {
- const int error = errno;
- if (error != EAGAIN) {
- ALOGE(
- "ProducerChannel::ProducerChannel: Failed to read dummy fence, "
- "error: %s",
- strerror(error));
- return ErrorStatus(error);
- }
- }
-
- ALOGW_IF(dummy_fence_count > 0,
- "ProducerChannel::ProducerChannel: %" PRIu64
- " dummy fence(s) was signaled during last release/gain cycle "
- "buffer_id=%d.",
- dummy_fence_count, buffer_id());
-
- post_fence_ = std::move(acquire_fence);
-
- // Signal any interested consumers. If there are none, the buffer will stay
- // in posted state until a consumer comes online. This behavior guarantees
- // that no frame is silently dropped.
- for (auto& consumer : consumer_channels_) {
- consumer->OnProducerPosted();
- }
-
- return {};
-}
-
-Status<LocalFence> ProducerChannel::OnProducerGain(Message& /*message*/) {
- ATRACE_NAME("ProducerChannel::OnGain");
- ALOGD_IF(TRACE, "%s: buffer_id=%d", __FUNCTION__, buffer_id());
-
- ClearAvailable();
- post_fence_.close();
- for (auto& consumer : consumer_channels_) {
- consumer->OnProducerGained();
- }
- return {std::move(returned_fence_)};
-}
-
-// TODO(b/112338294) Keep here for reference. Remove it after new logic is
-// written.
-/* Status<RemoteChannelHandle> ProducerChannel::OnProducerDetach(
- Message& message) {
- ATRACE_NAME("ProducerChannel::OnProducerDetach");
- ALOGD_IF(TRACE, "ProducerChannel::OnProducerDetach: buffer_id=%d",
- buffer_id());
-
- uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
- if (!BufferHubDefs::isClientGained(
- buffer_state, BufferHubDefs::kFirstClientStateMask)) {
- // Can only detach a ProducerBuffer when it's in gained state.
- ALOGW(
- "ProducerChannel::OnProducerDetach: The buffer (id=%d, state=%"
- PRIx32
- ") is not in gained state.",
- buffer_id(), buffer_state);
- return {};
- }
-
- int channel_id;
- auto status = message.PushChannel(0, nullptr, &channel_id);
- if (!status) {
- ALOGE(
- "ProducerChannel::OnProducerDetach: Failed to push detached buffer "
- "channel: %s",
- status.GetErrorMessage().c_str());
- return ErrorStatus(ENOMEM);
- }
-
- // Make sure we unlock the buffer.
- if (int ret = metadata_buffer_.Unlock()) {
- ALOGE("ProducerChannel::OnProducerDetach: Failed to unlock metadata.");
- return ErrorStatus(-ret);
- };
-
- std::unique_ptr<BufferChannel> channel =
- BufferChannel::Create(service(), buffer_id(), channel_id,
- std::move(buffer_), user_metadata_size_);
- if (!channel) {
- ALOGE("ProducerChannel::OnProducerDetach: Invalid buffer.");
- return ErrorStatus(EINVAL);
- }
-
- const auto channel_status =
- service()->SetChannel(channel_id, std::move(channel));
- if (!channel_status) {
- // Technically, this should never fail, as we just pushed the channel.
- // Note that LOG_FATAL will be stripped out in non-debug build.
- LOG_FATAL(
- "ProducerChannel::OnProducerDetach: Failed to set new detached "
- "buffer channel: %s.", channel_status.GetErrorMessage().c_str());
- }
-
- return status;
-} */
-
-Status<LocalFence> ProducerChannel::OnConsumerAcquire(Message& /*message*/) {
- ATRACE_NAME("ProducerChannel::OnConsumerAcquire");
- ALOGD_IF(TRACE, "ProducerChannel::OnConsumerAcquire: buffer_id=%d",
- buffer_id());
-
- // Return a borrowed fd to avoid unnecessary duplication of the underlying
- // fd. Serialization just needs to read the handle.
- return {std::move(post_fence_)};
-}
-
-Status<void> ProducerChannel::OnConsumerRelease(Message&,
- LocalFence release_fence) {
- ATRACE_NAME("ProducerChannel::OnConsumerRelease");
- ALOGD_IF(TRACE, "ProducerChannel::OnConsumerRelease: buffer_id=%d",
- buffer_id());
-
- // Attempt to merge the fences if necessary.
- if (release_fence) {
- if (returned_fence_) {
- LocalFence merged_fence(sync_merge("bufferhub_merged",
- returned_fence_.get_fd(),
- release_fence.get_fd()));
- const int error = errno;
- if (!merged_fence) {
- ALOGE("ProducerChannel::OnConsumerRelease: Failed to merge fences: %s",
- strerror(error));
- return ErrorStatus(error);
- }
- returned_fence_ = std::move(merged_fence);
- } else {
- returned_fence_ = std::move(release_fence);
- }
- }
-
- if (IsBufferReleasedByAllActiveClientsExceptForOrphans()) {
- buffer_state_->store(0U);
- SignalAvailable();
- if (orphaned_consumer_bit_mask_) {
- ALOGW(
- "%s: orphaned buffer detected during the this acquire/release cycle: "
- "id=%d orphaned=0x%" PRIx32 " queue_index=%" PRId64 ".",
- __FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
- metadata_header_->queueIndex);
- orphaned_consumer_bit_mask_ = 0;
- }
- }
-
- return {};
-}
-
-void ProducerChannel::OnConsumerOrphaned(const uint32_t& consumer_state_mask) {
- // Remember the ignored consumer so that newly added consumer won't be
- // taking the same state mask as this orphaned consumer.
- ALOGE_IF(orphaned_consumer_bit_mask_ & consumer_state_mask,
- "%s: Consumer (consumer_state_mask=%" PRIx32
- ") is already orphaned.",
- __FUNCTION__, consumer_state_mask);
- orphaned_consumer_bit_mask_ |= consumer_state_mask;
-
- if (IsBufferReleasedByAllActiveClientsExceptForOrphans()) {
- buffer_state_->store(0U);
- SignalAvailable();
- }
-
- // Atomically clear the fence state bit as an orphaned consumer will never
- // signal a release fence.
- fence_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
- // Atomically set the buffer state of this consumer to released state.
- buffer_state_->fetch_and(~consumer_state_mask, std::memory_order_release);
-
- ALOGW(
- "%s: detected new orphaned consumer buffer_id=%d "
- "consumer_state_mask=%" PRIx32 " queue_index=%" PRId64
- " buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
- __FUNCTION__, buffer_id(), consumer_state_mask,
- metadata_header_->queueIndex,
- buffer_state_->load(std::memory_order_acquire),
- fence_state_->load(std::memory_order_acquire));
-}
-
-void ProducerChannel::AddConsumer(ConsumerChannel* channel) {
- consumer_channels_.push_back(channel);
-}
-
-void ProducerChannel::RemoveConsumer(ConsumerChannel* channel) {
- consumer_channels_.erase(
- std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
- // Restore the consumer state bit and make it visible in other threads that
- // acquire the active_clients_bit_mask_.
- uint32_t consumer_state_mask = channel->client_state_mask();
- uint32_t current_active_clients_bit_mask =
- active_clients_bit_mask_->load(std::memory_order_acquire);
- uint32_t updated_active_clients_bit_mask =
- current_active_clients_bit_mask & (~consumer_state_mask);
- while (!active_clients_bit_mask_->compare_exchange_weak(
- current_active_clients_bit_mask, updated_active_clients_bit_mask,
- std::memory_order_acq_rel, std::memory_order_acquire)) {
- ALOGI(
- "%s: Failed to remove consumer state mask. Current active clients bit "
- "mask is changed to %" PRIx32
- " when trying to acquire and modify it to %" PRIx32
- ". About to try again.",
- __FUNCTION__, current_active_clients_bit_mask,
- updated_active_clients_bit_mask);
- updated_active_clients_bit_mask =
- current_active_clients_bit_mask & (~consumer_state_mask);
- }
-
- const uint32_t current_buffer_state =
- buffer_state_->load(std::memory_order_acquire);
- if (BufferHubDefs::isClientPosted(current_buffer_state,
- consumer_state_mask) ||
- BufferHubDefs::isClientAcquired(current_buffer_state,
- consumer_state_mask)) {
- // The consumer client is being destoryed without releasing. This could
- // happen in corner cases when the consumer crashes. Here we mark it
- // orphaned before remove it from producer.
- OnConsumerOrphaned(consumer_state_mask);
- return;
- }
-
- if (BufferHubDefs::isClientReleased(current_buffer_state,
- consumer_state_mask) ||
- BufferHubDefs::isAnyClientGained(current_buffer_state)) {
- // The consumer is being close while it is suppose to signal a release
- // fence. Signal the dummy fence here.
- if (fence_state_->load(std::memory_order_acquire) & consumer_state_mask) {
- epoll_event event;
- event.events = EPOLLIN;
- event.data.u32 = consumer_state_mask;
- if (epoll_ctl(release_fence_fd_.Get(), EPOLL_CTL_MOD,
- dummy_fence_fd_.Get(), &event) < 0) {
- ALOGE(
- "%s: Failed to modify the shared release fence to include the "
- "dummy fence: %s",
- __FUNCTION__, strerror(errno));
- return;
- }
- ALOGW("%s: signal dummy release fence buffer_id=%d", __FUNCTION__,
- buffer_id());
- eventfd_write(dummy_fence_fd_.Get(), 1);
- }
- }
-}
-
-// Returns true if the given parameters match the underlying buffer
-// parameters.
-bool ProducerChannel::CheckParameters(uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t format,
- uint64_t usage,
- size_t user_metadata_size) const {
- return user_metadata_size == user_metadata_size_ &&
- buffer_.width() == width && buffer_.height() == height &&
- buffer_.layer_count() == layer_count && buffer_.format() == format &&
- buffer_.usage() == usage;
-}
-
-bool ProducerChannel::IsBufferReleasedByAllActiveClientsExceptForOrphans()
- const {
- return (buffer_state_->load(std::memory_order_acquire) &
- ~orphaned_consumer_bit_mask_ &
- active_clients_bit_mask_->load(std::memory_order_acquire)) == 0U;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
deleted file mode 100644
index 004dc7c..0000000
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ /dev/null
@@ -1,397 +0,0 @@
-#include <inttypes.h>
-
-#include <private/dvr/consumer_queue_channel.h>
-#include <private/dvr/producer_channel.h>
-#include <private/dvr/producer_queue_channel.h>
-
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::RemoteChannelHandle;
-using android::pdx::Status;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace android {
-namespace dvr {
-
-ProducerQueueChannel::ProducerQueueChannel(BufferHubService* service,
- int channel_id,
- const ProducerQueueConfig& config,
- const UsagePolicy& usage_policy,
- int* error)
- : BufferHubChannel(service, channel_id, channel_id, kProducerQueueType),
- config_(config),
- usage_policy_(usage_policy),
- capacity_(0) {
- *error = 0;
-}
-
-ProducerQueueChannel::~ProducerQueueChannel() {
- ALOGD_IF(TRACE, "ProducerQueueChannel::~ProducerQueueChannel: queue_id=%d",
- buffer_id());
- for (auto* consumer : consumer_channels_)
- consumer->OnProducerClosed();
-}
-
-/* static */
-Status<std::shared_ptr<ProducerQueueChannel>> ProducerQueueChannel::Create(
- BufferHubService* service, int channel_id,
- const ProducerQueueConfig& config, const UsagePolicy& usage_policy) {
- // Configuration between |usage_deny_set_mask| and |usage_deny_clear_mask|
- // should be mutually exclusive.
- if ((usage_policy.usage_deny_set_mask & usage_policy.usage_deny_clear_mask)) {
- ALOGE(
- "BufferHubService::OnCreateProducerQueue: illegal usage mask "
- "configuration: usage_deny_set_mask=%" PRIx64
- " usage_deny_clear_mask=%" PRIx64,
- usage_policy.usage_deny_set_mask, usage_policy.usage_deny_clear_mask);
- return ErrorStatus(EINVAL);
- }
-
- int error = 0;
- std::shared_ptr<ProducerQueueChannel> producer(new ProducerQueueChannel(
- service, channel_id, config, usage_policy, &error));
- if (error < 0)
- return ErrorStatus(-error);
- else
- return {std::move(producer)};
-}
-
-bool ProducerQueueChannel::HandleMessage(Message& message) {
- ATRACE_NAME("ProducerQueueChannel::HandleMessage");
- switch (message.GetOp()) {
- case BufferHubRPC::CreateConsumerQueue::Opcode:
- DispatchRemoteMethod<BufferHubRPC::CreateConsumerQueue>(
- *this, &ProducerQueueChannel::OnCreateConsumerQueue, message);
- return true;
-
- case BufferHubRPC::GetQueueInfo::Opcode:
- DispatchRemoteMethod<BufferHubRPC::GetQueueInfo>(
- *this, &ProducerQueueChannel::OnGetQueueInfo, message);
- return true;
-
- case BufferHubRPC::ProducerQueueAllocateBuffers::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
- *this, &ProducerQueueChannel::OnProducerQueueAllocateBuffers,
- message);
- return true;
-
- case BufferHubRPC::ProducerQueueInsertBuffer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ProducerQueueInsertBuffer>(
- *this, &ProducerQueueChannel::OnProducerQueueInsertBuffer, message);
- return true;
-
- case BufferHubRPC::ProducerQueueRemoveBuffer::Opcode:
- DispatchRemoteMethod<BufferHubRPC::ProducerQueueRemoveBuffer>(
- *this, &ProducerQueueChannel::OnProducerQueueRemoveBuffer, message);
- return true;
-
- default:
- return false;
- }
-}
-
-void ProducerQueueChannel::HandleImpulse(Message& /* message */) {
- ATRACE_NAME("ProducerQueueChannel::HandleImpulse");
-}
-
-BufferHubChannel::BufferInfo ProducerQueueChannel::GetBufferInfo() const {
- return BufferInfo(channel_id(), consumer_channels_.size(), capacity_,
- usage_policy_);
-}
-
-Status<RemoteChannelHandle> ProducerQueueChannel::OnCreateConsumerQueue(
- Message& message, bool silent) {
- ATRACE_NAME("ProducerQueueChannel::OnCreateConsumerQueue");
- ALOGD_IF(
- TRACE,
- "ProducerQueueChannel::OnCreateConsumerQueue: channel_id=%d slient=%d",
- channel_id(), silent);
-
- int channel_id;
- auto status = message.PushChannel(0, nullptr, &channel_id);
- if (!status) {
- ALOGE(
- "ProducerQueueChannel::OnCreateConsumerQueue: failed to push consumer "
- "channel: %s",
- status.GetErrorMessage().c_str());
- return ErrorStatus(ENOMEM);
- }
-
- auto consumer_queue_channel = std::make_shared<ConsumerQueueChannel>(
- service(), buffer_id(), channel_id, shared_from_this(), silent);
-
- // Register the existing buffers with the new consumer queue.
- for (size_t slot = 0; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
- if (auto buffer = buffers_[slot].lock())
- consumer_queue_channel->RegisterNewBuffer(buffer, slot);
- }
-
- const auto channel_status =
- service()->SetChannel(channel_id, consumer_queue_channel);
- if (!channel_status) {
- ALOGE(
- "ProducerQueueChannel::OnCreateConsumerQueue: Failed to set channel: "
- "%s",
- channel_status.GetErrorMessage().c_str());
- return ErrorStatus(ENOMEM);
- }
-
- return {status.take()};
-}
-
-Status<QueueInfo> ProducerQueueChannel::OnGetQueueInfo(Message&) {
- return {{config_, buffer_id()}};
-}
-
-Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ProducerQueueChannel::OnProducerQueueAllocateBuffers(
- Message& message, uint32_t width, uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage, size_t buffer_count) {
- ATRACE_NAME("ProducerQueueChannel::OnProducerQueueAllocateBuffers");
- ALOGD_IF(TRACE,
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: "
- "producer_channel_id=%d",
- channel_id());
-
- std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
-
- // Deny buffer allocation violating preset rules.
- if (usage & usage_policy_.usage_deny_set_mask) {
- ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %" PRIx64
- " is not permitted. Violating usage_deny_set_mask, the following bits "
- "shall not be set: %" PRIx64 ".",
- usage, usage_policy_.usage_deny_set_mask);
- return ErrorStatus(EINVAL);
- }
-
- if (~usage & usage_policy_.usage_deny_clear_mask) {
- ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %" PRIx64
- " is not permitted. Violating usage_deny_clear_mask, the following "
- "bits must be set: %" PRIx64 ".",
- usage, usage_policy_.usage_deny_clear_mask);
- return ErrorStatus(EINVAL);
- }
-
- // Force set mask and clear mask. Note that |usage_policy_.usage_set_mask_|
- // takes precedence and will overwrite |usage_policy_.usage_clear_mask|.
- uint64_t effective_usage =
- (usage & ~usage_policy_.usage_clear_mask) | usage_policy_.usage_set_mask;
-
- for (size_t i = 0; i < buffer_count; i++) {
- auto status = AllocateBuffer(message, width, height, layer_count, format,
- effective_usage);
- if (!status) {
- ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: Failed to "
- "allocate new buffer.");
- return ErrorStatus(status.error());
- }
- buffer_handles.push_back(status.take());
- }
-
- return {std::move(buffer_handles)};
-}
-
-Status<std::pair<RemoteChannelHandle, size_t>>
-ProducerQueueChannel::AllocateBuffer(Message& message, uint32_t width,
- uint32_t height, uint32_t layer_count,
- uint32_t format, uint64_t usage) {
- ATRACE_NAME("ProducerQueueChannel::AllocateBuffer");
- ALOGD_IF(TRACE,
- "ProducerQueueChannel::AllocateBuffer: producer_channel_id=%d",
- channel_id());
-
- if (capacity_ >= BufferHubRPC::kMaxQueueCapacity) {
- ALOGE("ProducerQueueChannel::AllocateBuffer: reaches kMaxQueueCapacity.");
- return ErrorStatus(E2BIG);
- }
-
- // Here we are creating a new BufferHubBuffer, initialize the producer
- // channel, and returning its file handle back to the client.
- // buffer_id is the id of the producer channel of BufferHubBuffer.
- int buffer_id;
- auto status = message.PushChannel(0, nullptr, &buffer_id);
-
- if (!status) {
- ALOGE("ProducerQueueChannel::AllocateBuffer: failed to push channel: %s",
- status.GetErrorMessage().c_str());
- return ErrorStatus(status.error());
- }
-
- ALOGD_IF(TRACE,
- "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%u "
- "height=%u layer_count=%u format=%u usage=%" PRIx64,
- buffer_id, width, height, layer_count, format, usage);
- auto buffer_handle = status.take();
-
- auto producer_channel_status =
- ProducerChannel::Create(service(), buffer_id, width, height, layer_count,
- format, usage, config_.user_metadata_size);
- if (!producer_channel_status) {
- ALOGE(
- "ProducerQueueChannel::AllocateBuffer: Failed to create producer "
- "buffer: %s",
- producer_channel_status.GetErrorMessage().c_str());
- return ErrorStatus(ENOMEM);
- }
- auto producer_channel = producer_channel_status.take();
-
- ALOGD_IF(
- TRACE,
- "ProducerQueueChannel::AllocateBuffer: buffer_id=%d, buffer_handle=%d",
- buffer_id, buffer_handle.value());
-
- const auto channel_status =
- service()->SetChannel(buffer_id, producer_channel);
- if (!channel_status) {
- ALOGE(
- "ProducerQueueChannel::AllocateBuffer: failed to set producer channel "
- "for new BufferHubBuffer: %s",
- channel_status.GetErrorMessage().c_str());
- return ErrorStatus(ENOMEM);
- }
-
- // Register the newly allocated buffer's channel_id into the first empty
- // buffer slot.
- size_t slot = 0;
- for (; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
- if (buffers_[slot].expired())
- break;
- }
- if (slot == BufferHubRPC::kMaxQueueCapacity) {
- ALOGE(
- "ProducerQueueChannel::AllocateBuffer: Cannot find empty slot for new "
- "buffer allocation.");
- return ErrorStatus(E2BIG);
- }
-
- buffers_[slot] = producer_channel;
- capacity_++;
-
- // Notify each consumer channel about the new buffer.
- for (auto* consumer_channel : consumer_channels_) {
- ALOGD(
- "ProducerQueueChannel::AllocateBuffer: Notified consumer with new "
- "buffer, buffer_id=%d",
- buffer_id);
- consumer_channel->RegisterNewBuffer(producer_channel, slot);
- }
-
- return {{std::move(buffer_handle), slot}};
-}
-
-Status<size_t> ProducerQueueChannel::OnProducerQueueInsertBuffer(
- pdx::Message& message, int buffer_cid) {
- ATRACE_NAME("ProducerQueueChannel::InsertBuffer");
- ALOGD_IF(TRACE,
- "ProducerQueueChannel::InsertBuffer: channel_id=%d, buffer_cid=%d",
- channel_id(), buffer_cid);
-
- if (capacity_ >= BufferHubRPC::kMaxQueueCapacity) {
- ALOGE("ProducerQueueChannel::InsertBuffer: reaches kMaxQueueCapacity.");
- return ErrorStatus(E2BIG);
- }
- auto producer_channel = std::static_pointer_cast<ProducerChannel>(
- service()->GetChannel(buffer_cid));
- if (producer_channel == nullptr ||
- producer_channel->channel_type() != BufferHubChannel::kProducerType) {
- // Rejects the request if the requested buffer channel is invalid and/or
- // it's not a ProducerChannel.
- ALOGE(
- "ProducerQueueChannel::InsertBuffer: Invalid buffer_cid=%d, "
- "producer_buffer=0x%p, channel_type=%d.",
- buffer_cid, producer_channel.get(),
- producer_channel == nullptr ? -1 : producer_channel->channel_type());
- return ErrorStatus(EINVAL);
- }
- if (producer_channel->GetActiveProcessId() != message.GetProcessId()) {
- // Rejects the request if the requested buffer channel is not currently
- // connected to the caller this is IPC request. This effectively prevents
- // fake buffer_cid from being injected.
- ALOGE(
- "ProducerQueueChannel::InsertBuffer: Requested buffer channel "
- "(buffer_cid=%d) is not connected to the calling process (pid=%d). "
- "It's connected to a different process (pid=%d).",
- buffer_cid, message.GetProcessId(),
- producer_channel->GetActiveProcessId());
- return ErrorStatus(EINVAL);
- }
- uint64_t buffer_state = producer_channel->buffer_state();
- // TODO(b/112007999) add an atomic variable in metadata header in shared
- // memory to indicate which client is the last producer of the buffer.
- // Currently, the first client is the only producer to the buffer.
- // Thus, it checks whether the first client gains the buffer below.
- if (!BufferHubDefs::isClientGained(buffer_state,
- BufferHubDefs::kFirstClientBitMask)) {
- // Rejects the request if the requested buffer is not in Gained state.
- ALOGE(
- "ProducerQueueChannel::InsertBuffer: The buffer (cid=%d, "
- "state=0x%" PRIx64 ") is not in gained state.",
- buffer_cid, buffer_state);
- return ErrorStatus(EINVAL);
- }
-
- // Register the to-be-inserted buffer's channel_id into the first empty
- // buffer slot.
- size_t slot = 0;
- for (; slot < BufferHubRPC::kMaxQueueCapacity; slot++) {
- if (buffers_[slot].expired())
- break;
- }
- if (slot == BufferHubRPC::kMaxQueueCapacity) {
- ALOGE(
- "ProducerQueueChannel::AllocateBuffer: Cannot find empty slot for new "
- "buffer allocation.");
- return ErrorStatus(E2BIG);
- }
-
- buffers_[slot] = producer_channel;
- capacity_++;
-
- // Notify each consumer channel about the new buffer.
- for (auto* consumer_channel : consumer_channels_) {
- ALOGD(
- "ProducerQueueChannel::AllocateBuffer: Notified consumer with new "
- "buffer, buffer_cid=%d",
- buffer_cid);
- consumer_channel->RegisterNewBuffer(producer_channel, slot);
- }
-
- return {slot};
-}
-
-Status<void> ProducerQueueChannel::OnProducerQueueRemoveBuffer(
- Message& /*message*/, size_t slot) {
- if (buffers_[slot].expired()) {
- ALOGE(
- "ProducerQueueChannel::OnProducerQueueRemoveBuffer: trying to remove "
- "an invalid buffer producer at slot %zu",
- slot);
- return ErrorStatus(EINVAL);
- }
-
- if (capacity_ == 0) {
- ALOGE(
- "ProducerQueueChannel::OnProducerQueueRemoveBuffer: trying to remove a "
- "buffer producer while the queue's capacity is already zero.");
- return ErrorStatus(EINVAL);
- }
-
- buffers_[slot].reset();
- capacity_--;
- return {};
-}
-
-void ProducerQueueChannel::AddConsumer(ConsumerQueueChannel* channel) {
- consumer_channels_.push_back(channel);
-}
-
-void ProducerQueueChannel::RemoveConsumer(ConsumerQueueChannel* channel) {
- consumer_channels_.erase(
- std::find(consumer_channels_.begin(), consumer_channels_.end(), channel));
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/performanced/Android.bp b/services/vr/performanced/Android.bp
deleted file mode 100644
index 5eca88b..0000000
--- a/services/vr/performanced/Android.bp
+++ /dev/null
@@ -1,63 +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-MIT
- default_applicable_licenses: ["frameworks_native_license"],
-}
-
-cc_defaults {
- name: "performanced_defaults",
- static_libs: [
- "libperformance",
- "libvr_manager",
- ],
- shared_libs: [
- "libbinder",
- "libbase",
- "libcutils",
- "liblog",
- "libutils",
- "libpdx_default_transport",
- ],
-}
-
-cc_binary {
- name: "performanced",
- system_ext_specific: true,
- defaults: ["performanced_defaults"],
- srcs: [
- "cpu_set.cpp",
- "main.cpp",
- "performance_service.cpp",
- "task.cpp",
- ],
- cflags: [
- "-DLOG_TAG=\"performanced\"",
- "-DTRACE=0",
- "-Wall",
- "-Werror",
- ],
- init_rc: ["performanced.rc"],
-}
-
-cc_test {
- name: "performance_service_tests",
- defaults: ["performanced_defaults"],
- srcs: ["performance_service_tests.cpp"],
-}
diff --git a/services/vr/performanced/CPPLINT.cfg b/services/vr/performanced/CPPLINT.cfg
deleted file mode 100644
index fd379da..0000000
--- a/services/vr/performanced/CPPLINT.cfg
+++ /dev/null
@@ -1 +0,0 @@
-filter=-runtime/int
diff --git a/services/vr/performanced/cpu_set.cpp b/services/vr/performanced/cpu_set.cpp
deleted file mode 100644
index d940b79..0000000
--- a/services/vr/performanced/cpu_set.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-#include "cpu_set.h"
-
-#include <log/log.h>
-
-#include <algorithm>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include <android-base/file.h>
-
-#include "directory_reader.h"
-#include "stdio_filebuf.h"
-#include "task.h"
-#include "unique_file.h"
-
-using android::pdx::ErrorStatus;
-using android::pdx::Status;
-
-namespace {
-
-constexpr int kDirectoryFlags = O_RDONLY | O_DIRECTORY | O_CLOEXEC;
-constexpr pid_t kKernelThreadDaemonPid = 2;
-
-} // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-bool CpuSet::prefix_enabled_ = false;
-
-void CpuSetManager::Load(const std::string& cpuset_root) {
- if (!root_set_)
- root_set_ = Create(cpuset_root);
-}
-
-std::unique_ptr<CpuSet> CpuSetManager::Create(const std::string& path) {
- base::unique_fd root_cpuset_fd(open(path.c_str(), kDirectoryFlags));
- if (root_cpuset_fd.get() < 0) {
- ALOGE("CpuSet::Create: Failed to open \"%s\": %s", path.c_str(),
- strerror(errno));
- return nullptr;
- }
-
- return Create(std::move(root_cpuset_fd), "/", nullptr);
-}
-
-std::unique_ptr<CpuSet> CpuSetManager::Create(base::unique_fd base_fd,
- const std::string& name,
- CpuSet* parent) {
- DirectoryReader directory(base::unique_fd(dup(base_fd)));
- if (!directory) {
- ALOGE("CpuSet::Create: Failed to opendir %s cpuset: %s", name.c_str(),
- strerror(directory.GetError()));
- return nullptr;
- }
-
- std::unique_ptr<CpuSet> group(
- new CpuSet(parent, name, base::unique_fd(dup(base_fd))));
- path_map_.insert(std::make_pair(group->path(), group.get()));
-
- while (dirent* entry = directory.Next()) {
- if (entry->d_type == DT_DIR) {
- std::string directory_name(entry->d_name);
-
- if (directory_name == "." || directory_name == "..")
- continue;
-
- base::unique_fd entry_fd(
- openat(base_fd.get(), directory_name.c_str(), kDirectoryFlags));
- if (entry_fd.get() >= 0) {
- auto child =
- Create(std::move(entry_fd), directory_name.c_str(), group.get());
-
- if (child)
- group->AddChild(std::move(child));
- else
- return nullptr;
- } else {
- ALOGE("CpuSet::Create: Failed to openat \"%s\": %s", entry->d_name,
- strerror(errno));
- return nullptr;
- }
- }
- }
-
- return group;
-}
-
-CpuSet* CpuSetManager::Lookup(const std::string& path) {
- auto search = path_map_.find(path);
- if (search != path_map_.end())
- return search->second;
- else
- return nullptr;
-}
-
-std::vector<CpuSet*> CpuSetManager::GetCpuSets() {
- std::vector<CpuSet*> sets(path_map_.size());
-
- for (const auto& pair : path_map_) {
- sets.push_back(pair.second);
- }
-
- return sets;
-}
-
-void CpuSetManager::DumpState(std::ostringstream& stream) const {
- size_t max_path = 0;
- std::vector<CpuSet*> sets;
-
- for (const auto& pair : path_map_) {
- max_path = std::max(max_path, pair.second->path().length());
- sets.push_back(pair.second);
- }
-
- std::sort(sets.begin(), sets.end(), [](const CpuSet* a, const CpuSet* b) {
- return a->path() < b->path();
- });
-
- stream << std::left;
- stream << std::setw(max_path) << "Path";
- stream << " ";
- stream << std::setw(6) << "CPUs";
- stream << " ";
- stream << std::setw(6) << "Tasks";
- stream << std::endl;
-
- stream << std::string(max_path, '_');
- stream << " ";
- stream << std::string(6, '_');
- stream << " ";
- stream << std::string(6, '_');
- stream << std::endl;
-
- for (const auto set : sets) {
- stream << std::left;
- stream << std::setw(max_path) << set->path();
- stream << " ";
- stream << std::right;
- stream << std::setw(6) << set->GetCpuList();
- stream << " ";
- stream << std::setw(6) << set->GetTasks().size();
- stream << std::endl;
- }
-}
-
-void CpuSetManager::MoveUnboundTasks(const std::string& target_set) {
- auto root = Lookup("/");
- if (!root) {
- ALOGE("CpuSetManager::MoveUnboundTasks: Failed to find root cpuset!");
- return;
- }
-
- auto target = Lookup(target_set);
- if (!target) {
- ALOGE(
- "CpuSetManager::MoveUnboundTasks: Failed to find target cpuset \"%s\"!",
- target_set.c_str());
- return;
- }
-
- auto cpu_list = root->GetCpuList();
-
- for (auto task_id : root->GetTasks()) {
- Task task(task_id);
-
- // Move only unbound kernel threads to the target cpuset.
- if (task.cpus_allowed_list() == cpu_list &&
- task.parent_process_id() == kKernelThreadDaemonPid) {
- ALOGD_IF(TRACE,
- "CpuSetManager::MoveUnboundTasks: Moving task_id=%d name=%s to "
- "target_set=%s tgid=%d ppid=%d.",
- task_id, task.name().c_str(), target_set.c_str(),
- task.thread_group_id(), task.parent_process_id());
-
- auto status = target->AttachTask(task_id);
- ALOGW_IF(!status && status.error() != EINVAL,
- "CpuSetManager::MoveUnboundTasks: Failed to attach task_id=%d "
- "to cpuset=%s: %s",
- task_id, target_set.c_str(), status.GetErrorMessage().c_str());
- } else {
- ALOGD_IF(TRACE,
- "CpuSet::MoveUnboundTasks: Skipping task_id=%d name=%s cpus=%s.",
- task_id, task.name().c_str(), task.cpus_allowed_list().c_str());
- }
- }
-}
-
-CpuSet::CpuSet(CpuSet* parent, const std::string& name,
- base::unique_fd&& cpuset_fd)
- : parent_(parent), name_(name), cpuset_fd_(std::move(cpuset_fd)) {
- if (parent_ == nullptr)
- path_ = name_;
- else if (parent_->IsRoot())
- path_ = parent_->name() + name_;
- else
- path_ = parent_->path() + "/" + name_;
-
- ALOGI("CpuSet::CpuSet: path=%s", path().c_str());
-}
-
-base::unique_fd CpuSet::OpenPropertyFile(const std::string& name) const {
- return OpenFile(prefix_enabled_ ? "cpuset." + name : name);
-}
-
-UniqueFile CpuSet::OpenPropertyFilePointer(const std::string& name) const {
- return OpenFilePointer(prefix_enabled_ ? "cpuset." + name : name);
-}
-
-base::unique_fd CpuSet::OpenFile(const std::string& name, int flags) const {
- const std::string relative_path = "./" + name;
- return base::unique_fd(
- openat(cpuset_fd_.get(), relative_path.c_str(), flags));
-}
-
-UniqueFile CpuSet::OpenFilePointer(const std::string& name, int flags) const {
- const std::string relative_path = "./" + name;
- base::unique_fd fd(openat(cpuset_fd_.get(), relative_path.c_str(), flags));
- if (fd.get() < 0) {
- ALOGE("CpuSet::OpenPropertyFilePointer: Failed to open %s/%s: %s",
- path_.c_str(), name.c_str(), strerror(errno));
- return nullptr;
- }
-
- UniqueFile fp(fdopen(fd.release(), "r"));
- if (!fp)
- ALOGE("CpuSet::OpenPropertyFilePointer: Failed to fdopen %s/%s: %s",
- path_.c_str(), name.c_str(), strerror(errno));
-
- return fp;
-}
-
-Status<void> CpuSet::AttachTask(pid_t task_id) const {
- auto file = OpenFile("tasks", O_RDWR);
- if (file.get() >= 0) {
- std::ostringstream stream;
- stream << task_id;
- std::string value = stream.str();
-
- const bool ret = base::WriteStringToFd(value, file.get());
- if (!ret)
- return ErrorStatus(errno);
- else
- return {};
- } else {
- const int error = errno;
- ALOGE("CpuSet::AttachTask: Failed to open %s/tasks: %s", path_.c_str(),
- strerror(error));
- return ErrorStatus(error);
- }
-}
-
-std::vector<pid_t> CpuSet::GetTasks() const {
- std::vector<pid_t> tasks;
-
- if (auto file = OpenFilePointer("tasks")) {
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- for (std::string line; std::getline(file_stream, line);) {
- pid_t task_id = std::strtol(line.c_str(), nullptr, 10);
- tasks.push_back(task_id);
- }
- }
-
- return tasks;
-}
-
-std::string CpuSet::GetCpuList() const {
- if (auto file = OpenPropertyFilePointer("cpus")) {
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- std::string line;
- if (std::getline(file_stream, line))
- return line;
- }
-
- ALOGE("CpuSet::GetCpuList: Failed to read cpu list!!!");
- return "";
-}
-
-void CpuSet::AddChild(std::unique_ptr<CpuSet> child) {
- children_.push_back(std::move(child));
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/performanced/cpu_set.h b/services/vr/performanced/cpu_set.h
deleted file mode 100644
index 4c25e9e..0000000
--- a/services/vr/performanced/cpu_set.h
+++ /dev/null
@@ -1,108 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_CPU_SET_H_
-#define ANDROID_DVR_PERFORMANCED_CPU_SET_H_
-
-#include <fcntl.h>
-
-#include <memory>
-#include <mutex>
-#include <sstream>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
-#include <pdx/status.h>
-
-#include "unique_file.h"
-
-namespace android {
-namespace dvr {
-
-class CpuSet {
- public:
- // Returns the parent group for this group, if any. This pointer is owned by
- // the group hierarchy and is only valid as long as the hierarchy is valid.
- CpuSet* parent() const { return parent_; }
- std::string name() const { return name_; }
- std::string path() const { return path_; }
-
- bool IsRoot() const { return parent_ == nullptr; }
-
- std::string GetCpuList() const;
-
- pdx::Status<void> AttachTask(pid_t task_id) const;
- std::vector<pid_t> GetTasks() const;
-
- private:
- friend class CpuSetManager;
-
- CpuSet(CpuSet* parent, const std::string& name, base::unique_fd&& cpuset_fd);
-
- void AddChild(std::unique_ptr<CpuSet> child);
-
- base::unique_fd OpenPropertyFile(const std::string& name) const;
- UniqueFile OpenPropertyFilePointer(const std::string& name) const;
-
- base::unique_fd OpenFile(const std::string& name, int flags = O_RDONLY) const;
- UniqueFile OpenFilePointer(const std::string& name,
- int flags = O_RDONLY) const;
-
- CpuSet* parent_;
- std::string name_;
- std::string path_;
- base::unique_fd cpuset_fd_;
- std::vector<std::unique_ptr<CpuSet>> children_;
-
- static void SetPrefixEnabled(bool enabled) { prefix_enabled_ = enabled; }
- static bool prefix_enabled_;
-
- CpuSet(const CpuSet&) = delete;
- void operator=(const CpuSet&) = delete;
-};
-
-class CpuSetManager {
- public:
- CpuSetManager() {}
-
- // Creats a CpuSet hierarchy by walking the directory tree starting at
- // |cpuset_root|. This argument must be the path to the root cpuset for the
- // system, which is usually /dev/cpuset.
- void Load(const std::string& cpuset_root);
-
- // Lookup and return a CpuSet from a cpuset path. Ownership of the pointer
- // DOES NOT pass to the caller; the pointer remains valid as long as the
- // CpuSet hierarchy is valid.
- CpuSet* Lookup(const std::string& path);
-
- // Returns a vector of all the cpusets found at initializaiton. Ownership of
- // the pointers to CpuSets DOES NOT pass to the caller; the pointers remain
- // valid as long as the CpuSet hierarchy is valid.
- std::vector<CpuSet*> GetCpuSets();
-
- // Moves all unbound tasks from the root set into the target set. This is used
- // to shield the system from interference from unbound kernel threads.
- void MoveUnboundTasks(const std::string& target_set);
-
- void DumpState(std::ostringstream& stream) const;
-
- operator bool() const { return root_set_ != nullptr; }
-
- private:
- // Creates a CpuSet from a path to a cpuset cgroup directory. Recursively
- // creates child groups for each directory found under |path|.
- std::unique_ptr<CpuSet> Create(const std::string& path);
- std::unique_ptr<CpuSet> Create(base::unique_fd base_fd,
- const std::string& name, CpuSet* parent);
-
- std::unique_ptr<CpuSet> root_set_;
- std::unordered_map<std::string, CpuSet*> path_map_;
-
- CpuSetManager(const CpuSetManager&) = delete;
- void operator=(const CpuSetManager&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_CPU_SET_H_
diff --git a/services/vr/performanced/directory_reader.h b/services/vr/performanced/directory_reader.h
deleted file mode 100644
index f8359c4..0000000
--- a/services/vr/performanced/directory_reader.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
-#define ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <android-base/unique_fd.h>
-
-namespace android {
-namespace dvr {
-
-// Utility class around readdir() that handles automatic cleanup.
-class DirectoryReader {
- public:
- explicit DirectoryReader(base::unique_fd directory_fd) {
- int fd = directory_fd.release();
- directory_ = fdopendir(fd);
- error_ = errno;
- if (directory_ == nullptr)
- close(fd);
- }
-
- ~DirectoryReader() {
- if (directory_)
- closedir(directory_);
- }
-
- bool IsValid() const { return directory_ != nullptr; }
- explicit operator bool() const { return IsValid(); }
- int GetError() const { return error_; }
-
- // Returns a pointer to a dirent describing the next directory entry. The
- // pointer is only valid unitl the next call to Next() or the DirectoryReader
- // is destroyed. Returns nullptr when the end of the directory is reached.
- dirent* Next() {
- if (directory_)
- return readdir(directory_);
- else
- return nullptr;
- }
-
- private:
- DIR* directory_;
- int error_;
-
- DirectoryReader(const DirectoryReader&) = delete;
- void operator=(const DirectoryReader&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_DIRECTORY_READER_H_
diff --git a/services/vr/performanced/main.cpp b/services/vr/performanced/main.cpp
deleted file mode 100644
index d7dc8f6..0000000
--- a/services/vr/performanced/main.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-#include <errno.h>
-#include <sys/capability.h>
-#include <sys/prctl.h>
-#include <sys/stat.h>
-
-#include <cutils/properties.h>
-#include <cutils/sched_policy.h>
-#include <log/log.h>
-#include <sys/resource.h>
-#include <utils/threads.h>
-
-#include <pdx/service_dispatcher.h>
-#include <private/android_filesystem_config.h>
-
-#include "performance_service.h"
-
-namespace {
-
-// Annoying that sys/capability.h doesn't define this directly.
-constexpr int kMaxCapNumber = (CAP_TO_INDEX(CAP_LAST_CAP) + 1);
-
-} // anonymous namespace
-
-int main(int /*argc*/, char** /*argv*/) {
- int ret = -1;
-
- struct __user_cap_header_struct capheader;
- struct __user_cap_data_struct capdata[kMaxCapNumber];
-
- std::shared_ptr<android::pdx::Service> service;
- std::unique_ptr<android::pdx::ServiceDispatcher> dispatcher;
-
- ALOGI("Starting up...");
-
- // We need to be able to create endpoints with full perms.
- umask(0000);
-
- // Keep capabilities when switching UID to AID_SYSTEM.
- ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
- CHECK_ERROR(ret < 0, error, "Failed to set KEEPCAPS: %s", strerror(errno));
-
- // Set UID and GID to system.
- ret = setresgid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM);
- CHECK_ERROR(ret < 0, error, "Failed to set GID: %s", strerror(errno));
- ret = setresuid(AID_SYSTEM, AID_SYSTEM, AID_SYSTEM);
- CHECK_ERROR(ret < 0, error, "Failed to set UID: %s", strerror(errno));
-
- // Keep CAP_SYS_NICE, allowing control of scheduler class, priority, and
- // cpuset for other tasks in the system.
- memset(&capheader, 0, sizeof(capheader));
- memset(&capdata, 0, sizeof(capdata));
- capheader.version = _LINUX_CAPABILITY_VERSION_3;
- capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE);
- capdata[CAP_TO_INDEX(CAP_SYS_NICE)].permitted |= CAP_TO_MASK(CAP_SYS_NICE);
-
- // Drop all caps but the ones configured above.
- ret = capset(&capheader, capdata);
- CHECK_ERROR(ret < 0, error, "Could not set capabilities: %s",
- strerror(errno));
-
- dispatcher = android::pdx::ServiceDispatcher::Create();
- CHECK_ERROR(!dispatcher, error, "Failed to create service dispatcher.");
-
- service = android::dvr::PerformanceService::Create();
- CHECK_ERROR(!service, error, "Failed to create performance service service.");
- dispatcher->AddService(service);
-
- ALOGI("Entering message loop.");
-
- ret = dispatcher->EnterDispatchLoop();
- CHECK_ERROR(ret < 0, error, "Dispatch loop exited because: %s\n",
- strerror(-ret));
-
-error:
- return ret;
-}
diff --git a/services/vr/performanced/performance_service.cpp b/services/vr/performanced/performance_service.cpp
deleted file mode 100644
index 73dcf76..0000000
--- a/services/vr/performanced/performance_service.cpp
+++ /dev/null
@@ -1,461 +0,0 @@
-#include "performance_service.h"
-
-#include <sstream>
-
-#include <sched.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include <pdx/default_transport/service_endpoint.h>
-#include <pdx/rpc/argument_encoder.h>
-#include <pdx/rpc/message_buffer.h>
-#include <pdx/rpc/remote_method.h>
-#include <private/android_filesystem_config.h>
-#include <private/dvr/performance_rpc.h>
-#include <private/dvr/trusted_uids.h>
-
-#include "task.h"
-
-// This prctl is only available in Android kernels.
-#define PR_SET_TIMERSLACK_PID 41
-
-using android::dvr::IsTrustedUid;
-using android::dvr::Task;
-using android::pdx::ErrorStatus;
-using android::pdx::Message;
-using android::pdx::Status;
-using android::pdx::default_transport::Endpoint;
-using android::pdx::rpc::DispatchRemoteMethod;
-
-namespace {
-
-const char kCpuSetBasePath[] = "/dev/cpuset";
-
-const char kRootCpuSet[] = "/";
-
-const char kVrAppRenderPolicy[] = "vr:app:render";
-
-const bool kAllowAppsToRequestVrAppRenderPolicy = false;
-
-constexpr unsigned long kTimerSlackForegroundNs = 50000;
-constexpr unsigned long kTimerSlackBackgroundNs = 40000000;
-
-// Expands the given parameter pack expression using an initializer list to
-// guarantee ordering and a comma expression to guarantee even void expressions
-// are valid elements of the initializer list.
-#define EXPAND_PACK(...) \
- std::initializer_list<int> { (__VA_ARGS__, 0)... }
-
-// Returns true if the sender's euid matches any of the uids in |UIDs|.
-template <uid_t... UIDs>
-struct UserId {
- static bool Check(const Message& sender, const Task&) {
- const uid_t uid = sender.GetEffectiveUserId();
- bool allow = false;
- EXPAND_PACK(allow |= (uid == UIDs));
- return allow;
- }
-};
-
-// Returns true if the sender's egid matches any of the gids in |GIDs|.
-template <gid_t... GIDs>
-struct GroupId {
- static bool Check(const Message& sender, const Task&) {
- const gid_t gid = sender.GetEffectiveGroupId();
- bool allow = false;
- EXPAND_PACK(allow |= (gid == GIDs));
- return allow;
- }
-};
-
-// Returns true if the sender's euid is trusted according to VR manager service.
-struct Trusted {
- static bool Check(const Message& sender, const Task&) {
- return IsTrustedUid(sender.GetEffectiveUserId());
- }
-};
-
-// Returns returns true if the task belongs to the sending process.
-struct SameProcess {
- static bool Check(const Message& sender, const Task& task) {
- return sender.GetProcessId() == task.thread_group_id();
- }
-};
-
-// Returns true if any of the checks in |Allows| pass, false otherwise.
-template <typename... Allows>
-struct CheckOr {
- static bool Check(const Message& sender, const Task& task) {
- bool allow = false;
- EXPAND_PACK(allow |= Allows::Check(sender, task));
- return allow;
- }
-};
-
-// Returns true if all of the checks in |Allows| pass, false otherwise.
-template <typename... Allows>
-struct CheckAnd {
- static bool Check(const Message& sender, const Task& task) {
- bool allow = true;
- EXPAND_PACK(allow &= Allows::Check(sender, task));
- return allow;
- }
-};
-
-} // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-PerformanceService::PerformanceService()
- : BASE("PerformanceService",
- Endpoint::Create(PerformanceRPC::kClientPath)) {
- cpuset_.Load(kCpuSetBasePath);
-
- Task task(getpid());
- ALOGI("Running in cpuset=%s uid=%d gid=%d", task.GetCpuSetPath().c_str(),
- task.user_id()[Task::kUidReal], task.group_id()[Task::kUidReal]);
-
- // Errors here are checked in IsInitialized().
- sched_fifo_min_priority_ = sched_get_priority_min(SCHED_FIFO);
- sched_fifo_max_priority_ = sched_get_priority_max(SCHED_FIFO);
-
- const int fifo_range = sched_fifo_max_priority_ - sched_fifo_min_priority_;
- const int fifo_low = sched_fifo_min_priority_;
- const int fifo_medium = sched_fifo_min_priority_ + fifo_range / 5;
-
- // TODO(eieio): Make this configurable on the command line or config file.
- cpuset_.MoveUnboundTasks("/kernel");
-
- // TODO(eieio): Replace this witha device-specific config file. This is just a
- // hack for now to put some form of permission logic in place while a longer
- // term solution is developed.
- using AllowRootSystemGraphics =
- CheckAnd<SameProcess, CheckOr<UserId<AID_ROOT, AID_SYSTEM, AID_GRAPHICS>,
- GroupId<AID_SYSTEM, AID_GRAPHICS>>>;
- using AllowRootSystemAudio =
- CheckAnd<SameProcess, CheckOr<UserId<AID_ROOT, AID_SYSTEM, AID_AUDIO>,
- GroupId<AID_SYSTEM, AID_AUDIO>>>;
- using AllowRootSystemTrusted =
- CheckOr<Trusted, UserId<AID_ROOT, AID_SYSTEM>, GroupId<AID_SYSTEM>>;
-
- auto vr_app_render_permission_check = [](
- const pdx::Message& sender, const Task& task) {
- // For vr:app:render, in addition to system/root apps and VrCore, we
- // also allow apps to request vr:app:render if
- // kAllowAppsToRequestVrAppRenderPolicy == true, but not for other
- // apps, only for themselves.
- return (task && task.thread_group_id() == sender.GetProcessId() &&
- kAllowAppsToRequestVrAppRenderPolicy)
- || AllowRootSystemTrusted::Check(sender, task);
- };
-
- partition_permission_check_ = AllowRootSystemTrusted::Check;
-
- // Setup the scheduler classes.
- // TODO(eieio): Replace this with a device-specific config file.
- scheduler_policies_ = {
- {"audio:low",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium,
- .permission_check = AllowRootSystemAudio::Check}},
- {"audio:high",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium + 3,
- .permission_check = AllowRootSystemAudio::Check}},
- {"graphics",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium,
- .permission_check = AllowRootSystemGraphics::Check}},
- {"graphics:low",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium,
- .permission_check = AllowRootSystemGraphics::Check}},
- {"graphics:high",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium + 2,
- .permission_check = AllowRootSystemGraphics::Check}},
- {"sensors",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_low,
- .permission_check = AllowRootSystemTrusted::Check}},
- {"sensors:low",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_low,
- .permission_check = AllowRootSystemTrusted::Check}},
- {"sensors:high",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_low + 1,
- .permission_check = AllowRootSystemTrusted::Check}},
- {"vr:system:arp",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium + 2,
- .permission_check = AllowRootSystemTrusted::Check,
- "/system/performance"}},
- {kVrAppRenderPolicy,
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_FIFO | SCHED_RESET_ON_FORK,
- .priority = fifo_medium + 1,
- .permission_check = vr_app_render_permission_check,
- "/application/performance"}},
- {"normal",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_NORMAL,
- .priority = 0}},
- {"foreground",
- {.timer_slack = kTimerSlackForegroundNs,
- .scheduler_policy = SCHED_NORMAL,
- .priority = 0}},
- {"background",
- {.timer_slack = kTimerSlackBackgroundNs,
- .scheduler_policy = SCHED_BATCH,
- .priority = 0}},
- {"batch",
- {.timer_slack = kTimerSlackBackgroundNs,
- .scheduler_policy = SCHED_BATCH,
- .priority = 0}},
- };
-}
-
-bool PerformanceService::IsInitialized() const {
- return BASE::IsInitialized() && cpuset_ && sched_fifo_min_priority_ >= 0 &&
- sched_fifo_max_priority_ >= 0;
-}
-
-std::string PerformanceService::DumpState(size_t /*max_length*/) {
- std::ostringstream stream;
- stream << "vr_app_render_thread: " << vr_app_render_thread_ << std::endl;
- cpuset_.DumpState(stream);
- return stream.str();
-}
-
-Status<void> PerformanceService::OnSetSchedulerPolicy(
- Message& message, pid_t task_id, const std::string& scheduler_policy) {
- ALOGI(
- "PerformanceService::OnSetSchedulerPolicy: task_id=%d "
- "scheduler_policy=%s",
- task_id, scheduler_policy.c_str());
-
- Task task(task_id);
- if (!task) {
- ALOGE(
- "PerformanceService::OnSetSchedulerPolicy: Unable to access /proc/%d "
- "to gather task information.",
- task_id);
- return ErrorStatus(EINVAL);
- }
-
- auto search = scheduler_policies_.find(scheduler_policy);
- if (search != scheduler_policies_.end()) {
- auto config = search->second;
-
- // Make sure the sending process is allowed to make the requested change to
- // this task.
- if (!config.IsAllowed(message, task))
- return ErrorStatus(EPERM);
-
- if (scheduler_policy == kVrAppRenderPolicy) {
- // We only allow one vr:app:render thread at a time
- SetVrAppRenderThread(task_id);
- }
-
- // Get the thread group's cpu set. Policies that do not specify a cpuset
- // should default to this cpuset.
- std::string thread_group_cpuset;
- Task thread_group{task.thread_group_id()};
- if (thread_group) {
- thread_group_cpuset = thread_group.GetCpuSetPath();
- } else {
- ALOGE(
- "PerformanceService::OnSetSchedulerPolicy: Failed to get thread "
- "group tgid=%d for task_id=%d",
- task.thread_group_id(), task_id);
- thread_group_cpuset = kRootCpuSet;
- }
-
- std::string target_cpuset;
- if (config.cpuset.empty()) {
- target_cpuset = thread_group_cpuset;
- } else {
- target_cpuset = config.cpuset;
- }
- ALOGI("PerformanceService::OnSetSchedulerPolicy: Using cpuset=%s",
- target_cpuset.c_str());
-
- auto target_set = cpuset_.Lookup(target_cpuset);
- if (target_set) {
- auto attach_status = target_set->AttachTask(task_id);
- ALOGW_IF(!attach_status,
- "PerformanceService::OnSetSchedulerPolicy: Failed to attach "
- "task=%d to cpuset=%s: %s",
- task_id, target_cpuset.c_str(),
- attach_status.GetErrorMessage().c_str());
- } else {
- ALOGW(
- "PerformanceService::OnSetSchedulerPolicy: Failed to lookup "
- "cpuset=%s",
- target_cpuset.c_str());
- }
-
- struct sched_param param;
- param.sched_priority = config.priority;
-
- sched_setscheduler(task_id, config.scheduler_policy, ¶m);
- prctl(PR_SET_TIMERSLACK_PID, config.timer_slack, task_id);
- return {};
- } else {
- ALOGE(
- "PerformanceService::OnSetSchedulerPolicy: Invalid scheduler_policy=%s "
- "requested by task=%d.",
- scheduler_policy.c_str(), task_id);
- return ErrorStatus(EINVAL);
- }
-}
-
-Status<void> PerformanceService::OnSetCpuPartition(
- Message& message, pid_t task_id, const std::string& partition) {
- Task task(task_id);
- if (!task)
- return ErrorStatus(EINVAL);
- if (task.thread_group_id() != message.GetProcessId())
- return ErrorStatus(EPERM);
-
- // Temporary permission check.
- // TODO(eieio): Replace this with a configuration file.
- if (partition_permission_check_ &&
- !partition_permission_check_(message, task)) {
- return ErrorStatus(EPERM);
- }
-
- auto target_set = cpuset_.Lookup(partition);
- if (!target_set)
- return ErrorStatus(ENOENT);
-
- auto attach_status = target_set->AttachTask(task_id);
- if (!attach_status)
- return attach_status;
-
- return {};
-}
-
-Status<void> PerformanceService::OnSetSchedulerClass(
- Message& message, pid_t task_id, const std::string& scheduler_class) {
- Task task(task_id);
- if (!task)
- return ErrorStatus(EINVAL);
-
- auto search = scheduler_policies_.find(scheduler_class);
- if (search != scheduler_policies_.end()) {
- auto config = search->second;
-
- // Make sure the sending process is allowed to make the requested change to
- // this task.
- if (!config.IsAllowed(message, task))
- return ErrorStatus(EPERM);
-
- if (scheduler_class == kVrAppRenderPolicy) {
- // We only allow one vr:app:render thread at a time
- SetVrAppRenderThread(task_id);
- }
-
- struct sched_param param;
- param.sched_priority = config.priority;
-
- sched_setscheduler(task_id, config.scheduler_policy, ¶m);
- prctl(PR_SET_TIMERSLACK_PID, config.timer_slack, task_id);
- ALOGI("PerformanceService::OnSetSchedulerClass: Set task=%d to class=%s.",
- task_id, scheduler_class.c_str());
- return {};
- } else {
- ALOGE(
- "PerformanceService::OnSetSchedulerClass: Invalid class=%s requested "
- "by task=%d.",
- scheduler_class.c_str(), task_id);
- return ErrorStatus(EINVAL);
- }
-}
-
-Status<std::string> PerformanceService::OnGetCpuPartition(Message& message,
- pid_t task_id) {
- // Make sure the task id is valid and belongs to the sending process.
- Task task(task_id);
- if (!task)
- return ErrorStatus(EINVAL);
- if (task.thread_group_id() != message.GetProcessId())
- return ErrorStatus(EPERM);
-
- return task.GetCpuSetPath();
-}
-
-Status<void> PerformanceService::HandleMessage(Message& message) {
- ALOGD_IF(TRACE, "PerformanceService::HandleMessage: op=%d", message.GetOp());
- switch (message.GetOp()) {
- case PerformanceRPC::SetSchedulerPolicy::Opcode:
- DispatchRemoteMethod<PerformanceRPC::SetSchedulerPolicy>(
- *this, &PerformanceService::OnSetSchedulerPolicy, message);
- return {};
-
- case PerformanceRPC::SetCpuPartition::Opcode:
- DispatchRemoteMethod<PerformanceRPC::SetCpuPartition>(
- *this, &PerformanceService::OnSetCpuPartition, message);
- return {};
-
- case PerformanceRPC::SetSchedulerClass::Opcode:
- DispatchRemoteMethod<PerformanceRPC::SetSchedulerClass>(
- *this, &PerformanceService::OnSetSchedulerClass, message);
- return {};
-
- case PerformanceRPC::GetCpuPartition::Opcode:
- DispatchRemoteMethod<PerformanceRPC::GetCpuPartition>(
- *this, &PerformanceService::OnGetCpuPartition, message);
- return {};
-
- default:
- return Service::HandleMessage(message);
- }
-}
-
-void PerformanceService::SetVrAppRenderThread(pid_t new_vr_app_render_thread) {
- ALOGI("SetVrAppRenderThread old=%d new=%d",
- vr_app_render_thread_, new_vr_app_render_thread);
-
- if (vr_app_render_thread_ >= 0 &&
- vr_app_render_thread_ != new_vr_app_render_thread) {
- // Restore the default scheduler policy and priority on the previous
- // vr:app:render thread.
- struct sched_param param;
- param.sched_priority = 0;
- if (sched_setscheduler(vr_app_render_thread_, SCHED_NORMAL, ¶m) < 0) {
- if (errno == ESRCH) {
- ALOGI("Failed to revert %s scheduler policy. Couldn't find thread %d."
- " Was the app killed?", kVrAppRenderPolicy, vr_app_render_thread_);
- } else {
- ALOGE("Failed to revert %s scheduler policy: %s",
- kVrAppRenderPolicy, strerror(errno));
- }
- }
-
- // Restore the default timer slack on the previous vr:app:render thread.
- prctl(PR_SET_TIMERSLACK_PID, kTimerSlackForegroundNs,
- vr_app_render_thread_);
- }
-
- // We could also reset the thread's cpuset here, but the cpuset is already
- // managed by Android. Better to let Android adjust the cpuset as the app
- // moves to the background, rather than adjust it ourselves here, and risk
- // stomping on the value set by Android.
-
- vr_app_render_thread_ = new_vr_app_render_thread;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/performanced/performance_service.h b/services/vr/performanced/performance_service.h
deleted file mode 100644
index fe63756..0000000
--- a/services/vr/performanced/performance_service.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
-#define ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
-
-#include <functional>
-#include <string>
-#include <unordered_map>
-
-#include <pdx/service.h>
-
-#include "cpu_set.h"
-#include "task.h"
-
-namespace android {
-namespace dvr {
-
-// PerformanceService manages compute partitions usings cpusets. Different
-// cpusets are assigned specific purposes and performance characteristics;
-// clients may request for threads to be moved into these cpusets to help
-// achieve system performance goals.
-class PerformanceService : public pdx::ServiceBase<PerformanceService> {
- public:
- pdx::Status<void> HandleMessage(pdx::Message& message) override;
- bool IsInitialized() const override;
-
- std::string DumpState(size_t max_length) override;
-
- private:
- friend BASE;
-
- PerformanceService();
-
- pdx::Status<void> OnSetSchedulerPolicy(pdx::Message& message, pid_t task_id,
- const std::string& scheduler_class);
-
- pdx::Status<void> OnSetCpuPartition(pdx::Message& message, pid_t task_id,
- const std::string& partition);
- pdx::Status<void> OnSetSchedulerClass(pdx::Message& message, pid_t task_id,
- const std::string& scheduler_class);
- pdx::Status<std::string> OnGetCpuPartition(pdx::Message& message,
- pid_t task_id);
-
- // Set which thread gets the vr:app:render policy. Only one thread at a time
- // is allowed to have vr:app:render. If multiple threads are allowed
- // vr:app:render, and those threads busy loop, the system can freeze. When
- // SetVrAppRenderThread() is called, the thread which we had previously
- // assigned vr:app:render will have its scheduling policy reset to default
- // values.
- void SetVrAppRenderThread(pid_t new_vr_app_render_thread);
-
- CpuSetManager cpuset_;
-
- int sched_fifo_min_priority_;
- int sched_fifo_max_priority_;
-
- struct SchedulerPolicyConfig {
- unsigned long timer_slack;
- int scheduler_policy;
- int priority;
- std::function<bool(const pdx::Message& message, const Task& task)>
- permission_check;
- std::string cpuset;
-
- // Check the permisison of the given task to use this scheduler class. If a
- // permission check function is not set then operations are only allowed on
- // tasks in the sender's process.
- bool IsAllowed(const pdx::Message& sender, const Task& task) const {
- if (permission_check)
- return permission_check(sender, task);
- else if (!task || task.thread_group_id() != sender.GetProcessId())
- return false;
- else
- return true;
- }
- };
-
- std::unordered_map<std::string, SchedulerPolicyConfig> scheduler_policies_;
-
- std::function<bool(const pdx::Message& message, const Task& task)>
- partition_permission_check_;
-
- pid_t vr_app_render_thread_ = -1;
-
- PerformanceService(const PerformanceService&) = delete;
- void operator=(const PerformanceService&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_PERFORMANCE_SERVICE_H_
diff --git a/services/vr/performanced/performance_service_tests.cpp b/services/vr/performanced/performance_service_tests.cpp
deleted file mode 100644
index a24c889..0000000
--- a/services/vr/performanced/performance_service_tests.cpp
+++ /dev/null
@@ -1,529 +0,0 @@
-#include <errno.h>
-#include <sched.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <condition_variable>
-#include <cstdlib>
-#include <iostream>
-#include <mutex>
-#include <sstream>
-#include <thread>
-#include <utility>
-
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <dvr/performance_client_api.h>
-#include <gtest/gtest.h>
-#include <private/android_filesystem_config.h>
-
-#include "stdio_filebuf.h"
-#include "unique_file.h"
-
-using android::base::Trim;
-using android::dvr::UniqueFile;
-using android::dvr::stdio_filebuf;
-
-namespace {
-
-const char kTrustedUidEnvironmentVariable[] = "GTEST_TRUSTED_UID";
-
-const char kProcBase[] = "/proc";
-
-std::pair<UniqueFile, int> OpenTaskFile(pid_t task_id,
- const std::string& name) {
- std::ostringstream stream;
- stream << kProcBase << "/" << task_id << "/" << name;
-
- UniqueFile file{fopen(stream.str().c_str(), "r")};
- const int error = file ? 0 : errno;
- return {std::move(file), error};
-}
-
-std::string GetTaskCpuSet(pid_t task_id) {
- int error;
- UniqueFile file;
-
- std::tie(file, error) = OpenTaskFile(task_id, "cpuset");
- if (!file)
- return std::string("errno:") + strerror(error);
-
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- std::string line;
- std::getline(file_stream, line);
- return Trim(line);
-}
-
-} // anonymous namespace
-
-TEST(PerformanceTest, SetCpuPartition) {
- int error;
-
- // Test setting the the partition for the current task.
- error = dvrSetCpuPartition(0, "/application/background");
- EXPECT_EQ(0, error);
-
- error = dvrSetCpuPartition(0, "/application/performance");
- EXPECT_EQ(0, error);
-
- // Test setting the partition for one of our tasks.
- bool done = false;
- pid_t task_id = 0;
- std::mutex mutex;
- std::condition_variable done_condition, id_condition;
-
- std::thread thread([&] {
- std::unique_lock<std::mutex> lock(mutex);
-
- task_id = gettid();
- id_condition.notify_one();
-
- done_condition.wait(lock, [&done] { return done; });
- });
-
- {
- std::unique_lock<std::mutex> lock(mutex);
- id_condition.wait(lock, [&task_id] { return task_id != 0; });
- }
- EXPECT_NE(0, task_id);
-
- error = dvrSetCpuPartition(task_id, "/application");
- EXPECT_EQ(0, error);
-
- {
- std::lock_guard<std::mutex> lock(mutex);
- done = true;
- done_condition.notify_one();
- }
- thread.join();
-
- // Test setting the partition for a task that doesn't belong to us.
- error = dvrSetCpuPartition(1, "/application");
- EXPECT_EQ(-EINVAL, error);
-
- // Test setting the partition to one that doesn't exist.
- error = dvrSetCpuPartition(0, "/foobar");
- EXPECT_EQ(-ENOENT, error);
-
- // Set the test back to the root partition.
- error = dvrSetCpuPartition(0, "/");
- EXPECT_EQ(0, error);
-}
-
-TEST(PerformanceTest, SetSchedulerClass) {
- int error;
-
- // TODO(eieio): Test all supported scheduler classes and priority levels.
-
- error = dvrSetSchedulerClass(0, "background");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0));
-
- error = dvrSetSchedulerClass(0, "audio:low");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
- error = dvrSetSchedulerClass(0, "normal");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-
- error = dvrSetSchedulerClass(0, "foobar");
- EXPECT_EQ(-EINVAL, error);
-}
-
-TEST(PerformanceTest, SetSchedulerPolicy) {
- int error;
-
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_BATCH, sched_getscheduler(0));
-
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-
- error = dvrSetSchedulerPolicy(0, "foobar");
- EXPECT_EQ(-EINVAL, error);
-
- // Set the test back to the root partition.
- error = dvrSetCpuPartition(0, "/");
- EXPECT_EQ(0, error);
-
- const std::string original_cpuset = GetTaskCpuSet(gettid());
- EXPECT_EQ("/", original_cpuset);
-
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
- const std::string new_cpuset = GetTaskCpuSet(gettid());
- EXPECT_NE(original_cpuset, new_cpuset);
-
- // The cpuset for the thread group is now new_cpuset. Scheduler profiles that
- // do not specify a cpuset should not change the cpuset of a thread, except to
- // restore it to the thread group cpuset.
- std::string thread_original_cpuset;
- std::string thread_new_cpuset;
- std::string thread_final_cpuset;
-
- std::thread thread{
- [&thread_original_cpuset, &thread_new_cpuset, &thread_final_cpuset]() {
- thread_original_cpuset = GetTaskCpuSet(gettid());
-
- int error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(0, error);
-
- thread_new_cpuset = GetTaskCpuSet(gettid());
-
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- thread_final_cpuset = GetTaskCpuSet(gettid());
- }};
- thread.join();
-
- EXPECT_EQ(new_cpuset, thread_original_cpuset);
- EXPECT_NE(new_cpuset, thread_new_cpuset);
- EXPECT_EQ(new_cpuset, thread_final_cpuset);
-
- error = dvrSetCpuPartition(0, original_cpuset.c_str());
- EXPECT_EQ(0, error);
-}
-
-TEST(PerformanceTest, SchedulerClassResetOnFork) {
- int error;
-
- error = dvrSetSchedulerClass(0, "graphics:high");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_FIFO | SCHED_RESET_ON_FORK, sched_getscheduler(0));
-
- int scheduler = -1;
- std::thread thread([&]() { scheduler = sched_getscheduler(0); });
- thread.join();
-
- EXPECT_EQ(SCHED_NORMAL, scheduler);
-
- // Return to SCHED_NORMAL.
- error = dvrSetSchedulerClass(0, "normal");
- EXPECT_EQ(0, error);
- EXPECT_EQ(SCHED_NORMAL, sched_getscheduler(0));
-}
-
-TEST(PerformanceTest, GetCpuPartition) {
- int error;
- char partition[PATH_MAX + 1];
-
- error = dvrSetCpuPartition(0, "/");
- ASSERT_EQ(0, error);
-
- error = dvrGetCpuPartition(0, partition, sizeof(partition));
- EXPECT_EQ(0, error);
- EXPECT_EQ("/", std::string(partition));
-
- error = dvrSetCpuPartition(0, "/application");
- EXPECT_EQ(0, error);
-
- error = dvrGetCpuPartition(0, partition, sizeof(partition));
- EXPECT_EQ(0, error);
- EXPECT_EQ("/application", std::string(partition));
-
- // Test passing a buffer that is too short.
- error = dvrGetCpuPartition(0, partition, 5);
- EXPECT_EQ(-ENOBUFS, error);
-
- // Test getting the partition for a task that doesn't belong to us.
- error = dvrGetCpuPartition(1, partition, sizeof(partition));
- EXPECT_EQ(-EINVAL, error);
-
- // Test passing a nullptr value for partition buffer.
- error = dvrGetCpuPartition(0, nullptr, sizeof(partition));
- EXPECT_EQ(-EINVAL, error);
-}
-
-TEST(PerformanceTest, Permissions) {
- int error;
-
- const int original_uid = getuid();
- const int original_gid = getgid();
- int trusted_uid = -1;
-
- // See if the environment variable GTEST_TRUSTED_UID is set. If it is enable
- // testing the ActivityManager trusted uid permission checks using that uid.
- const char* trusted_uid_env = std::getenv(kTrustedUidEnvironmentVariable);
- if (trusted_uid_env)
- trusted_uid = std::atoi(trusted_uid_env);
-
- ASSERT_EQ(AID_ROOT, original_uid)
- << "This test must run as root to function correctly!";
-
- // Test unprivileged policies on a task that does not belong to this process.
- // Use the init process (task_id=1) as the target.
- error = dvrSetSchedulerPolicy(1, "batch");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(1, "background");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(1, "foreground");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(1, "normal");
- EXPECT_EQ(-EINVAL, error);
-
- // Switch the uid/gid to an id that should not have permission to access any
- // privileged actions.
- ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
- << "Failed to set gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(AID_NOBODY, AID_NOBODY, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(-EINVAL, error);
-
- // uid=AID_SYSTEM / gid=AID_NOBODY
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(AID_SYSTEM, AID_SYSTEM, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(0, error);
-
- // uid=AID_NOBODY / gid=AID_SYSTEM
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
- << "Failed to restore gid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(AID_SYSTEM, AID_SYSTEM, -1))
- << "Failed to set gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(AID_SYSTEM, AID_NOBODY, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(0, error);
-
- // uid=AID_GRAPHICS / gid=AID_NOBODY
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
- << "Failed to restore gid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
- << "Failed to set gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(AID_GRAPHICS, AID_GRAPHICS, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(-EINVAL, error);
-
- // uid=AID_NOBODY / gid=AID_GRAPHICS
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
- << "Failed to restore gid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(AID_GRAPHICS, AID_GRAPHICS, -1))
- << "Failed to set gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(AID_NOBODY, AID_NOBODY, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(-EINVAL, error);
-
- if (trusted_uid != -1) {
- // uid=<trusted uid> / gid=AID_NOBODY
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
- << "Failed to restore gid: " << strerror(errno);
- ASSERT_EQ(0, setresgid(AID_NOBODY, AID_NOBODY, -1))
- << "Failed to set gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(trusted_uid, trusted_uid, -1))
- << "Failed to set uid: " << strerror(errno);
-
- // Unprivileged policies.
- error = dvrSetSchedulerPolicy(0, "batch");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "background");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "foreground");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "normal");
- EXPECT_EQ(0, error);
-
- // Privileged policies.
- error = dvrSetSchedulerPolicy(0, "audio:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "audio:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "graphics:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:low");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "sensors:high");
- EXPECT_EQ(-EINVAL, error);
- error = dvrSetSchedulerPolicy(0, "vr:system:arp");
- EXPECT_EQ(0, error);
- error = dvrSetSchedulerPolicy(0, "vr:app:render");
- EXPECT_EQ(0, error);
- }
-
- // Restore original effective uid/gid.
- ASSERT_EQ(0, setresgid(original_gid, original_gid, -1))
- << "Failed to restore gid: " << strerror(errno);
- ASSERT_EQ(0, setresuid(original_uid, original_uid, -1))
- << "Failed to restore uid: " << strerror(errno);
-}
diff --git a/services/vr/performanced/performanced.rc b/services/vr/performanced/performanced.rc
deleted file mode 100644
index af9760e..0000000
--- a/services/vr/performanced/performanced.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service performanced /system/bin/performanced
- class core
- user root
- group system readproc
- socket pdx/system/performance/client stream 0666 system system u:object_r:pdx_performance_client_endpoint_socket:s0
diff --git a/services/vr/performanced/stdio_filebuf.h b/services/vr/performanced/stdio_filebuf.h
deleted file mode 100644
index 5988aa8..0000000
--- a/services/vr/performanced/stdio_filebuf.h
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
-// Copyright (c) 2016 Google, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#ifndef ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
-#define ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
-
-#include <cstdio>
-#include <istream>
-#include <locale>
-#include <streambuf>
-
-namespace android {
-namespace dvr {
-
-// An implementation of std::basic_streambuf backed by a FILE pointer. This is
-// ported from the internal llvm-libc++ support for std::cin. It's really
-// unfortunate that we have to do this, but the C++11 standard is too pendantic
-// to support creating streams from file descriptors or FILE pointers. This
-// implementation uses all standard interfaces, except for the call to
-// std::__throw_runtime_error(), which is only needed to deal with exceeding
-// locale encoding limits. This class is meant to be used for reading system
-// files, which don't require exotic locale support, so this call could be
-// removed in the future, if necessary.
-//
-// Original source file: llvm-libcxx/llvm-libc++/include/__std_stream
-// Original class name: __stdinbuf
-//
-template <class _CharT>
-class stdio_filebuf
- : public std::basic_streambuf<_CharT, std::char_traits<_CharT> > {
- public:
- typedef _CharT char_type;
- typedef std::char_traits<char_type> traits_type;
- typedef typename traits_type::int_type int_type;
- typedef typename traits_type::pos_type pos_type;
- typedef typename traits_type::off_type off_type;
- typedef typename traits_type::state_type state_type;
-
- explicit stdio_filebuf(FILE* __fp);
- ~stdio_filebuf() override;
-
- protected:
- virtual int_type underflow() override;
- virtual int_type uflow() override;
- virtual int_type pbackfail(int_type __c = traits_type::eof()) override;
- virtual void imbue(const std::locale& __loc) override;
-
- private:
- FILE* __file_;
- const std::codecvt<char_type, char, state_type>* __cv_;
- state_type __st_;
- int __encoding_;
- int_type __last_consumed_;
- bool __last_consumed_is_next_;
- bool __always_noconv_;
-
- stdio_filebuf(const stdio_filebuf&);
- stdio_filebuf& operator=(const stdio_filebuf&);
-
- int_type __getchar(bool __consume);
-
- static const int __limit = 8;
-};
-
-template <class _CharT>
-stdio_filebuf<_CharT>::stdio_filebuf(FILE* __fp)
- : __file_(__fp),
- __last_consumed_(traits_type::eof()),
- __last_consumed_is_next_(false) {
- imbue(this->getloc());
-}
-
-template <class _CharT>
-stdio_filebuf<_CharT>::~stdio_filebuf() {
- if (__file_)
- fclose(__file_);
-}
-
-template <class _CharT>
-void stdio_filebuf<_CharT>::imbue(const std::locale& __loc) {
- __cv_ = &std::use_facet<std::codecvt<char_type, char, state_type> >(__loc);
- __encoding_ = __cv_->encoding();
- __always_noconv_ = __cv_->always_noconv();
- if (__encoding_ > __limit)
- std::__throw_runtime_error("unsupported locale for standard io");
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::underflow() {
- return __getchar(false);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::uflow() {
- return __getchar(true);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::__getchar(
- bool __consume) {
- if (__last_consumed_is_next_) {
- int_type __result = __last_consumed_;
- if (__consume) {
- __last_consumed_ = traits_type::eof();
- __last_consumed_is_next_ = false;
- }
- return __result;
- }
- char __extbuf[__limit];
- int __nread = std::max(1, __encoding_);
- for (int __i = 0; __i < __nread; ++__i) {
- int __c = getc(__file_);
- if (__c == EOF)
- return traits_type::eof();
- __extbuf[__i] = static_cast<char>(__c);
- }
- char_type __1buf;
- if (__always_noconv_)
- __1buf = static_cast<char_type>(__extbuf[0]);
- else {
- const char* __enxt;
- char_type* __inxt;
- std::codecvt_base::result __r;
- do {
- state_type __sv_st = __st_;
- __r = __cv_->in(__st_, __extbuf, __extbuf + __nread, __enxt, &__1buf,
- &__1buf + 1, __inxt);
- switch (__r) {
- case std::codecvt_base::ok:
- break;
- case std::codecvt_base::partial:
- __st_ = __sv_st;
- if (__nread == sizeof(__extbuf))
- return traits_type::eof();
- {
- int __c = getc(__file_);
- if (__c == EOF)
- return traits_type::eof();
- __extbuf[__nread] = static_cast<char>(__c);
- }
- ++__nread;
- break;
- case std::codecvt_base::error:
- return traits_type::eof();
- case std::codecvt_base::noconv:
- __1buf = static_cast<char_type>(__extbuf[0]);
- break;
- }
- } while (__r == std::codecvt_base::partial);
- }
- if (!__consume) {
- for (int __i = __nread; __i > 0;) {
- if (ungetc(traits_type::to_int_type(__extbuf[--__i]), __file_) == EOF)
- return traits_type::eof();
- }
- } else
- __last_consumed_ = traits_type::to_int_type(__1buf);
- return traits_type::to_int_type(__1buf);
-}
-
-template <class _CharT>
-typename stdio_filebuf<_CharT>::int_type stdio_filebuf<_CharT>::pbackfail(
- int_type __c) {
- if (traits_type::eq_int_type(__c, traits_type::eof())) {
- if (!__last_consumed_is_next_) {
- __c = __last_consumed_;
- __last_consumed_is_next_ =
- !traits_type::eq_int_type(__last_consumed_, traits_type::eof());
- }
- return __c;
- }
- if (__last_consumed_is_next_) {
- char __extbuf[__limit];
- char* __enxt;
- const char_type __ci = traits_type::to_char_type(__last_consumed_);
- const char_type* __inxt;
- switch (__cv_->out(__st_, &__ci, &__ci + 1, __inxt, __extbuf,
- __extbuf + sizeof(__extbuf), __enxt)) {
- case std::codecvt_base::ok:
- break;
- case std::codecvt_base::noconv:
- __extbuf[0] = static_cast<char>(__last_consumed_);
- __enxt = __extbuf + 1;
- break;
- case std::codecvt_base::partial:
- case std::codecvt_base::error:
- return traits_type::eof();
- }
- while (__enxt > __extbuf)
- if (ungetc(*--__enxt, __file_) == EOF)
- return traits_type::eof();
- }
- __last_consumed_ = __c;
- __last_consumed_is_next_ = true;
- return __c;
-}
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_STDIO_FILEBUF_H_
diff --git a/services/vr/performanced/task.cpp b/services/vr/performanced/task.cpp
deleted file mode 100644
index 2fc96bf..0000000
--- a/services/vr/performanced/task.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-#include "task.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <log/log.h>
-#include <stdio.h>
-
-#include <cctype>
-#include <cstdlib>
-#include <memory>
-#include <sstream>
-
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-
-#include "stdio_filebuf.h"
-
-namespace {
-
-const char kProcBase[] = "/proc";
-
-android::base::unique_fd OpenTaskDirectory(pid_t task_id) {
- std::ostringstream stream;
- stream << kProcBase << "/" << task_id;
-
- return android::base::unique_fd(
- open(stream.str().c_str(), O_RDONLY | O_DIRECTORY));
-}
-
-void ParseUidStatusField(const std::string& value, std::array<int, 4>& ids) {
- const char* start = value.c_str();
-
- ids[0] = std::strtol(start, const_cast<char**>(&start), 10);
- ids[1] = std::strtol(start, const_cast<char**>(&start), 10);
- ids[2] = std::strtol(start, const_cast<char**>(&start), 10);
- ids[3] = std::strtol(start, const_cast<char**>(&start), 10);
-}
-
-} // anonymous namespace
-
-namespace android {
-namespace dvr {
-
-Task::Task(pid_t task_id)
- : task_id_(task_id),
- thread_group_id_(-1),
- parent_process_id_(-1),
- thread_count_(0),
- cpus_allowed_mask_(0) {
- task_fd_ = OpenTaskDirectory(task_id_);
- const int error = errno;
- ALOGE_IF(task_fd_.get() < 0 && error != EACCES,
- "Task::Task: Failed to open task directory for task_id=%d: %s",
- task_id, strerror(error));
-
- if (IsValid()) {
- ReadStatusFields();
- ALOGD_IF(TRACE,
- "Task::Task: task_id=%d name=%s tgid=%d ppid=%d cpu_mask=%x",
- task_id_, name_.c_str(), thread_group_id_, parent_process_id_,
- cpus_allowed_mask_);
- }
-}
-
-base::unique_fd Task::OpenTaskFile(const std::string& name) const {
- const std::string relative_path = "./" + name;
- return base::unique_fd(
- openat(task_fd_.get(), relative_path.c_str(), O_RDONLY));
-}
-
-UniqueFile Task::OpenTaskFilePointer(const std::string& name) const {
- const std::string relative_path = "./" + name;
- base::unique_fd fd(openat(task_fd_.get(), relative_path.c_str(), O_RDONLY));
- if (fd.get() < 0) {
- ALOGE("Task::OpenTaskFilePointer: Failed to open /proc/%d/%s: %s", task_id_,
- name.c_str(), strerror(errno));
- return nullptr;
- }
-
- UniqueFile fp(fdopen(fd.release(), "r"));
- if (!fp)
- ALOGE("Task::OpenTaskFilePointer: Failed to fdopen /proc/%d/%s: %s",
- task_id_, name.c_str(), strerror(errno));
-
- return fp;
-}
-
-std::string Task::GetStatusField(const std::string& field) const {
- if (auto file = OpenTaskFilePointer("status")) {
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- for (std::string line; std::getline(file_stream, line);) {
- auto offset = line.find(field);
-
- ALOGD_IF(TRACE,
- "Task::GetStatusField: field=\"%s\" line=\"%s\" offset=%zd",
- field.c_str(), line.c_str(), offset);
-
- if (offset == std::string::npos)
- continue;
-
- // The status file has lines with the format <field>:<value>. Extract the
- // value after the colon.
- return android::base::Trim(line.substr(offset + field.size() + 1));
- }
- }
-
- return "[unknown]";
-}
-
-void Task::ReadStatusFields() {
- if (auto file = OpenTaskFilePointer("status")) {
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- for (std::string line; std::getline(file_stream, line);) {
- auto offset = line.find(':');
- if (offset == std::string::npos) {
- ALOGW("ReadStatusFields: Failed to find delimiter \":\" in line=\"%s\"",
- line.c_str());
- continue;
- }
-
- std::string key = line.substr(0, offset);
- std::string value = android::base::Trim(line.substr(offset + 1));
-
- ALOGD_IF(TRACE, "Task::ReadStatusFields: key=\"%s\" value=\"%s\"",
- key.c_str(), value.c_str());
-
- if (key == "Name")
- name_ = value;
- else if (key == "Tgid")
- thread_group_id_ = std::strtol(value.c_str(), nullptr, 10);
- else if (key == "PPid")
- parent_process_id_ = std::strtol(value.c_str(), nullptr, 10);
- else if (key == "Uid")
- ParseUidStatusField(value, user_id_);
- else if (key == "Gid")
- ParseUidStatusField(value, group_id_);
- else if (key == "Threads")
- thread_count_ = std::strtoul(value.c_str(), nullptr, 10);
- else if (key == "Cpus_allowed")
- cpus_allowed_mask_ = std::strtoul(value.c_str(), nullptr, 16);
- else if (key == "Cpus_allowed_list")
- cpus_allowed_list_ = value;
- }
- }
-}
-
-std::string Task::GetCpuSetPath() const {
- if (auto file = OpenTaskFilePointer("cpuset")) {
- stdio_filebuf<char> filebuf(file.get());
- std::istream file_stream(&filebuf);
-
- std::string line = "";
- std::getline(file_stream, line);
-
- return android::base::Trim(line);
- } else {
- return "";
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/performanced/task.h b/services/vr/performanced/task.h
deleted file mode 100644
index 4a3b7f2..0000000
--- a/services/vr/performanced/task.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_TASK_H_
-#define ANDROID_DVR_PERFORMANCED_TASK_H_
-
-#include <sys/types.h>
-
-#include <array>
-#include <cstdio>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include <android-base/unique_fd.h>
-
-#include "unique_file.h"
-
-namespace android {
-namespace dvr {
-
-// Task provides access to task-related information from the procfs
-// pseudo-filesystem.
-class Task {
- public:
- explicit Task(pid_t task_id);
-
- bool IsValid() const { return task_fd_.get() >= 0; }
- explicit operator bool() const { return IsValid(); }
-
- pid_t task_id() const { return task_id_; }
- std::string name() const { return name_; }
- pid_t thread_group_id() const { return thread_group_id_; }
- pid_t parent_process_id() const { return parent_process_id_; }
- size_t thread_count() const { return thread_count_; }
- uint32_t cpus_allowed_mask() const { return cpus_allowed_mask_; }
- const std::string& cpus_allowed_list() const { return cpus_allowed_list_; }
- const std::array<int, 4>& user_id() const { return user_id_; }
- const std::array<int, 4>& group_id() const { return group_id_; }
-
- // Indices into user and group id arrays.
- enum {
- kUidReal = 0,
- kUidEffective,
- kUidSavedSet,
- kUidFilesystem,
- };
-
- std::string GetCpuSetPath() const;
-
- private:
- pid_t task_id_;
- base::unique_fd task_fd_;
-
- // Fields read from /proc/<task_id_>/status.
- std::string name_;
- pid_t thread_group_id_;
- pid_t parent_process_id_;
- std::array<int, 4> user_id_;
- std::array<int, 4> group_id_;
- size_t thread_count_;
- uint32_t cpus_allowed_mask_;
- std::string cpus_allowed_list_;
-
- // Opens the file /proc/<task_id_>/|name| and returns the open file
- // descriptor.
- base::unique_fd OpenTaskFile(const std::string& name) const;
-
- // Similar to OpenTaskFile() but returns a file pointer.
- UniqueFile OpenTaskFilePointer(const std::string& name) const;
-
- // Reads the field named |field| from /proc/<task_id_>/status.
- std::string GetStatusField(const std::string& field) const;
-
- // Reads a subset of the fields in /proc/<task_id_>/status.
- void ReadStatusFields();
-
- Task(const Task&) = delete;
- void operator=(const Task&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_TASK_H_
diff --git a/services/vr/performanced/unique_file.h b/services/vr/performanced/unique_file.h
deleted file mode 100644
index 86e487a..0000000
--- a/services/vr/performanced/unique_file.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
-#define ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
-
-#include <stdio.h>
-
-#include <memory>
-
-namespace android {
-namespace dvr {
-
-// Utility to manage the lifetime of a file pointer.
-struct FileDeleter {
- void operator()(FILE* fp) { fclose(fp); }
-};
-using UniqueFile = std::unique_ptr<FILE, FileDeleter>;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_PERFORMANCED_UNIQUE_FILE_H_
diff --git a/services/vr/virtual_touchpad/Android.bp b/services/vr/virtual_touchpad/Android.bp
deleted file mode 100644
index f2ec5a4..0000000
--- a/services/vr/virtual_touchpad/Android.bp
+++ /dev/null
@@ -1,140 +0,0 @@
-
-
-// Touchpad implementation.
-
-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"],
-}
-
-src = [
- "EvdevInjector.cpp",
- "VirtualTouchpadEvdev.cpp",
-]
-
-shared_libs = [
- "libbase",
- "liblog",
- "libutils",
-]
-
-header_libraries = [
- "jni_headers",
- "libdvr_headers",
-]
-
-cc_library {
- srcs: src,
- export_include_dirs: ["include"],
- shared_libs: shared_libs,
- header_libs: header_libraries,
- cflags: [
- "-DLOG_TAG=\"VrVirtualTouchpad\"",
- "-Wall",
- "-Werror",
- ],
- name: "libvirtualtouchpad",
-}
-
-// Touchpad unit tests.
-
-test_static_libs = [
- "libcutils",
- "libvirtualtouchpad",
- "libbase",
- "liblog",
- "libutils",
-]
-
-test_src_files = ["tests/VirtualTouchpad_test.cpp"]
-
-cc_test {
- srcs: test_src_files,
- static_libs: test_static_libs,
- header_libs: header_libraries,
- cflags: [
- "-Wall",
- "-Werror",
- ],
- host_ldlibs: [
- "-llog",
- ],
- name: "VirtualTouchpad_test",
- stl: "libc++_static",
-}
-
-// Service.
-
-service_src = [
- "main.cpp",
- "VirtualTouchpadService.cpp",
- ":virtualtouchpad_aidl",
-]
-
-service_static_libs = [
- "libcutils",
- "libvirtualtouchpad",
-]
-
-service_shared_libs = [
- "libbase",
- "libbinder",
- "liblog",
- "libutils",
-]
-
-cc_binary {
- srcs: service_src,
- static_libs: service_static_libs,
- shared_libs: service_shared_libs,
- header_libs: header_libraries,
- cflags: [
- "-DLOG_TAG=\"VrVirtualTouchpad\"",
- "-Wall",
- "-Werror",
- ],
- host_ldlibs: ["-llog"],
- name: "virtual_touchpad",
- init_rc: ["virtual_touchpad.rc"],
- compile_multilib: "64",
- stl: "libc++_static",
-}
-
-// Touchpad client library.
-
-client_src = [
- "VirtualTouchpadClient.cpp",
- "DvrVirtualTouchpadClient.cpp",
- ":virtualtouchpad_aidl",
-]
-
-client_shared_libs = [
- "libbase",
- "libbinder",
- "liblog",
- "libutils",
-]
-
-cc_library {
- srcs: client_src,
- shared_libs: client_shared_libs,
- header_libs: header_libraries,
- cflags: [
- "-DLOG_TAG=\"VirtualTouchpadClient\"",
- "-Wall",
- "-Werror",
- ],
- host_ldlibs: ["-llog"],
- name: "libvirtualtouchpadclient",
- export_include_dirs: ["include"],
-}
-
-filegroup {
- name: "virtualtouchpad_aidl",
- srcs: ["aidl/android/dvr/IVirtualTouchpadService.aidl"],
- path: "aidl",
-}
diff --git a/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
deleted file mode 100644
index 3ab77a7..0000000
--- a/services/vr/virtual_touchpad/DvrVirtualTouchpadClient.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "VirtualTouchpadClient.h"
-#include "dvr/virtual_touchpad_client.h"
-
-struct DvrVirtualTouchpad {};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-namespace {
-android::dvr::VirtualTouchpad* FromC(DvrVirtualTouchpad* client) {
- return reinterpret_cast<android::dvr::VirtualTouchpad*>(client);
-}
-} // namespace
-
-DvrVirtualTouchpad* dvrVirtualTouchpadCreate() {
- return reinterpret_cast<DvrVirtualTouchpad*>(
- android::dvr::VirtualTouchpadClient::Create().release());
-}
-
-void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client) {
- delete FromC(client);
-}
-
-int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client) {
- return FromC(client)->Attach();
-}
-
-int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client) {
- return FromC(client)->Detach();
-}
-
-int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
- float y, float pressure) {
- return FromC(client)->Touch(touchpad, x, y, pressure);
-}
-
-int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
- int buttons) {
- return FromC(client)->ButtonState(touchpad, buttons);
-}
-
-int dvrVirtualTouchpadScroll(DvrVirtualTouchpad* client, int touchpad, float x,
- float y) {
- return FromC(client)->Scroll(touchpad, x, y);
-}
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
diff --git a/services/vr/virtual_touchpad/EvdevInjector.cpp b/services/vr/virtual_touchpad/EvdevInjector.cpp
deleted file mode 100644
index 7fad379..0000000
--- a/services/vr/virtual_touchpad/EvdevInjector.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-#include "EvdevInjector.h"
-
-#include <errno.h>
-#include <inttypes.h>
-#include <linux/input.h>
-#include <log/log.h>
-#include <string.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
-
-namespace android {
-namespace dvr {
-
-int EvdevInjector::UInput::Open() {
- errno = 0;
- fd_.reset(open("/dev/uinput", O_WRONLY | O_NONBLOCK));
- if (fd_.get() < 0) {
- ALOGE("couldn't open uinput (r=%d errno=%d)", fd_.get(), errno);
- }
- return errno;
-}
-
-int EvdevInjector::UInput::Close() {
- errno = 0;
- fd_.reset();
- return errno;
-}
-
-int EvdevInjector::UInput::Write(const void* buf, size_t count) {
- ALOGV("UInput::Write(%zu, %02X...)", count, *static_cast<const char*>(buf));
- errno = 0;
- ssize_t r = write(fd_.get(), buf, count);
- if (r != static_cast<ssize_t>(count)) {
- ALOGE("write(%zu) failed (r=%zd errno=%d)", count, r, errno);
- }
- return errno;
-}
-
-int EvdevInjector::UInput::IoctlSetInt(int request, int value) {
- ALOGV("UInput::IoctlSetInt(0x%X, 0x%X)", request, value);
- errno = 0;
- if (const int status = ioctl(fd_.get(), request, value)) {
- ALOGE("ioctl(%d, 0x%X, 0x%X) failed (r=%d errno=%d)", fd_.get(), request,
- value, status, errno);
- }
- return errno;
-}
-
-int EvdevInjector::UInput::IoctlVoid(int request) {
- ALOGV("UInput::IoctlVoid(0x%X)", request);
- errno = 0;
- if (const int status = ioctl(fd_.get(), request)) {
- ALOGE("ioctl(%d, 0x%X) failed (r=%d errno=%d)", fd_.get(), request, status,
- errno);
- }
- return errno;
-}
-
-void EvdevInjector::Close() {
- uinput_->Close();
- state_ = State::CLOSED;
-}
-
-int EvdevInjector::ConfigureBegin(const char* device_name, int16_t bustype,
- int16_t vendor, int16_t product,
- int16_t version) {
- ALOGV("ConfigureBegin %s 0x%04" PRIX16 " 0x%04" PRIX16 " 0x%04" PRIX16
- " 0x%04" PRIX16 "",
- device_name, bustype, vendor, product, version);
- if (!device_name || strlen(device_name) >= UINPUT_MAX_NAME_SIZE) {
- return Error(ERROR_DEVICE_NAME);
- }
- if (const int status = RequireState(State::NEW)) {
- return status;
- }
- if (!uinput_) {
- owned_uinput_.reset(new EvdevInjector::UInput());
- uinput_ = owned_uinput_.get();
- }
- if (const int status = uinput_->Open()) {
- // Without uinput we're dead in the water.
- state_ = State::CLOSED;
- return Error(status);
- }
- state_ = State::CONFIGURING;
- // Initialize device setting structure.
- memset(&uidev_, 0, sizeof(uidev_));
- strncpy(uidev_.name, device_name, UINPUT_MAX_NAME_SIZE);
- uidev_.id.bustype = bustype;
- uidev_.id.vendor = vendor;
- uidev_.id.product = product;
- uidev_.id.version = version;
- return 0;
-}
-
-int EvdevInjector::ConfigureInputProperty(int property) {
- ALOGV("ConfigureInputProperty %d", property);
- if (property < 0 || property >= INPUT_PROP_CNT) {
- ALOGE("property 0x%X out of range [0,0x%X)", property, INPUT_PROP_CNT);
- return Error(ERROR_PROPERTY_RANGE);
- }
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- if (const int status = uinput_->IoctlSetInt(UI_SET_PROPBIT, property)) {
- ALOGE("failed to set property %d", property);
- return Error(status);
- }
- return 0;
-}
-
-int EvdevInjector::ConfigureKey(uint16_t key) {
- ALOGV("ConfigureKey 0x%02" PRIX16 "", key);
- if (key < 0 || key >= KEY_CNT) {
- ALOGE("key 0x%X out of range [0,0x%X)", key, KEY_CNT);
- return Error(ERROR_KEY_RANGE);
- }
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- if (const int status = EnableEventType(EV_KEY)) {
- return status;
- }
- if (const int status = uinput_->IoctlSetInt(UI_SET_KEYBIT, key)) {
- ALOGE("failed to enable EV_KEY 0x%02" PRIX16 "", key);
- return Error(status);
- }
- return 0;
-}
-
-int EvdevInjector::ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max,
- int32_t fuzz, int32_t flat) {
- ALOGV("ConfigureAbs 0x%" PRIX16 " %" PRId32 " %" PRId32 " %" PRId32
- " %" PRId32 "",
- abs_type, min, max, fuzz, flat);
- if (abs_type < 0 || abs_type >= ABS_CNT) {
- ALOGE("EV_ABS type 0x%" PRIX16 " out of range [0,0x%X)", abs_type, ABS_CNT);
- return Error(ERROR_ABS_RANGE);
- }
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- if (const int status = EnableEventType(EV_ABS)) {
- return status;
- }
- if (const int status = uinput_->IoctlSetInt(UI_SET_ABSBIT, abs_type)) {
- ALOGE("failed to enable EV_ABS 0x%" PRIX16 "", abs_type);
- return Error(status);
- }
- uidev_.absmin[abs_type] = min;
- uidev_.absmax[abs_type] = max;
- uidev_.absfuzz[abs_type] = fuzz;
- uidev_.absflat[abs_type] = flat;
- return 0;
-}
-
-int EvdevInjector::ConfigureMultiTouchXY(int x0, int y0, int x1, int y1) {
- if (const int status = ConfigureAbs(ABS_MT_POSITION_X, x0, x1, 0, 0)) {
- return status;
- }
- if (const int status = ConfigureAbs(ABS_MT_POSITION_Y, y0, y1, 0, 0)) {
- return status;
- }
- return 0;
-}
-
-int EvdevInjector::ConfigureAbsSlots(int slots) {
- return ConfigureAbs(ABS_MT_SLOT, 0, slots, 0, 0);
-}
-
-int EvdevInjector::ConfigureRel(uint16_t rel_type) {
- ALOGV("ConfigureRel 0x%" PRIX16 "", rel_type);
- if (rel_type < 0 || rel_type >= REL_CNT) {
- ALOGE("EV_REL type 0x%" PRIX16 " out of range [0,0x%X)", rel_type, REL_CNT);
- return Error(ERROR_REL_RANGE);
- }
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- if (const int status = EnableEventType(EV_REL)) {
- return status;
- }
- if (const int status = uinput_->IoctlSetInt(UI_SET_RELBIT, rel_type)) {
- ALOGE("failed to enable EV_REL 0x%" PRIX16 "", rel_type);
- return Error(status);
- }
- return 0;
-}
-
-int EvdevInjector::ConfigureEnd() {
- ALOGV("ConfigureEnd:");
- ALOGV(" name=\"%s\"", uidev_.name);
- ALOGV(" id.bustype=0x%04" PRIX16, uidev_.id.bustype);
- ALOGV(" id.vendor=0x%04" PRIX16, uidev_.id.vendor);
- ALOGV(" id.product=0x%04" PRIX16, uidev_.id.product);
- ALOGV(" id.version=0x%04" PRIX16, uidev_.id.version);
- ALOGV(" ff_effects_max=%" PRIu32, uidev_.ff_effects_max);
- for (int i = 0; i < ABS_CNT; ++i) {
- if (uidev_.absmin[i]) {
- ALOGV(" absmin[%d]=%" PRId32, i, uidev_.absmin[i]);
- }
- if (uidev_.absmax[i]) {
- ALOGV(" absmax[%d]=%" PRId32, i, uidev_.absmax[i]);
- }
- if (uidev_.absfuzz[i]) {
- ALOGV(" absfuzz[%d]=%" PRId32, i, uidev_.absfuzz[i]);
- }
- if (uidev_.absflat[i]) {
- ALOGV(" absflat[%d]=%" PRId32, i, uidev_.absflat[i]);
- }
- }
-
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- // Write out device settings.
- if (const int status = uinput_->Write(&uidev_, sizeof uidev_)) {
- ALOGE("failed to write device settings");
- return Error(status);
- }
- // Create device node.
- if (const int status = uinput_->IoctlVoid(UI_DEV_CREATE)) {
- ALOGE("failed to create device node");
- return Error(status);
- }
- state_ = State::READY;
- return 0;
-}
-
-int EvdevInjector::Send(uint16_t type, uint16_t code, int32_t value) {
- ALOGV("Send(0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32 ")", type, code, value);
- if (const int status = RequireState(State::READY)) {
- return status;
- }
- struct input_event event;
- memset(&event, 0, sizeof(event));
- event.type = type;
- event.code = code;
- event.value = value;
- if (const int status = uinput_->Write(&event, sizeof(event))) {
- ALOGE("failed to write event 0x%" PRIX16 ", 0x%" PRIX16 ", 0x%" PRIX32,
- type, code, value);
- return Error(status);
- }
- return 0;
-}
-
-int EvdevInjector::SendSynReport() { return Send(EV_SYN, SYN_REPORT, 0); }
-
-int EvdevInjector::SendKey(uint16_t code, int32_t value) {
- return Send(EV_KEY, code, value);
-}
-
-int EvdevInjector::SendAbs(uint16_t code, int32_t value) {
- return Send(EV_ABS, code, value);
-}
-
-int EvdevInjector::SendRel(uint16_t code, int32_t value) {
- return Send(EV_REL, code, value);
-}
-
-int EvdevInjector::SendMultiTouchSlot(int32_t slot) {
- if (latest_slot_ != slot) {
- if (const int status = SendAbs(ABS_MT_SLOT, slot)) {
- return status;
- }
- latest_slot_ = slot;
- }
- return 0;
-}
-
-int EvdevInjector::SendMultiTouchXY(int32_t slot, int32_t id, int32_t x,
- int32_t y) {
- if (const int status = SendMultiTouchSlot(slot)) {
- return status;
- }
- if (const int status = SendAbs(ABS_MT_TRACKING_ID, id)) {
- return status;
- }
- if (const int status = SendAbs(ABS_MT_POSITION_X, x)) {
- return status;
- }
- if (const int status = SendAbs(ABS_MT_POSITION_Y, y)) {
- return status;
- }
- return 0;
-}
-
-int EvdevInjector::SendMultiTouchLift(int32_t slot) {
- if (const int status = SendMultiTouchSlot(slot)) {
- return status;
- }
- if (const int status = SendAbs(ABS_MT_TRACKING_ID, -1)) {
- return status;
- }
- return 0;
-}
-
-int EvdevInjector::Error(int code) {
- if (!error_) {
- error_ = code;
- }
- return code;
-}
-
-int EvdevInjector::RequireState(State required_state) {
- if (error_) {
- return error_;
- }
- if (state_ != required_state) {
- ALOGE("in state %d but require state %d", static_cast<int>(state_),
- static_cast<int>(required_state));
- return Error(ERROR_SEQUENCING);
- }
- return 0;
-}
-
-int EvdevInjector::EnableEventType(uint16_t type) {
- if (const int status = RequireState(State::CONFIGURING)) {
- return status;
- }
- if (enabled_event_types_.count(type) > 0) {
- return 0;
- }
- if (const int status = uinput_->IoctlSetInt(UI_SET_EVBIT, type)) {
- ALOGE("failed to enable event type 0x%X", type);
- return Error(status);
- }
- enabled_event_types_.insert(type);
- return 0;
-}
-
-void EvdevInjector::dumpInternal(String8& result) {
- result.appendFormat("injector_state = %d\n", static_cast<int>(state_));
- result.appendFormat("injector_error = %d\n", error_);
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/virtual_touchpad/EvdevInjector.h b/services/vr/virtual_touchpad/EvdevInjector.h
deleted file mode 100644
index e87c959..0000000
--- a/services/vr/virtual_touchpad/EvdevInjector.h
+++ /dev/null
@@ -1,148 +0,0 @@
-#ifndef ANDROID_DVR_EVDEV_INJECTOR_H
-#define ANDROID_DVR_EVDEV_INJECTOR_H
-
-#include <android-base/unique_fd.h>
-#include <linux/uinput.h>
-#include <utils/String8.h>
-
-#include <cstdint>
-#include <memory>
-#include <unordered_set>
-
-namespace android {
-namespace dvr {
-
-// Simulated evdev input device.
-//
-class EvdevInjector {
- public:
- // EvdevInjector-specific error codes are negative integers; other non-zero
- // values returned from public routines are |errno| codes from underlying I/O.
- // EvdevInjector maintains a 'sticky' error state, similar to |errno|, so that
- // a caller can perform a sequence of operations and check for errors at the
- // end using |GetError()|. In general, the first such error will be recorded
- // and will suppress effects of further device operations until |ResetError()|
- // is called.
- //
- enum : int {
- ERROR_DEVICE_NAME = -1, // Invalid device name.
- ERROR_PROPERTY_RANGE = -2, // |INPUT_PROP_*| code out of range.
- ERROR_KEY_RANGE = -3, // |KEY_*|/|BTN_*| code out of range.
- ERROR_ABS_RANGE = -4, // |ABS_*| code out of range.
- ERROR_SEQUENCING = -5, // Configure/Send out of order.
- ERROR_REL_RANGE = -6, // |REL_*| code out of range.
- };
-
- // Key event |value| is not defined in <linux/input.h>.
- enum : int32_t { KEY_RELEASE = 0, KEY_PRESS = 1, KEY_REPEAT = 2 };
-
- // UInput provides a shim to intercept /dev/uinput operations
- // just above the system call level, for testing.
- //
- class UInput {
- public:
- UInput() {}
- virtual ~UInput() {}
- virtual int Open();
- virtual int Close();
- virtual int Write(const void* buf, size_t count);
- virtual int IoctlVoid(int request);
- virtual int IoctlSetInt(int request, int value);
-
- private:
- base::unique_fd fd_;
- };
-
- EvdevInjector() {}
- ~EvdevInjector() { Close(); }
- void Close();
-
- int GetError() const { return error_; }
- void ResetError() { error_ = 0; }
-
- // Configuration must be performed before sending any events.
- // |ConfigureBegin()| must be called first, and |ConfigureEnd()| last,
- // with zero or more other |Configure...()| calls in between in any order.
-
- // Configure the basic evdev device properties; must be called first.
- int ConfigureBegin(const char* device_name, int16_t bustype, int16_t vendor,
- int16_t product, int16_t version);
-
- // Configure an optional input device property.
- // @param property One of the |INPUT_PROP_*| constants from <linux/input.h>.
- int ConfigureInputProperty(int property);
-
- // Configure an input key.
- // @param key One of the |KEY_*| or |BTN_*| constants from <linux/input.h>.
- int ConfigureKey(uint16_t key);
-
- // Configure an absolute axis.
- // @param abs_type One of the |KEY_*| or |BTN_*| constants from
- // <linux/input.h>.
- int ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max, int32_t fuzz,
- int32_t flat);
-
- // Configure the number of multitouch slots.
- int ConfigureAbsSlots(int slots);
-
- // Configure multitouch coordinate range.
- int ConfigureMultiTouchXY(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
-
- // Configure a relative axis.
- // @param rel_type One of the |REL_*| constants from <linux/input.h>.
- int ConfigureRel(uint16_t rel_type);
-
- // Complete configuration and create the input device.
- int ConfigureEnd();
-
- // Send various events.
- //
- int Send(uint16_t type, uint16_t code, int32_t value);
- int SendSynReport();
- int SendKey(uint16_t code, int32_t value);
- int SendAbs(uint16_t code, int32_t value);
- int SendRel(uint16_t code, int32_t value);
- int SendMultiTouchSlot(int32_t slot);
- int SendMultiTouchXY(int32_t slot, int32_t id, int32_t x, int32_t y);
- int SendMultiTouchLift(int32_t slot);
-
- void dumpInternal(String8& result);
-
- protected:
- // Must be called only between construction and ConfigureBegin().
- inline void SetUInputForTesting(UInput* uinput) { uinput_ = uinput; }
- // Caller must not retain pointer longer than EvdevInjector.
- inline const uinput_user_dev* GetUiDevForTesting() const { return &uidev_; }
-
- private:
- // Phase to enforce that configuration is complete before events are sent.
- enum class State { NEW, CONFIGURING, READY, CLOSED };
-
- // Sets |error_| if it is not already set; returns |code|.
- int Error(int code);
-
- // Returns a nonzero error if the injector is not in the required |state|.
- int RequireState(State state);
-
- // Configures an event type if necessary.
- // @param type One of the |EV_*| constants from <linux/input.h>.
- int EnableEventType(uint16_t type);
-
- // Active pointer to owned or testing UInput.
- UInput* uinput_ = nullptr;
- std::unique_ptr<UInput> owned_uinput_;
-
- State state_ = State::NEW;
- int error_ = 0;
- uinput_user_dev uidev_;
- std::unordered_set<uint16_t> enabled_event_types_;
- int32_t latest_slot_ = -1;
-
- EvdevInjector(const EvdevInjector&) = delete;
- void operator=(const EvdevInjector&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_EVDEV_INJECTOR_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
deleted file mode 100644
index 00e4ce6..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "VirtualTouchpadClient.h"
-
-#include <android/dvr/IVirtualTouchpadService.h>
-#include <binder/IServiceManager.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-class VirtualTouchpadClientImpl : public VirtualTouchpadClient {
- public:
- VirtualTouchpadClientImpl() {}
- ~VirtualTouchpadClientImpl() override {
- if (service_ != nullptr) {
- Detach();
- }
- }
-
- status_t Attach() {
- if (service_ != nullptr) {
- return ALREADY_EXISTS;
- }
- sp<IServiceManager> sm = defaultServiceManager();
- if (sm == nullptr) {
- ALOGE("no service manager");
- return NO_INIT;
- }
- sp<IVirtualTouchpadService> service =
- interface_cast<IVirtualTouchpadService>(
- sm->getService(IVirtualTouchpadService::SERVICE_NAME()));
- if (service == nullptr) {
- ALOGE("failed to get service");
- return NAME_NOT_FOUND;
- }
- service_ = service;
- return service_->attach().transactionError();
- }
-
- status_t Detach() {
- if (service_ == nullptr) {
- return NO_INIT;
- }
- status_t status = service_->detach().transactionError();
- service_ = nullptr;
- return status;
- }
-
- status_t Touch(int touchpad, float x, float y, float pressure) override {
- if (service_ == nullptr) {
- return NO_INIT;
- }
- return service_->touch(touchpad, x, y, pressure).transactionError();
- }
-
- status_t ButtonState(int touchpad, int buttons) override {
- if (service_ == nullptr) {
- return NO_INIT;
- }
- return service_->buttonState(touchpad, buttons).transactionError();
- }
-
- status_t Scroll(int touchpad, float x, float y) override {
- if (service_ == nullptr) {
- return NO_INIT;
- }
- return service_->scroll(touchpad, x, y).transactionError();
- }
-
- void dumpInternal(String8& result) override {
- result.append("[virtual touchpad]\n");
- result.appendFormat("connected = %s\n\n",
- service_ != nullptr ? "true" : "false");
- }
-
- private:
- sp<IVirtualTouchpadService> service_;
-};
-
-} // anonymous namespace
-
-std::unique_ptr<VirtualTouchpad> VirtualTouchpadClient::Create() {
- return std::unique_ptr<VirtualTouchpad>(new VirtualTouchpadClientImpl());
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
deleted file mode 100644
index bcfdad3..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-#include "VirtualTouchpadEvdev.h"
-
-#include <android/input.h>
-#include <inttypes.h>
-#include <linux/input.h>
-#include <log/log.h>
-
-// References:
-// [0] Multi-touch (MT) Protocol,
-// https://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-// Virtual evdev device properties. The name is arbitrary, but Android can
-// use it to look up device configuration, so it must be unique. Vendor and
-// product values must be 0 to indicate an internal device and prevent a
-// similar lookup that could conflict with a physical device.
-static const char* const kDeviceNameFormat = "vr-virtual-touchpad-%d";
-static constexpr int16_t kDeviceBusType = BUS_VIRTUAL;
-static constexpr int16_t kDeviceVendor = 0;
-static constexpr int16_t kDeviceProduct = 0;
-static constexpr int16_t kDeviceVersion = 0x0001;
-
-static constexpr int32_t kWidth = 0x10000;
-static constexpr int32_t kHeight = 0x10000;
-static constexpr int32_t kSlots = 2;
-
-static constexpr float kScrollScale = 100.0f;
-
-int32_t scale_relative_scroll(float x) {
- return kScrollScale * x;
-}
-
-} // anonymous namespace
-
-std::unique_ptr<VirtualTouchpad> VirtualTouchpadEvdev::Create() {
- std::unique_ptr<VirtualTouchpadEvdev> touchpad(new VirtualTouchpadEvdev());
- touchpad->Reset();
- return touchpad;
-}
-
-void VirtualTouchpadEvdev::Reset() {
- for (auto& touchpad : touchpad_) {
- if (touchpad.injector) {
- touchpad.injector->Close();
- }
- touchpad.injector = nullptr;
- touchpad.owned_injector.reset();
- touchpad.last_device_x = INT32_MIN;
- touchpad.last_device_y = INT32_MIN;
- touchpad.touches = 0;
- touchpad.last_motion_event_buttons = 0;
- }
-}
-
-status_t VirtualTouchpadEvdev::Attach() {
- status_t status = OK;
- for (int i = 0; i < kTouchpads; ++i) {
- Touchpad& touchpad = touchpad_[i];
- if (!touchpad.injector) {
- touchpad.owned_injector.reset(new EvdevInjector());
- touchpad.injector = touchpad.owned_injector.get();
- }
- String8 DeviceName;
- DeviceName.appendFormat(kDeviceNameFormat, i);
- touchpad.injector->ConfigureBegin(DeviceName, kDeviceBusType,
- kDeviceVendor, kDeviceProduct,
- kDeviceVersion);
- touchpad.injector->ConfigureInputProperty(INPUT_PROP_DIRECT);
- touchpad.injector->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1);
- touchpad.injector->ConfigureAbsSlots(kSlots);
- touchpad.injector->ConfigureRel(REL_WHEEL);
- touchpad.injector->ConfigureRel(REL_HWHEEL);
- touchpad.injector->ConfigureKey(BTN_TOUCH);
- touchpad.injector->ConfigureKey(BTN_BACK);
- touchpad.injector->ConfigureEnd();
- if (const status_t configuration_status = touchpad.injector->GetError()) {
- status = configuration_status;
- }
- }
- return status;
-}
-
-status_t VirtualTouchpadEvdev::Detach() {
- Reset();
- return OK;
-}
-
-int VirtualTouchpadEvdev::Touch(int touchpad_id, float x, float y,
- float pressure) {
- if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
- return EINVAL;
- }
- int32_t device_x = x * kWidth;
- int32_t device_y = y * kHeight;
- Touchpad& touchpad = touchpad_[touchpad_id];
- touchpad.touches = ((touchpad.touches & 1) << 1) | (pressure > 0);
- ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d", x, y, pressure, device_x,
- device_y, touchpad.touches);
-
- if (!touchpad.injector) {
- return EvdevInjector::ERROR_SEQUENCING;
- }
- touchpad.injector->ResetError();
- switch (touchpad.touches) {
- case 0b00: // Hover continues.
- if (device_x != touchpad.last_device_x ||
- device_y != touchpad.last_device_y) {
- touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
- touchpad.injector->SendSynReport();
- }
- break;
- case 0b01: // Touch begins.
- // Press.
- touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
- touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_PRESS);
- touchpad.injector->SendSynReport();
- break;
- case 0b10: // Touch ends.
- touchpad.injector->SendKey(BTN_TOUCH, EvdevInjector::KEY_RELEASE);
- touchpad.injector->SendMultiTouchLift(0);
- touchpad.injector->SendSynReport();
- break;
- case 0b11: // Touch continues.
- if (device_x != touchpad.last_device_x ||
- device_y != touchpad.last_device_y) {
- touchpad.injector->SendMultiTouchXY(0, 0, device_x, device_y);
- touchpad.injector->SendSynReport();
- }
- break;
- }
- touchpad.last_device_x = device_x;
- touchpad.last_device_y = device_y;
-
- return touchpad.injector->GetError();
-}
-
-int VirtualTouchpadEvdev::ButtonState(int touchpad_id, int buttons) {
- if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
- return EINVAL;
- }
- Touchpad& touchpad = touchpad_[touchpad_id];
- const int changes = touchpad.last_motion_event_buttons ^ buttons;
- if (!changes) {
- return 0;
- }
- if (buttons & ~AMOTION_EVENT_BUTTON_BACK) {
- return ENOTSUP;
- }
- ALOGV("change %X from %X to %X", changes, touchpad.last_motion_event_buttons,
- buttons);
-
- if (!touchpad.injector) {
- return EvdevInjector::ERROR_SEQUENCING;
- }
- touchpad.injector->ResetError();
- if (changes & AMOTION_EVENT_BUTTON_BACK) {
- touchpad.injector->SendKey(BTN_BACK, (buttons & AMOTION_EVENT_BUTTON_BACK)
- ? EvdevInjector::KEY_PRESS
- : EvdevInjector::KEY_RELEASE);
- touchpad.injector->SendSynReport();
- }
- touchpad.last_motion_event_buttons = buttons;
- return touchpad.injector->GetError();
-}
-
-int VirtualTouchpadEvdev::Scroll(int touchpad_id, float x, float y) {
- if (touchpad_id < 0 || touchpad_id >= kTouchpads) {
- return EINVAL;
- }
- if ((x < -1.0f) || (x > 1.0f) || (y < -1.0f) || (y > 1.0f)) {
- return EINVAL;
- }
- Touchpad& touchpad = touchpad_[touchpad_id];
- if (!touchpad.injector) {
- return EvdevInjector::ERROR_SEQUENCING;
- }
- touchpad.injector->ResetError();
- const int32_t scaled_x = scale_relative_scroll(x);
- const int32_t scaled_y = scale_relative_scroll(y);
- ALOGV("(%f,%f) -> (%" PRId32 ",%" PRId32 ")", x, y, scaled_x, scaled_y);
- if (scaled_x) {
- touchpad.injector->SendRel(REL_HWHEEL, scaled_x);
- }
- if (scaled_y) {
- touchpad.injector->SendRel(REL_WHEEL, scaled_y);
- }
- if (scaled_x || scaled_y) {
- touchpad.injector->SendSynReport();
- }
- return touchpad.injector->GetError();
-}
-
-void VirtualTouchpadEvdev::dumpInternal(String8& result) {
- for (int i = 0; i < kTouchpads; ++i) {
- const auto& touchpad = touchpad_[i];
- result.appendFormat("[virtual touchpad %d]\n", i);
- if (!touchpad.injector) {
- result.append("injector = none\n");
- return;
- }
- result.appendFormat("injector = %s\n",
- touchpad.owned_injector ? "normal" : "test");
- result.appendFormat("touches = %d\n", touchpad.touches);
- result.appendFormat("last_position = (%" PRId32 ", %" PRId32 ")\n",
- touchpad.last_device_x, touchpad.last_device_y);
- result.appendFormat("last_buttons = 0x%" PRIX32 "\n",
- touchpad.last_motion_event_buttons);
- touchpad.injector->dumpInternal(result);
- result.append("\n");
- }
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
deleted file mode 100644
index c9578bf..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
-
-#include "EvdevInjector.h"
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-class EvdevInjector;
-
-// VirtualTouchpadEvdev implements a VirtualTouchpad by injecting evdev events.
-//
-class VirtualTouchpadEvdev : public VirtualTouchpad {
- public:
- static std::unique_ptr<VirtualTouchpad> Create();
- ~VirtualTouchpadEvdev() override {}
-
- // VirtualTouchpad implementation:
- status_t Attach() override;
- status_t Detach() override;
- status_t Touch(int touchpad, float x, float y, float pressure) override;
- status_t ButtonState(int touchpad, int buttons) override;
- status_t Scroll(int touchpad, float x, float y) override;
- void dumpInternal(String8& result) override;
-
- protected:
- static constexpr int kTouchpads = 2;
-
- VirtualTouchpadEvdev() {}
- void Reset();
-
- // Must be called only between construction (or Detach()) and Attach().
- inline void SetEvdevInjectorForTesting(int touchpad,
- EvdevInjector* injector) {
- touchpad_[touchpad].injector = injector;
- }
-
- private:
- // Per-touchpad state.
- struct Touchpad {
- // Except for testing, the |EvdevInjector| used to inject evdev events.
- std::unique_ptr<EvdevInjector> owned_injector;
-
- // Active pointer to |owned_injector_| or to a testing injector.
- EvdevInjector* injector = nullptr;
-
- // Previous (x, y) position in device space, to suppress redundant events.
- int32_t last_device_x;
- int32_t last_device_y;
-
- // Records current touch state (0=up 1=down) in bit 0, and previous state
- // in bit 1, to track transitions.
- int touches;
-
- // Previous injected button state, to detect changes.
- int32_t last_motion_event_buttons;
- };
- Touchpad touchpad_[kTouchpads];
-
- VirtualTouchpadEvdev(const VirtualTouchpadEvdev&) = delete;
- void operator=(const VirtualTouchpadEvdev&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_EVDEV_H
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
deleted file mode 100644
index d0a9da1..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "VirtualTouchpadService.h"
-
-#include <inttypes.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/PermissionCache.h>
-#include <binder/Status.h>
-#include <cutils/log.h>
-#include <linux/input.h>
-#include <private/android_filesystem_config.h>
-#include <utils/Errors.h>
-
-namespace android {
-namespace dvr {
-
-namespace {
-const String16 kDumpPermission("android.permission.DUMP");
-const String16 kTouchPermission("android.permission.RESTRICTED_VR_ACCESS");
-} // anonymous namespace
-
-VirtualTouchpadService::~VirtualTouchpadService() {
- if (client_pid_) {
- client_pid_ = 0;
- touchpad_->Detach();
- }
-}
-
-binder::Status VirtualTouchpadService::attach() {
- pid_t pid;
- if (!CheckTouchPermission(&pid)) {
- return binder::Status::fromStatusT(PERMISSION_DENIED);
- }
- if (client_pid_ == pid) {
- // The same client has called attach() twice with no intervening detach().
- // This indicates a problem with the client, so return an error.
- // However, since the client is already attached, any touchpad actions
- // it takes will still work.
- ALOGE("pid=%ld attached twice", static_cast<long>(pid));
- return binder::Status::fromStatusT(ALREADY_EXISTS);
- }
- if (client_pid_ != 0) {
- // Attach while another client is attached. This can happen if the client
- // dies without cleaning up after itself, so move ownership to the current
- // caller. If two actual clients have connected, the problem will be
- // reported when the previous client performs any touchpad action.
- ALOGE("pid=%ld replaces %ld", static_cast<long>(pid),
- static_cast<long>(client_pid_));
- client_pid_ = pid;
- return binder::Status::ok();
- }
- client_pid_ = pid;
- if (const status_t error = touchpad_->Attach()) {
- return binder::Status::fromStatusT(error);
- }
- return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::detach() {
- if (!CheckPermissions()) {
- return binder::Status::fromStatusT(PERMISSION_DENIED);
- }
- client_pid_ = 0;
- if (const status_t error = touchpad_->Detach()) {
- return binder::Status::fromStatusT(error);
- }
- return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::touch(int touchpad, float x, float y,
- float pressure) {
- if (!CheckPermissions()) {
- return binder::Status::fromStatusT(PERMISSION_DENIED);
- }
- if (const status_t error = touchpad_->Touch(touchpad, x, y, pressure)) {
- return binder::Status::fromStatusT(error);
- }
- return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::buttonState(int touchpad, int buttons) {
- if (!CheckPermissions()) {
- return binder::Status::fromStatusT(PERMISSION_DENIED);
- }
- if (const status_t error = touchpad_->ButtonState(touchpad, buttons)) {
- return binder::Status::fromStatusT(error);
- }
- return binder::Status::ok();
-}
-
-binder::Status VirtualTouchpadService::scroll(int touchpad, float x, float y) {
- if (!CheckPermissions()) {
- return binder::Status::fromStatusT(PERMISSION_DENIED);
- }
- if (const status_t error = touchpad_->Scroll(touchpad, x, y)) {
- return binder::Status::fromStatusT(error);
- }
- return binder::Status::ok();
-}
-
-status_t VirtualTouchpadService::dump(
- int fd, const Vector<String16>& args[[gnu::unused]]) {
- String8 result;
- const android::IPCThreadState* ipc = android::IPCThreadState::self();
- const pid_t pid = ipc->getCallingPid();
- const uid_t uid = ipc->getCallingUid();
- if ((uid != AID_SHELL) &&
- !PermissionCache::checkPermission(kDumpPermission, pid, uid)) {
- result.appendFormat("Permission denial: can't dump " LOG_TAG
- " from pid=%ld, uid=%ld\n",
- static_cast<long>(pid), static_cast<long>(uid));
- } else {
- result.appendFormat("[service]\nclient_pid = %ld\n\n",
- static_cast<long>(client_pid_));
- touchpad_->dumpInternal(result);
- }
- write(fd, result.c_str(), result.size());
- return OK;
-}
-
-bool VirtualTouchpadService::CheckPermissions() {
- pid_t pid;
- if (!CheckTouchPermission(&pid)) {
- return false;
- }
- if (client_pid_ != pid) {
- ALOGE("pid=%ld is not owner", static_cast<long>(pid));
- return false;
- }
- return true;
-}
-
-bool VirtualTouchpadService::CheckTouchPermission(pid_t* out_pid) {
- const android::IPCThreadState* ipc = android::IPCThreadState::self();
- *out_pid = ipc->getCallingPid();
- const uid_t uid = ipc->getCallingUid();
- const bool permission = PermissionCache::checkPermission(kTouchPermission, *out_pid, uid);
- if (!permission) {
- ALOGE("permission denied to pid=%ld uid=%ld", static_cast<long>(*out_pid),
- static_cast<long>(uid));
- }
- return permission;
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
deleted file mode 100644
index 2c88aec..0000000
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
-
-#include <android/dvr/BnVirtualTouchpadService.h>
-
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-// VirtualTouchpadService implements the service side of
-// the Binder interface defined in VirtualTouchpadService.aidl.
-//
-class VirtualTouchpadService : public BnVirtualTouchpadService {
- public:
- explicit VirtualTouchpadService(std::unique_ptr<VirtualTouchpad> touchpad)
- : touchpad_(std::move(touchpad)), client_pid_(0) {}
- ~VirtualTouchpadService() override;
-
- protected:
- // Implements IVirtualTouchpadService.
- binder::Status attach() override;
- binder::Status detach() override;
- binder::Status touch(int touchpad, float x, float y, float pressure) override;
- binder::Status buttonState(int touchpad, int buttons) override;
- binder::Status scroll(int touchpad, float x, float y) override;
-
- // Implements BBinder::dump().
- status_t dump(int fd, const Vector<String16>& args) override;
-
- private:
- bool CheckPermissions();
- bool CheckTouchPermission(pid_t* out_pid);
-
- std::unique_ptr<VirtualTouchpad> touchpad_;
-
- // Only one client at a time can use the virtual touchpad.
- pid_t client_pid_;
-
- VirtualTouchpadService(const VirtualTouchpadService&) = delete;
- void operator=(const VirtualTouchpadService&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_SERVICE_H
diff --git a/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl b/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl
deleted file mode 100644
index 89aa44a..0000000
--- a/services/vr/virtual_touchpad/aidl/android/dvr/IVirtualTouchpadService.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-package android.dvr;
-
-/** @hide */
-interface IVirtualTouchpadService
-{
- const String SERVICE_NAME = "virtual_touchpad";
-
- /**
- * Initialize the virtual touchpad.
- */
- void attach() = 0;
-
- /**
- * Shut down the virtual touchpad.
- */
- void detach() = 1;
-
- /**
- * Generate a simulated touch event.
- *
- * @param touchpad Selects touchpad.
- * @param x Horizontal touch position.
- * @param y Vertical touch position.
- * @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
- *
- * Position values in the range [0.0, 1.0) map to the screen.
- */
- void touch(int touchpad, float x, float y, float pressure) = 2;
-
- /**
- * Generate a simulated touchpad button state event.
- *
- * @param touchpad Selects touchpad.
- * @param buttons A union of MotionEvent BUTTON_* values.
- */
- void buttonState(int touchpad, int buttons) = 3;
-
- /**
- * Generate a simulated scroll event.
- *
- * @param touchpad Selects touchpad.
- * @param x Horizontal scroll increment.
- * @param y Vertical scroll increment.
- *
- * Scroll values are in the range [-1.0, 1.0].
- */
- void scroll(int touchpad, float x, float y) = 4;
-}
diff --git a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc
deleted file mode 100644
index 205e8b9..0000000
--- a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-0.idc
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Virtual touchpad for the primary display
-device.internal = 1
-
-touch.deviceType = touchScreen
-
-# Have input flinger treat injected scroll events like a G1 ball
-# rather than the default mouse wheel, because the latter requires
-# a visible pointer for targeting.
-device.type = rotaryEncoder
-device.res = 1.0e+2
-device.scalingFactor = 1.0e-2
diff --git a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc b/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
deleted file mode 100644
index d9714e0..0000000
--- a/services/vr/virtual_touchpad/idc/vr-virtual-touchpad-1.idc
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Virtual touchpad for the VR virtual display
-device.internal = 1
-
-touch.deviceType = touchScreen
-
-# Have input flinger treat injected scroll events like a G1 ball
-# rather than the default mouse wheel, because the latter requires
-# a visible pointer for targeting.
-device.type = rotaryEncoder
-device.res = 1.0e+2
-device.scalingFactor = 1.0e-2
-
-# This displayID matches the unique ID of the virtual display created for VR.
-# This will indicate to input flinger than it should link this input device
-# with the virtual display.
-touch.displayId = virtual:android:277f1a09-b88d-4d1e-8716-796f114d080b
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpad.h b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
deleted file mode 100644
index 99b72fc..0000000
--- a/services/vr/virtual_touchpad/include/VirtualTouchpad.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
-
-#include "dvr/virtual_touchpad_client.h"
-
-#include <memory>
-#include <utils/Errors.h>
-#include <utils/String8.h>
-
-namespace android {
-namespace dvr {
-
-// Provides a virtual touchpad for injecting events into the input system.
-//
-class VirtualTouchpad {
- public:
- enum : int {
- PRIMARY = DVR_VIRTUAL_TOUCHPAD_PRIMARY,
- VIRTUAL = DVR_VIRTUAL_TOUCHPAD_VIRTUAL,
- };
-
- virtual ~VirtualTouchpad() {}
-
- // Create a virtual touchpad.
- // Implementations should provide this, and hide their constructors.
- // For the user, switching implementations should be as simple as changing
- // the class whose |Create()| is called.
- // Implementations should be minimial; major resource allocation should
- // be performed in Attach().
- static std::unique_ptr<VirtualTouchpad> Create() {
- return nullptr;
- }
-
- // Initialize a virtual touchpad.
- virtual status_t Attach() = 0;
-
- // Shut down a virtual touchpad.
- virtual status_t Detach() = 0;
-
- // Generate a simulated touch event.
- //
- // @param touchpad Touchpad selector index.
- // @param x Horizontal touch position.
- // @param y Vertical touch position.
- // Values must be in the range [0.0, 1.0).
- // @param pressure Touch pressure.
- // Positive values represent contact; use 1.0f if contact
- // is binary. Use 0.0f for no contact.
- // @returns OK on success.
- //
- virtual status_t Touch(int touchpad, float x, float y, float pressure) = 0;
-
- // Generate a simulated touchpad button state.
- //
- // @param touchpad Touchpad selector index.
- // @param buttons A union of MotionEvent BUTTON_* values.
- // @returns OK on success.
- //
- // Currently only BUTTON_BACK is supported, as the implementation
- // restricts itself to operations actually required by VrWindowManager.
- //
- virtual status_t ButtonState(int touchpad, int buttons) = 0;
-
- // Generate a simulated scroll event.
- //
- // @param touchpad Touchpad selector index.
- // @param x Horizontal scroll increment.
- // @param y Vertical scroll increment.
- // Values must be in the range [-1.0, 1.0].
- // @returns OK on success.
- //
- virtual status_t Scroll(int touchpad, float x, float y) = 0;
-
- // Report state for 'dumpsys'.
- virtual void dumpInternal(String8& result) = 0;
-
- protected:
- VirtualTouchpad() {}
-
- private:
- VirtualTouchpad(const VirtualTouchpad&) = delete;
- void operator=(const VirtualTouchpad&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_INTERFACE_H
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
deleted file mode 100644
index 268e4bd..0000000
--- a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
-
-#include "VirtualTouchpad.h"
-
-namespace android {
-namespace dvr {
-
-// VirtualTouchpadClient implements a VirtualTouchpad by connecting to
-// a VirtualTouchpadService over Binder.
-//
-class VirtualTouchpadClient : public VirtualTouchpad {
- public:
- // VirtualTouchpad implementation:
- static std::unique_ptr<VirtualTouchpad> Create();
-
- protected:
- VirtualTouchpadClient() {}
- ~VirtualTouchpadClient() override {}
-
- private:
- VirtualTouchpadClient(const VirtualTouchpadClient&) = delete;
- void operator=(const VirtualTouchpadClient&) = delete;
-};
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h b/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
deleted file mode 100644
index 09fb1cc..0000000
--- a/services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h
+++ /dev/null
@@ -1,79 +0,0 @@
-#ifndef ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
-#define ANDROID_DVR_VIRTUAL_TOUCHPAD_C_CLIENT_H
-
-#include <dvr/dvr_api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
-
-// Creates a new virtual touchpad client.
-//
-// @return Pointer to the created virtual touchpad client; nullptr on failure.
-//
-DvrVirtualTouchpad* dvrVirtualTouchpadCreate();
-
-// Destroys a virtual touchpad client.
-//
-// @param client Pointer to the virtual touchpad client to be destroyed.
-//
-void dvrVirtualTouchpadDestroy(DvrVirtualTouchpad* client);
-
-// Initialize the virtual touchpad.
-//
-// In the current server implementation, attachment creates and configures
-// the kernel virtual touchpad device(s). A single client may be attached
-// and detached repeatedly, e.g. on entering and leaving VR mode.
-//
-// @param client Pointer to the virtual touchpad client to be attached.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadAttach(DvrVirtualTouchpad* client);
-
-// Shut down the virtual touchpad.
-//
-// @param client Pointer to the virtual touchpad client to be detached.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadDetach(DvrVirtualTouchpad* client);
-
-// Generate a simulated touch event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param x Horizontal touch position.
-// @param y Vertical touch position.
-// @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadTouch(DvrVirtualTouchpad* client, int touchpad, float x,
- float y, float pressure);
-
-// Generate a simulated touchpad button state event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param buttons A union of MotionEvent BUTTON_* values.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadButtonState(DvrVirtualTouchpad* client, int touchpad,
- int buttons);
-
-// Generate a simulated scroll event.
-//
-// @param client Pointer to the virtual touchpad client.
-// @param touchpad Selects touchpad.
-// @param x Horizontal scroll increment.
-// @param y Vertical scroll increment.
-// @return Zero on success, status_t-style error code on failure.
-//
-int dvrVirtualTouchpadScroll(DvrVirtualTouchpad* client, int touchpad, float x,
- float y);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_VIRTUAL_TOUCHPAD_CLIENT_H
diff --git a/services/vr/virtual_touchpad/main.cpp b/services/vr/virtual_touchpad/main.cpp
deleted file mode 100644
index 55ac9bf..0000000
--- a/services/vr/virtual_touchpad/main.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <log/log.h>
-
-#include "VirtualTouchpadEvdev.h"
-#include "VirtualTouchpadService.h"
-
-int main() {
- ALOGI("Starting");
- android::sp<android::dvr::VirtualTouchpadService> touchpad_service =
- new android::dvr::VirtualTouchpadService(
- android::dvr::VirtualTouchpadEvdev::Create());
-
- signal(SIGPIPE, SIG_IGN);
- android::sp<android::ProcessState> ps(android::ProcessState::self());
- ps->setThreadPoolMaxThreadCount(4);
- ps->startThreadPool();
- ps->giveThreadPoolName();
-
- android::sp<android::IServiceManager> sm(android::defaultServiceManager());
- const android::status_t service_status =
- sm->addService(android::String16(touchpad_service->SERVICE_NAME()),
- touchpad_service, false /*allowIsolated*/);
- if (service_status != android::OK) {
- ALOGE("virtual touchpad service not added: %d",
- static_cast<int>(service_status));
- exit(2);
- }
-
- android::IPCThreadState::self()->joinThreadPool();
- return 0;
-}
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
deleted file mode 100644
index 198ed06..0000000
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ /dev/null
@@ -1,320 +0,0 @@
-#include <android/input.h>
-#include <gtest/gtest.h>
-#include <linux/input.h>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include "EvdevInjector.h"
-#include "VirtualTouchpadEvdev.h"
-
-namespace android {
-namespace dvr {
-
-namespace {
-
-class UInputForTesting : public EvdevInjector::UInput {
- public:
- ~UInputForTesting() override {}
- void WriteInputEvent(uint16_t type, uint16_t code, int32_t value) {
- struct input_event event;
- memset(&event, 0, sizeof(event));
- event.type = type;
- event.code = code;
- event.value = value;
- Write(&event, sizeof(event));
- }
-};
-
-// Recording test implementation of UInput.
-//
-class UInputRecorder : public UInputForTesting {
- public:
- UInputRecorder() {}
- ~UInputRecorder() override {}
-
- const std::string& GetString() const { return s_; }
- void Reset() { s_.clear(); }
-
- // UInput overrides:
-
- int Open() override {
- s_ += "o;";
- return 0;
- }
-
- int Close() override {
- s_ += "c;";
- return 0;
- }
-
- int Write(const void* buf, size_t count) override {
- s_ += "w(";
- s_ += Encode(&count, sizeof(count));
- s_ += ",";
- s_ += Encode(buf, count);
- s_ += ");";
- return 0;
- }
-
- int IoctlVoid(int request) override {
- s_ += "i(";
- s_ += Encode(&request, sizeof(request));
- s_ += ");";
- return 0;
- }
-
- int IoctlSetInt(int request, int value) override {
- s_ += "i(";
- s_ += Encode(&request, sizeof(request));
- s_ += ",";
- s_ += Encode(&value, sizeof(value));
- s_ += ");";
- return 0;
- }
-
- private:
- std::string s_;
-
- std::string Encode(const void* buf, size_t count) {
- const char* in = static_cast<const char*>(buf);
- char out[2 * count + 1];
- for (size_t i = 0; i < count; ++i) {
- snprintf(&out[2 * i], 3, "%02X", in[i]);
- }
- return out;
- }
-};
-
-class EvdevInjectorForTesting : public EvdevInjector {
- public:
- EvdevInjectorForTesting() { SetUInputForTesting(&record); }
- const uinput_user_dev* GetUiDev() const { return GetUiDevForTesting(); }
- UInputRecorder record;
-};
-
-class VirtualTouchpadForTesting : public VirtualTouchpadEvdev {
- public:
- static std::unique_ptr<VirtualTouchpad> Create() {
- return std::unique_ptr<VirtualTouchpad>(New());
- }
- static VirtualTouchpadForTesting* New() {
- VirtualTouchpadForTesting* const touchpad = new VirtualTouchpadForTesting();
- touchpad->Reset();
- for (int t = 0; t < kTouchpads; ++t) {
- touchpad->SetEvdevInjectorForTesting(t, &touchpad->injector[t]);
- }
- return touchpad;
- }
- int GetTouchpadCount() const { return kTouchpads; }
- EvdevInjectorForTesting injector[kTouchpads];
-};
-
-} // anonymous namespace
-
-class VirtualTouchpadTest : public testing::Test {};
-
-TEST_F(VirtualTouchpadTest, Goodness) {
- std::unique_ptr<VirtualTouchpadForTesting> touchpad(
- VirtualTouchpadForTesting::New());
- UInputRecorder expect;
-
- status_t touch_status = touchpad->Attach();
- EXPECT_EQ(0, touch_status);
-
- // Check some aspects of uinput_user_dev.
- const uinput_user_dev* uidev;
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- uidev = touchpad->injector[t].GetUiDev();
- String8 name;
- name.appendFormat("vr-virtual-touchpad-%d", t);
- EXPECT_EQ(name, uidev->name);
- for (int i = 0; i < ABS_CNT; ++i) {
- EXPECT_EQ(0, uidev->absmin[i]);
- EXPECT_EQ(0, uidev->absfuzz[i]);
- EXPECT_EQ(0, uidev->absflat[i]);
- if (i != ABS_MT_POSITION_X && i != ABS_MT_POSITION_Y &&
- i != ABS_MT_SLOT) {
- EXPECT_EQ(0, uidev->absmax[i]);
- }
- }
- }
- const int32_t width = 1 + uidev->absmax[ABS_MT_POSITION_X];
- const int32_t height = 1 + uidev->absmax[ABS_MT_POSITION_Y];
-
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- // Check the system calls performed by initialization.
- expect.Reset();
- // From ConfigureBegin():
- expect.Open();
- // From ConfigureInputProperty(INPUT_PROP_DIRECT):
- expect.IoctlSetInt(UI_SET_PROPBIT, INPUT_PROP_DIRECT);
- // From ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1):
- expect.IoctlSetInt(UI_SET_EVBIT, EV_ABS);
- expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_X);
- expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_POSITION_Y);
- // From ConfigureAbsSlots(kSlots):
- expect.IoctlSetInt(UI_SET_ABSBIT, ABS_MT_SLOT);
- // From ConfigureRel(REL_WHEEL):
- expect.IoctlSetInt(UI_SET_EVBIT, EV_REL);
- expect.IoctlSetInt(UI_SET_RELBIT, REL_WHEEL);
- // From ConfigureRel(REL_HWHEEL):
- expect.IoctlSetInt(UI_SET_RELBIT, REL_HWHEEL);
- // From ConfigureKey(BTN_TOUCH):
- expect.IoctlSetInt(UI_SET_EVBIT, EV_KEY);
- expect.IoctlSetInt(UI_SET_KEYBIT, BTN_TOUCH);
- expect.IoctlSetInt(UI_SET_KEYBIT, BTN_BACK);
- // From ConfigureEnd():
- expect.Write(touchpad->injector[t].GetUiDev(), sizeof(uinput_user_dev));
- expect.IoctlVoid(UI_DEV_CREATE);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0);
- expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->Touch(t, 0, 0, 0);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.75f * height);
- expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_PRESS);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->Touch(t, 0.25f, 0.75f, 0.5f);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.99f * width);
- expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_Y, 0.99f * height);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->Touch(t, 0.99f, 0.99f, 0.99f);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->Touch(t, 1.0f, 1.0f, 1.0f);
- EXPECT_EQ(EINVAL, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE);
- expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->Touch(t, 0.25f, 0.75f, -0.01f);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->ButtonState(t, AMOTION_EVENT_BUTTON_BACK);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE);
- expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- touch_status = touchpad->ButtonState(t, 0);
- EXPECT_EQ(0, touch_status);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-
- expect.Reset();
- expect.Close();
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- touchpad->injector[t].record.Reset();
- }
- touch_status = touchpad->Detach();
- EXPECT_EQ(0, touch_status);
- for (int t = 0; t < touchpad->GetTouchpadCount(); ++t) {
- SCOPED_TRACE(t);
- EXPECT_EQ(expect.GetString(), touchpad->injector[t].record.GetString());
- }
-}
-
-TEST_F(VirtualTouchpadTest, Badness) {
- std::unique_ptr<VirtualTouchpadForTesting> touchpad(
- VirtualTouchpadForTesting::New());
- UInputRecorder expect;
- UInputRecorder& record = touchpad->injector[VirtualTouchpad::PRIMARY].record;
-
- status_t touch_status = touchpad->Attach();
- EXPECT_EQ(0, touch_status);
-
- // Touch off-screen should return an error,
- // and should not result in any system calls.
- expect.Reset();
- record.Reset();
- touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f);
- EXPECT_NE(OK, touch_status);
- touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f);
- EXPECT_NE(OK, touch_status);
- touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f);
- EXPECT_NE(OK, touch_status);
- touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f);
- EXPECT_NE(OK, touch_status);
- EXPECT_EQ(expect.GetString(), record.GetString());
-
- // Unsupported button should return an error,
- // and should not result in any system calls.
- expect.Reset();
- record.Reset();
- touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
- AMOTION_EVENT_BUTTON_FORWARD);
- EXPECT_NE(OK, touch_status);
- EXPECT_EQ(expect.GetString(), record.GetString());
-
- // Repeated attach is an error.
- touch_status = touchpad->Attach();
- EXPECT_NE(0, touch_status);
-}
-
-} // namespace dvr
-} // namespace android
diff --git a/services/vr/virtual_touchpad/virtual_touchpad.rc b/services/vr/virtual_touchpad/virtual_touchpad.rc
deleted file mode 100644
index 1612743..0000000
--- a/services/vr/virtual_touchpad/virtual_touchpad.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service virtual_touchpad /system/bin/virtual_touchpad
- class core
- user system
- group system input uhid
- task_profiles VrServiceCapacityNormal