Merge "Exclude CtsHardwareTestCases flaky tests in inputflinger presubmit" into main
diff --git a/.gitignore b/.gitignore
index ed653c6..1ad8a24 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@
.idea/
.vscode/
*.code-workspace
+
+# Rust artifacts
+**/target/
diff --git a/include/android/sharedmem.h b/include/android/sharedmem.h
index 645fa8a..1d513a6 100644
--- a/include/android/sharedmem.h
+++ b/include/android/sharedmem.h
@@ -53,27 +53,27 @@
/**
* Create a shared memory region.
*
- * Create shared memory region and returns a file descriptor. The resulting file descriptor can be
- * mmap'ed to process memory space with PROT_READ | PROT_WRITE | PROT_EXEC. Access to shared memory
- * region can be restricted with {@link ASharedMemory_setProt}.
+ * Create a shared memory region and returns a file descriptor. The resulting file descriptor can be
+ * mapped into the process' memory using mmap(2) with `PROT_READ | PROT_WRITE | PROT_EXEC`.
+ * Access to shared memory regions can be restricted with {@link ASharedMemory_setProt}.
*
- * Use close() to release the shared memory region.
+ * Use close(2) to release the shared memory region.
*
* Use <a href="/reference/android/os/ParcelFileDescriptor">android.os.ParcelFileDescriptor</a>
* to pass the file descriptor to another process. File descriptors may also be sent to other
- * processes over a Unix domain socket with sendmsg and SCM_RIGHTS. See sendmsg(3) and
+ * processes over a Unix domain socket with sendmsg(2) and `SCM_RIGHTS`. See sendmsg(3) and
* cmsg(3) man pages for more information.
*
* If you intend to share this file descriptor with a child process after
- * calling exec(3), note that you will need to use fcntl(2) with F_SETFD
- * to clear the FD_CLOEXEC flag for this to work on all versions of Android.
+ * calling exec(3), note that you will need to use fcntl(2) with `F_SETFD`
+ * to clear the `FD_CLOEXEC` flag for this to work on all versions of Android.
*
* Available since API level 26.
*
* \param name an optional name.
* \param size size of the shared memory region
* \return file descriptor that denotes the shared memory;
- * -1 and sets errno on failure, or -EINVAL if the error is that size was 0.
+ * -1 and sets `errno` on failure, or `-EINVAL` if the error is that size was 0.
*/
int ASharedMemory_create(const char *name, size_t size) __INTRODUCED_IN(26);
@@ -83,7 +83,7 @@
* Available since API level 26.
*
* \param fd file descriptor of the shared memory region
- * \return size in bytes; 0 if fd is not a valid shared memory file descriptor.
+ * \return size in bytes; 0 if `fd` is not a valid shared memory file descriptor.
*/
size_t ASharedMemory_getSize(int fd) __INTRODUCED_IN(26);
@@ -115,9 +115,9 @@
* Available since API level 26.
*
* \param fd file descriptor of the shared memory region.
- * \param prot any bitwise-or'ed combination of PROT_READ, PROT_WRITE, PROT_EXEC denoting
+ * \param prot any bitwise-or'ed combination of `PROT_READ`, `PROT_WRITE`, `PROT_EXEC` denoting
* updated access. Note access can only be removed, but not added back.
- * \return 0 for success, -1 and sets errno on failure.
+ * \return 0 for success, -1 and sets `errno` on failure.
*/
int ASharedMemory_setProt(int fd, int prot) __INTRODUCED_IN(26);
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 0f4a6ca..aa67869 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -29,7 +29,6 @@
#include <binder/Parcel.h>
#include <binder/RecordedTransaction.h>
#include <binder/RpcServer.h>
-#include <cutils/compiler.h>
#include <private/android_filesystem_config.h>
#include <pthread.h>
#include <utils/misc.h>
@@ -402,7 +401,7 @@
}
}
- if (CC_UNLIKELY(kEnableKernelIpc && mRecordingOn && code != START_RECORDING_TRANSACTION)) {
+ if (kEnableKernelIpc && mRecordingOn && code != START_RECORDING_TRANSACTION) [[unlikely]] {
Extras* e = mExtras.load(std::memory_order_acquire);
AutoMutex lock(e->mLock);
if (mRecordingOn) {
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index ef0ae4f..3bc4f92 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -23,7 +23,6 @@
#include <binder/IResultReceiver.h>
#include <binder/RpcSession.h>
#include <binder/Stability.h>
-#include <cutils/compiler.h>
#include <utils/Log.h>
#include <stdio.h>
@@ -166,7 +165,7 @@
trackedUid = IPCThreadState::self()->getCallingUid();
AutoMutex _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[trackedUid];
- if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
+ if (trackedValue & LIMIT_REACHED_MASK) [[unlikely]] {
if (sBinderProxyThrottleCreate) {
return nullptr;
}
@@ -364,7 +363,7 @@
Stability::Level required = privateVendor ? Stability::VENDOR
: Stability::getLocalLevel();
- if (CC_UNLIKELY(!Stability::check(stability, required))) {
+ if (!Stability::check(stability, required)) [[unlikely]] {
ALOGE("Cannot do a user transaction on a %s binder (%s) in a %s context.",
Stability::levelString(stability).c_str(),
String8(getInterfaceDescriptor()).c_str(),
@@ -374,7 +373,7 @@
}
status_t status;
- if (CC_UNLIKELY(isRpcBinder())) {
+ if (isRpcBinder()) [[unlikely]] {
status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data, reply,
flags);
} else {
@@ -589,7 +588,9 @@
}
BpBinder::~BpBinder() {
- if (CC_UNLIKELY(isRpcBinder())) return;
+ if (isRpcBinder()) [[unlikely]] {
+ return;
+ }
if constexpr (!kEnableKernelIpc) {
LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
@@ -603,14 +604,13 @@
if (mTrackedUid >= 0) {
AutoMutex _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[mTrackedUid];
- if (CC_UNLIKELY((trackedValue & COUNTING_VALUE_MASK) == 0)) {
+ if ((trackedValue & COUNTING_VALUE_MASK) == 0) [[unlikely]] {
ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this,
binderHandle());
} else {
- if (CC_UNLIKELY(
- (trackedValue & LIMIT_REACHED_MASK) &&
- ((trackedValue & COUNTING_VALUE_MASK) <= sBinderProxyCountLowWatermark)
- )) {
+ auto countingValue = trackedValue & COUNTING_VALUE_MASK;
+ if ((trackedValue & LIMIT_REACHED_MASK) &&
+ (countingValue <= sBinderProxyCountLowWatermark)) [[unlikely]] {
ALOGI("Limit reached bit reset for uid %d (fewer than %d proxies from uid %d held)",
getuid(), sBinderProxyCountLowWatermark, mTrackedUid);
sTrackingMap[mTrackedUid] &= ~LIMIT_REACHED_MASK;
@@ -630,7 +630,9 @@
}
void BpBinder::onFirstRef() {
- if (CC_UNLIKELY(isRpcBinder())) return;
+ if (isRpcBinder()) [[unlikely]] {
+ return;
+ }
if constexpr (!kEnableKernelIpc) {
LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
@@ -643,7 +645,7 @@
}
void BpBinder::onLastStrongRef(const void* /*id*/) {
- if (CC_UNLIKELY(isRpcBinder())) {
+ if (isRpcBinder()) [[unlikely]] {
(void)rpcSession()->sendDecStrong(this);
return;
}
@@ -684,7 +686,9 @@
bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
{
// RPC binder doesn't currently support inc from weak binders
- if (CC_UNLIKELY(isRpcBinder())) return false;
+ if (isRpcBinder()) [[unlikely]] {
+ return false;
+ }
if constexpr (!kEnableKernelIpc) {
LOG_ALWAYS_FATAL("Binder kernel driver disabled at build time");
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 817e0fc..6e3abf5 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -41,7 +41,6 @@
#include <android-base/scopeguard.h>
#include <cutils/ashmem.h>
-#include <cutils/compiler.h>
#include <utils/Flattenable.h>
#include <utils/Log.h>
#include <utils/String16.h>
diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h
index 5fa2ff6..96b9733 100644
--- a/libs/binder/include/binder/SafeInterface.h
+++ b/libs/binder/include/binder/SafeInterface.h
@@ -18,7 +18,6 @@
#include <binder/IInterface.h>
#include <binder/Parcel.h>
-#include <cutils/compiler.h>
// Set to 1 to enable CallStacks when logging errors
#define SI_DUMP_CALLSTACKS 0
@@ -218,7 +217,7 @@
template <typename Function>
status_t callParcel(const char* name, Function f) const {
status_t error = f();
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
ALOG(LOG_ERROR, mLogTag, "Failed to %s, (%d: %s)", name, error, strerror(-error));
#if SI_DUMP_CALLSTACKS
CallStack callStack(mLogTag);
@@ -265,7 +264,7 @@
data.writeInterfaceToken(this->getInterfaceDescriptor());
status_t error = writeInputs(&data, std::forward<Args>(args)...);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by writeInputs
return error;
}
@@ -273,7 +272,7 @@
// Send the data Parcel to the remote and retrieve the reply parcel
Parcel reply;
error = this->remote()->transact(static_cast<uint32_t>(tag), data, &reply);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
ALOG(LOG_ERROR, mLogTag, "Failed to transact (%d)", error);
#if SI_DUMP_CALLSTACKS
CallStack callStack(mLogTag);
@@ -283,7 +282,7 @@
// Read the outputs from the reply Parcel into the output arguments
error = readOutputs(reply, std::forward<Args>(args)...);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by readOutputs
return error;
}
@@ -291,7 +290,7 @@
// Retrieve the result code from the reply Parcel
status_t result = NO_ERROR;
error = reply.readInt32(&result);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
ALOG(LOG_ERROR, mLogTag, "Failed to obtain result");
#if SI_DUMP_CALLSTACKS
CallStack callStack(mLogTag);
@@ -315,7 +314,7 @@
Parcel data;
data.writeInterfaceToken(this->getInterfaceDescriptor());
status_t error = writeInputs(&data, std::forward<Args>(args)...);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by writeInputs
return;
}
@@ -324,7 +323,7 @@
Parcel reply;
error = this->remote()->transact(static_cast<uint32_t>(tag), data, &reply,
IBinder::FLAG_ONEWAY);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
ALOG(LOG_ERROR, mLogTag, "Failed to transact (%d)", error);
#if SI_DUMP_CALLSTACKS
CallStack callStack(mLogTag);
@@ -406,7 +405,7 @@
template <typename T, typename... Remaining>
status_t writeInputs(Parcel* data, T&& t, Remaining&&... remaining) const {
status_t error = writeIfInput(data, std::forward<T>(t));
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by writeIfInput
return error;
}
@@ -429,7 +428,7 @@
template <typename T, typename... Remaining>
status_t readOutputs(const Parcel& reply, T&& t, Remaining&&... remaining) const {
status_t error = readIfOutput(reply, std::forward<T>(t));
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by readIfOutput
return error;
}
@@ -458,7 +457,7 @@
// Read the inputs from the data Parcel into the argument tuple
status_t error = InputReader<ParamTuple>{mLogTag}.readInputs(data, &rawArgs);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by read
return error;
}
@@ -468,14 +467,14 @@
// Extract the outputs from the argument tuple and write them into the reply Parcel
error = OutputWriter<ParamTuple>{mLogTag}.writeOutputs(reply, &rawArgs);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by write
return error;
}
// Return the result code in the reply Parcel
error = reply->writeInt32(result);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
ALOG(LOG_ERROR, mLogTag, "Failed to write result");
#if SI_DUMP_CALLSTACKS
CallStack callStack(mLogTag);
@@ -500,7 +499,7 @@
// Read the inputs from the data Parcel into the argument tuple
status_t error = InputReader<ParamTuple>{mLogTag}.readInputs(data, &rawArgs);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged by read
return error;
}
@@ -596,7 +595,7 @@
typename std::enable_if<(I < sizeof...(Params)), status_t>::type dispatchArg(
const Parcel& data, RawTuple* args) {
status_t error = readIfInput<I>(data, args);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged in read
return error;
}
@@ -694,7 +693,7 @@
typename std::enable_if<(I < sizeof...(Params)), status_t>::type dispatchArg(
Parcel* reply, RawTuple* args) {
status_t error = writeIfOutput<I>(reply, args);
- if (CC_UNLIKELY(error != NO_ERROR)) {
+ if (error != NO_ERROR) [[unlikely]] {
// A message will have been logged in read
return error;
}
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 692cc95..8e95d69 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -59,12 +59,13 @@
auto basename = Basename(program);
auto format = R"(dispatch calls to RPC service.
Usage:
- %s [-g] <service_name>
+ %s [-g] [-i <ip_address>] <service_name>
<service_name>: the service to connect to.
%s [-g] manager
Runs an RPC-friendly service that redirects calls to servicemanager.
-g: use getService() instead of checkService().
+ -i: use ip_address when setting up the server instead of '127.0.0.1'
If successful, writes port number and a new line character to stdout, and
blocks until killed.
@@ -74,7 +75,8 @@
return EX_USAGE;
}
-int Dispatch(const char* name, const ServiceRetriever& serviceRetriever) {
+int Dispatch(const char* name, const ServiceRetriever& serviceRetriever,
+ const char* ip_address = kLocalInetAddress) {
auto sm = defaultServiceManager();
if (nullptr == sm) {
LOG(ERROR) << "No servicemanager";
@@ -91,7 +93,7 @@
return EX_SOFTWARE;
}
unsigned int port;
- if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
+ if (status_t status = rpcServer->setupInetServer(ip_address, 0, &port); status != OK) {
LOG(ERROR) << "setupInetServer failed: " << statusToString(status);
return EX_SOFTWARE;
}
@@ -188,7 +190,8 @@
// Workaround for b/191059588.
// TODO(b/191059588): Once we can run RpcServer on single-threaded services,
// `servicedispatcher manager` should call Dispatch("manager") directly.
-int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
+int wrapServiceManager(const ServiceRetriever& serviceRetriever,
+ const char* ip_address = kLocalInetAddress) {
auto sm = defaultServiceManager();
if (nullptr == sm) {
LOG(ERROR) << "No servicemanager";
@@ -212,7 +215,7 @@
auto rpcServer = RpcServer::make();
rpcServer->setRootObject(service);
unsigned int port;
- if (status_t status = rpcServer->setupInetServer(kLocalInetAddress, 0, &port); status != OK) {
+ if (status_t status = rpcServer->setupInetServer(ip_address, 0, &port); status != OK) {
LOG(ERROR) << "Unable to set up inet server: " << statusToString(status);
return EX_SOFTWARE;
}
@@ -272,11 +275,15 @@
int opt;
ServiceRetriever serviceRetriever = &android::IServiceManager::checkService;
- while (-1 != (opt = getopt(argc, argv, "g"))) {
+ char* ip_address = nullptr;
+ while (-1 != (opt = getopt(argc, argv, "gi:"))) {
switch (opt) {
case 'g': {
serviceRetriever = &android::IServiceManager::getService;
} break;
+ case 'i': {
+ ip_address = optarg;
+ } break;
default: {
return Usage(argv[0]);
}
@@ -291,7 +298,15 @@
auto name = argv[optind];
if (name == "manager"sv) {
- return wrapServiceManager(serviceRetriever);
+ if (ip_address) {
+ return wrapServiceManager(serviceRetriever, ip_address);
+ } else {
+ return wrapServiceManager(serviceRetriever);
+ }
}
- return Dispatch(name, serviceRetriever);
+ if (ip_address) {
+ return Dispatch(name, serviceRetriever, ip_address);
+ } else {
+ return Dispatch(name, serviceRetriever);
+ }
}
diff --git a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
index 5079431..0a584bf 100644
--- a/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/BpBinderFuzzFunctions.h
@@ -26,7 +26,6 @@
#include <binder/Parcel.h>
#include <binder/Stability.h>
-#include <cutils/compiler.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <utils/Mutex.h>
diff --git a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
index bf7c613..a6dc182 100644
--- a/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
+++ b/libs/binder/tests/unit_fuzzers/IBinderFuzzFunctions.h
@@ -23,7 +23,6 @@
#include <binder/IResultReceiver.h>
#include <binder/Parcel.h>
#include <binder/Stability.h>
-#include <cutils/compiler.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
#include <utils/Mutex.h>
diff --git a/libs/binder/trusty/fuzzer/Android.bp b/libs/binder/trusty/fuzzer/Android.bp
index 2f1f54b..4f9b5c4 100644
--- a/libs/binder/trusty/fuzzer/Android.bp
+++ b/libs/binder/trusty/fuzzer/Android.bp
@@ -24,6 +24,7 @@
"-DTRUSTY_APP_PORT=\"com.android.trusty.binder.test.service\"",
"-DTRUSTY_APP_UUID=\"d42f06c5-9dc5-455b-9914-cf094116cfa8\"",
"-DTRUSTY_APP_FILENAME=\"binder-test-service.syms.elf\"",
+ "-DTRUSTY_APP_MAX_CONNECTIONS=1",
],
}
@@ -35,5 +36,30 @@
"-DTRUSTY_APP_PORT=\"com.android.trusty.binderRpcTestService.V0\"",
"-DTRUSTY_APP_UUID=\"87e424e5-69d7-4bbd-8b7c-7e24812cbc94\"",
"-DTRUSTY_APP_FILENAME=\"binderRpcTestService.syms.elf\"",
+ "-DTRUSTY_APP_MAX_CONNECTIONS=1",
+ ],
+}
+
+cc_fuzz {
+ name: "trusty_binder_fuzzer_multi_connection",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.binder.test.service\"",
+ "-DTRUSTY_APP_UUID=\"d42f06c5-9dc5-455b-9914-cf094116cfa8\"",
+ "-DTRUSTY_APP_FILENAME=\"binder-test-service.syms.elf\"",
+ "-DTRUSTY_APP_MAX_CONNECTIONS=10",
+ ],
+}
+
+cc_fuzz {
+ name: "trusty_binder_rpc_fuzzer_multi_connection",
+ defaults: ["trusty_fuzzer_defaults"],
+ srcs: [":trusty_tipc_fuzzer"],
+ cflags: [
+ "-DTRUSTY_APP_PORT=\"com.android.trusty.binderRpcTestService.V0\"",
+ "-DTRUSTY_APP_UUID=\"87e424e5-69d7-4bbd-8b7c-7e24812cbc94\"",
+ "-DTRUSTY_APP_FILENAME=\"binderRpcTestService.syms.elf\"",
+ "-DTRUSTY_APP_MAX_CONNECTIONS=10",
],
}
diff --git a/libs/bufferstreams/rust/src/lib.rs b/libs/bufferstreams/rust/src/lib.rs
index 87f3104..5964281 100644
--- a/libs/bufferstreams/rust/src/lib.rs
+++ b/libs/bufferstreams/rust/src/lib.rs
@@ -159,7 +159,7 @@
/// Struct used to contain the buffer.
pub struct Frame {
/// A handle to the C buffer interface.
- pub buffer: AHardwareBuffer,
+ pub buffer: HardwareBuffer,
/// The time at which the buffer was dispatched.
pub present_time: Instant,
/// A fence used for reading/writing safely.
diff --git a/libs/bufferstreams/rust/src/stream_config.rs b/libs/bufferstreams/rust/src/stream_config.rs
index d0c621b..454bdf1 100644
--- a/libs/bufferstreams/rust/src/stream_config.rs
+++ b/libs/bufferstreams/rust/src/stream_config.rs
@@ -33,9 +33,9 @@
}
impl StreamConfig {
- /// Tries to create a new AHardwareBuffer from settings in a [StreamConfig].
- pub fn create_hardware_buffer(&self) -> Option<AHardwareBuffer> {
- AHardwareBuffer::new(self.width, self.height, self.layers, self.format, self.usage)
+ /// Tries to create a new HardwareBuffer from settings in a [StreamConfig].
+ pub fn create_hardware_buffer(&self) -> Option<HardwareBuffer> {
+ HardwareBuffer::new(self.width, self.height, self.layers, self.format, self.usage)
}
}
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index 6d1dfe8..aab1276 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -58,7 +58,7 @@
],
export_shared_lib_headers: [
- "android.hardware.graphics.common-V4-ndk",
+ "android.hardware.graphics.common-V5-ndk",
"android.hardware.graphics.mapper@4.0",
"libhidlbase",
],
diff --git a/libs/gralloc/types/Gralloc4.cpp b/libs/gralloc/types/Gralloc4.cpp
index 61e6657..ce35906 100644
--- a/libs/gralloc/types/Gralloc4.cpp
+++ b/libs/gralloc/types/Gralloc4.cpp
@@ -1307,6 +1307,10 @@
return "SitedInterstitial";
case ChromaSiting::COSITED_HORIZONTAL:
return "CositedHorizontal";
+ case ChromaSiting::COSITED_VERTICAL:
+ return "CositedVertical";
+ case ChromaSiting::COSITED_BOTH:
+ return "CositedBoth";
}
}
diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp
index 1c0439e..5dc195c 100644
--- a/libs/graphicsenv/IGpuService.cpp
+++ b/libs/graphicsenv/IGpuService.cpp
@@ -64,9 +64,17 @@
void setTargetStatsArray(const std::string& appPackageName, const uint64_t driverVersionCode,
const GpuStatsInfo::Stats stats, const uint64_t* values,
const uint32_t valueCount) override {
- for (uint32_t i = 0; i < valueCount; i++) {
- setTargetStats(appPackageName, driverVersionCode, stats, values[i]);
- }
+ Parcel data, reply;
+ data.writeInterfaceToken(IGpuService::getInterfaceDescriptor());
+
+ data.writeUtf8AsUtf16(appPackageName);
+ data.writeUint64(driverVersionCode);
+ data.writeInt32(static_cast<int32_t>(stats));
+ data.writeUint32(valueCount);
+ data.write(values, valueCount * sizeof(uint64_t));
+
+ remote()->transact(BnGpuService::SET_TARGET_STATS_ARRAY, data, &reply,
+ IBinder::FLAG_ONEWAY);
}
void setUpdatableDriverPath(const std::string& driverPath) override {
@@ -164,6 +172,31 @@
return OK;
}
+ case SET_TARGET_STATS_ARRAY: {
+ CHECK_INTERFACE(IGpuService, data, reply);
+
+ std::string appPackageName;
+ if ((status = data.readUtf8FromUtf16(&appPackageName)) != OK) return status;
+
+ uint64_t driverVersionCode;
+ if ((status = data.readUint64(&driverVersionCode)) != OK) return status;
+
+ int32_t stats;
+ if ((status = data.readInt32(&stats)) != OK) return status;
+
+ uint32_t valueCount;
+ if ((status = data.readUint32(&valueCount)) != OK) return status;
+
+ std::vector<uint64_t> values(valueCount);
+ if ((status = data.read(values.data(), valueCount * sizeof(uint64_t))) != OK) {
+ return status;
+ }
+
+ setTargetStatsArray(appPackageName, driverVersionCode,
+ static_cast<GpuStatsInfo::Stats>(stats), values.data(), valueCount);
+
+ return OK;
+ }
case SET_UPDATABLE_DRIVER_PATH: {
CHECK_INTERFACE(IGpuService, data, reply);
diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h
index e3857d2..45f05d6 100644
--- a/libs/graphicsenv/include/graphicsenv/IGpuService.h
+++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h
@@ -63,6 +63,7 @@
SET_UPDATABLE_DRIVER_PATH,
GET_UPDATABLE_DRIVER_PATH,
TOGGLE_ANGLE_AS_SYSTEM_DRIVER,
+ SET_TARGET_STATS_ARRAY,
// Always append new enum to the end.
};
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8a57f92..f0604b9 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -2604,6 +2604,7 @@
outMode.xDpi = mode.xDpi;
outMode.yDpi = mode.yDpi;
outMode.refreshRate = mode.refreshRate;
+ outMode.vsyncRate = mode.vsyncRate;
outMode.appVsyncOffset = mode.appVsyncOffset;
outMode.sfVsyncOffset = mode.sfVsyncOffset;
outMode.presentationDeadline = mode.presentationDeadline;
diff --git a/libs/gui/aidl/android/gui/DisplayMode.aidl b/libs/gui/aidl/android/gui/DisplayMode.aidl
index ce30426..b057653 100644
--- a/libs/gui/aidl/android/gui/DisplayMode.aidl
+++ b/libs/gui/aidl/android/gui/DisplayMode.aidl
@@ -29,7 +29,9 @@
float yDpi = 0.0f;
int[] supportedHdrTypes;
+ // Some modes have peak refresh rate lower than the panel vsync rate.
float refreshRate = 0.0f;
+ float vsyncRate = 0.0f;
long appVsyncOffset = 0;
long sfVsyncOffset = 0;
long presentationDeadline = 0;
diff --git a/libs/nativewindow/include/android/data_space.h b/libs/nativewindow/include/android/data_space.h
index 47a4bfc..eab21fb 100644
--- a/libs/nativewindow/include/android/data_space.h
+++ b/libs/nativewindow/include/android/data_space.h
@@ -81,11 +81,12 @@
STANDARD_UNSPECIFIED = 0 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.300 0.600
* blue 0.150 0.060
* red 0.640 0.330
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* Use the unadjusted KR = 0.2126, KB = 0.0722 luminance interpretation
* for RGB conversion.
@@ -93,11 +94,12 @@
STANDARD_BT709 = 1 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.290 0.600
* blue 0.150 0.060
* red 0.640 0.330
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* KR = 0.299, KB = 0.114. This adjusts the luminance interpretation
* for RGB conversion from the one purely determined by the primaries
@@ -107,11 +109,12 @@
STANDARD_BT601_625 = 2 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.290 0.600
* blue 0.150 0.060
* red 0.640 0.330
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* Use the unadjusted KR = 0.222, KB = 0.071 luminance interpretation
* for RGB conversion.
@@ -119,11 +122,12 @@
STANDARD_BT601_625_UNADJUSTED = 3 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.310 0.595
* blue 0.155 0.070
* red 0.630 0.340
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* KR = 0.299, KB = 0.114. This adjusts the luminance interpretation
* for RGB conversion from the one purely determined by the primaries
@@ -133,11 +137,12 @@
STANDARD_BT601_525 = 4 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.310 0.595
* blue 0.155 0.070
* red 0.630 0.340
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* Use the unadjusted KR = 0.212, KB = 0.087 luminance interpretation
* for RGB conversion (as in SMPTE 240M).
@@ -145,11 +150,12 @@
STANDARD_BT601_525_UNADJUSTED = 5 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.170 0.797
* blue 0.131 0.046
* red 0.708 0.292
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation
* for RGB conversion.
@@ -157,11 +163,12 @@
STANDARD_BT2020 = 6 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.170 0.797
* blue 0.131 0.046
* red 0.708 0.292
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*
* Use the unadjusted KR = 0.2627, KB = 0.0593 luminance interpretation
* for RGB conversion using the linear domain.
@@ -169,11 +176,12 @@
STANDARD_BT2020_CONSTANT_LUMINANCE = 7 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.21 0.71
* blue 0.14 0.08
* red 0.67 0.33
- * white (C) 0.310 0.316
+ * white (C) 0.310 0.316</pre>
*
* Use the unadjusted KR = 0.30, KB = 0.11 luminance interpretation
* for RGB conversion.
@@ -181,11 +189,12 @@
STANDARD_BT470M = 8 << 16,
/**
+ * <pre>
* Primaries: x y
* green 0.243 0.692
* blue 0.145 0.049
* red 0.681 0.319
- * white (C) 0.310 0.316
+ * white (C) 0.310 0.316</pre>
*
* Use the unadjusted KR = 0.254, KB = 0.068 luminance interpretation
* for RGB conversion.
@@ -194,21 +203,23 @@
/**
* SMPTE EG 432-1 and SMPTE RP 431-2. (DCI-P3)
+ * <pre>
* Primaries: x y
* green 0.265 0.690
* blue 0.150 0.060
* red 0.680 0.320
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*/
STANDARD_DCI_P3 = 10 << 16,
/**
* Adobe RGB
+ * <pre>
* Primaries: x y
* green 0.210 0.710
* blue 0.150 0.060
* red 0.640 0.330
- * white (D65) 0.3127 0.3290
+ * white (D65) 0.3127 0.3290</pre>
*/
STANDARD_ADOBE_RGB = 11 << 16,
@@ -242,83 +253,86 @@
TRANSFER_UNSPECIFIED = 0 << 22,
/**
+ * Linear transfer.
+ * <pre>
* Transfer characteristic curve:
- * E = L
- * L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E = L
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_LINEAR = 1 << 22,
/**
+ * sRGB transfer.
+ * <pre>
* Transfer characteristic curve:
- *
* E = 1.055 * L^(1/2.4) - 0.055 for 0.0031308 <= L <= 1
* = 12.92 * L for 0 <= L < 0.0031308
* L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_SRGB = 2 << 22,
/**
- * BT.601 525, BT.601 625, BT.709, BT.2020
- *
+ * SMPTE 170M transfer.
+ * <pre>
* Transfer characteristic curve:
- * E = 1.099 * L ^ 0.45 - 0.099 for 0.018 <= L <= 1
- * = 4.500 * L for 0 <= L < 0.018
- * L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E = 1.099 * L ^ 0.45 - 0.099 for 0.018 <= L <= 1
+ * = 4.500 * L for 0 <= L < 0.018
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_SMPTE_170M = 3 << 22,
/**
- * Assumed display gamma 2.2.
- *
+ * Display gamma 2.2.
+ * <pre>
* Transfer characteristic curve:
- * E = L ^ (1/2.2)
- * L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E = L ^ (1/2.2)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_GAMMA2_2 = 4 << 22,
/**
- * display gamma 2.6.
- *
+ * Display gamma 2.6.
+ * <pre>
* Transfer characteristic curve:
- * E = L ^ (1/2.6)
- * L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E = L ^ (1/2.6)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_GAMMA2_6 = 5 << 22,
/**
- * display gamma 2.8.
- *
+ * Display gamma 2.8.
+ * <pre>
* Transfer characteristic curve:
- * E = L ^ (1/2.8)
- * L - luminance of image 0 <= L <= 1 for conventional colorimetry
- * E - corresponding electrical signal
+ * E = L ^ (1/2.8)
+ * L - luminance of image 0 <= L <= 1 for conventional colorimetry
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_GAMMA2_8 = 6 << 22,
/**
- * SMPTE ST 2084 (Dolby Perceptual Quantizer)
- *
+ * SMPTE ST 2084 (Dolby Perceptual Quantizer).
+ * <pre>
* Transfer characteristic curve:
- * E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m
- * c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375
- * c2 = 32 * 2413 / 4096 = 18.8515625
- * c3 = 32 * 2392 / 4096 = 18.6875
- * m = 128 * 2523 / 4096 = 78.84375
- * n = 0.25 * 2610 / 4096 = 0.1593017578125
- * L - luminance of image 0 <= L <= 1 for HDR colorimetry.
- * L = 1 corresponds to 10000 cd/m2
- * E - corresponding electrical signal
+ * E = ((c1 + c2 * L^n) / (1 + c3 * L^n)) ^ m
+ * c1 = c3 - c2 + 1 = 3424 / 4096 = 0.8359375
+ * c2 = 32 * 2413 / 4096 = 18.8515625
+ * c3 = 32 * 2392 / 4096 = 18.6875
+ * m = 128 * 2523 / 4096 = 78.84375
+ * n = 0.25 * 2610 / 4096 = 0.1593017578125
+ * L - luminance of image 0 <= L <= 1 for HDR colorimetry.
+ * L = 1 corresponds to 10000 cd/m2
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_ST2084 = 7 << 22,
/**
- * ARIB STD-B67 Hybrid Log Gamma
- *
+ * ARIB STD-B67 Hybrid Log Gamma.
+ * <pre>
* Transfer characteristic curve:
* E = r * L^0.5 for 0 <= L <= 1
* = a * ln(L - b) + c for 1 < L
@@ -328,7 +342,7 @@
* r = 0.5
* L - luminance of image 0 <= L for HDR colorimetry. L = 1 corresponds
* to reference white level of 100 cd/m2
- * E - corresponding electrical signal
+ * E - corresponding electrical signal</pre>
*/
TRANSFER_HLG = 8 << 22,
@@ -384,21 +398,22 @@
RANGE_EXTENDED = 3 << 27,
/**
- * scRGB linear encoding:
+ * scRGB linear encoding
*
* The red, green, and blue components are stored in extended sRGB space,
* but are linear, not gamma-encoded.
- * The RGB primaries and the white point are the same as BT.709.
*
* The values are floating point.
* A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
* Values beyond the range [0.0 - 1.0] would correspond to other colors
* spaces and/or HDR content.
+ *
+ * Uses extended range, linear transfer and BT.709 standard.
*/
ADATASPACE_SCRGB_LINEAR = 406913024, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_EXTENDED
/**
- * sRGB gamma encoding:
+ * sRGB gamma encoding
*
* The red, green and blue components are stored in sRGB space, and
* converted to linear space when read, using the SRGB transfer function
@@ -408,29 +423,29 @@
* The alpha component, if present, is always stored in linear space and
* is left unmodified when read or written.
*
- * Use full range and BT.709 standard.
+ * Uses full range, sRGB transfer BT.709 standard.
*/
ADATASPACE_SRGB = 142671872, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_FULL
/**
- * scRGB:
+ * scRGB
*
* The red, green, and blue components are stored in extended sRGB space,
* and gamma-encoded using the SRGB transfer function.
- * The RGB primaries and the white point are the same as BT.709.
*
* The values are floating point.
* A pixel value of 1.0, 1.0, 1.0 corresponds to sRGB white (D65) at 80 nits.
* Values beyond the range [0.0 - 1.0] would correspond to other colors
* spaces and/or HDR content.
+ *
+ * Uses extended range, sRGB transfer and BT.709 standard.
*/
ADATASPACE_SCRGB = 411107328, // STANDARD_BT709 | TRANSFER_SRGB | RANGE_EXTENDED
/**
* Display P3
*
- * Use same primaries and white-point as DCI-P3
- * but sRGB transfer function.
+ * Uses full range, sRGB transfer and D65 DCI-P3 standard.
*/
ADATASPACE_DISPLAY_P3 = 143261696, // STANDARD_DCI_P3 | TRANSFER_SRGB | RANGE_FULL
@@ -439,7 +454,7 @@
*
* Ultra High-definition television
*
- * Use full range, SMPTE 2084 (PQ) transfer and BT2020 standard
+ * Uses full range, SMPTE 2084 (PQ) transfer and BT2020 standard.
*/
ADATASPACE_BT2020_PQ = 163971072, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_FULL
@@ -448,14 +463,14 @@
*
* Ultra High-definition television
*
- * Use limited range, SMPTE 2084 (PQ) transfer and BT2020 standard
+ * Uses limited range, SMPTE 2084 (PQ) transfer and BT2020 standard.
*/
ADATASPACE_BT2020_ITU_PQ = 298188800, // STANDARD_BT2020 | TRANSFER_ST2084 | RANGE_LIMITED
/**
* Adobe RGB
*
- * Use full range, gamma 2.2 transfer and Adobe RGB primaries
+ * Uses full range, gamma 2.2 transfer and Adobe RGB standard.
*
* Note: Application is responsible for gamma encoding the data as
* a 2.2 gamma encoding is not supported in HW.
@@ -465,9 +480,9 @@
/**
* JPEG File Interchange Format (JFIF)
*
- * Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255
+ * Same model as BT.601-625, but all values (Y, Cb, Cr) range from 0 to 255.
*
- * Use full range, SMPTE 170M transfer and BT.601_625 standard.
+ * Uses full range, SMPTE 170M transfer and BT.601_625 standard.
*/
ADATASPACE_JFIF = 146931712, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_FULL
@@ -476,7 +491,7 @@
*
* Standard-definition television, 625 Lines (PAL)
*
- * Use limited range, SMPTE 170M transfer and BT.601_625 standard.
+ * Uses limited range, SMPTE 170M transfer and BT.601_625 standard.
*/
ADATASPACE_BT601_625 = 281149440, // STANDARD_BT601_625 | TRANSFER_SMPTE_170M | RANGE_LIMITED
@@ -485,7 +500,7 @@
*
* Standard-definition television, 525 Lines (NTSC)
*
- * Use limited range, SMPTE 170M transfer and BT.601_525 standard.
+ * Uses limited range, SMPTE 170M transfer and BT.601_525 standard.
*/
ADATASPACE_BT601_525 = 281280512, // STANDARD_BT601_525 | TRANSFER_SMPTE_170M | RANGE_LIMITED
@@ -494,7 +509,7 @@
*
* Ultra High-definition television
*
- * Use full range, SMPTE 170M transfer and BT2020 standard
+ * Uses full range, SMPTE 170M transfer and BT2020 standard.
*/
ADATASPACE_BT2020 = 147193856, // STANDARD_BT2020 | TRANSFER_SMPTE_170M | RANGE_FULL
@@ -503,16 +518,16 @@
*
* High-definition television
*
- * Use limited range, SMPTE 170M transfer and BT.709 standard.
+ * Uses limited range, SMPTE 170M transfer and BT.709 standard.
*/
ADATASPACE_BT709 = 281083904, // STANDARD_BT709 | TRANSFER_SMPTE_170M | RANGE_LIMITED
/**
- * SMPTE EG 432-1 and SMPTE RP 431-2.
+ * SMPTE EG 432-1 and SMPTE RP 431-2
*
* Digital Cinema DCI-P3
*
- * Use full range, gamma 2.6 transfer and D65 DCI-P3 standard
+ * Uses full range, gamma 2.6 transfer and D65 DCI-P3 standard.
*
* Note: Application is responsible for gamma encoding the data as
* a 2.6 gamma encoding is not supported in HW.
@@ -520,7 +535,7 @@
ADATASPACE_DCI_P3 = 155844608, // STANDARD_DCI_P3 | TRANSFER_GAMMA2_6 | RANGE_FULL
/**
- * sRGB linear encoding:
+ * sRGB linear encoding
*
* The red, green, and blue components are stored in sRGB space, but
* are linear, not gamma-encoded.
@@ -528,32 +543,34 @@
*
* The values are encoded using the full range ([0,255] for 8-bit) for all
* components.
+ *
+ * Uses full range, linear transfer and BT.709 standard.
*/
ADATASPACE_SRGB_LINEAR = 138477568, // STANDARD_BT709 | TRANSFER_LINEAR | RANGE_FULL
/**
- * Hybrid Log Gamma encoding:
+ * Hybrid Log Gamma encoding
*
- * Use full range, hybrid log gamma transfer and BT2020 standard.
+ * Uses full range, hybrid log gamma transfer and BT2020 standard.
*/
ADATASPACE_BT2020_HLG = 168165376, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_FULL
/**
- * ITU Hybrid Log Gamma encoding:
+ * ITU Hybrid Log Gamma encoding
*
- * Use limited range, hybrid log gamma transfer and BT2020 standard.
+ * Uses limited range, hybrid log gamma transfer and BT2020 standard.
*/
ADATASPACE_BT2020_ITU_HLG = 302383104, // STANDARD_BT2020 | TRANSFER_HLG | RANGE_LIMITED
/**
- * Depth:
+ * Depth
*
* This value is valid with formats HAL_PIXEL_FORMAT_Y16 and HAL_PIXEL_FORMAT_BLOB.
*/
ADATASPACE_DEPTH = 4096,
/**
- * ISO 16684-1:2011(E) Dynamic Depth:
+ * ISO 16684-1:2011(E) Dynamic Depth
*
* Embedded depth metadata following the dynamic depth specification.
*/
diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs
index a2ec57c..6eb3bbc 100644
--- a/libs/nativewindow/rust/src/lib.rs
+++ b/libs/nativewindow/rust/src/lib.rs
@@ -16,15 +16,17 @@
extern crate nativewindow_bindgen as ffi;
-pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
+pub use ffi::{AHardwareBuffer, AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
-use std::os::raw::c_void;
-use std::ptr;
+use std::fmt::{self, Debug, Formatter};
+use std::mem::ManuallyDrop;
+use std::ptr::{self, NonNull};
/// Wrapper around an opaque C AHardwareBuffer.
-pub struct AHardwareBuffer(*mut ffi::AHardwareBuffer);
+#[derive(PartialEq, Eq)]
+pub struct HardwareBuffer(NonNull<AHardwareBuffer>);
-impl AHardwareBuffer {
+impl HardwareBuffer {
/// Test whether the given format and usage flag combination is allocatable. If this function
/// returns true, it means that a buffer with the given description can be allocated on this
/// implementation, unless resource exhaustion occurs. If this function returns false, it means
@@ -79,13 +81,13 @@
rfu0: 0,
rfu1: 0,
};
- let mut buffer = ptr::null_mut();
+ let mut ptr = ptr::null_mut();
// SAFETY: The returned pointer is valid until we drop/deallocate it. The function may fail
// and return a status, but we check it later.
- let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_desc, &mut buffer) };
+ let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_desc, &mut ptr) };
if status == 0 {
- Some(Self(buffer))
+ Some(Self(NonNull::new(ptr).expect("Allocated AHardwareBuffer was null")))
} else {
None
}
@@ -101,9 +103,15 @@
///
/// This function adopts the pointer but does NOT increment the refcount on the buffer. If the
/// caller uses the pointer after the created object is dropped it will cause a memory leak.
- pub unsafe fn take_from_raw(buffer_ptr: *mut c_void) -> Self {
- assert!(!buffer_ptr.is_null());
- Self(buffer_ptr as *mut ffi::AHardwareBuffer)
+ pub unsafe fn from_raw(buffer_ptr: NonNull<AHardwareBuffer>) -> Self {
+ Self(buffer_ptr)
+ }
+
+ /// Get the internal |AHardwareBuffer| pointer without decrementing the refcount. This can
+ /// be used to provide a pointer to the AHB for a C/C++ API over the FFI.
+ pub fn into_raw(self) -> NonNull<AHardwareBuffer> {
+ let buffer = ManuallyDrop::new(self);
+ buffer.0
}
/// Get the system wide unique id for an AHardwareBuffer. This function may panic in extreme
@@ -113,7 +121,7 @@
pub fn id(&self) -> u64 {
let mut out_id = 0;
// SAFETY: Neither pointers can be null.
- let status = unsafe { ffi::AHardwareBuffer_getId(self.0, &mut out_id) };
+ let status = unsafe { ffi::AHardwareBuffer_getId(self.0.as_ref(), &mut out_id) };
assert_eq!(status, 0, "id() failed for AHardwareBuffer with error code: {status}");
out_id
@@ -161,27 +169,55 @@
rfu1: 0,
};
// SAFETY: neither the buffer nor AHardwareBuffer_Desc pointers will be null.
- unsafe { ffi::AHardwareBuffer_describe(self.0, &mut buffer_desc) };
+ unsafe { ffi::AHardwareBuffer_describe(self.0.as_ref(), &mut buffer_desc) };
buffer_desc
}
}
-impl Drop for AHardwareBuffer {
+impl Drop for HardwareBuffer {
fn drop(&mut self) {
// SAFETY: self.0 will never be null. AHardwareBuffers allocated from within Rust will have
// a refcount of one, and there is a safety warning on taking an AHardwareBuffer from a raw
// pointer requiring callers to ensure the refcount is managed appropriately.
- unsafe { ffi::AHardwareBuffer_release(self.0) }
+ unsafe { ffi::AHardwareBuffer_release(self.0.as_ptr()) }
}
}
+impl Debug for HardwareBuffer {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ f.debug_struct("HardwareBuffer").field("id", &self.id()).finish()
+ }
+}
+
+impl Clone for HardwareBuffer {
+ fn clone(&self) -> Self {
+ // SAFETY: ptr is guaranteed to be non-null and the acquire can not fail.
+ unsafe { ffi::AHardwareBuffer_acquire(self.0.as_ptr()) };
+ Self(self.0)
+ }
+}
+
+// SAFETY: The underlying *AHardwareBuffers can be moved between threads.
+unsafe impl Send for HardwareBuffer {}
+
+// SAFETY: The underlying *AHardwareBuffers can be used from multiple threads.
+//
+// AHardwareBuffers are backed by C++ GraphicBuffers, which are mostly immutable. The only cases
+// where they are not immutable are:
+//
+// - reallocation (which is never actually done across the codebase and requires special
+// privileges/platform code access to do)
+// - "locking" for reading/writing (which is explicitly allowed to be done across multiple threads
+// according to the docs on the underlying gralloc calls)
+unsafe impl Sync for HardwareBuffer {}
+
#[cfg(test)]
-mod ahardwarebuffer_tests {
+mod test {
use super::*;
#[test]
fn create_valid_buffer_returns_ok() {
- let buffer = AHardwareBuffer::new(
+ let buffer = HardwareBuffer::new(
512,
512,
1,
@@ -193,19 +229,12 @@
#[test]
fn create_invalid_buffer_returns_err() {
- let buffer = AHardwareBuffer::new(512, 512, 1, 0, AHardwareBuffer_UsageFlags(0));
+ let buffer = HardwareBuffer::new(512, 512, 1, 0, AHardwareBuffer_UsageFlags(0));
assert!(buffer.is_none());
}
#[test]
- #[should_panic]
- fn take_from_raw_panics_on_null() {
- // SAFETY: Passing a null pointer is safe, it should just panic.
- unsafe { AHardwareBuffer::take_from_raw(ptr::null_mut()) };
- }
-
- #[test]
- fn take_from_raw_allows_getters() {
+ fn from_raw_allows_getters() {
let buffer_desc = ffi::AHardwareBuffer_Desc {
width: 1024,
height: 512,
@@ -225,13 +254,13 @@
// SAFETY: The pointer must be valid because it was just allocated successfully, and we
// don't use it after calling this.
- let buffer = unsafe { AHardwareBuffer::take_from_raw(raw_buffer_ptr as *mut c_void) };
+ let buffer = unsafe { HardwareBuffer::from_raw(NonNull::new(raw_buffer_ptr).unwrap()) };
assert_eq!(buffer.width(), 1024);
}
#[test]
fn basic_getters() {
- let buffer = AHardwareBuffer::new(
+ let buffer = HardwareBuffer::new(
1024,
512,
1,
@@ -252,7 +281,7 @@
#[test]
fn id_getter() {
- let buffer = AHardwareBuffer::new(
+ let buffer = HardwareBuffer::new(
1024,
512,
1,
@@ -263,4 +292,38 @@
assert_ne!(0, buffer.id());
}
+
+ #[test]
+ fn clone() {
+ let buffer = HardwareBuffer::new(
+ 1024,
+ 512,
+ 1,
+ AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+ )
+ .expect("Buffer with some basic parameters was not created successfully");
+ let buffer2 = buffer.clone();
+
+ assert_eq!(buffer, buffer2);
+ }
+
+ #[test]
+ fn into_raw() {
+ let buffer = HardwareBuffer::new(
+ 1024,
+ 512,
+ 1,
+ AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+ )
+ .expect("Buffer with some basic parameters was not created successfully");
+ let buffer2 = buffer.clone();
+
+ let raw_buffer = buffer.into_raw();
+ // SAFETY: This is the same pointer we had before.
+ let remade_buffer = unsafe { HardwareBuffer::from_raw(raw_buffer) };
+
+ assert_eq!(remade_buffer, buffer2);
+ }
}
diff --git a/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs b/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs
index fbd49c0..876f6c8 100644
--- a/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs
+++ b/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs
@@ -21,8 +21,8 @@
use nativewindow::*;
#[inline]
-fn create_720p_buffer() -> AHardwareBuffer {
- AHardwareBuffer::new(
+fn create_720p_buffer() -> HardwareBuffer {
+ HardwareBuffer::new(
1280,
720,
1,
diff --git a/libs/ui/include/ui/DisplayMode.h b/libs/ui/include/ui/DisplayMode.h
index 65a8769..a469c78 100644
--- a/libs/ui/include/ui/DisplayMode.h
+++ b/libs/ui/include/ui/DisplayMode.h
@@ -37,7 +37,9 @@
float yDpi = 0;
std::vector<ui::Hdr> supportedHdrTypes;
- float refreshRate = 0;
+ // Some modes have peak refresh rate lower than the panel vsync rate.
+ float refreshRate = 0.f;
+ float vsyncRate = 0.f;
nsecs_t appVsyncOffset = 0;
nsecs_t sfVsyncOffset = 0;
nsecs_t presentationDeadline = 0;
diff --git a/services/inputflinger/InputDeviceMetricsSource.h b/services/inputflinger/InputDeviceMetricsSource.h
index 3ac91c8..a6be8f4 100644
--- a/services/inputflinger/InputDeviceMetricsSource.h
+++ b/services/inputflinger/InputDeviceMetricsSource.h
@@ -47,6 +47,8 @@
ftl_first = UNKNOWN,
ftl_last = TRACKBALL,
+ // Used by latency fuzzer
+ kMaxValue = ftl_last
};
/** Returns the InputDeviceUsageSource that corresponds to the key event. */
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 27b86bd..276f75c 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -47,6 +47,8 @@
#include <queue>
#include <sstream>
+#include "../InputDeviceMetricsSource.h"
+
#include "Connection.h"
#include "DebugConfig.h"
#include "InputDispatcher.h"
@@ -4226,6 +4228,11 @@
return splitMotionEntry;
}
+void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
+ std::scoped_lock _l(mLock);
+ mLatencyTracker.setInputDevices(args.inputDeviceInfos);
+}
+
void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) {
if (debugInboundEventDetails()) {
ALOGD("notifyConfigurationChanged - eventTime=%" PRId64, args.eventTime);
@@ -4438,7 +4445,9 @@
IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
!mInputFilterEnabled) {
const bool isDown = args.action == AMOTION_EVENT_ACTION_DOWN;
- mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime);
+ std::set<InputDeviceUsageSource> sources = getUsageSourcesForMotionArgs(args);
+ mLatencyTracker.trackListener(args.id, isDown, args.eventTime, args.readTime,
+ args.deviceId, sources);
}
needWake = enqueueInboundEventLocked(std::move(newEntry));
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 62e2d58..ee5a797 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -92,7 +92,7 @@
status_t start() override;
status_t stop() override;
- void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) 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;
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.cpp b/services/inputflinger/dispatcher/InputEventTimeline.cpp
index 3edb638..a7c6d16 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.cpp
+++ b/services/inputflinger/dispatcher/InputEventTimeline.cpp
@@ -16,6 +16,8 @@
#include "InputEventTimeline.h"
+#include "../InputDeviceMetricsSource.h"
+
namespace android::inputdispatcher {
ConnectionTimeline::ConnectionTimeline(nsecs_t deliveryTime, nsecs_t consumeTime,
@@ -64,8 +66,15 @@
return !operator==(rhs);
}
-InputEventTimeline::InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime)
- : isDown(isDown), eventTime(eventTime), readTime(readTime) {}
+InputEventTimeline::InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime,
+ uint16_t vendorId, uint16_t productId,
+ std::set<InputDeviceUsageSource> sources)
+ : isDown(isDown),
+ eventTime(eventTime),
+ readTime(readTime),
+ vendorId(vendorId),
+ productId(productId),
+ sources(sources) {}
bool InputEventTimeline::operator==(const InputEventTimeline& rhs) const {
if (connectionTimelines.size() != rhs.connectionTimelines.size()) {
@@ -80,7 +89,8 @@
return false;
}
}
- return isDown == rhs.isDown && eventTime == rhs.eventTime && readTime == rhs.readTime;
+ return isDown == rhs.isDown && eventTime == rhs.eventTime && readTime == rhs.readTime &&
+ vendorId == rhs.vendorId && productId == rhs.productId && sources == rhs.sources;
}
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputEventTimeline.h b/services/inputflinger/dispatcher/InputEventTimeline.h
index daf375d..e9deb2d 100644
--- a/services/inputflinger/dispatcher/InputEventTimeline.h
+++ b/services/inputflinger/dispatcher/InputEventTimeline.h
@@ -16,6 +16,8 @@
#pragma once
+#include "../InputDeviceMetricsSource.h"
+
#include <binder/IBinder.h>
#include <input/Input.h>
#include <unordered_map>
@@ -73,10 +75,14 @@
};
struct InputEventTimeline {
- InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime);
+ InputEventTimeline(bool isDown, nsecs_t eventTime, nsecs_t readTime, uint16_t vendorId,
+ uint16_t productId, std::set<InputDeviceUsageSource> sources);
const bool isDown; // True if this is an ACTION_DOWN event
const nsecs_t eventTime;
const nsecs_t readTime;
+ const uint16_t vendorId;
+ const uint16_t productId;
+ const std::set<InputDeviceUsageSource> sources;
struct IBinderHash {
std::size_t operator()(const sp<IBinder>& b) const {
diff --git a/services/inputflinger/dispatcher/LatencyTracker.cpp b/services/inputflinger/dispatcher/LatencyTracker.cpp
index b7c36a8..698bd9f 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.cpp
+++ b/services/inputflinger/dispatcher/LatencyTracker.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "LatencyTracker"
#include "LatencyTracker.h"
+#include "../InputDeviceMetricsSource.h"
#include <inttypes.h>
@@ -23,6 +24,7 @@
#include <android-base/stringprintf.h>
#include <android/os/IInputConstants.h>
#include <input/Input.h>
+#include <input/InputDevice.h>
#include <log/log.h>
using android::base::HwTimeoutMultiplier;
@@ -66,7 +68,8 @@
}
void LatencyTracker::trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime,
- nsecs_t readTime) {
+ nsecs_t readTime, DeviceId deviceId,
+ const std::set<InputDeviceUsageSource>& sources) {
reportAndPruneMatureRecords(eventTime);
const auto it = mTimelines.find(inputEventId);
if (it != mTimelines.end()) {
@@ -78,7 +81,29 @@
eraseByValue(mEventTimes, inputEventId);
return;
}
- mTimelines.emplace(inputEventId, InputEventTimeline(isDown, eventTime, readTime));
+
+ // Create an InputEventTimeline for the device ID. The vendorId and productId
+ // can be obtained from the InputDeviceIdentifier of the particular device.
+ const InputDeviceIdentifier* identifier = nullptr;
+ for (auto& inputDevice : mInputDevices) {
+ if (deviceId == inputDevice.getId()) {
+ identifier = &inputDevice.getIdentifier();
+ break;
+ }
+ }
+
+ // If no matching ids can be found for the device from among the input devices connected,
+ // the call to trackListener will be dropped.
+ // Note: there generally isn't expected to be a situation where we can't find an InputDeviceInfo
+ // but a possibility of it is handled in case of race conditions
+ if (identifier == nullptr) {
+ ALOGE("Could not find input device identifier. Dropping call to LatencyTracker.");
+ return;
+ }
+
+ mTimelines.emplace(inputEventId,
+ InputEventTimeline(isDown, eventTime, readTime, identifier->vendor,
+ identifier->product, sources));
mEventTimes.emplace(eventTime, inputEventId);
}
@@ -171,4 +196,8 @@
StringPrintf("%s mEventTimes.size() = %zu\n", prefix, mEventTimes.size());
}
+void LatencyTracker::setInputDevices(const std::vector<InputDeviceInfo>& inputDevices) {
+ mInputDevices = inputDevices;
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/LatencyTracker.h b/services/inputflinger/dispatcher/LatencyTracker.h
index 4212da8..890d61d 100644
--- a/services/inputflinger/dispatcher/LatencyTracker.h
+++ b/services/inputflinger/dispatcher/LatencyTracker.h
@@ -16,6 +16,8 @@
#pragma once
+#include "../InputDeviceMetricsSource.h"
+
#include <map>
#include <unordered_map>
@@ -23,6 +25,7 @@
#include <input/Input.h>
#include "InputEventTimeline.h"
+#include "NotifyArgs.h"
namespace android::inputdispatcher {
@@ -49,13 +52,15 @@
* duplicate events that happen to have the same eventTime and inputEventId. Therefore, we
* must drop all duplicate data.
*/
- void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime);
+ void trackListener(int32_t inputEventId, bool isDown, nsecs_t eventTime, nsecs_t readTime,
+ DeviceId deviceId, const std::set<InputDeviceUsageSource>& sources);
void trackFinishedEvent(int32_t inputEventId, const sp<IBinder>& connectionToken,
nsecs_t deliveryTime, nsecs_t consumeTime, nsecs_t finishTime);
void trackGraphicsLatency(int32_t inputEventId, const sp<IBinder>& connectionToken,
std::array<nsecs_t, GraphicsTimeline::SIZE> timeline);
std::string dump(const char* prefix) const;
+ void setInputDevices(const std::vector<InputDeviceInfo>& inputDevices);
private:
/**
@@ -76,6 +81,7 @@
std::multimap<nsecs_t /*eventTime*/, int32_t /*inputEventId*/> mEventTimes;
InputEventTimelineProcessor* mTimelineProcessor;
+ std::vector<InputDeviceInfo> mInputDevices;
void reportAndPruneMatureRecords(nsecs_t newEventTime);
};
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 76b04b6..64e8825 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -66,7 +66,6 @@
"SyncQueue_test.cpp",
"TimerProvider_test.cpp",
"TestInputListener.cpp",
- "TestInputListenerMatchers.cpp",
"TouchpadInputMapper_test.cpp",
"KeyboardInputMapper_test.cpp",
"UinputDevice.cpp",
diff --git a/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp b/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp
index 99a6a1f..b738abf 100644
--- a/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp
+++ b/services/inputflinger/tests/CapturedTouchpadEventConverter_test.cpp
@@ -29,8 +29,8 @@
#include "FakeInputReaderPolicy.h"
#include "InstrumentedInputReader.h"
#include "TestConstants.h"
+#include "TestEventMatchers.h"
#include "TestInputListener.h"
-#include "TestInputListenerMatchers.h"
namespace android {
diff --git a/services/inputflinger/tests/CursorInputMapper_test.cpp b/services/inputflinger/tests/CursorInputMapper_test.cpp
index e630915..b55c9cc 100644
--- a/services/inputflinger/tests/CursorInputMapper_test.cpp
+++ b/services/inputflinger/tests/CursorInputMapper_test.cpp
@@ -22,7 +22,7 @@
#include "FakePointerController.h"
#include "InputMapperTest.h"
#include "InterfaceMocks.h"
-#include "TestInputListenerMatchers.h"
+#include "TestEventMatchers.h"
#define TAG "CursorInputMapper_test"
diff --git a/services/inputflinger/tests/GestureConverter_test.cpp b/services/inputflinger/tests/GestureConverter_test.cpp
index 74ce359..d7dc800 100644
--- a/services/inputflinger/tests/GestureConverter_test.cpp
+++ b/services/inputflinger/tests/GestureConverter_test.cpp
@@ -27,8 +27,8 @@
#include "InstrumentedInputReader.h"
#include "NotifyArgs.h"
#include "TestConstants.h"
+#include "TestEventMatchers.h"
#include "TestInputListener.h"
-#include "TestInputListenerMatchers.h"
#include "include/gestures.h"
#include "ui/Rotation.h"
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 7925a27..2f63b2a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -16,7 +16,7 @@
#include "../dispatcher/InputDispatcher.h"
#include "../BlockingQueue.h"
-#include "TestInputListenerMatchers.h"
+#include "TestEventMatchers.h"
#include <NotifyArgsBuilders.h>
#include <android-base/properties.h>
@@ -136,16 +136,6 @@
using ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID;
-struct PointF {
- float x;
- float y;
- auto operator<=>(const PointF&) const = default;
-};
-
-inline std::string pointFToString(const PointF& p) {
- return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")";
-}
-
/**
* Return a DOWN key event with KEYCODE_A.
*/
@@ -158,64 +148,6 @@
return event;
}
-MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") {
- *result_listener << "expected downTime " << downTime << ", but got " << arg.getDownTime();
- return arg.getDownTime() == downTime;
-}
-
-MATCHER_P(WithSource, source, "InputEvent with specified source") {
- *result_listener << "expected source " << inputEventSourceToString(source) << ", but got "
- << inputEventSourceToString(arg.getSource());
- return arg.getSource() == source;
-}
-
-MATCHER_P(WithFlags, flags, "InputEvent with specified flags") {
- *result_listener << "expected flags " << std::hex << flags << ", but got " << arg.getFlags();
- return arg.getFlags() == flags;
-}
-
-MATCHER_P2(WithCoords, x, y, "MotionEvent with specified coordinates") {
- if (arg.getPointerCount() != 1) {
- *result_listener << "Expected 1 pointer, got " << arg.getPointerCount();
- return false;
- }
- const float receivedX = arg.getX(/*pointerIndex=*/0);
- const float receivedY = arg.getY(/*pointerIndex=*/0);
- *result_listener << "expected coords (" << x << ", " << y << "), but got (" << receivedX << ", "
- << receivedY << ")";
- return receivedX == x && receivedY == y;
-}
-
-MATCHER_P2(WithRawCoords, x, y, "MotionEvent with specified raw coordinates") {
- if (arg.getPointerCount() != 1) {
- *result_listener << "Expected 1 pointer, got " << arg.getPointerCount();
- return false;
- }
- const float receivedX = arg.getRawX(/*pointerIndex=*/0);
- const float receivedY = arg.getRawY(/*pointerIndex=*/0);
- *result_listener << "expected raw coords (" << x << ", " << y << "), but got (" << receivedX
- << ", " << receivedY << ")";
- return receivedX == x && receivedY == y;
-}
-
-MATCHER_P(WithPointerCount, pointerCount, "MotionEvent with specified number of pointers") {
- *result_listener << "expected pointerCount " << pointerCount << ", but got "
- << arg.getPointerCount();
- return arg.getPointerCount() == pointerCount;
-}
-
-MATCHER_P(WithPointers, pointers, "MotionEvent with specified pointers") {
- // Build a map for the received pointers, by pointer id
- std::map<int32_t /*pointerId*/, PointF> actualPointers;
- for (size_t pointerIndex = 0; pointerIndex < arg.getPointerCount(); pointerIndex++) {
- const int32_t pointerId = arg.getPointerId(pointerIndex);
- actualPointers[pointerId] = {arg.getX(pointerIndex), arg.getY(pointerIndex)};
- }
- *result_listener << "expected pointers " << dumpMap(pointers, constToString, pointFToString)
- << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
- return pointers == actualPointers;
-}
-
// --- FakeInputDispatcherPolicy ---
class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 6032e30..64ae9e8 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -31,8 +31,8 @@
#include <SensorInputMapper.h>
#include <SingleTouchInputMapper.h>
#include <SwitchInputMapper.h>
+#include <TestEventMatchers.h>
#include <TestInputListener.h>
-#include <TestInputListenerMatchers.h>
#include <TouchInputMapper.h>
#include <UinputDevice.h>
#include <VibratorInputMapper.h>
diff --git a/services/inputflinger/tests/LatencyTracker_test.cpp b/services/inputflinger/tests/LatencyTracker_test.cpp
index fa149db..6606de8 100644
--- a/services/inputflinger/tests/LatencyTracker_test.cpp
+++ b/services/inputflinger/tests/LatencyTracker_test.cpp
@@ -15,11 +15,14 @@
*/
#include "../dispatcher/LatencyTracker.h"
+#include "../InputDeviceMetricsSource.h"
#include <android-base/properties.h>
#include <binder/Binder.h>
#include <gtest/gtest.h>
+#include <gui/constants.h>
#include <inttypes.h>
+#include <linux/input.h>
#include <log/log.h>
#define TAG "LatencyTracker_test"
@@ -30,6 +33,29 @@
namespace android::inputdispatcher {
+namespace {
+
+constexpr DeviceId DEVICE_ID = 100;
+
+static InputDeviceInfo generateTestDeviceInfo(uint16_t vendorId, uint16_t productId,
+ DeviceId deviceId) {
+ InputDeviceIdentifier identifier;
+ identifier.vendor = vendorId;
+ identifier.product = productId;
+ auto info = InputDeviceInfo();
+ info.initialize(deviceId, /*generation=*/1, /*controllerNumber=*/1, identifier, "Test Device",
+ /*isExternal=*/false, /*hasMic=*/false, ADISPLAY_ID_NONE);
+ return info;
+}
+
+void setDefaultInputDeviceInfo(LatencyTracker& tracker) {
+ InputDeviceInfo deviceInfo = generateTestDeviceInfo(
+ /*vendorId=*/0, /*productId=*/0, DEVICE_ID);
+ tracker.setInputDevices({deviceInfo});
+}
+
+} // namespace
+
const std::chrono::duration ANR_TIMEOUT = std::chrono::milliseconds(
android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
HwTimeoutMultiplier());
@@ -38,7 +64,10 @@
InputEventTimeline t(
/*isDown=*/true,
/*eventTime=*/2,
- /*readTime=*/3);
+ /*readTime=*/3,
+ /*vendorId=*/0,
+ /*productId=*/0,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN});
ConnectionTimeline expectedCT(/*deliveryTime=*/6, /*consumeTime=*/7, /*finishTime=*/8);
std::array<nsecs_t, GraphicsTimeline::SIZE> graphicsTimeline;
graphicsTimeline[GraphicsTimeline::GPU_COMPLETED_TIME] = 9;
@@ -60,6 +89,7 @@
connection2 = sp<BBinder>::make();
mTracker = std::make_unique<LatencyTracker>(this);
+ setDefaultInputDeviceInfo(*mTracker);
}
void TearDown() override {}
@@ -88,7 +118,8 @@
const nsecs_t triggerEventTime =
lastEventTime + std::chrono::nanoseconds(ANR_TIMEOUT).count() + 1;
mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/true, triggerEventTime,
- /*readTime=*/3);
+ /*readTime=*/3, DEVICE_ID,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN});
}
void LatencyTrackerTest::assertReceivedTimeline(const InputEventTimeline& timeline) {
@@ -138,9 +169,11 @@
*/
TEST_F(LatencyTrackerTest, TrackListener_DoesNotTriggerReporting) {
mTracker->trackListener(/*inputEventId=*/1, /*isDown=*/false, /*eventTime=*/2,
- /*readTime=*/3);
+ /*readTime=*/3, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
triggerEventReporting(/*eventTime=*/2);
- assertReceivedTimeline(InputEventTimeline{false, 2, 3});
+ assertReceivedTimeline(InputEventTimeline{/*isDown=*/false, /*eventTime=*/2,
+ /*readTime=*/3, /*vendorId=*/0, /*productID=*/0,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN}});
}
/**
@@ -171,7 +204,8 @@
const auto& [connectionToken, expectedCT] = *expected.connectionTimelines.begin();
- mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime);
+ mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime,
+ DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
mTracker->trackFinishedEvent(inputEventId, connectionToken, expectedCT.deliveryTime,
expectedCT.consumeTime, expectedCT.finishTime);
mTracker->trackGraphicsLatency(inputEventId, connectionToken, expectedCT.graphicsTimeline);
@@ -191,8 +225,10 @@
// In the following 2 calls to trackListener, the inputEventId's are the same, but event times
// are different.
- mTracker->trackListener(inputEventId, isDown, /*eventTime=*/1, readTime);
- mTracker->trackListener(inputEventId, isDown, /*eventTime=*/2, readTime);
+ mTracker->trackListener(inputEventId, isDown, /*eventTime=*/1, readTime, DEVICE_ID,
+ {InputDeviceUsageSource::UNKNOWN});
+ mTracker->trackListener(inputEventId, isDown, /*eventTime=*/2, readTime, DEVICE_ID,
+ {InputDeviceUsageSource::UNKNOWN});
triggerEventReporting(/*eventTime=*/2);
// Since we sent duplicate input events, the tracker should just delete all of them, because it
@@ -205,7 +241,10 @@
InputEventTimeline timeline1(
/*isDown*/ true,
/*eventTime*/ 2,
- /*readTime*/ 3);
+ /*readTime*/ 3,
+ /*vendorId=*/0,
+ /*productId=*/0,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN});
timeline1.connectionTimelines.emplace(connection1,
ConnectionTimeline(/*deliveryTime*/ 6, /*consumeTime*/ 7,
/*finishTime*/ 8));
@@ -219,7 +258,10 @@
InputEventTimeline timeline2(
/*isDown=*/false,
/*eventTime=*/20,
- /*readTime=*/30);
+ /*readTime=*/30,
+ /*vendorId=*/0,
+ /*productId=*/0,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN});
timeline2.connectionTimelines.emplace(connection2,
ConnectionTimeline(/*deliveryTime=*/60,
/*consumeTime=*/70,
@@ -232,10 +274,10 @@
// Start processing first event
mTracker->trackListener(inputEventId1, timeline1.isDown, timeline1.eventTime,
- timeline1.readTime);
+ timeline1.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
// Start processing second event
mTracker->trackListener(inputEventId2, timeline2.isDown, timeline2.eventTime,
- timeline2.readTime);
+ timeline2.readTime, DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
mTracker->trackFinishedEvent(inputEventId1, connection1, connectionTimeline1.deliveryTime,
connectionTimeline1.consumeTime, connectionTimeline1.finishTime);
@@ -261,9 +303,11 @@
for (size_t i = 1; i <= 100; i++) {
mTracker->trackListener(/*inputEventId=*/i, timeline.isDown, timeline.eventTime,
- timeline.readTime);
- expectedTimelines.push_back(
- InputEventTimeline{timeline.isDown, timeline.eventTime, timeline.readTime});
+ timeline.readTime, /*deviceId=*/DEVICE_ID,
+ /*sources=*/{InputDeviceUsageSource::UNKNOWN});
+ expectedTimelines.push_back(InputEventTimeline{timeline.isDown, timeline.eventTime,
+ timeline.readTime, timeline.vendorId,
+ timeline.productId, timeline.sources});
}
// Now, complete the first event that was sent.
mTracker->trackFinishedEvent(/*inputEventId=*/1, token, expectedCT.deliveryTime,
@@ -289,10 +333,38 @@
expectedCT.consumeTime, expectedCT.finishTime);
mTracker->trackGraphicsLatency(inputEventId, connection1, expectedCT.graphicsTimeline);
- mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime);
+ mTracker->trackListener(inputEventId, expected.isDown, expected.eventTime, expected.readTime,
+ DEVICE_ID, {InputDeviceUsageSource::UNKNOWN});
triggerEventReporting(expected.eventTime);
- assertReceivedTimeline(
- InputEventTimeline{expected.isDown, expected.eventTime, expected.readTime});
+ assertReceivedTimeline(InputEventTimeline{expected.isDown, expected.eventTime,
+ expected.readTime, expected.vendorId,
+ expected.productId, expected.sources});
+}
+
+/**
+ * Check that LatencyTracker has the received timeline that contains the correctly
+ * resolved product ID, vendor ID and source for a particular device ID from
+ * among a list of devices.
+ */
+TEST_F(LatencyTrackerTest, TrackListenerCheck_DeviceInfoFieldsInputEventTimeline) {
+ constexpr int32_t inputEventId = 1;
+ InputEventTimeline timeline(
+ /*isDown*/ true, /*eventTime*/ 2, /*readTime*/ 3,
+ /*vendorId=*/50, /*productId=*/60,
+ /*sources=*/
+ {InputDeviceUsageSource::TOUCHSCREEN, InputDeviceUsageSource::STYLUS_DIRECT});
+ InputDeviceInfo deviceInfo1 = generateTestDeviceInfo(
+ /*vendorId=*/5, /*productId=*/6, /*deviceId=*/DEVICE_ID + 1);
+ InputDeviceInfo deviceInfo2 = generateTestDeviceInfo(
+ /*vendorId=*/50, /*productId=*/60, /*deviceId=*/DEVICE_ID);
+
+ mTracker->setInputDevices({deviceInfo1, deviceInfo2});
+ mTracker->trackListener(inputEventId, timeline.isDown, timeline.eventTime, timeline.readTime,
+ DEVICE_ID,
+ {InputDeviceUsageSource::TOUCHSCREEN,
+ InputDeviceUsageSource::STYLUS_DIRECT});
+ triggerEventReporting(timeline.eventTime);
+ assertReceivedTimeline(timeline);
}
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/tests/TestEventMatchers.h b/services/inputflinger/tests/TestEventMatchers.h
new file mode 100644
index 0000000..ee6ff53
--- /dev/null
+++ b/services/inputflinger/tests/TestEventMatchers.h
@@ -0,0 +1,611 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cmath>
+#include <compare>
+
+#include <android-base/stringprintf.h>
+#include <android/input.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <input/Input.h>
+#include <input/PrintTools.h>
+
+#include "NotifyArgs.h"
+#include "TestConstants.h"
+
+namespace android {
+
+struct PointF {
+ float x;
+ float y;
+ auto operator<=>(const PointF&) const = default;
+};
+
+inline std::string pointFToString(const PointF& p) {
+ return std::string("(") + std::to_string(p.x) + ", " + std::to_string(p.y) + ")";
+}
+
+/// Source
+class WithSourceMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithSourceMatcher(uint32_t source) : mSource(source) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return mSource == args.source;
+ }
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mSource == args.source;
+ }
+
+ bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
+ return mSource == event.getSource();
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with source " << inputEventSourceToString(mSource);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong source"; }
+
+private:
+ const uint32_t mSource;
+};
+
+inline WithSourceMatcher WithSource(uint32_t source) {
+ return WithSourceMatcher(source);
+}
+
+/// Key action
+class WithKeyActionMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithKeyActionMatcher(int32_t action) : mAction(action) {}
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mAction == args.action;
+ }
+
+ bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
+ return mAction == event.getAction();
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with key action " << KeyEvent::actionToString(mAction);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
+
+private:
+ const int32_t mAction;
+};
+
+inline WithKeyActionMatcher WithKeyAction(int32_t action) {
+ return WithKeyActionMatcher(action);
+}
+
+/// Motion action
+class WithMotionActionMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithMotionActionMatcher(int32_t action) : mAction(action) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ bool matches = mAction == args.action;
+ if (args.action == AMOTION_EVENT_ACTION_CANCEL) {
+ matches &= (args.flags & AMOTION_EVENT_FLAG_CANCELED) != 0;
+ }
+ return matches;
+ }
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+ bool matches = mAction == event.getAction();
+ if (event.getAction() == AMOTION_EVENT_ACTION_CANCEL) {
+ matches &= (event.getFlags() & AMOTION_EVENT_FLAG_CANCELED) != 0;
+ }
+ return matches;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with motion action " << MotionEvent::actionToString(mAction);
+ if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
+ *os << " and FLAG_CANCELED";
+ }
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
+
+private:
+ const int32_t mAction;
+};
+
+inline WithMotionActionMatcher WithMotionAction(int32_t action) {
+ return WithMotionActionMatcher(action);
+}
+
+/// Display Id
+class WithDisplayIdMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithDisplayIdMatcher(int32_t displayId) : mDisplayId(displayId) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return mDisplayId == args.displayId;
+ }
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mDisplayId == args.displayId;
+ }
+
+ bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
+ return mDisplayId == event.getDisplayId();
+ }
+
+ void DescribeTo(std::ostream* os) const { *os << "with display id " << mDisplayId; }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong display id"; }
+
+private:
+ const int32_t mDisplayId;
+};
+
+inline WithDisplayIdMatcher WithDisplayId(int32_t displayId) {
+ return WithDisplayIdMatcher(displayId);
+}
+
+/// Device Id
+class WithDeviceIdMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithDeviceIdMatcher(int32_t deviceId) : mDeviceId(deviceId) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return mDeviceId == args.deviceId;
+ }
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mDeviceId == args.deviceId;
+ }
+
+ bool MatchAndExplain(const NotifyDeviceResetArgs& args, std::ostream*) const {
+ return mDeviceId == args.deviceId;
+ }
+
+ bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
+ return mDeviceId == event.getDeviceId();
+ }
+
+ void DescribeTo(std::ostream* os) const { *os << "with device id " << mDeviceId; }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong device id"; }
+
+private:
+ const int32_t mDeviceId;
+};
+
+inline WithDeviceIdMatcher WithDeviceId(int32_t deviceId) {
+ return WithDeviceIdMatcher(deviceId);
+}
+
+/// Flags
+class WithFlagsMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithFlagsMatcher(int32_t flags) : mFlags(flags) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return mFlags == args.flags;
+ }
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mFlags == args.flags;
+ }
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+ return mFlags == event.getFlags();
+ }
+
+ bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
+ return mFlags == event.getFlags();
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with flags " << base::StringPrintf("0x%x", mFlags);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong flags"; }
+
+private:
+ const int32_t mFlags;
+};
+
+inline WithFlagsMatcher WithFlags(int32_t flags) {
+ return WithFlagsMatcher(flags);
+}
+
+/// DownTime
+class WithDownTimeMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithDownTimeMatcher(nsecs_t downTime) : mDownTime(downTime) {}
+
+ bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
+ return mDownTime == args.downTime;
+ }
+
+ bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
+ return mDownTime == args.downTime;
+ }
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
+ return mDownTime == event.getDownTime();
+ }
+
+ bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
+ return mDownTime == event.getDownTime();
+ }
+
+ void DescribeTo(std::ostream* os) const { *os << "with down time " << mDownTime; }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong down time"; }
+
+private:
+ const nsecs_t mDownTime;
+};
+
+inline WithDownTimeMatcher WithDownTime(nsecs_t downTime) {
+ return WithDownTimeMatcher(downTime);
+}
+
+/// Coordinate matcher
+class WithCoordsMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithCoordsMatcher(size_t pointerIndex, float x, float y)
+ : mPointerIndex(pointerIndex), mX(x), mY(y) {}
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
+ if (mPointerIndex >= event.getPointerCount()) {
+ *os << "Pointer index " << mPointerIndex << " is out of bounds";
+ return false;
+ }
+
+ bool matches = mX == event.getX(mPointerIndex) && mY == event.getY(mPointerIndex);
+ if (!matches) {
+ *os << "expected coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex
+ << ", but got (" << event.getX(mPointerIndex) << ", " << event.getY(mPointerIndex)
+ << ")";
+ }
+ return matches;
+ }
+
+ bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
+ if (mPointerIndex >= event.pointerCoords.size()) {
+ *os << "Pointer index " << mPointerIndex << " is out of bounds";
+ return false;
+ }
+
+ bool matches = mX == event.pointerCoords[mPointerIndex].getX() &&
+ mY == event.pointerCoords[mPointerIndex].getY();
+ if (!matches) {
+ *os << "expected coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex
+ << ", but got (" << event.pointerCoords[mPointerIndex].getX() << ", "
+ << event.pointerCoords[mPointerIndex].getY() << ")";
+ }
+ return matches;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with coords (" << mX << ", " << mY << ") at pointer index " << mPointerIndex;
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong coords"; }
+
+private:
+ const size_t mPointerIndex;
+ const float mX;
+ const float mY;
+};
+
+inline WithCoordsMatcher WithCoords(float x, float y) {
+ return WithCoordsMatcher(0, x, y);
+}
+
+inline WithCoordsMatcher WithPointerCoords(size_t pointerIndex, float x, float y) {
+ return WithCoordsMatcher(pointerIndex, x, y);
+}
+
+/// Raw coordinate matcher
+class WithRawCoordsMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithRawCoordsMatcher(size_t pointerIndex, float rawX, float rawY)
+ : mPointerIndex(pointerIndex), mRawX(rawX), mRawY(rawY) {}
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
+ if (mPointerIndex >= event.getPointerCount()) {
+ *os << "Pointer index " << mPointerIndex << " is out of bounds";
+ return false;
+ }
+
+ bool matches =
+ mRawX == event.getRawX(mPointerIndex) && mRawY == event.getRawY(mPointerIndex);
+ if (!matches) {
+ *os << "expected raw coords (" << mRawX << ", " << mRawY << ") at pointer index "
+ << mPointerIndex << ", but got (" << event.getRawX(mPointerIndex) << ", "
+ << event.getRawY(mPointerIndex) << ")";
+ }
+ return matches;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with raw coords (" << mRawX << ", " << mRawY << ") at pointer index "
+ << mPointerIndex;
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong raw coords"; }
+
+private:
+ const size_t mPointerIndex;
+ const float mRawX;
+ const float mRawY;
+};
+
+inline WithRawCoordsMatcher WithRawCoords(float rawX, float rawY) {
+ return WithRawCoordsMatcher(0, rawX, rawY);
+}
+
+inline WithRawCoordsMatcher WithPointerRawCoords(size_t pointerIndex, float rawX, float rawY) {
+ return WithRawCoordsMatcher(pointerIndex, rawX, rawY);
+}
+
+/// Pointer count
+class WithPointerCountMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithPointerCountMatcher(size_t pointerCount) : mPointerCount(pointerCount) {}
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
+ if (event.getPointerCount() != mPointerCount) {
+ *os << "expected pointer count " << mPointerCount << ", but got "
+ << event.getPointerCount();
+ return false;
+ }
+ return true;
+ }
+
+ bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
+ if (event.pointerCoords.size() != mPointerCount) {
+ *os << "expected pointer count " << mPointerCount << ", but got "
+ << event.pointerCoords.size();
+ return false;
+ }
+ return true;
+ }
+
+ void DescribeTo(std::ostream* os) const { *os << "with pointer count " << mPointerCount; }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointer count"; }
+
+private:
+ const size_t mPointerCount;
+};
+
+inline WithPointerCountMatcher WithPointerCount(size_t pointerCount) {
+ return WithPointerCountMatcher(pointerCount);
+}
+
+/// Pointers matcher
+class WithPointersMatcher {
+public:
+ using is_gtest_matcher = void;
+ explicit WithPointersMatcher(std::map<int32_t, PointF> pointers) : mPointers(pointers) {}
+
+ bool MatchAndExplain(const MotionEvent& event, std::ostream* os) const {
+ std::map<int32_t, PointF> actualPointers;
+ for (size_t pointerIndex = 0; pointerIndex < event.getPointerCount(); pointerIndex++) {
+ const int32_t pointerId = event.getPointerId(pointerIndex);
+ actualPointers[pointerId] = {event.getX(pointerIndex), event.getY(pointerIndex)};
+ }
+
+ if (mPointers != actualPointers) {
+ *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
+ << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
+ return false;
+ }
+ return true;
+ }
+
+ bool MatchAndExplain(const NotifyMotionArgs& event, std::ostream* os) const {
+ std::map<int32_t, PointF> actualPointers;
+ for (size_t pointerIndex = 0; pointerIndex < event.pointerCoords.size(); pointerIndex++) {
+ const int32_t pointerId = event.pointerProperties[pointerIndex].id;
+ actualPointers[pointerId] = {event.pointerCoords[pointerIndex].getX(),
+ event.pointerCoords[pointerIndex].getY()};
+ }
+
+ if (mPointers != actualPointers) {
+ *os << "expected pointers " << dumpMap(mPointers, constToString, pointFToString)
+ << ", but got " << dumpMap(actualPointers, constToString, pointFToString);
+ return false;
+ }
+ return true;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "with pointers " << dumpMap(mPointers, constToString, pointFToString);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const { *os << "wrong pointers"; }
+
+private:
+ const std::map<int32_t, PointF> mPointers;
+};
+
+inline WithPointersMatcher WithPointers(
+ const std::map<int32_t /*id*/, PointF /*coords*/>& pointers) {
+ return WithPointersMatcher(pointers);
+}
+
+MATCHER_P(WithKeyCode, keyCode, "KeyEvent with specified key code") {
+ *result_listener << "expected key code " << keyCode << ", but got " << arg.keyCode;
+ return arg.keyCode == keyCode;
+}
+
+MATCHER_P(WithRepeatCount, repeatCount, "KeyEvent with specified repeat count") {
+ 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;
+}
+
+MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
+ const auto argX = arg.xCursorPosition;
+ const auto argY = arg.yCursorPosition;
+ *result_listener << "expected cursor position (" << x << ", " << y << "), but got (" << argX
+ << ", " << argY << ")";
+ return (isnan(x) ? isnan(argX) : x == argX) && (isnan(y) ? isnan(argY) : y == argY);
+}
+
+MATCHER_P2(WithRelativeMotion, x, y, "InputEvent with specified relative motion") {
+ const auto argX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
+ const auto argY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
+ *result_listener << "expected relative motion (" << x << ", " << y << "), but got (" << argX
+ << ", " << argY << ")";
+ return argX == x && argY == y;
+}
+
+MATCHER_P3(WithGestureOffset, dx, dy, epsilon,
+ "InputEvent with specified touchpad gesture offset") {
+ const auto argGestureX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET);
+ const auto argGestureY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET);
+ const double xDiff = fabs(argGestureX - dx);
+ const double yDiff = fabs(argGestureY - dy);
+ *result_listener << "expected gesture offset (" << dx << ", " << dy << ") within " << epsilon
+ << ", but got (" << argGestureX << ", " << argGestureY << ")";
+ return xDiff <= epsilon && yDiff <= epsilon;
+}
+
+MATCHER_P3(WithGestureScrollDistance, x, y, epsilon,
+ "InputEvent with specified touchpad gesture scroll distance") {
+ const auto argXDistance =
+ arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE);
+ const auto argYDistance =
+ arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE);
+ const double xDiff = fabs(argXDistance - x);
+ const double yDiff = fabs(argYDistance - y);
+ *result_listener << "expected gesture offset (" << x << ", " << y << ") within " << epsilon
+ << ", but got (" << argXDistance << ", " << argYDistance << ")";
+ return xDiff <= epsilon && yDiff <= epsilon;
+}
+
+MATCHER_P2(WithGesturePinchScaleFactor, factor, epsilon,
+ "InputEvent with specified touchpad pinch gesture scale factor") {
+ const auto argScaleFactor =
+ arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR);
+ *result_listener << "expected gesture scale factor " << factor << " within " << epsilon
+ << " but got " << argScaleFactor;
+ return fabs(argScaleFactor - factor) <= epsilon;
+}
+
+MATCHER_P(WithGestureSwipeFingerCount, count,
+ "InputEvent with specified touchpad swipe finger count") {
+ const auto argFingerCount =
+ arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SWIPE_FINGER_COUNT);
+ *result_listener << "expected gesture swipe finger count " << count << " but got "
+ << argFingerCount;
+ return fabs(argFingerCount - count) <= EPSILON;
+}
+
+MATCHER_P(WithPressure, pressure, "InputEvent with specified pressure") {
+ const auto argPressure = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
+ *result_listener << "expected pressure " << pressure << ", but got " << argPressure;
+ return argPressure == pressure;
+}
+
+MATCHER_P2(WithTouchDimensions, maj, min, "InputEvent with specified touch dimensions") {
+ const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
+ const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
+ *result_listener << "expected touch dimensions " << maj << " major x " << min
+ << " minor, but got " << argMajor << " major x " << argMinor << " minor";
+ return argMajor == maj && argMinor == min;
+}
+
+MATCHER_P2(WithToolDimensions, maj, min, "InputEvent with specified tool dimensions") {
+ const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR);
+ const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR);
+ *result_listener << "expected tool dimensions " << maj << " major x " << min
+ << " minor, but got " << argMajor << " major x " << argMinor << " minor";
+ return argMajor == maj && argMinor == min;
+}
+
+MATCHER_P(WithToolType, toolType, "InputEvent with specified tool type") {
+ const auto argToolType = arg.pointerProperties[0].toolType;
+ *result_listener << "expected tool type " << ftl::enum_string(toolType) << ", but got "
+ << ftl::enum_string(argToolType);
+ return argToolType == toolType;
+}
+
+MATCHER_P2(WithPointerToolType, pointer, toolType,
+ "InputEvent with specified tool type for pointer") {
+ const auto argToolType = arg.pointerProperties[pointer].toolType;
+ *result_listener << "expected pointer " << pointer << " to have tool type "
+ << ftl::enum_string(toolType) << ", but got " << ftl::enum_string(argToolType);
+ return argToolType == toolType;
+}
+
+MATCHER_P(WithMotionClassification, classification,
+ "InputEvent with specified MotionClassification") {
+ *result_listener << "expected classification " << motionClassificationToString(classification)
+ << ", but got " << motionClassificationToString(arg.classification);
+ return arg.classification == classification;
+}
+
+MATCHER_P(WithButtonState, buttons, "InputEvent with specified button state") {
+ *result_listener << "expected button state " << buttons << ", but got " << arg.buttonState;
+ return arg.buttonState == buttons;
+}
+
+MATCHER_P(WithActionButton, actionButton, "InputEvent with specified action button") {
+ *result_listener << "expected action button " << actionButton << ", but got "
+ << arg.actionButton;
+ return arg.actionButton == actionButton;
+}
+
+MATCHER_P(WithEventTime, eventTime, "InputEvent with specified eventTime") {
+ *result_listener << "expected event time " << eventTime << ", but got " << arg.eventTime;
+ return arg.eventTime == eventTime;
+}
+
+MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") {
+ *result_listener << "expected down time " << downTime << ", but got " << arg.downTime;
+ return arg.downTime == downTime;
+}
+
+MATCHER_P2(WithPrecision, xPrecision, yPrecision, "MotionEvent with specified precision") {
+ *result_listener << "expected x-precision " << xPrecision << " and y-precision " << yPrecision
+ << ", but got " << arg.xPrecision << " and " << arg.yPrecision;
+ return arg.xPrecision == xPrecision && arg.yPrecision == yPrecision;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/TestInputListenerMatchers.cpp b/services/inputflinger/tests/TestInputListenerMatchers.cpp
deleted file mode 100644
index 1464e60..0000000
--- a/services/inputflinger/tests/TestInputListenerMatchers.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2023 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 "TestInputListenerMatchers.h"
-
-namespace android {
-
-WithKeyActionMatcher WithKeyAction(int32_t action) {
- return WithKeyActionMatcher(action);
-}
-
-WithMotionActionMatcher WithMotionAction(int32_t action) {
- return WithMotionActionMatcher(action);
-}
-
-WithDisplayIdMatcher WithDisplayId(int32_t displayId) {
- return WithDisplayIdMatcher(displayId);
-}
-
-WithDeviceIdMatcher WithDeviceId(int32_t deviceId) {
- return WithDeviceIdMatcher(deviceId);
-}
-
-} // namespace android
diff --git a/services/inputflinger/tests/TestInputListenerMatchers.h b/services/inputflinger/tests/TestInputListenerMatchers.h
deleted file mode 100644
index 31ad569..0000000
--- a/services/inputflinger/tests/TestInputListenerMatchers.h
+++ /dev/null
@@ -1,330 +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.
- */
-
-#pragma once
-
-#include <cmath>
-
-#include <android/input.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <input/Input.h>
-
-#include "NotifyArgs.h"
-#include "TestConstants.h"
-
-namespace android {
-
-MATCHER_P(WithSource, source, "InputEvent with specified source") {
- *result_listener << "expected source " << inputEventSourceToString(source) << ", but got "
- << inputEventSourceToString(arg.source);
- return arg.source == source;
-}
-
-/// Key action
-class WithKeyActionMatcher {
-public:
- using is_gtest_matcher = void;
- explicit WithKeyActionMatcher(int32_t action) : mAction(action) {}
-
- bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
- return mAction == args.action;
- }
-
- bool MatchAndExplain(const KeyEvent& event, std::ostream*) const {
- return mAction == event.getAction();
- }
-
- void DescribeTo(std::ostream* os) const {
- *os << "with key action " << KeyEvent::actionToString(mAction);
- }
-
- void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
-
-private:
- const int32_t mAction;
-};
-
-WithKeyActionMatcher WithKeyAction(int32_t action);
-
-/// Motion action
-class WithMotionActionMatcher {
-public:
- using is_gtest_matcher = void;
- explicit WithMotionActionMatcher(int32_t action) : mAction(action) {}
-
- bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
- bool matches = mAction == args.action;
- if (args.action == AMOTION_EVENT_ACTION_CANCEL) {
- matches &= (args.flags & AMOTION_EVENT_FLAG_CANCELED) != 0;
- }
- return matches;
- }
-
- bool MatchAndExplain(const MotionEvent& event, std::ostream*) const {
- bool matches = mAction == event.getAction();
- if (event.getAction() == AMOTION_EVENT_ACTION_CANCEL) {
- matches &= (event.getFlags() & AMOTION_EVENT_FLAG_CANCELED) != 0;
- }
- return matches;
- }
-
- void DescribeTo(std::ostream* os) const {
- *os << "with motion action " << MotionEvent::actionToString(mAction);
- if (mAction == AMOTION_EVENT_ACTION_CANCEL) {
- *os << " and FLAG_CANCELED";
- }
- }
-
- void DescribeNegationTo(std::ostream* os) const { *os << "wrong action"; }
-
-private:
- const int32_t mAction;
-};
-
-WithMotionActionMatcher WithMotionAction(int32_t action);
-
-/// Display Id
-class WithDisplayIdMatcher {
-public:
- using is_gtest_matcher = void;
- explicit WithDisplayIdMatcher(int32_t displayId) : mDisplayId(displayId) {}
-
- bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
- return mDisplayId == args.displayId;
- }
-
- bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
- return mDisplayId == args.displayId;
- }
-
- bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
- return mDisplayId == event.getDisplayId();
- }
-
- void DescribeTo(std::ostream* os) const { *os << "with display id " << mDisplayId; }
-
- void DescribeNegationTo(std::ostream* os) const { *os << "wrong display id"; }
-
-private:
- const int32_t mDisplayId;
-};
-
-WithDisplayIdMatcher WithDisplayId(int32_t displayId);
-
-/// Device Id
-class WithDeviceIdMatcher {
-public:
- using is_gtest_matcher = void;
- explicit WithDeviceIdMatcher(int32_t deviceId) : mDeviceId(deviceId) {}
-
- bool MatchAndExplain(const NotifyMotionArgs& args, std::ostream*) const {
- return mDeviceId == args.deviceId;
- }
-
- bool MatchAndExplain(const NotifyKeyArgs& args, std::ostream*) const {
- return mDeviceId == args.deviceId;
- }
-
- bool MatchAndExplain(const NotifyDeviceResetArgs& args, std::ostream*) const {
- return mDeviceId == args.deviceId;
- }
-
- bool MatchAndExplain(const InputEvent& event, std::ostream*) const {
- return mDeviceId == event.getDeviceId();
- }
-
- void DescribeTo(std::ostream* os) const { *os << "with device id " << mDeviceId; }
-
- void DescribeNegationTo(std::ostream* os) const { *os << "wrong device id"; }
-
-private:
- const int32_t mDeviceId;
-};
-
-WithDeviceIdMatcher WithDeviceId(int32_t deviceId);
-
-MATCHER_P(WithKeyCode, keyCode, "KeyEvent with specified key code") {
- *result_listener << "expected key code " << keyCode << ", but got " << arg.keyCode;
- return arg.keyCode == keyCode;
-}
-
-MATCHER_P(WithRepeatCount, repeatCount, "KeyEvent with specified repeat count") {
- return arg.getRepeatCount() == repeatCount;
-}
-
-MATCHER_P(WithPointerCount, count, "MotionEvent with specified number of pointers") {
- *result_listener << "expected " << count << " pointer(s), but got " << arg.getPointerCount();
- return arg.getPointerCount() == count;
-}
-
-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;
-}
-
-MATCHER_P2(WithCoords, x, y, "InputEvent with specified coords") {
- const auto argX = arg.pointerCoords[0].getX();
- const auto argY = arg.pointerCoords[0].getY();
- *result_listener << "expected coords (" << x << ", " << y << "), but got (" << argX << ", "
- << argY << ")";
- return argX == x && argY == y;
-}
-
-MATCHER_P2(WithCursorPosition, x, y, "InputEvent with specified cursor position") {
- const auto argX = arg.xCursorPosition;
- const auto argY = arg.yCursorPosition;
- *result_listener << "expected cursor position (" << x << ", " << y << "), but got (" << argX
- << ", " << argY << ")";
- return (isnan(x) ? isnan(argX) : x == argX) && (isnan(y) ? isnan(argY) : y == argY);
-}
-
-MATCHER_P3(WithPointerCoords, pointer, x, y, "InputEvent with specified coords for pointer") {
- const auto argX = arg.pointerCoords[pointer].getX();
- const auto argY = arg.pointerCoords[pointer].getY();
- *result_listener << "expected pointer " << pointer << " to have coords (" << x << ", " << y
- << "), but got (" << argX << ", " << argY << ")";
- return argX == x && argY == y;
-}
-
-MATCHER_P2(WithRelativeMotion, x, y, "InputEvent with specified relative motion") {
- const auto argX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X);
- const auto argY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y);
- *result_listener << "expected relative motion (" << x << ", " << y << "), but got (" << argX
- << ", " << argY << ")";
- return argX == x && argY == y;
-}
-
-MATCHER_P3(WithGestureOffset, dx, dy, epsilon,
- "InputEvent with specified touchpad gesture offset") {
- const auto argGestureX = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_X_OFFSET);
- const auto argGestureY = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_Y_OFFSET);
- const double xDiff = fabs(argGestureX - dx);
- const double yDiff = fabs(argGestureY - dy);
- *result_listener << "expected gesture offset (" << dx << ", " << dy << ") within " << epsilon
- << ", but got (" << argGestureX << ", " << argGestureY << ")";
- return xDiff <= epsilon && yDiff <= epsilon;
-}
-
-MATCHER_P3(WithGestureScrollDistance, x, y, epsilon,
- "InputEvent with specified touchpad gesture scroll distance") {
- const auto argXDistance =
- arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_X_DISTANCE);
- const auto argYDistance =
- arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SCROLL_Y_DISTANCE);
- const double xDiff = fabs(argXDistance - x);
- const double yDiff = fabs(argYDistance - y);
- *result_listener << "expected gesture offset (" << x << ", " << y << ") within " << epsilon
- << ", but got (" << argXDistance << ", " << argYDistance << ")";
- return xDiff <= epsilon && yDiff <= epsilon;
-}
-
-MATCHER_P2(WithGesturePinchScaleFactor, factor, epsilon,
- "InputEvent with specified touchpad pinch gesture scale factor") {
- const auto argScaleFactor =
- arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_PINCH_SCALE_FACTOR);
- *result_listener << "expected gesture scale factor " << factor << " within " << epsilon
- << " but got " << argScaleFactor;
- return fabs(argScaleFactor - factor) <= epsilon;
-}
-
-MATCHER_P(WithGestureSwipeFingerCount, count,
- "InputEvent with specified touchpad swipe finger count") {
- const auto argFingerCount =
- arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_GESTURE_SWIPE_FINGER_COUNT);
- *result_listener << "expected gesture swipe finger count " << count << " but got "
- << argFingerCount;
- return fabs(argFingerCount - count) <= EPSILON;
-}
-
-MATCHER_P(WithPressure, pressure, "InputEvent with specified pressure") {
- const auto argPressure = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE);
- *result_listener << "expected pressure " << pressure << ", but got " << argPressure;
- return argPressure == pressure;
-}
-
-MATCHER_P2(WithTouchDimensions, maj, min, "InputEvent with specified touch dimensions") {
- const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR);
- const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR);
- *result_listener << "expected touch dimensions " << maj << " major x " << min
- << " minor, but got " << argMajor << " major x " << argMinor << " minor";
- return argMajor == maj && argMinor == min;
-}
-
-MATCHER_P2(WithToolDimensions, maj, min, "InputEvent with specified tool dimensions") {
- const auto argMajor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR);
- const auto argMinor = arg.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR);
- *result_listener << "expected tool dimensions " << maj << " major x " << min
- << " minor, but got " << argMajor << " major x " << argMinor << " minor";
- return argMajor == maj && argMinor == min;
-}
-
-MATCHER_P(WithToolType, toolType, "InputEvent with specified tool type") {
- const auto argToolType = arg.pointerProperties[0].toolType;
- *result_listener << "expected tool type " << ftl::enum_string(toolType) << ", but got "
- << ftl::enum_string(argToolType);
- return argToolType == toolType;
-}
-
-MATCHER_P2(WithPointerToolType, pointer, toolType,
- "InputEvent with specified tool type for pointer") {
- const auto argToolType = arg.pointerProperties[pointer].toolType;
- *result_listener << "expected pointer " << pointer << " to have tool type "
- << ftl::enum_string(toolType) << ", but got " << ftl::enum_string(argToolType);
- return argToolType == toolType;
-}
-
-MATCHER_P(WithFlags, flags, "InputEvent with specified flags") {
- *result_listener << "expected flags " << flags << ", but got " << arg.flags;
- return arg.flags == static_cast<int32_t>(flags);
-}
-
-MATCHER_P(WithMotionClassification, classification,
- "InputEvent with specified MotionClassification") {
- *result_listener << "expected classification " << motionClassificationToString(classification)
- << ", but got " << motionClassificationToString(arg.classification);
- return arg.classification == classification;
-}
-
-MATCHER_P(WithButtonState, buttons, "InputEvent with specified button state") {
- *result_listener << "expected button state " << buttons << ", but got " << arg.buttonState;
- return arg.buttonState == buttons;
-}
-
-MATCHER_P(WithActionButton, actionButton, "InputEvent with specified action button") {
- *result_listener << "expected action button " << actionButton << ", but got "
- << arg.actionButton;
- return arg.actionButton == actionButton;
-}
-
-MATCHER_P(WithEventTime, eventTime, "InputEvent with specified eventTime") {
- *result_listener << "expected event time " << eventTime << ", but got " << arg.eventTime;
- return arg.eventTime == eventTime;
-}
-
-MATCHER_P(WithDownTime, downTime, "InputEvent with specified downTime") {
- *result_listener << "expected down time " << downTime << ", but got " << arg.downTime;
- return arg.downTime == downTime;
-}
-
-MATCHER_P2(WithPrecision, xPrecision, yPrecision, "MotionEvent with specified precision") {
- *result_listener << "expected x-precision " << xPrecision << " and y-precision " << yPrecision
- << ", but got " << arg.xPrecision << " and " << arg.yPrecision;
- return arg.xPrecision == xPrecision && arg.yPrecision == yPrecision;
-}
-
-} // namespace android
diff --git a/services/inputflinger/tests/TouchpadInputMapper_test.cpp b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
index 02abf9f..6203a1d 100644
--- a/services/inputflinger/tests/TouchpadInputMapper_test.cpp
+++ b/services/inputflinger/tests/TouchpadInputMapper_test.cpp
@@ -23,7 +23,7 @@
#include "FakePointerController.h"
#include "InputMapperTest.h"
#include "InterfaceMocks.h"
-#include "TestInputListenerMatchers.h"
+#include "TestEventMatchers.h"
#define TAG "TouchpadInputMapper_test"
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 7cfcf71..78f7291 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -23,8 +23,8 @@
#include <thread>
#include "ui/events/ozone/evdev/touch_filter/neural_stylus_palm_detection_filter.h"
+#include "TestEventMatchers.h"
#include "TestInputListener.h"
-#include "TestInputListenerMatchers.h"
using ::testing::AllOf;
diff --git a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
index 72780fb..6daeaaf 100644
--- a/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
+++ b/services/inputflinger/tests/fuzzers/LatencyTrackerFuzzer.cpp
@@ -15,6 +15,9 @@
*/
#include <fuzzer/FuzzedDataProvider.h>
+#include <linux/input.h>
+
+#include "../../InputDeviceMetricsSource.h"
#include "dispatcher/LatencyTracker.h"
namespace android {
@@ -65,7 +68,11 @@
int32_t isDown = fdp.ConsumeBool();
nsecs_t eventTime = fdp.ConsumeIntegral<nsecs_t>();
nsecs_t readTime = fdp.ConsumeIntegral<nsecs_t>();
- tracker.trackListener(inputEventId, isDown, eventTime, readTime);
+ const DeviceId deviceId = fdp.ConsumeIntegral<int32_t>();
+ std::set<InputDeviceUsageSource> sources = {
+ fdp.ConsumeEnum<InputDeviceUsageSource>()};
+ tracker.trackListener(inputEventId, isDown, eventTime, readTime, deviceId,
+ sources);
},
[&]() -> void {
int32_t inputEventId = fdp.ConsumeIntegral<int32_t>();
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 71c75f9..9d0f285 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -31,9 +31,6 @@
"-Wconversion",
"-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
- static_libs: [
- "libsurfaceflingerflags",
- ],
}
cc_defaults {
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
index 2dc7332..370e4b6 100644
--- a/services/surfaceflinger/CompositionEngine/Android.bp
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -63,6 +63,7 @@
cc_library {
name: "libcompositionengine",
defaults: ["libcompositionengine_defaults"],
+ static_libs: ["libsurfaceflingerflags"],
srcs: [
"src/planner/CachedSet.cpp",
"src/planner/Flattener.cpp",
@@ -107,6 +108,7 @@
"libgtest",
"libgmock",
"libcompositionengine",
+ "libsurfaceflingerflags_test",
],
local_include_dirs: ["include"],
export_include_dirs: ["include"],
@@ -141,6 +143,7 @@
"librenderengine_mocks",
"libgmock",
"libgtest",
+ "libsurfaceflingerflags_test",
],
// For some reason, libvulkan isn't picked up from librenderengine
// Probably ASAN related?
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 03c0993..4db2b66 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -731,6 +731,10 @@
: parentSnapshot.outputFilter.layerStack;
}
+ if (forceUpdate || snapshot.clientChanges & layer_state_t::eTrustedOverlayChanged) {
+ snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
+ }
+
if (snapshot.isHiddenByPolicyFromParent &&
!snapshot.changes.test(RequestedLayerState::Changes::Created)) {
if (forceUpdate ||
@@ -761,10 +765,6 @@
(requested.flags & layer_state_t::eLayerSkipScreenshot);
}
- if (forceUpdate || snapshot.clientChanges & layer_state_t::eTrustedOverlayChanged) {
- snapshot.isTrustedOverlay = parentSnapshot.isTrustedOverlay || requested.isTrustedOverlay;
- }
-
if (forceUpdate || snapshot.clientChanges & layer_state_t::eStretchChanged) {
snapshot.stretchEffect = (requested.stretchEffect.hasEffect())
? requested.stretchEffect
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index 48a9190..f25619a 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -247,10 +247,13 @@
layerSettings.frameNumber = mSnapshot->frameNumber;
layerSettings.bufferId = mSnapshot->externalTexture->getId();
+ const bool useFiltering = targetSettings.needsFiltering ||
+ mSnapshot->geomLayerTransform.needsBilinearFiltering();
+
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
getDrawingTransformMatrix(layerSettings.source.buffer.buffer, mSnapshot->geomContentCrop,
- mSnapshot->geomBufferTransform, targetSettings.needsFiltering,
+ mSnapshot->geomBufferTransform, useFiltering,
textureMatrix);
if (mSnapshot->geomBufferUsesDisplayInverseTransform) {
@@ -301,7 +304,7 @@
mat4::translate(vec4(translateX, translateY, 0.f, 1.f)) *
mat4::scale(vec4(scaleWidth, scaleHeight, 1.0f, 1.0f));
- layerSettings.source.buffer.useTextureFiltering = targetSettings.needsFiltering;
+ layerSettings.source.buffer.useTextureFiltering = useFiltering;
layerSettings.source.buffer.textureTransform =
mat4(static_cast<const float*>(textureMatrix)) * tr;
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 1f922f1..c4c9fa5 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -28,10 +28,13 @@
#include "VSyncDispatchTimerQueue.h"
#include "VSyncTracker.h"
+#include <com_android_graphics_surfaceflinger_flags.h>
+
#undef LOG_TAG
#define LOG_TAG "VSyncDispatch"
namespace android::scheduler {
+using namespace com::android::graphics::surfaceflinger;
using base::StringAppendF;
@@ -100,8 +103,14 @@
mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
bool const wouldSkipAWakeup =
mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance)));
- if (wouldSkipAVsyncTarget && wouldSkipAWakeup) {
- return getExpectedCallbackTime(nextVsyncTime, timing);
+ if (flags::dont_skip_on_early()) {
+ if (wouldSkipAVsyncTarget || wouldSkipAWakeup) {
+ return getExpectedCallbackTime(mArmedInfo->mActualVsyncTime, timing);
+ }
+ } else {
+ if (wouldSkipAVsyncTarget && wouldSkipAWakeup) {
+ return getExpectedCallbackTime(nextVsyncTime, timing);
+ }
}
nextVsyncTime = adjustVsyncIfNeeded(tracker, nextVsyncTime);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 2b70301..e08690a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1047,6 +1047,7 @@
const auto peakFps = mode->getPeakFps();
outMode.refreshRate = peakFps.getValue();
+ outMode.vsyncRate = mode->getVsyncRate().getValue();
const auto vsyncConfigSet =
mVsyncConfiguration->getConfigsForRefreshRate(Fps::fromValue(outMode.refreshRate));
@@ -6446,6 +6447,8 @@
mMisc2FlagEarlyBootValue == mMisc2FlagLateBootValue ? "stable" : "modified");
StringAppendF(&result, "VrrConfigFlagValue: %s\n",
flagutils::vrrConfigEnabled() ? "true" : "false");
+ StringAppendF(&result, "DontSkipOnEarlyFlagValue: %s\n",
+ flags::dont_skip_on_early() ? "true" : "false");
getRenderEngine().dump(result);
@@ -9187,6 +9190,7 @@
outMode.xDpi = mode.xDpi;
outMode.yDpi = mode.yDpi;
outMode.refreshRate = mode.refreshRate;
+ outMode.vsyncRate = mode.vsyncRate;
outMode.appVsyncOffset = mode.appVsyncOffset;
outMode.sfVsyncOffset = mode.sfVsyncOffset;
outMode.presentationDeadline = mode.presentationDeadline;
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index 2f5a360..a8727f9 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -182,8 +182,9 @@
uint16_t now = mFdp.ConsumeIntegral<uint16_t>();
uint16_t historySize = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
uint16_t minimumSamplesForPrediction = mFdp.ConsumeIntegralInRange<uint16_t>(1, UINT16_MAX);
- scheduler::VSyncPredictor tracker{kDisplayId, mFdp.ConsumeIntegral<uint16_t>() /*period*/,
- historySize, minimumSamplesForPrediction,
+ nsecs_t idealPeriod = mFdp.ConsumeIntegralInRange<nsecs_t>(1, UINT32_MAX);
+ scheduler::VSyncPredictor tracker{kDisplayId, idealPeriod, historySize,
+ minimumSamplesForPrediction,
mFdp.ConsumeIntegral<uint32_t>() /*outlierTolerancePercent*/};
uint16_t period = mFdp.ConsumeIntegral<uint16_t>();
tracker.setPeriod(period);
diff --git a/services/surfaceflinger/surfaceflinger_flags.aconfig b/services/surfaceflinger/surfaceflinger_flags.aconfig
index fedf08b..5a277bd 100644
--- a/services/surfaceflinger/surfaceflinger_flags.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags.aconfig
@@ -12,7 +12,7 @@
name: "connected_display"
namespace: "core_graphics"
description: "Controls SurfaceFlinger support for Connected Displays in 24Q1"
- bug: "299486625"
+ bug: "278199093"
is_fixed_read_only: true
}
@@ -38,3 +38,18 @@
bug: "283055450"
is_fixed_read_only: true
}
+
+flag {
+ name: "dont_skip_on_early"
+ namespace: "core_graphics"
+ description: "This flag is guarding the behaviour where SurfaceFlinger is trying to opportunistically present a frame when the configuration change from late to early"
+ bug: "273702768"
+}
+
+flag {
+ name: "multithreaded_present"
+ namespace: "core_graphics"
+ description: "Controls whether to offload present calls to another thread"
+ bug: "259132483"
+ is_fixed_read_only: true
+}
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 36b1972..5888a55 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -32,7 +32,6 @@
"BootDisplayMode_test.cpp",
"Binder_test.cpp",
"BufferGenerator.cpp",
- "CommonTypes_test.cpp",
"Credentials_test.cpp",
"DereferenceSurfaceControl_test.cpp",
"DisplayConfigs_test.cpp",
@@ -67,6 +66,7 @@
static_libs: [
"liblayers_proto",
"android.hardware.graphics.composer@2.1",
+ "libsurfaceflingerflags",
],
shared_libs: [
"android.hardware.graphics.common@1.2",
diff --git a/services/surfaceflinger/tests/BootDisplayMode_test.cpp b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
index f2874ae..4f41a81 100644
--- a/services/surfaceflinger/tests/BootDisplayMode_test.cpp
+++ b/services/surfaceflinger/tests/BootDisplayMode_test.cpp
@@ -28,33 +28,95 @@
using gui::aidl_utils::statusTFromBinderStatus;
-TEST(BootDisplayModeTest, setBootDisplayMode) {
- sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
+struct BootDisplayModeTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ mSf = ComposerServiceAIDL::getComposerService();
- const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
- ASSERT_FALSE(ids.empty());
- auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
- bool bootModeSupport = false;
- binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
- ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
- if (bootModeSupport) {
- status = sf->setBootDisplayMode(displayToken, 0);
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
+ bool bootModeSupport = false;
+ binder::Status status = mSf->getBootDisplayModeSupport(&bootModeSupport);
+ ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
+
+ if (!bootModeSupport) {
+ GTEST_SKIP() << "Boot mode not supported";
+ }
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ mOldMode = info.preferredBootDisplayMode;
+ const auto newMode = [&]() -> std::optional<ui::DisplayModeId> {
+ for (const auto& mode : info.supportedDisplayModes) {
+ if (mode.id != mOldMode) {
+ return std::optional(mode.id);
+ }
+ }
+ return std::nullopt;
+ }();
+
+ if (!newMode) {
+ GTEST_SKIP() << "Only a single mode is supported";
+ }
+
+ mNewMode = *newMode;
}
+
+ void TearDown() override {
+ binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mOldMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(mOldMode, info.preferredBootDisplayMode);
+ }
+
+ ui::DisplayModeId mOldMode;
+ ui::DisplayModeId mNewMode;
+ sp<gui::ISurfaceComposer> mSf;
+ sp<IBinder> mDisplayToken;
+};
+
+TEST_F(BootDisplayModeTest, setBootDisplayMode) {
+ // Set a new mode and check that it got applied
+ binder::Status status = mSf->setBootDisplayMode(mDisplayToken, mNewMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(mNewMode, info.preferredBootDisplayMode);
}
-TEST(BootDisplayModeTest, clearBootDisplayMode) {
- sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
- const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
- ASSERT_FALSE(ids.empty());
- auto displayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
- bool bootModeSupport = false;
- binder::Status status = sf->getBootDisplayModeSupport(&bootModeSupport);
- ASSERT_NO_FATAL_FAILURE(statusTFromBinderStatus(status));
- if (bootModeSupport) {
- status = sf->clearBootDisplayMode(displayToken);
- ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
- }
+TEST_F(BootDisplayModeTest, clearBootDisplayMode) {
+ // Clear once to figure out what the system default is
+ binder::Status status = mSf->clearBootDisplayMode(mDisplayToken);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ gui::DynamicDisplayInfo info;
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ const ui::DisplayModeId systemMode = info.preferredBootDisplayMode;
+ const ui::DisplayModeId newMode = systemMode == mOldMode ? mNewMode : mOldMode;
+
+ // Now set a new mode and clear the boot mode again to figure out if the api worked.
+ status = mSf->setBootDisplayMode(mDisplayToken, newMode);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(newMode, info.preferredBootDisplayMode);
+
+ status = mSf->clearBootDisplayMode(mDisplayToken);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+
+ status = mSf->getDynamicDisplayInfoFromToken(mDisplayToken, &info);
+ EXPECT_EQ(NO_ERROR, statusTFromBinderStatus(status));
+ EXPECT_EQ(systemMode, info.preferredBootDisplayMode);
}
} // namespace android
diff --git a/services/surfaceflinger/tests/CommonTypes_test.cpp b/services/surfaceflinger/tests/CommonTypes_test.cpp
deleted file mode 100644
index 25b4615..0000000
--- a/services/surfaceflinger/tests/CommonTypes_test.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2019 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 <aidl/android/hardware/graphics/common/BlendMode.h>
-#include <aidl/android/hardware/graphics/common/Dataspace.h>
-
-#include <android/data_space.h>
-#include <android/hardware/graphics/common/1.2/types.h>
-#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
-
-using AidlBlendMode = aidl::android::hardware::graphics::common::BlendMode;
-using AidlDataspace = aidl::android::hardware::graphics::common::Dataspace;
-
-using HidlBlendMode = android::hardware::graphics::composer::V2_1::IComposerClient::BlendMode;
-using HidlDataspace = android::hardware::graphics::common::V1_2::Dataspace;
-
-static_assert(static_cast<uint32_t>(AidlBlendMode::INVALID) ==
- static_cast<uint32_t>(HidlBlendMode::INVALID));
-static_assert(static_cast<uint32_t>(AidlBlendMode::NONE) ==
- static_cast<uint32_t>(HidlBlendMode::NONE));
-static_assert(static_cast<uint32_t>(AidlBlendMode::PREMULTIPLIED) ==
- static_cast<uint32_t>(HidlBlendMode::PREMULTIPLIED));
-static_assert(static_cast<uint32_t>(AidlBlendMode::COVERAGE) ==
- static_cast<uint32_t>(HidlBlendMode::COVERAGE));
-
-static_assert(static_cast<uint32_t>(ADATASPACE_UNKNOWN) ==
- static_cast<uint32_t>(AidlDataspace::UNKNOWN));
-static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB_LINEAR) ==
- static_cast<uint32_t>(AidlDataspace::SCRGB_LINEAR));
-static_assert(static_cast<uint32_t>(ADATASPACE_SRGB) == static_cast<uint32_t>(AidlDataspace::SRGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB) ==
- static_cast<uint32_t>(AidlDataspace::SCRGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_DISPLAY_P3) ==
- static_cast<uint32_t>(AidlDataspace::DISPLAY_P3));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT2020_PQ) ==
- static_cast<uint32_t>(AidlDataspace::BT2020_PQ));
-static_assert(static_cast<uint32_t>(ADATASPACE_ADOBE_RGB) ==
- static_cast<uint32_t>(AidlDataspace::ADOBE_RGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT2020) ==
- static_cast<uint32_t>(AidlDataspace::BT2020));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT709) ==
- static_cast<uint32_t>(AidlDataspace::BT709));
-static_assert(static_cast<uint32_t>(ADATASPACE_DCI_P3) ==
- static_cast<uint32_t>(AidlDataspace::DCI_P3));
-static_assert(static_cast<uint32_t>(ADATASPACE_SRGB_LINEAR) ==
- static_cast<uint32_t>(AidlDataspace::SRGB_LINEAR));
-
-static_assert(static_cast<uint32_t>(ADATASPACE_UNKNOWN) ==
- static_cast<uint32_t>(HidlDataspace::UNKNOWN));
-static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::V0_SCRGB_LINEAR));
-static_assert(static_cast<uint32_t>(ADATASPACE_SRGB) ==
- static_cast<uint32_t>(HidlDataspace::V0_SRGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_SCRGB) ==
- static_cast<uint32_t>(HidlDataspace::V0_SCRGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_DISPLAY_P3) ==
- static_cast<uint32_t>(HidlDataspace::DISPLAY_P3));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT2020_PQ) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_PQ));
-static_assert(static_cast<uint32_t>(ADATASPACE_ADOBE_RGB) ==
- static_cast<uint32_t>(HidlDataspace::ADOBE_RGB));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT2020) ==
- static_cast<uint32_t>(HidlDataspace::BT2020));
-static_assert(static_cast<uint32_t>(ADATASPACE_BT709) ==
- static_cast<uint32_t>(HidlDataspace::V0_BT709));
-static_assert(static_cast<uint32_t>(ADATASPACE_DCI_P3) ==
- static_cast<uint32_t>(HidlDataspace::DCI_P3));
-static_assert(static_cast<uint32_t>(ADATASPACE_SRGB_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::V0_SRGB_LINEAR));
-
-static_assert(static_cast<uint32_t>(AidlDataspace::UNKNOWN) ==
- static_cast<uint32_t>(HidlDataspace::UNKNOWN));
-static_assert(static_cast<uint32_t>(AidlDataspace::ARBITRARY) ==
- static_cast<uint32_t>(HidlDataspace::ARBITRARY));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_SHIFT) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_SHIFT));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_MASK) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_MASK));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_UNSPECIFIED) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_UNSPECIFIED));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT709) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT709));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT601_625) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT601_625));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT601_625_UNADJUSTED) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT601_625_UNADJUSTED));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT601_525) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT601_525));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT601_525_UNADJUSTED) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT601_525_UNADJUSTED));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT2020) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT2020));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT2020_CONSTANT_LUMINANCE) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT2020_CONSTANT_LUMINANCE));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_BT470M) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_BT470M));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_FILM) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_FILM));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_DCI_P3) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_DCI_P3));
-static_assert(static_cast<uint32_t>(AidlDataspace::STANDARD_ADOBE_RGB) ==
- static_cast<uint32_t>(HidlDataspace::STANDARD_ADOBE_RGB));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_SHIFT) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_SHIFT));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_MASK) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_MASK));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_UNSPECIFIED) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_UNSPECIFIED));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_SRGB) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_SRGB));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_SMPTE_170M) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_SMPTE_170M));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_GAMMA2_2) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_GAMMA2_2));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_GAMMA2_6) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_GAMMA2_6));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_GAMMA2_8) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_GAMMA2_8));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_ST2084) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_ST2084));
-static_assert(static_cast<uint32_t>(AidlDataspace::TRANSFER_HLG) ==
- static_cast<uint32_t>(HidlDataspace::TRANSFER_HLG));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_SHIFT) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_SHIFT));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_MASK) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_MASK));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_UNSPECIFIED) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_UNSPECIFIED));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_FULL) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_FULL));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_LIMITED) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_LIMITED));
-static_assert(static_cast<uint32_t>(AidlDataspace::RANGE_EXTENDED) ==
- static_cast<uint32_t>(HidlDataspace::RANGE_EXTENDED));
-static_assert(static_cast<uint32_t>(AidlDataspace::SRGB_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::V0_SRGB_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::SCRGB_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::V0_SCRGB_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::SRGB) ==
- static_cast<uint32_t>(HidlDataspace::V0_SRGB));
-static_assert(static_cast<uint32_t>(AidlDataspace::SCRGB) ==
- static_cast<uint32_t>(HidlDataspace::V0_SCRGB));
-static_assert(static_cast<uint32_t>(AidlDataspace::JFIF) ==
- static_cast<uint32_t>(HidlDataspace::V0_JFIF));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT601_625) ==
- static_cast<uint32_t>(HidlDataspace::V0_BT601_625));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT601_525) ==
- static_cast<uint32_t>(HidlDataspace::V0_BT601_525));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT709) ==
- static_cast<uint32_t>(HidlDataspace::V0_BT709));
-static_assert(static_cast<uint32_t>(AidlDataspace::DCI_P3_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::DCI_P3_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::DCI_P3) ==
- static_cast<uint32_t>(HidlDataspace::DCI_P3));
-static_assert(static_cast<uint32_t>(AidlDataspace::DISPLAY_P3_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::DISPLAY_P3_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::DISPLAY_P3) ==
- static_cast<uint32_t>(HidlDataspace::DISPLAY_P3));
-static_assert(static_cast<uint32_t>(AidlDataspace::ADOBE_RGB) ==
- static_cast<uint32_t>(HidlDataspace::ADOBE_RGB));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_LINEAR) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_LINEAR));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020) ==
- static_cast<uint32_t>(HidlDataspace::BT2020));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_PQ) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_PQ));
-static_assert(static_cast<uint32_t>(AidlDataspace::DEPTH) ==
- static_cast<uint32_t>(HidlDataspace::DEPTH));
-static_assert(static_cast<uint32_t>(AidlDataspace::SENSOR) ==
- static_cast<uint32_t>(HidlDataspace::SENSOR));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_ITU) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_ITU));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_ITU_PQ) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_ITU_PQ));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_ITU_HLG) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_ITU_HLG));
-static_assert(static_cast<uint32_t>(AidlDataspace::BT2020_HLG) ==
- static_cast<uint32_t>(HidlDataspace::BT2020_HLG));
-static_assert(static_cast<uint32_t>(AidlDataspace::DISPLAY_BT2020) ==
- static_cast<uint32_t>(HidlDataspace::DISPLAY_BT2020));
-static_assert(static_cast<uint32_t>(AidlDataspace::DYNAMIC_DEPTH) ==
- static_cast<uint32_t>(HidlDataspace::DYNAMIC_DEPTH));
-static_assert(static_cast<uint32_t>(AidlDataspace::JPEG_APP_SEGMENTS) ==
- static_cast<uint32_t>(HidlDataspace::JPEG_APP_SEGMENTS));
-static_assert(static_cast<uint32_t>(AidlDataspace::HEIF) ==
- static_cast<uint32_t>(HidlDataspace::HEIF));
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 69e9a16..822ac4d 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -275,18 +275,6 @@
ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, false));
}
-TEST_F(CredentialsTest, CaptureTest) {
- const auto display = getFirstDisplayToken();
- std::function<status_t()> condition = [=]() {
- sp<GraphicBuffer> outBuffer;
- DisplayCaptureArgs captureArgs;
- captureArgs.displayToken = display;
- ScreenCaptureResults captureResults;
- return ScreenCapture::captureDisplay(captureArgs, captureResults);
- };
- ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
-}
-
TEST_F(CredentialsTest, CaptureLayersTest) {
setupBackgroundSurface();
sp<GraphicBuffer> outBuffer;
diff --git a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
index 34c9182..f9b4bba 100644
--- a/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTypeTransaction_test.cpp
@@ -167,18 +167,18 @@
.setFlags(layer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
.apply(true);
- DisplayCaptureArgs args;
- args.displayToken = mDisplay;
+ LayerCaptureArgs args;
+ args.layerHandle = layer->getHandle();
ScreenCaptureResults captureResults;
{
// Ensure the UID is not root because root has all permissions
UIDFaker f(AID_APP_START);
- ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(args, captureResults));
+ ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
}
Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
- ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, captureResults));
+ ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
}
TEST_P(LayerTypeTransactionTest, RefreshRateIsInitialized) {
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index c99809b..ec21eaf 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -42,6 +42,12 @@
],
}
+cc_aconfig_library {
+ name: "libsurfaceflingerflags_test",
+ aconfig_declarations: "surfaceflinger_flags",
+ test: true,
+}
+
cc_test {
name: "libsurfaceflinger_unittest",
defaults: [
@@ -168,6 +174,7 @@
"libtimestats_proto",
"libtonemap",
"perfetto_trace_protos",
+ "libsurfaceflingerflags_test",
],
shared_libs: [
"android.hardware.configstore-utils",
diff --git a/services/surfaceflinger/tests/unittests/FlagUtils.h b/services/surfaceflinger/tests/unittests/FlagUtils.h
new file mode 100644
index 0000000..7103684
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/FlagUtils.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2023 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
+
+#define SET_FLAG_FOR_TEST(name, value) TestFlagSetter _testflag_((name), (name), (value))
+
+namespace android {
+class TestFlagSetter {
+public:
+ TestFlagSetter(bool (*getter)(), void((*setter)(bool)), bool flagValue) {
+ const bool initialValue = getter();
+ setter(flagValue);
+ mResetFlagValue = [=] { setter(initialValue); };
+ }
+
+ ~TestFlagSetter() { mResetFlagValue(); }
+
+private:
+ std::function<void()> mResetFlagValue;
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
index d319dcc..7f3171f 100644
--- a/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
+++ b/services/surfaceflinger/tests/unittests/LayerHierarchyTest.h
@@ -443,6 +443,17 @@
mLifecycleManager.applyTransactions(transactions);
}
+ void setTrustedOverlay(uint32_t id, bool isTrustedOverlay) {
+ 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.isTrustedOverlay = isTrustedOverlay;
+ mLifecycleManager.applyTransactions(transactions);
+ }
+
LayerLifecycleManager mLifecycleManager;
};
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 50dfcaa..fc4bb22 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -861,4 +861,15 @@
EXPECT_EQ(getSnapshot(1)->shadowSettings.length, SHADOW_RADIUS);
}
+TEST_F(LayerSnapshotTest, setTrustedOverlayForNonVisibleInput) {
+ hideLayer(1);
+ setTrustedOverlay(1, true);
+ Region touch{Rect{0, 0, 1000, 1000}};
+ setTouchableRegion(1, touch);
+
+ UPDATE_AND_VERIFY(mSnapshotBuilder, {2});
+ EXPECT_TRUE(getSnapshot(1)->inputInfo.inputConfig.test(
+ gui::WindowInfo::InputConfig::TRUSTED_OVERLAY));
+}
+
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
index 7af1da6..b8fdce1 100644
--- a/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncDispatchTimerQueueTest.cpp
@@ -30,13 +30,17 @@
#include <scheduler/TimeKeeper.h>
+#include "FlagUtils.h"
#include "Scheduler/VSyncDispatchTimerQueue.h"
#include "Scheduler/VSyncTracker.h"
+#include <com_android_graphics_surfaceflinger_flags.h>
+
using namespace testing;
using namespace std::literals;
namespace android::scheduler {
+using namespace com::android::graphics::surfaceflinger;
class MockVSyncTracker : public VSyncTracker {
public:
@@ -1061,6 +1065,48 @@
EXPECT_THAT(cb.mReadyTime[0], Eq(2000));
}
+TEST_F(VSyncDispatchTimerQueueTest, skipAVsyc) {
+ SET_FLAG_FOR_TEST(flags::dont_skip_on_early, false);
+
+ EXPECT_CALL(mMockClock, alarmAt(_, 500));
+ CountingCallback cb(mDispatch);
+ auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ EXPECT_TRUE(result.has_value());
+ EXPECT_EQ(500, *result);
+ mMockClock.advanceBy(300);
+
+ result = mDispatch->schedule(cb,
+ {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ EXPECT_TRUE(result.has_value());
+ EXPECT_EQ(1200, *result);
+
+ advanceToNextCallback();
+ ASSERT_THAT(cb.mCalls.size(), Eq(1));
+}
+
+TEST_F(VSyncDispatchTimerQueueTest, dontskipAVsyc) {
+ SET_FLAG_FOR_TEST(flags::dont_skip_on_early, true);
+
+ EXPECT_CALL(mMockClock, alarmAt(_, 500));
+ CountingCallback cb(mDispatch);
+ auto result =
+ mDispatch->schedule(cb,
+ {.workDuration = 500, .readyDuration = 0, .earliestVsync = 1000});
+ EXPECT_TRUE(result.has_value());
+ EXPECT_EQ(500, *result);
+ mMockClock.advanceBy(300);
+
+ result = mDispatch->schedule(cb,
+ {.workDuration = 800, .readyDuration = 0, .earliestVsync = 1000});
+ EXPECT_TRUE(result.has_value());
+ EXPECT_EQ(200, *result);
+
+ advanceToNextCallback();
+ ASSERT_THAT(cb.mCalls.size(), Eq(1));
+}
+
class VSyncDispatchTimerQueueEntryTest : public testing::Test {
protected:
nsecs_t const mPeriod = 1000;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 9b69438..0c48611 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -16,6 +16,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#include <aidl/android/hardware/graphics/common/Dataspace.h>
#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <android/hardware/graphics/common/1.0/types.h>
#include <android/hardware_buffer.h>
@@ -38,6 +39,7 @@
#include "driver.h"
using PixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
+using DataSpace = aidl::android::hardware::graphics::common::Dataspace;
using android::hardware::graphics::common::V1_0::BufferUsage;
namespace vulkan {
@@ -533,61 +535,51 @@
return native_format;
}
-android_dataspace GetNativeDataspace(VkColorSpaceKHR colorspace,
- PixelFormat pixelFormat) {
+DataSpace GetNativeDataspace(VkColorSpaceKHR colorspace,
+ PixelFormat pixelFormat) {
switch (colorspace) {
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
- return HAL_DATASPACE_V0_SRGB;
+ return DataSpace::SRGB;
case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
- return HAL_DATASPACE_DISPLAY_P3;
+ return DataSpace::DISPLAY_P3;
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
- return HAL_DATASPACE_V0_SCRGB_LINEAR;
+ return DataSpace::SCRGB_LINEAR;
case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
- return HAL_DATASPACE_V0_SCRGB;
+ return DataSpace::SCRGB;
case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
- return HAL_DATASPACE_DCI_P3_LINEAR;
+ return DataSpace::DCI_P3_LINEAR;
case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
- return HAL_DATASPACE_DCI_P3;
+ return DataSpace::DCI_P3;
case VK_COLOR_SPACE_BT709_LINEAR_EXT:
- return HAL_DATASPACE_V0_SRGB_LINEAR;
+ return DataSpace::SRGB_LINEAR;
case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
- return HAL_DATASPACE_V0_SRGB;
+ return DataSpace::SRGB;
case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
if (pixelFormat == PixelFormat::RGBA_FP16) {
- return static_cast<android_dataspace>(
- HAL_DATASPACE_STANDARD_BT2020 |
- HAL_DATASPACE_TRANSFER_LINEAR |
- HAL_DATASPACE_RANGE_EXTENDED);
+ return DataSpace::BT2020_LINEAR_EXTENDED;
} else {
- return HAL_DATASPACE_BT2020_LINEAR;
+ return DataSpace::BT2020_LINEAR;
}
case VK_COLOR_SPACE_HDR10_ST2084_EXT:
- return static_cast<android_dataspace>(
- HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
- HAL_DATASPACE_RANGE_FULL);
+ return DataSpace::BT2020_PQ;
case VK_COLOR_SPACE_DOLBYVISION_EXT:
- return static_cast<android_dataspace>(
- HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_ST2084 |
- HAL_DATASPACE_RANGE_FULL);
+ return DataSpace::BT2020_PQ;
case VK_COLOR_SPACE_HDR10_HLG_EXT:
- return static_cast<android_dataspace>(HAL_DATASPACE_BT2020_HLG);
+ return DataSpace::BT2020_HLG;
case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
- return static_cast<android_dataspace>(
- HAL_DATASPACE_STANDARD_ADOBE_RGB |
- HAL_DATASPACE_TRANSFER_LINEAR | HAL_DATASPACE_RANGE_FULL);
+ return DataSpace::ADOBE_RGB_LINEAR;
case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
- return HAL_DATASPACE_ADOBE_RGB;
-
+ return DataSpace::ADOBE_RGB;
// Pass through is intended to allow app to provide data that is passed
// to the display system without modification.
case VK_COLOR_SPACE_PASS_THROUGH_EXT:
- return HAL_DATASPACE_ARBITRARY;
+ return DataSpace::ARBITRARY;
default:
// This indicates that we don't know about the
// dataspace specified and we should indicate that
// it's unsupported
- return HAL_DATASPACE_UNKNOWN;
+ return DataSpace::UNKNOWN;
}
}
@@ -1575,9 +1567,9 @@
PixelFormat native_pixel_format =
GetNativePixelFormat(create_info->imageFormat);
- android_dataspace native_dataspace =
+ DataSpace native_dataspace =
GetNativeDataspace(create_info->imageColorSpace, native_pixel_format);
- if (native_dataspace == HAL_DATASPACE_UNKNOWN) {
+ if (native_dataspace == DataSpace::UNKNOWN) {
ALOGE(
"CreateSwapchainKHR(VkSwapchainCreateInfoKHR.imageColorSpace = %d) "
"failed: Unsupported color space",
@@ -1683,8 +1675,9 @@
}
/* Respect consumer default dataspace upon HAL_DATASPACE_ARBITRARY. */
- if (native_dataspace != HAL_DATASPACE_ARBITRARY) {
- err = native_window_set_buffers_data_space(window, native_dataspace);
+ if (native_dataspace != DataSpace::ARBITRARY) {
+ err = native_window_set_buffers_data_space(
+ window, static_cast<android_dataspace_t>(native_dataspace));
if (err != android::OK) {
ALOGE("native_window_set_buffers_data_space(%d) failed: %s (%d)",
native_dataspace, strerror(-err), err);